]> source.dussan.org Git - aspectj.git/commitdiff
implement @AspectJ ITD @DeclareParents and @DeclareImplements
authoravasseur <avasseur>
Mon, 17 Oct 2005 10:49:11 +0000 (10:49 +0000)
committeravasseur <avasseur>
Mon, 17 Oct 2005 10:49:11 +0000 (10:49 +0000)
changed AjType as ITD field is meaningless (as @AJ ITD is interface driven)

18 files changed:
aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AjTypeImpl.java
aspectj5rt/java5-src/org/aspectj/lang/annotation/DeclareImplements.java [new file with mode: 0644]
aspectj5rt/java5-src/org/aspectj/lang/annotation/DeclareParents.java
lib/test/aspectjrt.jar
tests/java5/ataspectj/annotationGen/ITDTest.aj
tests/java5/ataspectj/ataspectj/DeclareParentsImplementsTest.java [new file with mode: 0644]
tests/java5/ataspectj/ataspectj/DeclareParentsInterfaceTest.java [new file with mode: 0644]
tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjSyntaxTests.java
tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml
weaver/src/org/aspectj/weaver/AjcMemberMaker.java
weaver/src/org/aspectj/weaver/MethodDelegateTypeMunger.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/ResolvedType.java
weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java
weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java
weaver/src/org/aspectj/weaver/bcel/BcelField.java
weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java
weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java
weaver/src/org/aspectj/weaver/bcel/BcelWorld.java

index ca179ad6d3b9282dec2094bb06c8b1c9215bcc86..747902e3e0ca5658a0bdc6aa7c41387327a44d4a 100644 (file)
@@ -658,42 +658,72 @@ public class AjTypeImpl<T> implements AjType<T> {
        
        private void addAnnotationStyleITDMethods(List<InterTypeMethodDeclaration> toList, boolean publicOnly) {
                if (isAspect()) {
-                       Class<?>[] classes = clazz.getDeclaredClasses();
-                       for(Class<?> c : classes) {
-                               if (c.isAnnotationPresent(org.aspectj.lang.annotation.DeclareParents.class)) {
-                                       if (c.getInterfaces().length == 0) continue;
-                                       AjType<?> targetType = AjTypeSystem.getAjType((Class<?>)c.getInterfaces()[0]);
-                                       Method[] meths = c.getDeclaredMethods();
-                                       for (Method m : meths) {
-                                               if (!Modifier.isPublic(m.getModifiers()) && publicOnly) continue;
-                                               InterTypeMethodDeclaration itdm = 
-                                                       new InterTypeMethodDeclarationImpl(
-                                                                       this,targetType,m);
-                                               toList.add(itdm);
-                                       }
-                               }
-                       }
+            for (Field f : clazz.getDeclaredFields()) {
+                if (!f.getType().isInterface()) continue;
+                if (!Modifier.isPublic(f.getModifiers()) || !Modifier.isStatic(f.getModifiers())) continue;
+                if (f.isAnnotationPresent(org.aspectj.lang.annotation.DeclareParents.class)) {
+                    for (Method itdM : f.getType().getDeclaredMethods()) {
+                        if (!Modifier.isPublic(itdM.getModifiers()) && publicOnly) continue;
+                        InterTypeMethodDeclaration itdm = new InterTypeMethodDeclarationImpl(
+                                    this, AjTypeSystem.getAjType(f.getType()), itdM
+                        );
+                        toList.add(itdm);
+                    }
+                }
+            }
+//            Class<?>[] classes = clazz.getDeclaredClasses();
+//                     for(Class<?> c : classes) {
+//                             if (c.isAnnotationPresent(org.aspectj.lang.annotation.DeclareParents.class)) {
+//                                     if (c.getInterfaces().length == 0) continue;
+//                                     AjType<?> targetType = AjTypeSystem.getAjType((Class<?>)c.getInterfaces()[0]);
+//                                     Method[] meths = c.getDeclaredMethods();
+//                                     for (Method m : meths) {
+//                                             if (!Modifier.isPublic(m.getModifiers()) && publicOnly) continue;
+//                                             InterTypeMethodDeclaration itdm =
+//                                                     new InterTypeMethodDeclarationImpl(
+//                                                                     this,targetType,m);
+//                                             toList.add(itdm);
+//                                     }
+//                             }
+//                     }
                }
        }
 
        private void addAnnotationStyleITDFields(List<InterTypeFieldDeclaration> toList, boolean publicOnly) {
-               if (isAspect()) {
-                       Class<?>[] classes = clazz.getDeclaredClasses();
-                       for(Class<?> c : classes) {
-                               if (c.isAnnotationPresent(org.aspectj.lang.annotation.DeclareParents.class)) {
-                                       if (c.getInterfaces().length == 0) continue;
-                                       AjType<?> targetType = AjTypeSystem.getAjType((Class<?>)c.getInterfaces()[0]);
-                                       Field[] fields = c.getDeclaredFields();
-                                       for (Field f : fields) {
-                                               if (!Modifier.isPublic(f.getModifiers()) && publicOnly) continue;
-                                               InterTypeFieldDeclaration itdf = 
-                                                       new InterTypeFieldDeclarationImpl(
-                                                                       this,targetType,f);
-                                               toList.add(itdf);
-                                       }
-                               }
-                       }
-               }
+        return;
+        //AV: I think it is meaningless
+        //@AJ decp is interface driven ie no field
+//        if (isAspect()) {
+//                     for (Field f : clazz.getDeclaredFields()) {
+//                if (!f.getType().isInterface()) continue;
+//                if (!Modifier.isPublic(f.getModifiers()) || !Modifier.isStatic(f.getModifiers())) continue;
+//                if (f.isAnnotationPresent(org.aspectj.lang.annotation.DeclareParents.class)) {
+//                    for (Field itdF : f.getType().getDeclaredFields()) {
+//                        if (!Modifier.isPublic(itdF.getModifiers()) && publicOnly) continue;
+//                        InterTypeFieldDeclaration itdf = new InterTypeFieldDeclarationImpl(
+//                                    this, AjTypeSystem.getAjType(f.getType()), itdF
+//                        );
+//                        toList.add(itdf);
+//                    }
+//                }
+//            }
+//---old impl.
+//            Class<?>[] classes = clazz.getDeclaredClasses();
+//                     for(Class<?> c : classes) {
+//                             if (c.isAnnotationPresent(org.aspectj.lang.annotation.DeclareParents.class)) {
+//                                     if (c.getInterfaces().length == 0) continue;
+//                                     AjType<?> targetType = AjTypeSystem.getAjType((Class<?>)c.getInterfaces()[0]);
+//                                     Field[] fields = c.getDeclaredFields();
+//                                     for (Field f : fields) {
+//                                             if (!Modifier.isPublic(f.getModifiers()) && publicOnly) continue;
+//                                             InterTypeFieldDeclaration itdf =
+//                                                     new InterTypeFieldDeclarationImpl(
+//                                                                     this,targetType,f);
+//                                             toList.add(itdf);
+//                                     }
+//                             }
+//                     }
+//             }
        }
        /* (non-Javadoc)
         * @see org.aspectj.lang.reflect.AjType#getDeclaredITDConstructor(java.lang.Class, java.lang.Class...)
@@ -963,21 +993,50 @@ public class AjTypeImpl<T> implements AjType<T> {
        }
        
        private void addAnnotationStyleDeclareParents(List<DeclareParents> toList) {
-               Class<?>[] classes = clazz.getDeclaredClasses();
-               for (Class<?> c : classes) {
-                       if (c.isAnnotationPresent(org.aspectj.lang.annotation.DeclareParents.class)) {
-                               org.aspectj.lang.annotation.DeclareParents ann = c.getAnnotation(org.aspectj.lang.annotation.DeclareParents.class);
-                               if (c.getInterfaces().length == 0) continue;
-                               String parentType = c.getInterfaces()[0].getName();
-                               DeclareParentsImpl decp = new DeclareParentsImpl(
-                                               ann.value(),
-                                               parentType,
-                                               false,
-                                               this
-                                               );
-                               toList.add(decp);
-                       }
-               }
+        for (Field f : clazz.getDeclaredFields()) {
+            if (f.isAnnotationPresent(org.aspectj.lang.annotation.DeclareImplements.class)) {
+                if (!f.getType().isInterface()) continue;
+                org.aspectj.lang.annotation.DeclareImplements ann = f.getAnnotation(org.aspectj.lang.annotation.DeclareImplements.class);
+                String parentType = f.getType().getName();
+                DeclareParentsImpl decp = new DeclareParentsImpl(
+                        ann.value(),
+                        parentType,
+                        false,
+                        this
+                );
+                toList.add(decp);
+            }
+            if (f.isAnnotationPresent(org.aspectj.lang.annotation.DeclareParents.class)
+                && Modifier.isStatic(f.getModifiers())
+                && Modifier.isPublic(f.getModifiers())) {
+                if (!f.getType().isInterface()) continue;
+                org.aspectj.lang.annotation.DeclareParents ann = f.getAnnotation(org.aspectj.lang.annotation.DeclareParents.class);
+                String parentType = f.getType().getName();
+                DeclareParentsImpl decp = new DeclareParentsImpl(
+                        ann.value(),
+                        parentType,
+                        false,
+                        this
+                );
+                toList.add(decp);
+            }
+        }
+//
+//        Class<?>[] classes = clazz.getDeclaredClasses();
+//             for (Class<?> c : classes) {
+//                     if (c.isAnnotationPresent(org.aspectj.lang.annotation.DeclareParents.class)) {
+//                             org.aspectj.lang.annotation.DeclareParents ann = c.getAnnotation(org.aspectj.lang.annotation.DeclareParents.class);
+//                             if (c.getInterfaces().length == 0) continue;
+//                             String parentType = c.getInterfaces()[0].getName();
+//                             DeclareParentsImpl decp = new DeclareParentsImpl(
+//                                             ann.value(),
+//                                             parentType,
+//                                             false,
+//                                             this
+//                                             );
+//                             toList.add(decp);
+//                     }
+//             }
        }
 
        /* (non-Javadoc)
diff --git a/aspectj5rt/java5-src/org/aspectj/lang/annotation/DeclareImplements.java b/aspectj5rt/java5-src/org/aspectj/lang/annotation/DeclareImplements.java
new file mode 100644 (file)
index 0000000..dbb1bf1
--- /dev/null
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * initial implementation              Adrian Colyer
+ *******************************************************************************/
+package org.aspectj.lang.annotation;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Declare parents mixin annotation
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface DeclareImplements {
+
+    /**
+     * The target types expression
+     */
+    String value();
+    
+}
index 3dec04f27b2d83f0c9433af92adb72d4f2a4a012..e26e8c778d7f29a8a32fb9b5e3725c245067bcb5 100644 (file)
@@ -20,7 +20,7 @@ import java.lang.annotation.RetentionPolicy;
  * Declare parents mixin annotation
  */
 @Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
+@Target(ElementType.FIELD)
 public @interface DeclareParents {
 
     /**
index 0dbc1d49b9fe0d9132b23a4deedb4024268f188b..9317034115eed6164eade7ff698ef4442ca5cd0c 100644 (file)
Binary files a/lib/test/aspectjrt.jar and b/lib/test/aspectjrt.jar differ
index 841af326b234c67216137eec35be3181209bf085..bfa2e58bd0734420ac95c01d65346f4d03877f63 100644 (file)
@@ -145,9 +145,9 @@ public aspect ITDTest {
        } catch (ClassNotFoundException cnf) {
                throw new RuntimeException(cnf);
        }
-       assertEquals("1: ",1,x.getDeclaredITDFields().length);
-       assertEquals("i: ","i",x.getDeclaredITDFields()[0].getName());
-       assertEquals("1: ",1,x.getITDMethods().length);
+       //assertEquals("ITD field 1: ",1,x.getDeclaredITDFields().length);
+       //assertEquals("ITD filed name i: ","i",x.getDeclaredITDFields()[0].getName());
+       assertEquals("ITD method 1: ",1,x.getITDMethods().length);
        assertEquals("getNumber: ","getNumber",x.getITDMethods()[0].getName());
     }
     
@@ -163,6 +163,9 @@ class A {}
 class X {
        
        @org.aspectj.lang.annotation.DeclareParents("org.xyz..*")
+       public static I myMixin = new Mixin();
+
+
        public static class Mixin implements I {
                
                private int i = 0;
diff --git a/tests/java5/ataspectj/ataspectj/DeclareParentsImplementsTest.java b/tests/java5/ataspectj/ataspectj/DeclareParentsImplementsTest.java
new file mode 100644 (file)
index 0000000..aee1228
--- /dev/null
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://eclipse.org/legal/epl-v10.html 
+ * 
+ * Contributors:
+ *   Alexandre Vasseur         initial implementation
+ *******************************************************************************/
+package ataspectj;
+
+import junit.framework.TestCase;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.DeclareParents;
+import org.aspectj.lang.annotation.Before;
+
+import java.util.Arrays;
+
+/**
+ * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+ */
+public class DeclareParentsImplementsTest extends TestCase {
+
+    static class Target {
+        void target() {
+            log("hello");
+        }
+    }
+
+    static interface Introduced {
+        final static int field1 = 1;
+        void intro();
+    }
+
+    static class Implementation implements Introduced {
+        public void intro() {
+            log("intro-"+field1);
+            // we cannot copy the raw bytecode as there might be super.* calls, and other OO stuff
+        }
+    }
+
+    @Aspect
+    static class TestAspect {
+
+        @DeclareParents("ataspectj.DeclareParentsImplementsTest.Target")
+        public static Introduced i = new Implementation();//see here control of instantiation
+        // will lead to: class Target implements Introduced {
+        //    void intro(args) { TestAspect.i.intro(args); }
+        // }
+
+        @Before("execution(* ataspectj.DeclareParentsImplementsTest.Introduced.intro())")
+        public void before() {
+            log("aop");
+        }
+    }
+
+    static StringBuffer s_log = new StringBuffer();
+    static void log(String s) {
+        s_log.append(s).append(" ");
+    }
+
+    public void testDecPInt() {
+        Class[] intfs = Target.class.getInterfaces();
+        assertTrue("Was not introduced", Arrays.asList(intfs).contains(Introduced.class));
+    }
+
+    public void testDecPIntAdvised() {
+        s_log = new StringBuffer();
+        ((Introduced)new Target()).intro();
+        assertEquals("aop intro-1 ", s_log.toString());
+    }
+
+    public static void main(String[] args) {
+        TestHelper.runAndThrowOnFailure(suite());
+    }
+
+    public static junit.framework.Test suite() {
+        return new junit.framework.TestSuite(DeclareParentsImplementsTest.class);
+    }
+}
diff --git a/tests/java5/ataspectj/ataspectj/DeclareParentsInterfaceTest.java b/tests/java5/ataspectj/ataspectj/DeclareParentsInterfaceTest.java
new file mode 100644 (file)
index 0000000..ffac0e4
--- /dev/null
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://eclipse.org/legal/epl-v10.html 
+ * 
+ * Contributors:
+ *   Alexandre Vasseur         initial implementation
+ *******************************************************************************/
+package ataspectj;
+
+import junit.framework.TestCase;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.DeclareImplements;
+
+import java.util.Arrays;
+
+/**
+ * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+ */
+public class DeclareParentsInterfaceTest extends TestCase {
+
+    static class Target {
+        void target() {
+            log("hello");
+        }
+    }
+
+    static interface Marker {}
+
+    @Aspect
+    static class TestAspect {
+
+        @DeclareImplements("ataspectj.DeclareParentsInterfaceTest.Target")
+        Marker introduce;
+
+        @Before("execution(* ataspectj.DeclareParentsInterfaceTest.Marker+.target())")
+        public void before() {
+            log("aop");
+        }
+    }
+
+    static StringBuffer s_log = new StringBuffer();
+    static void log(String s) {
+        s_log.append(s).append(" ");
+    }
+
+    public void testDecPInt() {
+        Class[] intfs = Target.class.getInterfaces();
+        assertTrue("Was not introduced", Arrays.asList(intfs).contains(Marker.class));
+    }
+
+    public void testDecPIntAdvised() {
+        s_log = new StringBuffer();
+        new Target().target();
+        assertEquals("aop hello ", s_log.toString());
+    }
+
+    public static void main(String[] args) {
+        TestHelper.runAndThrowOnFailure(suite());
+    }
+
+    public static junit.framework.Test suite() {
+        return new junit.framework.TestSuite(DeclareParentsInterfaceTest.class);
+    }
+}
index e4f883c66d38586d8fdeb16e939229cbd1f7c044..5e802c4a7ca82865d57190fc97a0eed1edffedf8 100644 (file)
@@ -120,4 +120,12 @@ public class AtAjSyntaxTests extends XMLBasedAjcTestCase {
     public void testBug104212() {
         runTest("Bug104212");
     }
+
+    public void testDeclareParentsInterface() {
+        runTest("DeclareParentsInterface");
+    }
+
+    public void testDeclareParentsImplements() {
+        runTest("DeclareParentsImplements");
+    }
 }
\ No newline at end of file
index 04667476bf310d8d49ed10ff8fa99e81fc07fe6c..89f2e0f08e39209f96c3d35efef75962d92ab32a 100644 (file)
         <run class="ataspectj.Bug104212"/>
     </ajc-test>
 
+    <ajc-test dir="java5/ataspectj" title="DeclareParentsInterface">
+        <compile files="ataspectj/DeclareParentsInterfaceTest.java,ataspectj/TestHelper.java" options="-1.5 -Xdev:NoAtAspectJProcessing -Xlint:ignore"/>
+        <run class="ataspectj.DeclareParentsInterfaceTest"/>
+    </ajc-test>
+
+    <ajc-test dir="java5/ataspectj" title="DeclareParentsImplements">
+        <compile files="ataspectj/DeclareParentsImplementsTest.java,ataspectj/TestHelper.java" options="-1.5 -Xdev:NoAtAspectJProcessing -Xlint:ignore"/>
+        <run class="ataspectj.DeclareParentsImplementsTest"/>
+    </ajc-test>
 
 </suite>
\ No newline at end of file
index aff454f01ce5da0182112e615cccde9e6fa78aac..390b8e1739cee1deba12aa758713cdb61931c8ed 100644 (file)
@@ -751,6 +751,8 @@ public class AjcMemberMaker {
     public final static UnresolvedType DECLAREERROR_ANNOTATION = UnresolvedType.forName("org.aspectj.lang.annotation.DeclareError");
     public final static UnresolvedType DECLAREWARNING_ANNOTATION = UnresolvedType.forName("org.aspectj.lang.annotation.DeclareWarning");
     public final static UnresolvedType DECLAREPRECEDENCE_ANNOTATION = UnresolvedType.forName("org.aspectj.lang.annotation.DeclarePrecedence");
+    public final static UnresolvedType DECLAREIMPLEMENTS_ANNOTATION = UnresolvedType.forName("org.aspectj.lang.annotation.DeclareImplements");
+    public final static UnresolvedType DECLAREPARENTS_ANNOTATION = UnresolvedType.forName("org.aspectj.lang.annotation.DeclareParents");
 
     public final static UnresolvedType TYPEX_JOINPOINT = UnresolvedType.forName(JoinPoint.class.getName().replace('/','.'));
     public final static UnresolvedType TYPEX_PROCEEDINGJOINPOINT = UnresolvedType.forName(ProceedingJoinPoint.class.getName().replace('/','.'));
diff --git a/weaver/src/org/aspectj/weaver/MethodDelegateTypeMunger.java b/weaver/src/org/aspectj/weaver/MethodDelegateTypeMunger.java
new file mode 100644 (file)
index 0000000..17906b6
--- /dev/null
@@ -0,0 +1,92 @@
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: 
+ *     Alexandre Vasseur     initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.weaver;
+
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.weaver.patterns.TypePattern;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.Set;
+import java.util.Iterator;
+
+public class MethodDelegateTypeMunger extends ResolvedTypeMunger {
+
+    private final ResolvedMember aspectFieldDelegate;
+
+    private final TypePattern typePattern;
+
+    public MethodDelegateTypeMunger(ResolvedMember signature, ResolvedType aspect, String fieldName, TypePattern typePattern) {
+        super(MethodDelegate, signature);
+        this.typePattern = typePattern;
+
+        ResolvedMember[] fields = aspect.getDeclaredFields();//note: will unpack attributes
+        ResolvedMember field = null;
+        for (int i = 0; i < fields.length; i++) {
+            if (fieldName.equals(fields[i].getName())) {
+                field = fields[i];
+                break;
+            }
+        }
+        if (field == null) {
+            throw new RuntimeException("Should not happen: aspect field not found for @DeclareParents delegate");
+        } else {
+            aspectFieldDelegate = field;
+        }
+    }
+
+    public ResolvedMember getDelegate() {
+        return aspectFieldDelegate;
+    }
+
+//    public ResolvedMember getInterMethodBody(UnresolvedType aspectType) {
+//        return AjcMemberMaker.interMethodBody(signature, aspectType);
+//    }
+//
+//    public ResolvedMember getInterMethodDispatcher(UnresolvedType aspectType) {
+//        return AjcMemberMaker.interMethodDispatcher(signature, aspectType);
+//    }
+
+    public void write(DataOutputStream s) throws IOException {
+        ;//FIXME AVITD needed as changes public signature throw new RuntimeException("unimplemented");
+    }
+
+//    public static ResolvedTypeMunger readMethod(VersionedDataInputStream s, ISourceContext context) throws IOException {
+//        ResolvedMemberImpl rmi = ResolvedMemberImpl.readResolvedMember(s, context);
+//        Set superMethodsCalled = readSuperMethodsCalled(s);
+//        ISourceLocation sLoc = readSourceLocation(s);
+//        ResolvedTypeMunger munger = new MethodDelegateTypeMunger(rmi, superMethodsCalled);
+//        if (sLoc != null) munger.setSourceLocation(sLoc);
+//        return munger;
+//    }
+//
+//    public ResolvedMember getMatchingSyntheticMember(Member member, ResolvedType aspectType) {
+//        ResolvedMember ret = AjcMemberMaker.interMethodDispatcher(getSignature(), aspectType);
+//        if (ResolvedType.matches(ret, member)) return getSignature();
+//        return super.getMatchingSyntheticMember(member, aspectType);
+//    }
+
+    public boolean matches(ResolvedType matchType, ResolvedType aspectType) {
+        // match only on class
+        if (matchType.isEnum() || matchType.isInterface() || matchType.isAnnotation()) {
+            return false;
+        }
+
+        return typePattern.matchesStatically(matchType);
+    }
+
+    public boolean changesPublicSignature() {
+        return true;
+    }
+}
index 5fb3ca9f3a45a31a0545d2b9a3844492278d2d29..3eacaabe8e8d9aa87facc7a77be510fcf8d6bbd8 100644 (file)
@@ -7,12 +7,22 @@
  * http://www.eclipse.org/legal/cpl-v10.html 
  *  
  * Contributors: 
- *     PARC     initial implementation 
+ *     PARC     initial implementation
+ *     Alexandre Vasseur    @AspectJ ITDs
  * ******************************************************************/
 
 
 package org.aspectj.weaver;
 
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.bridge.Message;
+import org.aspectj.bridge.MessageUtil;
+import org.aspectj.util.FuzzyBoolean;
+import org.aspectj.weaver.bcel.BcelTypeMunger;
+import org.aspectj.weaver.patterns.Declare;
+import org.aspectj.weaver.patterns.PerClause;
+
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -25,30 +35,22 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.aspectj.bridge.IMessage;
-import org.aspectj.bridge.ISourceLocation;
-import org.aspectj.bridge.Message;
-import org.aspectj.bridge.MessageUtil;
-import org.aspectj.util.FuzzyBoolean;
-import org.aspectj.weaver.patterns.Declare;
-import org.aspectj.weaver.patterns.PerClause;
-
 public abstract class ResolvedType extends UnresolvedType implements AnnotatedElement {
 
-       private static final ResolvedType[] EMPTY_RESOLVED_TYPE_ARRAY  = new ResolvedType[0];
-       public static final String PARAMETERIZED_TYPE_IDENTIFIER = "P";
-       
-       private ResolvedType[] resolvedTypeParams;
-       
+    private static final ResolvedType[] EMPTY_RESOLVED_TYPE_ARRAY = new ResolvedType[0];
+    public static final String PARAMETERIZED_TYPE_IDENTIFIER = "P";
+
+    private ResolvedType[] resolvedTypeParams;
+
     protected World world;
-           
+
     protected ResolvedType(String signature, World world) {
         super(signature);
         this.world = world;
     }
-        
+
     protected ResolvedType(String signature, String signatureErasure, World world) {
-        super(signature,signatureErasure);
+        super(signature, signatureErasure);
         this.world = world;
     }
 
@@ -70,74 +72,79 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
     }
 
     public abstract ResolvedMember[] getDeclaredFields();
+
     public abstract ResolvedMember[] getDeclaredMethods();
+
     public abstract ResolvedType[] getDeclaredInterfaces();
+
     public abstract ResolvedMember[] getDeclaredPointcuts();
+
     /**
      * Returns a ResolvedType object representing the superclass of this type, or null.
      * If this represents a java.lang.Object, a primitive type, or void, this
-     * method returns null.  
+     * method returns null.
      */
     public abstract ResolvedType getSuperclass();
 
     /**
-     * Returns the modifiers for this type.  
-     * 
-     * See {@link java.lang.Class#getModifiers()} for a description
+     * Returns the modifiers for this type.
+     * <p/>
+     * See {@link Class#getModifiers()} for a description
      * of the weirdness of this methods on primitives and arrays.
      *
      * @param world the {@link World} in which the lookup is made.
      * @return an int representing the modifiers for this type
-     * @see     java.lang.reflect.Modifier
+     * @see java.lang.reflect.Modifier
      */
     public abstract int getModifiers();
 
     // return true if this resolved type couldn't be found (but we know it's name maybe)
-    public boolean isMissing() { return false; }
-    
+    public boolean isMissing() {
+        return false;
+    }
+
     public ResolvedType[] getAnnotationTypes() {
-       return EMPTY_RESOLVED_TYPE_ARRAY;
+        return EMPTY_RESOLVED_TYPE_ARRAY;
     }
-    
+
     public final UnresolvedType getSuperclass(World world) {
         return getSuperclass();
     }
 
-    
+
     // This set contains pairs of types whose signatures are concatenated
     // together, this means with a fast lookup we can tell if two types
     // are equivalent.
     static Set validBoxing = new HashSet();
-    
+
     static {
-      validBoxing.add("Ljava/lang/Byte;B");
-      validBoxing.add("Ljava/lang/Character;C");
-      validBoxing.add("Ljava/lang/Double;D");
-      validBoxing.add("Ljava/lang/Float;F");
-      validBoxing.add("Ljava/lang/Integer;I");
-      validBoxing.add("Ljava/lang/Long;J");
-      validBoxing.add("Ljava/lang/Short;S");
-      validBoxing.add("Ljava/lang/Boolean;Z");
-      validBoxing.add("BLjava/lang/Byte;");
-      validBoxing.add("CLjava/lang/Character;");
-      validBoxing.add("DLjava/lang/Double;");
-      validBoxing.add("FLjava/lang/Float;");
-      validBoxing.add("ILjava/lang/Integer;");
-      validBoxing.add("JLjava/lang/Long;");
-      validBoxing.add("SLjava/lang/Short;");
-      validBoxing.add("ZLjava/lang/Boolean;");
-    }
-    
-
-
-    // utilities                
+        validBoxing.add("Ljava/lang/Byte;B");
+        validBoxing.add("Ljava/lang/Character;C");
+        validBoxing.add("Ljava/lang/Double;D");
+        validBoxing.add("Ljava/lang/Float;F");
+        validBoxing.add("Ljava/lang/Integer;I");
+        validBoxing.add("Ljava/lang/Long;J");
+        validBoxing.add("Ljava/lang/Short;S");
+        validBoxing.add("Ljava/lang/Boolean;Z");
+        validBoxing.add("BLjava/lang/Byte;");
+        validBoxing.add("CLjava/lang/Character;");
+        validBoxing.add("DLjava/lang/Double;");
+        validBoxing.add("FLjava/lang/Float;");
+        validBoxing.add("ILjava/lang/Integer;");
+        validBoxing.add("JLjava/lang/Long;");
+        validBoxing.add("SLjava/lang/Short;");
+        validBoxing.add("ZLjava/lang/Boolean;");
+    }
+
+
+    // utilities
     public ResolvedType getResolvedComponentType() {
-       return null;
+        return null;
     }
 
-       public World getWorld() {
-               return world;
-       }
+    public World getWorld() {
+        return world;
+    }
 
     // ---- things from object
 
@@ -148,18 +155,18 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
             return super.equals(other);
         }
     }
+
     // ---- difficult things
-    
+
     /**
      * returns an iterator through all of the fields of this type, in order
      * for checking from JVM spec 2ed 5.4.3.2.  This means that the order is
-     *
+     * <p/>
      * <ul><li> fields from current class </li>
-     *     <li> recur into direct superinterfaces </li>
-     *     <li> recur into superclass </li>
+     * <li> recur into direct superinterfaces </li>
+     * <li> recur into superclass </li>
      * </ul>
-     * 
+     * <p/>
      * We keep a hashSet of interfaces that we've visited so we don't spiral
      * out into 2^n land.
      */
@@ -167,31 +174,31 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
         final Iterators.Filter dupFilter = Iterators.dupFilter();
         Iterators.Getter typeGetter = new Iterators.Getter() {
             public Iterator get(Object o) {
-                return 
-                    dupFilter.filter(
-                        ((ResolvedType)o).getDirectSupertypes());
+                return
+                        dupFilter.filter(
+                                ((ResolvedType) o).getDirectSupertypes());
             }
         };
         Iterators.Getter fieldGetter = new Iterators.Getter() {
             public Iterator get(Object o) {
-                return Iterators.array(((ResolvedType)o).getDeclaredFields());
+                return Iterators.array(((ResolvedType) o).getDeclaredFields());
             }
         };
-        return 
-            Iterators.mapOver(
-                Iterators.recur(this, typeGetter),
-                fieldGetter);
+        return
+                Iterators.mapOver(
+                        Iterators.recur(this, typeGetter),
+                        fieldGetter);
     }
 
     /**
      * returns an iterator through all of the methods of this type, in order
      * for checking from JVM spec 2ed 5.4.3.3.  This means that the order is
-     *
+     * <p/>
      * <ul><li> methods from current class </li>
-     *     <li> recur into superclass, all the way up, not touching interfaces </li>
-     *     <li> recur into all superinterfaces, in some unspecified order </li>
+     * <li> recur into superclass, all the way up, not touching interfaces </li>
+     * <li> recur into all superinterfaces, in some unspecified order </li>
      * </ul>
-     * 
+     * <p/>
      * We keep a hashSet of interfaces that we've visited so we don't spiral
      * out into 2^n land.
      * NOTE: Take a look at the javadoc on getMethodsWithoutIterator() to see if
@@ -201,38 +208,41 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
         final Iterators.Filter dupFilter = Iterators.dupFilter();
         Iterators.Getter ifaceGetter = new Iterators.Getter() {
             public Iterator get(Object o) {
-                return 
-                    dupFilter.filter(
-                        Iterators.array(((ResolvedType)o).getDeclaredInterfaces())
-                        );                       
+                return
+                        dupFilter.filter(
+                                Iterators.array(((ResolvedType) o).getDeclaredInterfaces())
+                        );
             }
         };
         Iterators.Getter methodGetter = new Iterators.Getter() {
             public Iterator get(Object o) {
-                return Iterators.array(((ResolvedType)o).getDeclaredMethods());
+                return Iterators.array(((ResolvedType) o).getDeclaredMethods());
             }
         };
-        return 
-            Iterators.mapOver(
-                Iterators.append(
-                    new Iterator() {
-                        ResolvedType curr = ResolvedType.this;
-                        public boolean hasNext() {
-                            return curr != null;
-                        }
-                        public Object next() {
-                            ResolvedType ret = curr;
-                            curr = curr.getSuperclass();
-                            return ret;
-                        }
-                        public void remove() {
-                            throw new UnsupportedOperationException();
-                        }
-                    },
-                    Iterators.recur(this, ifaceGetter)),
-                methodGetter);
+        return
+                Iterators.mapOver(
+                        Iterators.append(
+                                new Iterator() {
+                                    ResolvedType curr = ResolvedType.this;
+
+                                    public boolean hasNext() {
+                                        return curr != null;
+                                    }
+
+                                    public Object next() {
+                                        ResolvedType ret = curr;
+                                        curr = curr.getSuperclass();
+                                        return ret;
+                                    }
+
+                                    public void remove() {
+                                        throw new UnsupportedOperationException();
+                                    }
+                                },
+                                Iterators.recur(this, ifaceGetter)),
+                        methodGetter);
     }
-    
+
     /**
      * Return a list of methods, first those declared on this class, then those declared on the superclass (recurse) and then those declared
      * on the superinterfaces.  The getMethods() call above doesn't quite work the same as it will (through the iterator) return methods
@@ -241,52 +251,64 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
     public List getMethodsWithoutIterator(boolean includeITDs, boolean allowMissing) {
         List methods = new ArrayList();
         Set knowninterfaces = new HashSet();
-        addAndRecurse(knowninterfaces,methods,this,includeITDs,allowMissing);
+        addAndRecurse(knowninterfaces, methods, this, includeITDs, allowMissing);
         return methods;
     }
-    
-    private void addAndRecurse(Set knowninterfaces,List collector, ResolvedType rtx, boolean includeITDs, boolean allowMissing) {
-      collector.addAll(Arrays.asList(rtx.getDeclaredMethods())); // Add the methods declared on this type
-      // now add all the inter-typed members too
-      if (includeITDs && rtx.interTypeMungers != null) {
-         for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
-                               ConcreteTypeMunger tm = (ConcreteTypeMunger) i.next();  
-                               ResolvedMember rm = tm.getSignature();
-                               if (rm != null) {  // new parent type munger can have null signature...
-                                       collector.add(tm.getSignature());
-                               } 
-                       }
-      }
-      if (!rtx.equals(ResolvedType.OBJECT)) {
-         ResolvedType superType = rtx.getSuperclass();
-         if (superType != null && !superType.isMissing()) {
-                 addAndRecurse(knowninterfaces,collector,superType,includeITDs,allowMissing); // Recurse if we aren't at the top
-         }
-      }
-      ResolvedType[] interfaces = rtx.getDeclaredInterfaces(); // Go through the interfaces on the way back down
-      for (int i = 0; i < interfaces.length; i++) {
-               ResolvedType iface = interfaces[i];
-               if (!knowninterfaces.contains(iface)) { // Dont do interfaces more than once
-          knowninterfaces.add(iface); 
-          if (allowMissing && iface.isMissing()) {
-               if (iface instanceof MissingResolvedTypeWithKnownSignature) {
-                       ((MissingResolvedTypeWithKnownSignature)iface).raiseWarningOnMissingInterfaceWhilstFindingMethods();
-               }
-          } else {
-                 addAndRecurse(knowninterfaces,collector,iface,includeITDs,allowMissing);
-          }
-        }
-         }
+
+    private void addAndRecurse(Set knowninterfaces, List collector, ResolvedType rtx, boolean includeITDs, boolean allowMissing) {
+        collector.addAll(Arrays.asList(rtx.getDeclaredMethods())); // Add the methods declared on this type
+        // now add all the inter-typed members too
+        if (includeITDs && rtx.interTypeMungers != null) {
+            for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
+                ConcreteTypeMunger tm = (ConcreteTypeMunger) i.next();
+                ResolvedMember rm = tm.getSignature();
+                if (rm != null) {  // new parent type munger can have null signature...
+                    collector.add(tm.getSignature());
+                }
+            }
+        }
+        if (!rtx.equals(ResolvedType.OBJECT)) {
+            ResolvedType superType = rtx.getSuperclass();
+            if (superType != null && !superType.isMissing()) {
+                addAndRecurse(knowninterfaces, collector, superType, includeITDs, allowMissing); // Recurse if we aren't at the top
+            }
+        }
+        ResolvedType[] interfaces = rtx.getDeclaredInterfaces(); // Go through the interfaces on the way back down
+        for (int i = 0; i < interfaces.length; i++) {
+            ResolvedType iface = interfaces[i];
+
+            // we need to know if it is an interface from Parent kind munger
+            // as those are used for @AJ ITD and we precisely want to skip those
+            boolean shouldSkip = false;
+            for (int j = 0; j < rtx.interTypeMungers.size(); j++) {
+                ConcreteTypeMunger munger = (ConcreteTypeMunger) rtx.interTypeMungers.get(j);
+                if (munger.getMunger().getKind() == ResolvedTypeMunger.Parent) {
+                    shouldSkip = true;
+                    break;
+                }
+            }
+
+            if (!shouldSkip && !knowninterfaces.contains(iface)) { // Dont do interfaces more than once
+                knowninterfaces.add(iface);
+                if (allowMissing && iface.isMissing()) {
+                    if (iface instanceof MissingResolvedTypeWithKnownSignature) {
+                        ((MissingResolvedTypeWithKnownSignature) iface).raiseWarningOnMissingInterfaceWhilstFindingMethods();
+                    }
+                } else {
+                    addAndRecurse(knowninterfaces, collector, iface, includeITDs, allowMissing);
+                }
+            }
+        }
     }
 
     public ResolvedType[] getResolvedTypeParameters() {
-       if (resolvedTypeParams == null) {
-               resolvedTypeParams = world.resolve(typeParameters);
-       }
-       return resolvedTypeParams;
+        if (resolvedTypeParams == null) {
+            resolvedTypeParams = world.resolve(typeParameters);
+        }
+        return resolvedTypeParams;
     }
-    
-    /** 
+
+    /**
      * described in JVM spec 2ed 5.4.3.2
      */
     public ResolvedMember lookupField(Member m) {
@@ -300,20 +322,22 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
     public ResolvedMember lookupMethod(Member m) {
         return lookupMember(m, getMethods());
     }
-    
+
     public ResolvedMember lookupMethodInITDs(Member m) {
-       if (interTypeMungers != null) {
-                       for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
-                               ConcreteTypeMunger tm = (ConcreteTypeMunger) i.next();
-                               if (matches(tm.getSignature(), m)) {
-                                       return tm.getSignature();
-                               }
-                       }
-               }
-       return null;
-    }
-    
-    /** return null if not found */
+        if (interTypeMungers != null) {
+            for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
+                ConcreteTypeMunger tm = (ConcreteTypeMunger) i.next();
+                if (matches(tm.getSignature(), m)) {
+                    return tm.getSignature();
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * return null if not found
+     */
     private ResolvedMember lookupMember(Member m, Iterator i) {
         while (i.hasNext()) {
             ResolvedMember f = (ResolvedMember) i.next();
@@ -321,53 +345,55 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
         }
         return null; //ResolvedMember.Missing;
         //throw new BCException("can't find " + m);
-    }  
-    
-    /** return null if not found */
+    }
+
+    /**
+     * return null if not found
+     */
     private ResolvedMember lookupMember(Member m, ResolvedMember[] a) {
-               for (int i = 0; i < a.length; i++) {
-                       ResolvedMember f = a[i];
-            if (matches(f, m)) return f;       
-               }
-               return null;
-    }      
-    
-    
+        for (int i = 0; i < a.length; i++) {
+            ResolvedMember f = a[i];
+            if (matches(f, m)) return f;
+        }
+        return null;
+    }
+
+
     /**
      * Looks for the first member in the hierarchy matching aMember. This method
      * differs from lookupMember(Member) in that it takes into account parameters
      * which are type variables - which clearly an unresolved Member cannot do since
-     * it does not know anything about type variables. 
+     * it does not know anything about type variables.
      */
-     public ResolvedMember lookupResolvedMember(ResolvedMember aMember,boolean allowMissing) {
-       Iterator toSearch = null;
-       ResolvedMember found = null;
-       if ((aMember.getKind() == Member.METHOD) || (aMember.getKind() == Member.CONSTRUCTOR)) {
-               toSearch = getMethodsWithoutIterator(true,allowMissing).iterator();
-       } else {
-               if (aMember.getKind() != Member.FIELD) 
-                       throw new IllegalStateException("I didn't know you would look for members of kind " + aMember.getKind());
-               toSearch = getFields();
-       }
-       while(toSearch.hasNext()) {
-                       ResolvedMemberImpl candidate = (ResolvedMemberImpl) toSearch.next();                    
-                       if (candidate.matches(aMember)) {
-                               found = candidate;
-                               break;
-                       } 
-               }
-       
-       return found;
-    }
-    
+    public ResolvedMember lookupResolvedMember(ResolvedMember aMember, boolean allowMissing) {
+        Iterator toSearch = null;
+        ResolvedMember found = null;
+        if ((aMember.getKind() == Member.METHOD) || (aMember.getKind() == Member.CONSTRUCTOR)) {
+            toSearch = getMethodsWithoutIterator(true, allowMissing).iterator();
+        } else {
+            if (aMember.getKind() != Member.FIELD)
+                throw new IllegalStateException("I didn't know you would look for members of kind " + aMember.getKind());
+            toSearch = getFields();
+        }
+        while (toSearch.hasNext()) {
+            ResolvedMemberImpl candidate = (ResolvedMemberImpl) toSearch.next();
+            if (candidate.matches(aMember)) {
+                found = candidate;
+                break;
+            }
+        }
+
+        return found;
+    }
+
     public static boolean matches(Member m1, Member m2) {
         if (m1 == null) return m2 == null;
         if (m2 == null) return false;
-        
+
         // Check the names
         boolean equalNames = m1.getName().equals(m2.getName());
         if (!equalNames) return false;
-        
+
         // Check the signatures
         boolean equalSignatures = m1.getSignature().equals(m2.getSignature());
         if (equalSignatures) return true;
@@ -376,43 +402,47 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
         // the subsig might be ()LFastCar; - where FastCar is a subclass of Car
         boolean equalCovariantSignatures = m1.getParameterSignature().equals(m2.getParameterSignature());
         if (equalCovariantSignatures) return true;
-        
+
         return false;
     }
-    
+
     public static boolean conflictingSignature(Member m1, Member m2) {
-       if (m1 == null || m2 == null) return false;
-       
-       if (!m1.getName().equals(m2.getName())) { return false; }
-       if (m1.getKind() != m2.getKind()) { return false; }     
-       
-       if (m1.getKind() == Member.FIELD) {
-               return m1.getDeclaringType().equals(m2.getDeclaringType());
-       } else if (m1.getKind() == Member.POINTCUT) {
-               return true;
-       }
-       
-       UnresolvedType[] p1 = m1.getParameterTypes();
-       UnresolvedType[] p2 = m2.getParameterTypes();
-       int n = p1.length;
-       if (n != p2.length) return false;
-       
-       for (int i=0; i < n; i++) {
-               if (!p1[i].equals(p2[i])) return false;
-       }
-       return true;
-    }
-    
-    
+        if (m1 == null || m2 == null) return false;
+
+        if (!m1.getName().equals(m2.getName())) {
+            return false;
+        }
+        if (m1.getKind() != m2.getKind()) {
+            return false;
+        }
+
+        if (m1.getKind() == Member.FIELD) {
+            return m1.getDeclaringType().equals(m2.getDeclaringType());
+        } else if (m1.getKind() == Member.POINTCUT) {
+            return true;
+        }
+
+        UnresolvedType[] p1 = m1.getParameterTypes();
+        UnresolvedType[] p2 = m2.getParameterTypes();
+        int n = p1.length;
+        if (n != p2.length) return false;
+
+        for (int i = 0; i < n; i++) {
+            if (!p1[i].equals(p2[i])) return false;
+        }
+        return true;
+    }
+
+
     /**
      * returns an iterator through all of the pointcuts of this type, in order
      * for checking from JVM spec 2ed 5.4.3.2 (as for fields).  This means that the order is
-     *
+     * <p/>
      * <ul><li> pointcuts from current class </li>
-     *     <li> recur into direct superinterfaces </li>
-     *     <li> recur into superclass </li>
+     * <li> recur into direct superinterfaces </li>
+     * <li> recur into superclass </li>
      * </ul>
-     * 
+     * <p/>
      * We keep a hashSet of interfaces that we've visited so we don't spiral
      * out into 2^n land.
      */
@@ -421,26 +451,26 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
         // same order as fields
         Iterators.Getter typeGetter = new Iterators.Getter() {
             public Iterator get(Object o) {
-                return 
-                    dupFilter.filter(
-                        ((ResolvedType)o).getDirectSupertypes());
+                return
+                        dupFilter.filter(
+                                ((ResolvedType) o).getDirectSupertypes());
             }
         };
         Iterators.Getter pointcutGetter = new Iterators.Getter() {
             public Iterator get(Object o) {
                 //System.err.println("getting for " + o);
-                return Iterators.array(((ResolvedType)o).getDeclaredPointcuts());
+                return Iterators.array(((ResolvedType) o).getDeclaredPointcuts());
             }
         };
-        return 
-            Iterators.mapOver(
-                Iterators.recur(this, typeGetter),
-                pointcutGetter);
+        return
+                Iterators.mapOver(
+                        Iterators.recur(this, typeGetter),
+                        pointcutGetter);
     }
-    
+
     public ResolvedPointcutDefinition findPointcut(String name) {
         //System.err.println("looking for pointcuts " + this);
-        for (Iterator i = getPointcuts(); i.hasNext(); ) {
+        for (Iterator i = getPointcuts(); i.hasNext();) {
             ResolvedPointcutDefinition f = (ResolvedPointcutDefinition) i.next();
             //System.err.println(f);
             if (name.equals(f.getName())) {
@@ -449,309 +479,320 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
         }
         return null; // should we throw an exception here?
     }
-    
-    
+
     // all about collecting CrosscuttingMembers
 
-       //??? collecting data-structure, shouldn't really be a field
+    //??? collecting data-structure, shouldn't really be a field
     public CrosscuttingMembers crosscuttingMembers;
 
-       public CrosscuttingMembers collectCrosscuttingMembers() {
-               crosscuttingMembers = new CrosscuttingMembers(this);
-               crosscuttingMembers.setPerClause(getPerClause());
-               crosscuttingMembers.addShadowMungers(collectShadowMungers());
-               crosscuttingMembers.addTypeMungers(getTypeMungers());
+    public CrosscuttingMembers collectCrosscuttingMembers() {
+        crosscuttingMembers = new CrosscuttingMembers(this);
+        crosscuttingMembers.setPerClause(getPerClause());
+        crosscuttingMembers.addShadowMungers(collectShadowMungers());
+        crosscuttingMembers.addTypeMungers(getTypeMungers());
         //FIXME AV - skip but needed ?? or  ?? crosscuttingMembers.addLateTypeMungers(getLateTypeMungers());
-               crosscuttingMembers.addDeclares(collectDeclares(!this.doesNotExposeShadowMungers()));
-               crosscuttingMembers.addPrivilegedAccesses(getPrivilegedAccesses());
-               
-               //System.err.println("collected cc members: " + this + ", " + collectDeclares());
-               return crosscuttingMembers;
-       }
-       
-       public final Collection collectDeclares(boolean includeAdviceLike) {
-               if (! this.isAspect() ) return Collections.EMPTY_LIST;
-               
-               ArrayList ret = new ArrayList();
-               //if (this.isAbstract()) {
+        crosscuttingMembers.addDeclares(collectDeclares(!this.doesNotExposeShadowMungers()));
+        crosscuttingMembers.addPrivilegedAccesses(getPrivilegedAccesses());
+
+        //System.err.println("collected cc members: " + this + ", " + collectDeclares());
+        return crosscuttingMembers;
+    }
+
+    public final Collection collectDeclares(boolean includeAdviceLike) {
+        if (! this.isAspect()) return Collections.EMPTY_LIST;
+
+        ArrayList ret = new ArrayList();
+        //if (this.isAbstract()) {
 //             for (Iterator i = getDeclares().iterator(); i.hasNext();) {
 //                     Declare dec = (Declare) i.next();
 //                     if (!dec.isAdviceLike()) ret.add(dec);
 //             }
 //        
 //        if (!includeAdviceLike) return ret;
-        
-               if (!this.isAbstract()) {
-                       //ret.addAll(getDeclares());
-                       final Iterators.Filter dupFilter = Iterators.dupFilter();
-               Iterators.Getter typeGetter = new Iterators.Getter() {
-                   public Iterator get(Object o) {
-                       return 
-                           dupFilter.filter(
-                               ((ResolvedType)o).getDirectSupertypes());
-                   }
-               };
-               Iterator typeIterator = Iterators.recur(this, typeGetter);
-       
-               while (typeIterator.hasNext()) {
-                       ResolvedType ty = (ResolvedType) typeIterator.next();
-                       //System.out.println("super: " + ty + ", " + );
-                       for (Iterator i = ty.getDeclares().iterator(); i.hasNext();) {
-                                       Declare dec = (Declare) i.next();
-                                       if (dec.isAdviceLike()) {
-                                               if (includeAdviceLike) ret.add(dec);
-                                       } else {
-                                               ret.add(dec);
-                                       }
-                               }
-               }
-               }
-               
-               return ret;
-    }
-    
-       
-       
-       
+
+        if (!this.isAbstract()) {
+            //ret.addAll(getDeclares());
+            final Iterators.Filter dupFilter = Iterators.dupFilter();
+            Iterators.Getter typeGetter = new Iterators.Getter() {
+                public Iterator get(Object o) {
+                    return
+                            dupFilter.filter(
+                                    ((ResolvedType) o).getDirectSupertypes());
+                }
+            };
+            Iterator typeIterator = Iterators.recur(this, typeGetter);
+
+            while (typeIterator.hasNext()) {
+                ResolvedType ty = (ResolvedType) typeIterator.next();
+                //System.out.println("super: " + ty + ", " + );
+                for (Iterator i = ty.getDeclares().iterator(); i.hasNext();) {
+                    Declare dec = (Declare) i.next();
+                    if (dec.isAdviceLike()) {
+                        if (includeAdviceLike) ret.add(dec);
+                    } else {
+                        ret.add(dec);
+                    }
+                }
+            }
+        }
+
+        return ret;
+    }
+
+
     private final Collection collectShadowMungers() {
         if (! this.isAspect() || this.isAbstract() || this.doesNotExposeShadowMungers()) return Collections.EMPTY_LIST;
 
-               ArrayList acc = new ArrayList();
+        ArrayList acc = new ArrayList();
         final Iterators.Filter dupFilter = Iterators.dupFilter();
         Iterators.Getter typeGetter = new Iterators.Getter() {
             public Iterator get(Object o) {
-                return 
-                    dupFilter.filter(
-                        ((ResolvedType)o).getDirectSupertypes());
+                return
+                        dupFilter.filter(
+                                ((ResolvedType) o).getDirectSupertypes());
             }
         };
         Iterator typeIterator = Iterators.recur(this, typeGetter);
 
         while (typeIterator.hasNext()) {
             ResolvedType ty = (ResolvedType) typeIterator.next();
-            acc.addAll(ty.getDeclaredShadowMungers());     
+            acc.addAll(ty.getDeclaredShadowMungers());
         }
-        
+
         return acc;
     }
-    
-       protected boolean doesNotExposeShadowMungers() {
-               return false;
-       }
-
-       public PerClause getPerClause() { return null; }
-       protected Collection getDeclares() {
-               return Collections.EMPTY_LIST; 
-       }
-       protected Collection getTypeMungers() { return Collections.EMPTY_LIST; }
-       
-       protected Collection getPrivilegedAccesses() { return Collections.EMPTY_LIST; }
-       
-       
+
+    protected boolean doesNotExposeShadowMungers() {
+        return false;
+    }
+
+    public PerClause getPerClause() {
+        return null;
+    }
+
+    protected Collection getDeclares() {
+        return Collections.EMPTY_LIST;
+    }
+
+    protected Collection getTypeMungers() {
+        return Collections.EMPTY_LIST;
+    }
+
+    protected Collection getPrivilegedAccesses() {
+        return Collections.EMPTY_LIST;
+    }
 
     // ---- useful things
-    
-    public final boolean isInterface() {       
+
+    public final boolean isInterface() {
         return Modifier.isInterface(getModifiers());
     }
-    
-    public final boolean isAbstract() {       
+
+    public final boolean isAbstract() {
         return Modifier.isAbstract(getModifiers());
     }
-    
+
     public boolean isClass() {
-       return false;
+        return false;
     }
-    
+
     public boolean isAspect() {
-       return false;
+        return false;
     }
 
     public boolean isAnnotationStyleAspect() {
-       return false;
+        return false;
     }
 
     /**
      * Note: Only overridden by Name subtype.
      */
     public boolean isEnum() {
-       return false;
+        return false;
     }
-    
+
     /**
      * Note: Only overridden by Name subtype.
      */
     public boolean isAnnotation() {
-       return false;
+        return false;
     }
-    
+
+    /**
+     * Note: Only overridden by Name subtype
+     */
+    public void addAnnotation(AnnotationX annotationX) {
+        throw new RuntimeException("ResolvedType.addAnnotation() should never be called");
+    }
+
     /**
      * Note: Only overridden by Name subtype
      */
-       public void addAnnotation(AnnotationX annotationX) {
-               throw new RuntimeException("ResolvedType.addAnnotation() should never be called");
-       }
-       
-       /**
-        * Note: Only overridden by Name subtype
-        */
-       public AnnotationX[] getAnnotations() {
-               throw new RuntimeException("ResolvedType.getAnnotations() should never be called");
-       }
-
-    
+    public AnnotationX[] getAnnotations() {
+        throw new RuntimeException("ResolvedType.getAnnotations() should never be called");
+    }
+
+
     /**
      * Note: Only overridden by Name subtype.
      */
     public boolean isAnnotationWithRuntimeRetention() {
         return false;
     }
-    
+
     public boolean isSynthetic() {
-       return signature.indexOf("$ajc") != -1;
+        return signature.indexOf("$ajc") != -1;
     }
-    
+
     public final boolean isFinal() {
         return Modifier.isFinal(getModifiers());
     }
 
-       protected Map /*Type variable name -> UnresolvedType*/ getMemberParameterizationMap() {
-               if (!isParameterizedType()) return Collections.EMPTY_MAP;
-               TypeVariable[] tvs = getGenericType().getTypeVariables();
-               Map parameterizationMap = new HashMap();
-               for (int i = 0; i < tvs.length; i++) {
-                       parameterizationMap.put(tvs[i].getName(), typeParameters[i]);
-               }
-               return parameterizationMap;
-       }
-
-       
-       public Collection getDeclaredAdvice() {
-               List l = new ArrayList();
-               ResolvedMember[] methods = getDeclaredMethods();
-               if (isParameterizedType()) methods = getGenericType().getDeclaredMethods();
-               Map typeVariableMap = getMemberParameterizationMap();
-               for (int i=0, len = methods.length; i < len; i++) {
-                       ShadowMunger munger = methods[i].getAssociatedShadowMunger();
-                       if (munger != null) {
-                               if (this.isParameterizedType()) {
-                                       //munger.setPointcut(munger.getPointcut().parameterizeWith(typeVariableMap));
-                                       munger = munger.parameterizeWith(typeVariableMap);
-                                       if (munger instanceof Advice) {
-                                               Advice advice = (Advice) munger;
-                                               // update to use the parameterized signature...
-                                               UnresolvedType[] ptypes = methods[i].getGenericParameterTypes() ;
-                                               UnresolvedType[] newPTypes = new UnresolvedType[ptypes.length];
-                                               for (int j = 0; j < ptypes.length; j++) {
-                                                       if (ptypes[j] instanceof TypeVariableReferenceType) {
-                                                               TypeVariableReferenceType tvrt = (TypeVariableReferenceType) ptypes[j];
-                                                               if (typeVariableMap.containsKey(tvrt.getTypeVariable().getName())) {
-                                                                       newPTypes[j] = (UnresolvedType) typeVariableMap.get(tvrt.getTypeVariable().getName());
-                                                               } else {
-                                                                       newPTypes[j] = ptypes[j];
-                                                               }
-                                                       } else {
-                                                               newPTypes[j] = ptypes[j];
-                                                       }
-                                               }
-                                               advice.setBindingParameterTypes(newPTypes);
-                                       }
-                               }
-                               munger.setDeclaringType(this);
-                               l.add(munger);
-                       }
-               }
-               return l;
-       }
-       
-       public Collection getDeclaredShadowMungers() {
-               Collection c = getDeclaredAdvice();
-               return c;
-       }
-       
-       // ---- only for testing!
-
-
-       public ResolvedMember[] getDeclaredJavaFields() {
-               return filterInJavaVisible(getDeclaredFields());
-       }
-       public ResolvedMember[] getDeclaredJavaMethods() {
-               return filterInJavaVisible(getDeclaredMethods());
-       }
-       public ShadowMunger[] getDeclaredShadowMungersArray() {
-               List l = (List) getDeclaredShadowMungers();
-               return (ShadowMunger[]) l.toArray(new ShadowMunger[l.size()]);
-       }
-       private ResolvedMember[] filterInJavaVisible(ResolvedMember[] ms) {
-               List l = new ArrayList();
-               for (int i=0, len = ms.length; i < len; i++) {
-                       if (! ms[i].isAjSynthetic() && ms[i].getAssociatedShadowMunger() == null) {
-                               l.add(ms[i]);
-                       }
-               }
-               return (ResolvedMember[]) l.toArray(new ResolvedMember[l.size()]);
-       }
-       
-       public abstract ISourceContext getSourceContext();
+    protected Map /*Type variable name -> UnresolvedType*/ getMemberParameterizationMap() {
+        if (!isParameterizedType()) return Collections.EMPTY_MAP;
+        TypeVariable[] tvs = getGenericType().getTypeVariables();
+        Map parameterizationMap = new HashMap();
+        for (int i = 0; i < tvs.length; i++) {
+            parameterizationMap.put(tvs[i].getName(), typeParameters[i]);
+        }
+        return parameterizationMap;
+    }
+
+
+    public Collection getDeclaredAdvice() {
+        List l = new ArrayList();
+        ResolvedMember[] methods = getDeclaredMethods();
+        if (isParameterizedType()) methods = getGenericType().getDeclaredMethods();
+        Map typeVariableMap = getMemberParameterizationMap();
+        for (int i = 0, len = methods.length; i < len; i++) {
+            ShadowMunger munger = methods[i].getAssociatedShadowMunger();
+            if (munger != null) {
+                if (this.isParameterizedType()) {
+                    //munger.setPointcut(munger.getPointcut().parameterizeWith(typeVariableMap));
+                    munger = munger.parameterizeWith(typeVariableMap);
+                    if (munger instanceof Advice) {
+                        Advice advice = (Advice) munger;
+                        // update to use the parameterized signature...
+                        UnresolvedType[] ptypes = methods[i].getGenericParameterTypes();
+                        UnresolvedType[] newPTypes = new UnresolvedType[ptypes.length];
+                        for (int j = 0; j < ptypes.length; j++) {
+                            if (ptypes[j] instanceof TypeVariableReferenceType) {
+                                TypeVariableReferenceType tvrt = (TypeVariableReferenceType) ptypes[j];
+                                if (typeVariableMap.containsKey(tvrt.getTypeVariable().getName())) {
+                                    newPTypes[j] = (UnresolvedType) typeVariableMap.get(tvrt.getTypeVariable().getName());
+                                } else {
+                                    newPTypes[j] = ptypes[j];
+                                }
+                            } else {
+                                newPTypes[j] = ptypes[j];
+                            }
+                        }
+                        advice.setBindingParameterTypes(newPTypes);
+                    }
+                }
+                munger.setDeclaringType(this);
+                l.add(munger);
+            }
+        }
+        return l;
+    }
+
+    public Collection getDeclaredShadowMungers() {
+        Collection c = getDeclaredAdvice();
+        return c;
+    }
+
+    // ---- only for testing!
+
+
+    public ResolvedMember[] getDeclaredJavaFields() {
+        return filterInJavaVisible(getDeclaredFields());
+    }
+
+    public ResolvedMember[] getDeclaredJavaMethods() {
+        return filterInJavaVisible(getDeclaredMethods());
+    }
+
+    public ShadowMunger[] getDeclaredShadowMungersArray() {
+        List l = (List) getDeclaredShadowMungers();
+        return (ShadowMunger[]) l.toArray(new ShadowMunger[l.size()]);
+    }
+
+    private ResolvedMember[] filterInJavaVisible(ResolvedMember[] ms) {
+        List l = new ArrayList();
+        for (int i = 0, len = ms.length; i < len; i++) {
+            if (! ms[i].isAjSynthetic() && ms[i].getAssociatedShadowMunger() == null) {
+                l.add(ms[i]);
+            }
+        }
+        return (ResolvedMember[]) l.toArray(new ResolvedMember[l.size()]);
+    }
 
+    public abstract ISourceContext getSourceContext();
 
     // ---- fields
-    
+
     public static final ResolvedType[] NONE = new ResolvedType[0];
 
-    public static final Primitive BYTE    = new Primitive("B", 1, 0);
-    public static final Primitive CHAR    = new Primitive("C", 1, 1);
-    public static final Primitive DOUBLE  = new Primitive("D", 2, 2);
-    public static final Primitive FLOAT   = new Primitive("F", 1, 3);
-    public static final Primitive INT     = new Primitive("I", 1, 4);
-    public static final Primitive LONG    = new Primitive("J", 2, 5);
-    public static final Primitive SHORT   = new Primitive("S", 1, 6);
-    public static final Primitive VOID    = new Primitive("V", 0, 8);
+    public static final Primitive BYTE = new Primitive("B", 1, 0);
+    public static final Primitive CHAR = new Primitive("C", 1, 1);
+    public static final Primitive DOUBLE = new Primitive("D", 2, 2);
+    public static final Primitive FLOAT = new Primitive("F", 1, 3);
+    public static final Primitive INT = new Primitive("I", 1, 4);
+    public static final Primitive LONG = new Primitive("J", 2, 5);
+    public static final Primitive SHORT = new Primitive("S", 1, 6);
+    public static final Primitive VOID = new Primitive("V", 0, 8);
     public static final Primitive BOOLEAN = new Primitive("Z", 1, 7);
-    public static final Missing   MISSING = new Missing();
-    
+    public static final Missing MISSING = new Missing();
+
     // ---- types
     public static ResolvedType makeArray(ResolvedType type, int dim) {
-       if (dim == 0) return type;
-       ResolvedType array = new Array("[" + type.getSignature(),type.getWorld(),type);
-       return makeArray(array,dim-1);
+        if (dim == 0) return type;
+        ResolvedType array = new Array("[" + type.getSignature(), type.getWorld(), type);
+        return makeArray(array, dim - 1);
     }
-    
+
     static class Array extends ResolvedType {
         ResolvedType componentType;
+
         Array(String s, World world, ResolvedType componentType) {
             super(s, world);
             this.componentType = componentType;
         }
+
         public final ResolvedMember[] getDeclaredFields() {
             return ResolvedMember.NONE;
         }
+
         public final ResolvedMember[] getDeclaredMethods() {
             // ??? should this return clone?  Probably not...
             // If it ever does, here is the code:
             //  ResolvedMember cloneMethod =
             //    new ResolvedMember(Member.METHOD,this,Modifier.PUBLIC,UnresolvedType.OBJECT,"clone",new UnresolvedType[]{});
             //  return new ResolvedMember[]{cloneMethod};
-               return ResolvedMember.NONE;
+            return ResolvedMember.NONE;
         }
+
         public final ResolvedType[] getDeclaredInterfaces() {
             return
-                new ResolvedType[] {
-                    world.getCoreType(CLONEABLE), 
-                    world.getCoreType(SERIALIZABLE)
-                };
+                    new ResolvedType[]{
+                            world.getCoreType(CLONEABLE),
+                            world.getCoreType(SERIALIZABLE)
+                    };
         }
+
         public final ResolvedMember[] getDeclaredPointcuts() {
             return ResolvedMember.NONE;
         }
-        
+
         public boolean hasAnnotation(UnresolvedType ofType) {
-               return false;
+            return false;
         }
-        
+
         public final ResolvedType getSuperclass() {
             return world.getCoreType(OBJECT);
         }
+
         public final boolean isAssignableFrom(ResolvedType o) {
             if (! o.isArray()) return false;
             if (o.getComponentType().isPrimitiveType()) {
@@ -760,13 +801,13 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
                 return getComponentType().resolve(world).isAssignableFrom(o.getComponentType().resolve(world));
             }
         }
-        
+
         public boolean isAssignableFrom(ResolvedType o, boolean allowMissing) {
-               return isAssignableFrom(o);
+            return isAssignableFrom(o);
         }
-        
+
         public final boolean isCoerceableFrom(ResolvedType o) {
-            if (o.equals(UnresolvedType.OBJECT) || 
+            if (o.equals(UnresolvedType.OBJECT) ||
                     o.equals(UnresolvedType.SERIALIZABLE) ||
                     o.equals(UnresolvedType.CLONEABLE)) {
                 return true;
@@ -778,101 +819,119 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
                 return getComponentType().resolve(world).isCoerceableFrom(o.getComponentType().resolve(world));
             }
         }
+
         public final int getModifiers() {
             int mask = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;
             return (componentType.getModifiers() & mask) | Modifier.FINAL;
         }
+
         public UnresolvedType getComponentType() {
             return componentType;
         }
+
         public ResolvedType getResolvedComponentType() {
             return componentType;
         }
+
         public ISourceContext getSourceContext() {
-               return getResolvedComponentType().getSourceContext();
+            return getResolvedComponentType().getSourceContext();
         }
     }
-    
+
     static class Primitive extends ResolvedType {
         private int size;
         private int index;
+
         Primitive(String signature, int size, int index) {
             super(signature, null);
             this.size = size;
             this.index = index;
         }
+
         public final int getSize() {
             return size;
         }
+
         public final int getModifiers() {
             return Modifier.PUBLIC | Modifier.FINAL;
         }
+
         public final boolean isPrimitiveType() {
             return true;
         }
+
         public boolean hasAnnotation(UnresolvedType ofType) {
-               return false;
+            return false;
         }
+
         public final boolean isAssignableFrom(ResolvedType other) {
             if (!other.isPrimitiveType()) {
-               if (!world.isInJava5Mode()) return false;
-               return validBoxing.contains(this.getSignature()+other.getSignature());
+                if (!world.isInJava5Mode()) return false;
+                return validBoxing.contains(this.getSignature() + other.getSignature());
             }
-            return assignTable[((Primitive)other).index][index];
+            return assignTable[((Primitive) other).index][index];
         }
+
         public final boolean isAssignableFrom(ResolvedType other, boolean allowMissing) {
-               return isAssignableFrom(other);
-        }        
+            return isAssignableFrom(other);
+        }
+
         public final boolean isCoerceableFrom(ResolvedType other) {
             if (this == other) return true;
             if (! other.isPrimitiveType()) return false;
-            if (index > 6 || ((Primitive)other).index > 6) return false;
+            if (index > 6 || ((Primitive) other).index > 6) return false;
             return true;
         }
+
         public ResolvedType resolve(World world) {
             this.world = world;
             return super.resolve(world);
         }
+
         public final boolean needsNoConversionFrom(ResolvedType other) {
             if (! other.isPrimitiveType()) return false;
-            return noConvertTable[((Primitive)other).index][index];
-        }           
-        private static final boolean[][] assignTable = 
-            {// to: B     C      D       F      I       J       S      V       Z        from
-                { true , true , true , true , true , true , true , false, false }, // B
-                { false, true , true , true , true , true , false, false, false }, // C
-                { false, false, true , false, false, false, false, false, false }, // D
-                { false, false, true , true , false, false, false, false, false }, // F
-                { false, false, true , true , true , true , false, false, false }, // I
-                { false, false, true , true , false, true , false, false, false }, // J
-                { false, false, true , true , true , true , true , false, false }, // S
-                { false, false, false, false, false, false, false, true , false }, // V
-                { false, false, false, false, false, false, false, false, true  }, // Z
-            };             
-        private static final boolean[][] noConvertTable = 
-            {// to: B     C      D       F      I       J       S      V       Z        from
-                { true , true , false, false, true , false, true , false, false }, // B
-                { false, true , false, false, true , false, false, false, false }, // C
-                { false, false, true , false, false, false, false, false, false }, // D
-                { false, false, false, true , false, false, false, false, false }, // F
-                { false, false, false, false, true , false, false, false, false }, // I
-                { false, false, false, false, false, true , false, false, false }, // J
-                { false, false, false, false, true , false, true , false, false }, // S
-                { false, false, false, false, false, false, false, true , false }, // V
-                { false, false, false, false, false, false, false, false, true  }, // Z
-            };             
-                
+            return noConvertTable[((Primitive) other).index][index];
+        }
+
+        private static final boolean[][] assignTable =
+                {// to: B     C      D       F      I       J       S      V       Z        from
+                        {true, true, true, true, true, true, true, false, false}, // B
+                        {false, true, true, true, true, true, false, false, false}, // C
+                        {false, false, true, false, false, false, false, false, false}, // D
+                        {false, false, true, true, false, false, false, false, false}, // F
+                        {false, false, true, true, true, true, false, false, false}, // I
+                        {false, false, true, true, false, true, false, false, false}, // J
+                        {false, false, true, true, true, true, true, false, false}, // S
+                        {false, false, false, false, false, false, false, true, false}, // V
+                        {false, false, false, false, false, false, false, false, true}, // Z
+                };
+        private static final boolean[][] noConvertTable =
+                {// to: B     C      D       F      I       J       S      V       Z        from
+                        {true, true, false, false, true, false, true, false, false}, // B
+                        {false, true, false, false, true, false, false, false, false}, // C
+                        {false, false, true, false, false, false, false, false, false}, // D
+                        {false, false, false, true, false, false, false, false, false}, // F
+                        {false, false, false, false, true, false, false, false, false}, // I
+                        {false, false, false, false, false, true, false, false, false}, // J
+                        {false, false, false, false, true, false, true, false, false}, // S
+                        {false, false, false, false, false, false, false, true, false}, // V
+                        {false, false, false, false, false, false, false, false, true}, // Z
+                };
+
         // ----
+
         public final ResolvedMember[] getDeclaredFields() {
             return ResolvedMember.NONE;
         }
+
         public final ResolvedMember[] getDeclaredMethods() {
             return ResolvedMember.NONE;
         }
+
         public final ResolvedType[] getDeclaredInterfaces() {
             return ResolvedType.NONE;
         }
+
         public final ResolvedMember[] getDeclaredPointcuts() {
             return ResolvedMember.NONE;
         }
@@ -880,35 +939,41 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
         public final ResolvedType getSuperclass() {
             return null;
         }
-        
+
         public ISourceContext getSourceContext() {
-               return null;
+            return null;
         }
-   
+
     }
 
     static class Missing extends ResolvedType {
         Missing() {
             super(MISSING_NAME, null);
-        }       
+        }
 //        public final String toString() {
 //            return "<missing>";
 //        }      
+
         public final String getName() {
-               return MISSING_NAME;
+            return MISSING_NAME;
+        }
+
+        public final boolean isMissing() {
+            return true;
         }
-        
-        public final boolean isMissing() { return true; }
-        
+
         public boolean hasAnnotation(UnresolvedType ofType) {
-               return false;
+            return false;
         }
+
         public final ResolvedMember[] getDeclaredFields() {
             return ResolvedMember.NONE;
         }
+
         public final ResolvedMember[] getDeclaredMethods() {
             return ResolvedMember.NONE;
         }
+
         public final ResolvedType[] getDeclaredInterfaces() {
             return ResolvedType.NONE;
         }
@@ -916,183 +981,193 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
         public final ResolvedMember[] getDeclaredPointcuts() {
             return ResolvedMember.NONE;
         }
+
         public final ResolvedType getSuperclass() {
             return null;
         }
+
         public final int getModifiers() {
             return 0;
         }
+
         public final boolean isAssignableFrom(ResolvedType other) {
             return false;
-        }   
+        }
+
         public final boolean isAssignableFrom(ResolvedType other, boolean allowMissing) {
             return false;
-        }   
+        }
+
         public final boolean isCoerceableFrom(ResolvedType other) {
             return false;
-        }        
+        }
+
         public boolean needsNoConversionFrom(ResolvedType other) {
             return false;
         }
+
         public ISourceContext getSourceContext() {
-               return null;
+            return null;
         }
 
     }
 
-    /** 
+    /**
      * Look up a member, takes into account any ITDs on this type.
-     * return null if not found */
-       public ResolvedMember lookupMemberNoSupers(Member member) {
-               ResolvedMember ret = lookupDirectlyDeclaredMemberNoSupers(member);
-               if (ret == null && interTypeMungers != null) {
-                       for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
-                               ConcreteTypeMunger tm = (ConcreteTypeMunger) i.next();
-                               if (matches(tm.getSignature(), member)) {
-                                       return tm.getSignature();
-                               }
-                       }
-               }
-               return ret;
-       }
-       
-       public ResolvedMember lookupMemberWithSupersAndITDs(Member member) {
-               ResolvedMember ret = lookupMemberNoSupers(member);
-               if (ret != null) return ret;
-               
-               ResolvedType supert = getSuperclass();
-               if (supert != null) {
-                       ret = supert.lookupMemberNoSupers(member);
-               }
-               
-               return ret;
-       }
-       
-       /**
-        * as lookupMemberNoSupers, but does not include ITDs
-        * @param member
-        * @return
-        */
-       public ResolvedMember lookupDirectlyDeclaredMemberNoSupers(Member member) {
-               ResolvedMember ret;
-               if (member.getKind() == Member.FIELD) {
-                       ret = lookupMember(member, getDeclaredFields());
-               } else {
-                       // assert member.getKind() == Member.METHOD || member.getKind() == Member.CONSTRUCTOR
-                       ret = lookupMember(member, getDeclaredMethods());
-               }
-               return ret;
-       }
-       
-       /**
-        * This lookup has specialized behaviour - a null result tells the
-        * EclipseTypeMunger that it should make a default implementation of a
-        * method on this type.
-        * @param member
-        * @return
-        */
-       public ResolvedMember lookupMemberIncludingITDsOnInterfaces(Member member) {
-               return lookupMemberIncludingITDsOnInterfaces(member, this);
-       }
-       
-       private ResolvedMember lookupMemberIncludingITDsOnInterfaces(Member member, ResolvedType onType) {
-               ResolvedMember ret = onType.lookupMemberNoSupers(member);
-               if (ret != null) {
-                       return ret;
-               } else {
-                       ResolvedType superType = onType.getSuperclass();
-                       if (superType != null) {
-                               ret = lookupMemberIncludingITDsOnInterfaces(member,superType);
-                       }
-                       if (ret == null) {
-                               // try interfaces then, but only ITDs now...
-                               ResolvedType[] superInterfaces = onType.getDeclaredInterfaces();
-                               for (int i = 0; i < superInterfaces.length; i++) {
-                                       ret = superInterfaces[i].lookupMethodInITDs(member);
-                                       if (ret != null) return ret;
-                               }
-                       }
-               }
-               return ret;
-       }
-       
-       protected List interTypeMungers = new ArrayList(0);
-       
-       public List getInterTypeMungers() {
-               return interTypeMungers;
-       }
-    
-    public List getInterTypeParentMungers() {
-      List l = new ArrayList();
-      for (Iterator iter = interTypeMungers.iterator(); iter.hasNext();) {
-               ConcreteTypeMunger element = (ConcreteTypeMunger) iter.next();
-               if (element.getMunger() instanceof NewParentTypeMunger) l.add(element);
-       }
-      return l;
-    }
-    
-       /**
-        * ??? This method is O(N*M) where N = number of methods and M is number of
-        * inter-type declarations in my super
-        */
-     public List getInterTypeMungersIncludingSupers() {
-        ArrayList ret = new ArrayList();
-        collectInterTypeMungers(ret);
+     * return null if not found
+     */
+    public ResolvedMember lookupMemberNoSupers(Member member) {
+        ResolvedMember ret = lookupDirectlyDeclaredMemberNoSupers(member);
+        if (ret == null && interTypeMungers != null) {
+            for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
+                ConcreteTypeMunger tm = (ConcreteTypeMunger) i.next();
+                if (matches(tm.getSignature(), member)) {
+                    return tm.getSignature();
+                }
+            }
+        }
         return ret;
     }
 
-     
-    public List getInterTypeParentMungersIncludingSupers() {
-      ArrayList ret = new ArrayList();
-      collectInterTypeParentMungers(ret);
-      return ret;
-    }
-    
-    private void collectInterTypeParentMungers(List collector) {
-        for (Iterator iter = getDirectSupertypes(); iter.hasNext();) {
+    public ResolvedMember lookupMemberWithSupersAndITDs(Member member) {
+        ResolvedMember ret = lookupMemberNoSupers(member);
+        if (ret != null) return ret;
+
+        ResolvedType supert = getSuperclass();
+        if (supert != null) {
+            ret = supert.lookupMemberNoSupers(member);
+        }
+
+        return ret;
+    }
+
+    /**
+     * as lookupMemberNoSupers, but does not include ITDs
+     *
+     * @param member
+     * @return
+     */
+    public ResolvedMember lookupDirectlyDeclaredMemberNoSupers(Member member) {
+        ResolvedMember ret;
+        if (member.getKind() == Member.FIELD) {
+            ret = lookupMember(member, getDeclaredFields());
+        } else {
+            // assert member.getKind() == Member.METHOD || member.getKind() == Member.CONSTRUCTOR
+            ret = lookupMember(member, getDeclaredMethods());
+        }
+        return ret;
+    }
+
+    /**
+     * This lookup has specialized behaviour - a null result tells the
+     * EclipseTypeMunger that it should make a default implementation of a
+     * method on this type.
+     *
+     * @param member
+     * @return
+     */
+    public ResolvedMember lookupMemberIncludingITDsOnInterfaces(Member member) {
+        return lookupMemberIncludingITDsOnInterfaces(member, this);
+    }
+
+    private ResolvedMember lookupMemberIncludingITDsOnInterfaces(Member member, ResolvedType onType) {
+        ResolvedMember ret = onType.lookupMemberNoSupers(member);
+        if (ret != null) {
+            return ret;
+        } else {
+            ResolvedType superType = onType.getSuperclass();
+            if (superType != null) {
+                ret = lookupMemberIncludingITDsOnInterfaces(member, superType);
+            }
+            if (ret == null) {
+                // try interfaces then, but only ITDs now...
+                ResolvedType[] superInterfaces = onType.getDeclaredInterfaces();
+                for (int i = 0; i < superInterfaces.length; i++) {
+                    ret = superInterfaces[i].lookupMethodInITDs(member);
+                    if (ret != null) return ret;
+                }
+            }
+        }
+        return ret;
+    }
+
+    protected List interTypeMungers = new ArrayList(0);
+
+    public List getInterTypeMungers() {
+        return interTypeMungers;
+    }
+
+    public List getInterTypeParentMungers() {
+        List l = new ArrayList();
+        for (Iterator iter = interTypeMungers.iterator(); iter.hasNext();) {
+            ConcreteTypeMunger element = (ConcreteTypeMunger) iter.next();
+            if (element.getMunger() instanceof NewParentTypeMunger) l.add(element);
+        }
+        return l;
+    }
+
+    /**
+     * ??? This method is O(N*M) where N = number of methods and M is number of
+     * inter-type declarations in my super
+     */
+    public List getInterTypeMungersIncludingSupers() {
+        ArrayList ret = new ArrayList();
+        collectInterTypeMungers(ret);
+        return ret;
+    }
+
+
+    public List getInterTypeParentMungersIncludingSupers() {
+        ArrayList ret = new ArrayList();
+        collectInterTypeParentMungers(ret);
+        return ret;
+    }
+
+    private void collectInterTypeParentMungers(List collector) {
+        for (Iterator iter = getDirectSupertypes(); iter.hasNext();) {
             ResolvedType superType = (ResolvedType) iter.next();
             superType.collectInterTypeParentMungers(collector);
         }
         collector.addAll(getInterTypeParentMungers());
     }
-        
-        
+
+
     protected void collectInterTypeMungers(List collector) {
         for (Iterator iter = getDirectSupertypes(); iter.hasNext();) {
-                       ResolvedType superType = (ResolvedType) iter.next();
+            ResolvedType superType = (ResolvedType) iter.next();
             superType.collectInterTypeMungers(collector);
-               }
-        
-        outer: for (Iterator iter1 = collector.iterator(); iter1.hasNext(); ) {
+        }
+
+        outer:
+        for (Iterator iter1 = collector.iterator(); iter1.hasNext();) {
             ConcreteTypeMunger superMunger = (ConcreteTypeMunger) iter1.next();
-            if ( superMunger.getSignature() == null) continue;
-            
-            if ( !superMunger.getSignature().isAbstract()) continue;
-            
+            if (superMunger.getSignature() == null) continue;
+
+            if (!superMunger.getSignature().isAbstract()) continue;
+
             for (Iterator iter = getInterTypeMungers().iterator(); iter.hasNext();) {
-                ConcreteTypeMunger  myMunger = (ConcreteTypeMunger) iter.next();
+                ConcreteTypeMunger myMunger = (ConcreteTypeMunger) iter.next();
                 if (conflictingSignature(myMunger.getSignature(), superMunger.getSignature())) {
                     iter1.remove();
                     continue outer;
                 }
             }
-            
+
             if (!superMunger.getSignature().isPublic()) continue;
-            
-            for (Iterator iter = getMethods(); iter.hasNext(); ) {
-                ResolvedMember method = (ResolvedMember)iter.next();
+
+            for (Iterator iter = getMethods(); iter.hasNext();) {
+                ResolvedMember method = (ResolvedMember) iter.next();
                 if (conflictingSignature(method, superMunger.getSignature())) {
                     iter1.remove();
                     continue outer;
                 }
             }
         }
-        
+
         collector.addAll(getInterTypeMungers());
     }
-    
-    
+
+
     /**
      * Check:
      * 1) That we don't have any abstract type mungers unless this type is abstract.
@@ -1100,71 +1175,74 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
      */
     public void checkInterTypeMungers() {
         if (isAbstract()) return;
-        
+
         boolean itdProblem = false;
-        
+
         for (Iterator iter = getInterTypeMungersIncludingSupers().iterator(); iter.hasNext();) {
-                       ConcreteTypeMunger munger = (ConcreteTypeMunger) iter.next();
-                       itdProblem = checkAbstractDeclaration(munger) || itdProblem; // Rule 2
+            ConcreteTypeMunger munger = (ConcreteTypeMunger) iter.next();
+            itdProblem = checkAbstractDeclaration(munger) || itdProblem; // Rule 2
 
         }
-        
+
         if (itdProblem) return; // If the rules above are broken, return right now
-        
-               for (Iterator iter = getInterTypeMungersIncludingSupers().iterator(); iter.hasNext();) {
-                       ConcreteTypeMunger munger = (ConcreteTypeMunger) iter.next();
+
+        for (Iterator iter = getInterTypeMungersIncludingSupers().iterator(); iter.hasNext();) {
+            ConcreteTypeMunger munger = (ConcreteTypeMunger) iter.next();
             if (munger.getSignature() != null && munger.getSignature().isAbstract()) { // Rule 1
-                world.getMessageHandler().handleMessage(
-                    new Message("must implement abstract inter-type declaration: " + munger.getSignature(),
-                        "", IMessage.ERROR, getSourceLocation(), null, 
-                        new ISourceLocation[] { getMungerLocation(munger) }));
+                if (munger.getMunger().getKind() == ResolvedTypeMunger.MethodDelegate) {
+                    ;//ignore for @AJ ITD as munger.getSingature() is the interface method hence abstract
+                } else {
+                    world.getMessageHandler().handleMessage(
+                            new Message("must implement abstract inter-type declaration: " + munger.getSignature(),
+                                    "", IMessage.ERROR, getSourceLocation(), null,
+                                    new ISourceLocation[]{getMungerLocation(munger)}));
+                }
             }
-               }
+        }
     }
-    
+
     /**
      * See PR70794.  This method checks that if an abstract inter-type method declaration is made on
      * an interface then it must also be public.
      * This is a compiler limitation that could be made to work in the future (if someone
      * provides a worthwhile usecase)
-     * 
+     *
      * @return indicates if the munger failed the check
      */
     private boolean checkAbstractDeclaration(ConcreteTypeMunger munger) {
-               if (munger.getMunger()!=null && (munger.getMunger() instanceof NewMethodTypeMunger)) {
-                       ResolvedMember itdMember = munger.getSignature();
-                       ResolvedType onType = itdMember.getDeclaringType().resolve(world);
-                       if (onType.isInterface() && itdMember.isAbstract() && !itdMember.isPublic()) {
-                                       world.getMessageHandler().handleMessage(
-                                                       new Message(WeaverMessages.format(WeaverMessages.ITD_ABSTRACT_MUST_BE_PUBLIC_ON_INTERFACE,munger.getSignature(),onType),"",
-                                                                       Message.ERROR,getSourceLocation(),null,
-                                                                       new ISourceLocation[]{getMungerLocation(munger)})       
-                                               );
-                                       return true;
-                               }                       
-               }
-               return false;
-    }
-    
+        if (munger.getMunger() != null && (munger.getMunger() instanceof NewMethodTypeMunger)) {
+            ResolvedMember itdMember = munger.getSignature();
+            ResolvedType onType = itdMember.getDeclaringType().resolve(world);
+            if (onType.isInterface() && itdMember.isAbstract() && !itdMember.isPublic()) {
+                world.getMessageHandler().handleMessage(
+                        new Message(WeaverMessages.format(WeaverMessages.ITD_ABSTRACT_MUST_BE_PUBLIC_ON_INTERFACE, munger.getSignature(), onType), "",
+                                Message.ERROR, getSourceLocation(), null,
+                                new ISourceLocation[]{getMungerLocation(munger)})
+                );
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Get a source location for the munger.
      * Until intertype mungers remember where they came from, the source location
      * for the munger itself is null.  In these cases use the
      * source location for the aspect containing the ITD.
-     * 
      */
     private ISourceLocation getMungerLocation(ConcreteTypeMunger munger) {
-       ISourceLocation sloc = munger.getSourceLocation();
-       if (sloc == null) {
-               sloc = munger.getAspectType().getSourceLocation();
-       }
-       return sloc;
+        ISourceLocation sloc = munger.getSourceLocation();
+        if (sloc == null) {
+            sloc = munger.getAspectType().getSourceLocation();
+        }
+        return sloc;
     }
-       
+
     /**
      * Returns a ResolvedType object representing the declaring type of this type, or
      * null if this type does not represent a non-package-level-type.
-     * 
+     * <p/>
      * <strong>Warning</strong>:  This is guaranteed to work for all member types.
      * For anonymous/local types, the only guarantee is given in JLS 13.1, where
      * it guarantees that if you call getDeclaringType() repeatedly, you will eventually
@@ -1173,660 +1251,666 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
      * @return the declaring UnresolvedType object, or null.
      */
     public ResolvedType getDeclaringType() {
-       if (isArray()) return null;
-               String name = getName();
-               int lastDollar = name.lastIndexOf('$');
-               while (lastDollar != -1) {
-                       ResolvedType ret = world.resolve(UnresolvedType.forName(name.substring(0, lastDollar)), true);
-                       if (ret != ResolvedType.MISSING) return ret;
-                       lastDollar = name.lastIndexOf('$', lastDollar-1);
-               }
-               return null;
-    }
-       
-       
-       public static boolean isVisible(int modifiers, ResolvedType targetType, ResolvedType fromType) {
-               //System.err.println("mod: " + modifiers + ", " + targetType + " and " + fromType);
-               
-               if (Modifier.isPublic(modifiers)) {
-                       return true;
-               } else if (Modifier.isPrivate(modifiers)) {
-                       return targetType.getOutermostType().equals(fromType.getOutermostType());
-               } else if (Modifier.isProtected(modifiers)) {
-                       return samePackage(targetType, fromType) || targetType.isAssignableFrom(fromType);
-               } else { // package-visible
-                       return samePackage(targetType, fromType);
-               }       
-       }
-       
-       public static boolean hasBridgeModifier(int modifiers) {
-               return (modifiers & Constants.ACC_BRIDGE)!=0;
-       }
-
-       private static boolean samePackage(
-               ResolvedType targetType,
-               ResolvedType fromType)
-       {
-               String p1 = targetType.getPackageName();
-               String p2 = fromType.getPackageName();
-               if (p1 == null) return p2 == null;
-               if (p2 == null) return false;
-               return p1.equals(p2);
-       }
-       
-       public void addInterTypeMunger(ConcreteTypeMunger munger) {
-               ResolvedMember sig = munger.getSignature();
-               if (sig == null || munger.getMunger() == null || 
-                               munger.getMunger().getKind() == ResolvedTypeMunger.PrivilegedAccess)
-               {
-                       interTypeMungers.add(munger);
-                       return;
-               }
-               
-               //System.err.println("add: " + munger + " to " + this.getClassName() + " with " + interTypeMungers);
-               if (sig.getKind() == Member.METHOD) {
-                       if (!compareToExistingMembers(munger, getMethodsWithoutIterator(false,true) /*getMethods()*/)) return;
-                       if (this.isInterface()) {
-                               if (!compareToExistingMembers(munger, 
-                                               Arrays.asList(world.getCoreType(OBJECT).getDeclaredMethods()).iterator())) return;
-                       }
-               } else if (sig.getKind() == Member.FIELD) {
-                       if (!compareToExistingMembers(munger, Arrays.asList(getDeclaredFields()).iterator())) return;
-               } else {
-                       if (!compareToExistingMembers(munger, Arrays.asList(getDeclaredMethods()).iterator())) return;
-               }
-
-               
-               // now compare to existingMungers
-               for (Iterator i = interTypeMungers.iterator(); i.hasNext(); ) {
-                       ConcreteTypeMunger existingMunger = (ConcreteTypeMunger)i.next();
-                       if (conflictingSignature(existingMunger.getSignature(), munger.getSignature())) {
-                               //System.err.println("match " + munger + " with " + existingMunger);
-                               if (isVisible(munger.getSignature().getModifiers(),
-                                                       munger.getAspectType(), existingMunger.getAspectType()))
-                               {
-                                       //System.err.println("    is visible");
-                                       int c = compareMemberPrecedence(sig, existingMunger.getSignature());
-                                       if (c == 0) {
-                                               c = getWorld().compareByPrecedenceAndHierarchy(munger.getAspectType(), existingMunger.getAspectType());
-                                       }
-                                       //System.err.println("       compare: " + c);
-                                       if (c < 0) {
-                                               // the existing munger dominates the new munger
-                                               checkLegalOverride(munger.getSignature(), existingMunger.getSignature());
-                                               return;
-                                       } else if (c > 0) {
-                                               // the new munger dominates the existing one
-                                               checkLegalOverride(existingMunger.getSignature(), munger.getSignature());
-                                               i.remove();
-                                               break;
-                                       } else {
-                                               interTypeConflictError(munger, existingMunger);
-                                               interTypeConflictError(existingMunger, munger);
-                                               return;
-                                       }                                       
-                               }
-                       }
-               }
-               //System.err.println("adding: " + munger + " to " + this);
-               interTypeMungers.add(munger);
-       }
-       
-       private boolean compareToExistingMembers(ConcreteTypeMunger munger, List existingMembersList) {
-               return compareToExistingMembers(munger,existingMembersList.iterator());
-       }
-       
-       //??? returning too soon
-       private boolean compareToExistingMembers(ConcreteTypeMunger munger, Iterator existingMembers) {
-               ResolvedMember sig = munger.getSignature();
-               while (existingMembers.hasNext()) {
-                       ResolvedMember existingMember = (ResolvedMember)existingMembers.next();
-                       //System.err.println("Comparing munger: "+sig+" with member "+existingMember);
-                       if (conflictingSignature(existingMember, munger.getSignature())) {
-                               //System.err.println("conflict: existingMember=" + existingMember + "   typeMunger=" + munger);
-                               //System.err.println(munger.getSourceLocation() + ", " + munger.getSignature() + ", " + munger.getSignature().getSourceLocation());
-                               
-                               if (isVisible(existingMember.getModifiers(), this, munger.getAspectType())) {
-                                       int c = compareMemberPrecedence(sig, existingMember);
-                                       //System.err.println("   c: " + c);
-                                       if (c < 0) {
-                                               // existingMember dominates munger
-                                               checkLegalOverride(munger.getSignature(), existingMember);
-                                               return false;
-                                       } else if (c > 0) {
-                                               // munger dominates existingMember
-                                               checkLegalOverride(existingMember, munger.getSignature());
-                                               //interTypeMungers.add(munger);  
-                                               //??? might need list of these overridden abstracts
-                                               continue;
-                                       } else {
-                                         // bridge methods can differ solely in return type.
-                                         // FIXME this whole method seems very hokey - unaware of covariance/varargs/bridging - it
-                                         // could do with a rewrite !
-                                         boolean sameReturnTypes = (existingMember.getReturnType().equals(sig.getReturnType()));
-                                         if (sameReturnTypes)
-                                                 getWorld().getMessageHandler().handleMessage(
-                                                       MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT,munger.getAspectType().getName(),
-                                                                       existingMember),
-                                                       munger.getSourceLocation())
-                                                 );
-                                       }
-                               } else if (isDuplicateMemberWithinTargetType(existingMember,this,sig)) {
-                                       getWorld().getMessageHandler().handleMessage(
-                                                       MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT,munger.getAspectType().getName(),
-                                                                       existingMember),
-                                                       munger.getSourceLocation())
-                                               );;
-                               }
-                               //return;
-                       }
-               }
-               return true;
-       }
-       
-       // we know that the member signature matches, but that the member in the target type is not visible to the aspect.
-       // this may still be disallowed if it would result in two members within the same declaring type with the same
-       // signature AND more than one of them is concrete AND they are both visible within the target type.
-       private boolean isDuplicateMemberWithinTargetType(ResolvedMember existingMember, ResolvedType targetType,ResolvedMember itdMember) {
-           if ( (existingMember.isAbstract() || itdMember.isAbstract())) return false;
-           UnresolvedType declaringType = existingMember.getDeclaringType();
-           if (!targetType.equals(declaringType)) return false;
-           // now have to test that itdMember is visible from targetType
-           if (itdMember.isPrivate()) return false;
-           if (itdMember.isPublic()) return true;
-           // must be in same package to be visible then...
-           if (!targetType.getPackageName().equals(itdMember.getDeclaringType().getPackageName())) return false;
-           
-           // trying to put two members with the same signature into the exact same type..., and both visible in that type.
-           return true;
-       }
-       
-       /**
-        * @return true if the override is legal
-        * note: calling showMessage with two locations issues TWO messages, not ONE message
-        * with an additional source location.
-        */
-       public boolean checkLegalOverride(ResolvedMember parent, ResolvedMember child) {
-               //System.err.println("check: " + child.getDeclaringType() + " overrides " + parent.getDeclaringType());
-               if (Modifier.isFinal(parent.getModifiers())) {
-                       world.showMessage(Message.ERROR,
-                                       WeaverMessages.format(WeaverMessages.CANT_OVERRIDE_FINAL_MEMBER,parent),
-                                       child.getSourceLocation(),null);
-                       return false;
-               }
-               
-               boolean incompatibleReturnTypes = false;
-               
-               // In 1.5 mode, allow for covariance on return type
-               if (world.isInJava5Mode() && parent.getKind()==Member.METHOD) {
-             ResolvedType rtParentReturnType = parent.getReturnType().resolve(world);
-                 ResolvedType rtChildReturnType  = child.getReturnType().resolve(world);
-                 incompatibleReturnTypes = !rtParentReturnType.isAssignableFrom(rtChildReturnType);
-               } else {
-                 incompatibleReturnTypes =!parent.getReturnType().equals(child.getReturnType());
-               }
-               
-               if (incompatibleReturnTypes) {
-                       world.showMessage(IMessage.ERROR,
-                                       WeaverMessages.format(WeaverMessages.ITD_RETURN_TYPE_MISMATCH,parent,child),
-                                       child.getSourceLocation(), parent.getSourceLocation());
-                       return false;
-               }               
-               if (parent.getKind() == Member.POINTCUT) {
-                       UnresolvedType[] pTypes = parent.getParameterTypes();
-                       UnresolvedType[] cTypes = child.getParameterTypes();
-                       if (!Arrays.equals(pTypes, cTypes)) {
-                               world.showMessage(IMessage.ERROR,
-                                               WeaverMessages.format(WeaverMessages.ITD_PARAM_TYPE_MISMATCH,parent,child),
-                                               child.getSourceLocation(), parent.getSourceLocation());
-                               return false;
-                       }
-               }               
-               //System.err.println("check: " + child.getModifiers() + " more visible " + parent.getModifiers());
-               if (isMoreVisible(parent.getModifiers(), child.getModifiers())) {
-                       world.showMessage(IMessage.ERROR,
-                                       WeaverMessages.format(WeaverMessages.ITD_VISIBILITY_REDUCTION,parent,child),
-                                       child.getSourceLocation(), parent.getSourceLocation());
-                       return false;
-               }
-               
-               // check declared exceptions
-               ResolvedType[] childExceptions = world.resolve(child.getExceptions());
-               ResolvedType[] parentExceptions = world.resolve(parent.getExceptions());
-               ResolvedType runtimeException = world.resolve("java.lang.RuntimeException");
-               ResolvedType error = world.resolve("java.lang.Error");
-               
-               outer: for (int i=0, leni = childExceptions.length; i < leni; i++) {
-                       //System.err.println("checking: " + childExceptions[i]);
-                       if (runtimeException.isAssignableFrom(childExceptions[i])) continue;
-                       if (error.isAssignableFrom(childExceptions[i])) continue;
-                       
-                       for (int j = 0, lenj = parentExceptions.length; j < lenj; j++) {
-                               if (parentExceptions[j].isAssignableFrom(childExceptions[i])) continue outer;
-                       }
-                       
-                       // this message is now better handled my MethodVerifier in JDT core.
+        if (isArray()) return null;
+        String name = getName();
+        int lastDollar = name.lastIndexOf('$');
+        while (lastDollar != -1) {
+            ResolvedType ret = world.resolve(UnresolvedType.forName(name.substring(0, lastDollar)), true);
+            if (ret != ResolvedType.MISSING) return ret;
+            lastDollar = name.lastIndexOf('$', lastDollar - 1);
+        }
+        return null;
+    }
+
+
+    public static boolean isVisible(int modifiers, ResolvedType targetType, ResolvedType fromType) {
+        //System.err.println("mod: " + modifiers + ", " + targetType + " and " + fromType);
+
+        if (Modifier.isPublic(modifiers)) {
+            return true;
+        } else if (Modifier.isPrivate(modifiers)) {
+            return targetType.getOutermostType().equals(fromType.getOutermostType());
+        } else if (Modifier.isProtected(modifiers)) {
+            return samePackage(targetType, fromType) || targetType.isAssignableFrom(fromType);
+        } else { // package-visible
+            return samePackage(targetType, fromType);
+        }
+    }
+
+    public static boolean hasBridgeModifier(int modifiers) {
+        return (modifiers & Constants.ACC_BRIDGE) != 0;
+    }
+
+    private static boolean samePackage(
+            ResolvedType targetType,
+            ResolvedType fromType) {
+        String p1 = targetType.getPackageName();
+        String p2 = fromType.getPackageName();
+        if (p1 == null) return p2 == null;
+        if (p2 == null) return false;
+        return p1.equals(p2);
+    }
+
+    public void addInterTypeMunger(ConcreteTypeMunger munger) {
+        ResolvedMember sig = munger.getSignature();
+        if (sig == null || munger.getMunger() == null ||
+                munger.getMunger().getKind() == ResolvedTypeMunger.PrivilegedAccess) {
+            interTypeMungers.add(munger);
+            return;
+        }
+
+        //System.err.println("add: " + munger + " to " + this.getClassName() + " with " + interTypeMungers);
+        if (sig.getKind() == Member.METHOD) {
+            if (!compareToExistingMembers(munger, getMethodsWithoutIterator(false, true) /*getMethods()*/)) return;
+            if (this.isInterface()) {
+                if (!compareToExistingMembers(munger,
+                        Arrays.asList(world.getCoreType(OBJECT).getDeclaredMethods()).iterator())) return;
+            }
+        } else if (sig.getKind() == Member.FIELD) {
+            if (!compareToExistingMembers(munger, Arrays.asList(getDeclaredFields()).iterator())) return;
+        } else {
+            if (!compareToExistingMembers(munger, Arrays.asList(getDeclaredMethods()).iterator())) return;
+        }
+
+        // now compare to existingMungers
+        for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
+            ConcreteTypeMunger existingMunger = (ConcreteTypeMunger) i.next();
+            if (conflictingSignature(existingMunger.getSignature(), munger.getSignature())) {
+                //System.err.println("match " + munger + " with " + existingMunger);
+                if (isVisible(munger.getSignature().getModifiers(),
+                        munger.getAspectType(), existingMunger.getAspectType())) {
+                    //System.err.println("    is visible");
+                    int c = compareMemberPrecedence(sig, existingMunger.getSignature());
+                    if (c == 0) {
+                        c = getWorld().compareByPrecedenceAndHierarchy(munger.getAspectType(), existingMunger.getAspectType());
+                    }
+                    //System.err.println("       compare: " + c);
+                    if (c < 0) {
+                        // the existing munger dominates the new munger
+                        checkLegalOverride(munger.getSignature(), existingMunger.getSignature());
+                        return;
+                    } else if (c > 0) {
+                        // the new munger dominates the existing one
+                        checkLegalOverride(existingMunger.getSignature(), munger.getSignature());
+                        i.remove();
+                        break;
+                    } else {
+                        interTypeConflictError(munger, existingMunger);
+                        interTypeConflictError(existingMunger, munger);
+                        return;
+                    }
+                }
+            }
+        }
+        //System.err.println("adding: " + munger + " to " + this);
+        interTypeMungers.add(munger);
+    }
+
+    private boolean compareToExistingMembers(ConcreteTypeMunger munger, List existingMembersList) {
+        return compareToExistingMembers(munger, existingMembersList.iterator());
+    }
+
+    //??? returning too soon
+    private boolean compareToExistingMembers(ConcreteTypeMunger munger, Iterator existingMembers) {
+        ResolvedMember sig = munger.getSignature();
+        while (existingMembers.hasNext()) {
+            ResolvedMember existingMember = (ResolvedMember) existingMembers.next();
+            //System.err.println("Comparing munger: "+sig+" with member "+existingMember);
+            if (conflictingSignature(existingMember, munger.getSignature())) {
+                //System.err.println("conflict: existingMember=" + existingMember + "   typeMunger=" + munger);
+                //System.err.println(munger.getSourceLocation() + ", " + munger.getSignature() + ", " + munger.getSignature().getSourceLocation());
+
+                if (isVisible(existingMember.getModifiers(), this, munger.getAspectType())) {
+                    int c = compareMemberPrecedence(sig, existingMember);
+                    //System.err.println("   c: " + c);
+                    if (c < 0) {
+                        // existingMember dominates munger
+                        checkLegalOverride(munger.getSignature(), existingMember);
+                        return false;
+                    } else if (c > 0) {
+                        // munger dominates existingMember
+                        checkLegalOverride(existingMember, munger.getSignature());
+                        //interTypeMungers.add(munger);
+                        //??? might need list of these overridden abstracts
+                        continue;
+                    } else {
+                        // bridge methods can differ solely in return type.
+                        // FIXME this whole method seems very hokey - unaware of covariance/varargs/bridging - it
+                        // could do with a rewrite !
+                        boolean sameReturnTypes = (existingMember.getReturnType().equals(sig.getReturnType()));
+                        if (sameReturnTypes)
+                            getWorld().getMessageHandler().handleMessage(
+                                    MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT, munger.getAspectType().getName(),
+                                            existingMember),
+                                            munger.getSourceLocation())
+                            );
+                    }
+                } else if (isDuplicateMemberWithinTargetType(existingMember, this, sig)) {
+                    getWorld().getMessageHandler().handleMessage(
+                            MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT, munger.getAspectType().getName(),
+                                    existingMember),
+                                    munger.getSourceLocation())
+                    );
+                    ;
+                }
+                //return;
+            }
+        }
+        return true;
+    }
+
+    // we know that the member signature matches, but that the member in the target type is not visible to the aspect.
+    // this may still be disallowed if it would result in two members within the same declaring type with the same
+    // signature AND more than one of them is concrete AND they are both visible within the target type.
+    private boolean isDuplicateMemberWithinTargetType(ResolvedMember existingMember, ResolvedType targetType, ResolvedMember itdMember) {
+        if ((existingMember.isAbstract() || itdMember.isAbstract())) return false;
+        UnresolvedType declaringType = existingMember.getDeclaringType();
+        if (!targetType.equals(declaringType)) return false;
+        // now have to test that itdMember is visible from targetType
+        if (itdMember.isPrivate()) return false;
+        if (itdMember.isPublic()) return true;
+        // must be in same package to be visible then...
+        if (!targetType.getPackageName().equals(itdMember.getDeclaringType().getPackageName())) return false;
+
+        // trying to put two members with the same signature into the exact same type..., and both visible in that type.
+        return true;
+    }
+
+    /**
+     * @return true if the override is legal
+     *         note: calling showMessage with two locations issues TWO messages, not ONE message
+     *         with an additional source location.
+     */
+    public boolean checkLegalOverride(ResolvedMember parent, ResolvedMember child) {
+        //System.err.println("check: " + child.getDeclaringType() + " overrides " + parent.getDeclaringType());
+        if (Modifier.isFinal(parent.getModifiers())) {
+            world.showMessage(Message.ERROR,
+                    WeaverMessages.format(WeaverMessages.CANT_OVERRIDE_FINAL_MEMBER, parent),
+                    child.getSourceLocation(), null);
+            return false;
+        }
+
+        boolean incompatibleReturnTypes = false;
+
+        // In 1.5 mode, allow for covariance on return type
+        if (world.isInJava5Mode() && parent.getKind() == Member.METHOD) {
+            ResolvedType rtParentReturnType = parent.getReturnType().resolve(world);
+            ResolvedType rtChildReturnType = child.getReturnType().resolve(world);
+            incompatibleReturnTypes = !rtParentReturnType.isAssignableFrom(rtChildReturnType);
+        } else {
+            incompatibleReturnTypes = !parent.getReturnType().equals(child.getReturnType());
+        }
+
+        if (incompatibleReturnTypes) {
+            world.showMessage(IMessage.ERROR,
+                    WeaverMessages.format(WeaverMessages.ITD_RETURN_TYPE_MISMATCH, parent, child),
+                    child.getSourceLocation(), parent.getSourceLocation());
+            return false;
+        }
+        if (parent.getKind() == Member.POINTCUT) {
+            UnresolvedType[] pTypes = parent.getParameterTypes();
+            UnresolvedType[] cTypes = child.getParameterTypes();
+            if (!Arrays.equals(pTypes, cTypes)) {
+                world.showMessage(IMessage.ERROR,
+                        WeaverMessages.format(WeaverMessages.ITD_PARAM_TYPE_MISMATCH, parent, child),
+                        child.getSourceLocation(), parent.getSourceLocation());
+                return false;
+            }
+        }
+        //System.err.println("check: " + child.getModifiers() + " more visible " + parent.getModifiers());
+        if (isMoreVisible(parent.getModifiers(), child.getModifiers())) {
+            world.showMessage(IMessage.ERROR,
+                    WeaverMessages.format(WeaverMessages.ITD_VISIBILITY_REDUCTION, parent, child),
+                    child.getSourceLocation(), parent.getSourceLocation());
+            return false;
+        }
+
+        // check declared exceptions
+        ResolvedType[] childExceptions = world.resolve(child.getExceptions());
+        ResolvedType[] parentExceptions = world.resolve(parent.getExceptions());
+        ResolvedType runtimeException = world.resolve("java.lang.RuntimeException");
+        ResolvedType error = world.resolve("java.lang.Error");
+
+        outer:
+        for (int i = 0, leni = childExceptions.length; i < leni; i++) {
+            //System.err.println("checking: " + childExceptions[i]);
+            if (runtimeException.isAssignableFrom(childExceptions[i])) continue;
+            if (error.isAssignableFrom(childExceptions[i])) continue;
+
+            for (int j = 0, lenj = parentExceptions.length; j < lenj; j++) {
+                if (parentExceptions[j].isAssignableFrom(childExceptions[i])) continue outer;
+            }
+
+            // this message is now better handled my MethodVerifier in JDT core.
 //                     world.showMessage(IMessage.ERROR,
 //                                     WeaverMessages.format(WeaverMessages.ITD_DOESNT_THROW,childExceptions[i].getName()),
 //                                     child.getSourceLocation(), null);
-                                               
-                       return false;
-               }
-               if (parent.isStatic() && !child.isStatic()) {
-                       world.showMessage(IMessage.ERROR,
-                                       WeaverMessages.format(WeaverMessages.ITD_OVERRIDDEN_STATIC,child,parent),
-                                       child.getSourceLocation(),null);
-                       return false;
-               } else if (child.isStatic() && !parent.isStatic()) {
-                       world.showMessage(IMessage.ERROR,
-                                       WeaverMessages.format(WeaverMessages.ITD_OVERIDDING_STATIC,child,parent),
-                                       child.getSourceLocation(),null);
-                       return false;
-               }
-               return true;
-               
-       }
-       
-       private int compareMemberPrecedence(ResolvedMember m1, ResolvedMember m2) {
-               //if (!m1.getReturnType().equals(m2.getReturnType())) return 0;
-               
-               // need to allow for the special case of 'clone' - which is like abstract but is
-               // not marked abstract.  The code below this next line seems to make assumptions
-               // about what will have gotten through the compiler based on the normal
-               // java rules.  clone goes against these...
-               if (m2.isProtected() && m2.isNative() && m2.getName().equals("clone")) return +1;
-               
-               if (Modifier.isAbstract(m1.getModifiers())) return -1;
-               if (Modifier.isAbstract(m2.getModifiers())) return +1;
-       
-               if (m1.getDeclaringType().equals(m2.getDeclaringType())) return 0;
-               
-               ResolvedType t1 = m1.getDeclaringType().resolve(world);
-               ResolvedType t2 = m2.getDeclaringType().resolve(world);
-               if (t1.isAssignableFrom(t2)) {
-                       return -1;
-               }
-               if (t2.isAssignableFrom(t1)) {
-                       return +1;
-               }
-               return 0;
-       }
-       
-
-       public static boolean isMoreVisible(int m1, int m2) {
-               if (Modifier.isPrivate(m1)) return false;
-               if (isPackage(m1)) return Modifier.isPrivate(m2);
-               if (Modifier.isProtected(m1)) return /* private package */ (Modifier.isPrivate(m2) || isPackage(m2));
-               if (Modifier.isPublic(m1)) return /* private package protected */ ! Modifier.isPublic(m2);
-               throw new RuntimeException("bad modifier: " + m1);
-       }
-
-       private static boolean isPackage(int i) {
-               return (0 == (i & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED)));
-       }
-
-       private void interTypeConflictError(
-               ConcreteTypeMunger m1,
-               ConcreteTypeMunger m2)
-       {
-               //XXX this works only if we ignore separate compilation issues
-               //XXX dual errors possible if (this instanceof BcelObjectType) return;
-               
-               //System.err.println("conflict at " + m2.getSourceLocation());
-               getWorld().showMessage(IMessage.ERROR,
-                               WeaverMessages.format(WeaverMessages.ITD_CONFLICT,m1.getAspectType().getName(),
-                                                                       m2.getSignature(),m2.getAspectType().getName()),
-                                               m2.getSourceLocation(), getSourceLocation());
-       }
-       
-       
-       public ResolvedMember lookupSyntheticMember(Member member) {
-               //??? horribly inefficient
-               //for (Iterator i = 
-               //System.err.println("lookup " + member + " in " + interTypeMungers);
-               for (Iterator i = interTypeMungers.iterator(); i.hasNext(); ) {
-                       ConcreteTypeMunger m = (ConcreteTypeMunger)i.next();
-                       ResolvedMember ret = m.getMatchingSyntheticMember(member);
-                       if (ret != null) {
-                               //System.err.println("   found: " + ret);
-                               return ret;
-                       }
-               }
-               
+
+            return false;
+        }
+        if (parent.isStatic() && !child.isStatic()) {
+            world.showMessage(IMessage.ERROR,
+                    WeaverMessages.format(WeaverMessages.ITD_OVERRIDDEN_STATIC, child, parent),
+                    child.getSourceLocation(), null);
+            return false;
+        } else if (child.isStatic() && !parent.isStatic()) {
+            world.showMessage(IMessage.ERROR,
+                    WeaverMessages.format(WeaverMessages.ITD_OVERIDDING_STATIC, child, parent),
+                    child.getSourceLocation(), null);
+            return false;
+        }
+        return true;
+
+    }
+
+    private int compareMemberPrecedence(ResolvedMember m1, ResolvedMember m2) {
+        //if (!m1.getReturnType().equals(m2.getReturnType())) return 0;
+
+        // need to allow for the special case of 'clone' - which is like abstract but is
+        // not marked abstract.  The code below this next line seems to make assumptions
+        // about what will have gotten through the compiler based on the normal
+        // java rules.  clone goes against these...
+        if (m2.isProtected() && m2.isNative() && m2.getName().equals("clone")) return +1;
+
+        if (Modifier.isAbstract(m1.getModifiers())) return -1;
+        if (Modifier.isAbstract(m2.getModifiers())) return +1;
+
+        if (m1.getDeclaringType().equals(m2.getDeclaringType())) return 0;
+
+        ResolvedType t1 = m1.getDeclaringType().resolve(world);
+        ResolvedType t2 = m2.getDeclaringType().resolve(world);
+        if (t1.isAssignableFrom(t2)) {
+            return -1;
+        }
+        if (t2.isAssignableFrom(t1)) {
+            return +1;
+        }
+        return 0;
+    }
+
+
+    public static boolean isMoreVisible(int m1, int m2) {
+        if (Modifier.isPrivate(m1)) return false;
+        if (isPackage(m1)) return Modifier.isPrivate(m2);
+        if (Modifier.isProtected(m1)) return /* private package */ (Modifier.isPrivate(m2) || isPackage(m2));
+        if (Modifier.isPublic(m1)) return /* private package protected */ ! Modifier.isPublic(m2);
+        throw new RuntimeException("bad modifier: " + m1);
+    }
+
+    private static boolean isPackage(int i) {
+        return (0 == (i & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED)));
+    }
+
+    private void interTypeConflictError(
+            ConcreteTypeMunger m1,
+            ConcreteTypeMunger m2) {
+        //XXX this works only if we ignore separate compilation issues
+        //XXX dual errors possible if (this instanceof BcelObjectType) return;
+
+        //System.err.println("conflict at " + m2.getSourceLocation());
+        getWorld().showMessage(IMessage.ERROR,
+                WeaverMessages.format(WeaverMessages.ITD_CONFLICT, m1.getAspectType().getName(),
+                        m2.getSignature(), m2.getAspectType().getName()),
+                m2.getSourceLocation(), getSourceLocation());
+    }
+
+
+    public ResolvedMember lookupSyntheticMember(Member member) {
+        //??? horribly inefficient
+        //for (Iterator i =
+        //System.err.println("lookup " + member + " in " + interTypeMungers);
+        for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
+            ConcreteTypeMunger m = (ConcreteTypeMunger) i.next();
+            ResolvedMember ret = m.getMatchingSyntheticMember(member);
+            if (ret != null) {
+                //System.err.println("   found: " + ret);
+                return ret;
+            }
+        }
+
 //             if (this.getSuperclass() != ResolvedType.OBJECT && this.getSuperclass() != null) {
 //                     return getSuperclass().lookupSyntheticMember(member);
 //             }
-               
-               return null;
-       }
-
-       public void clearInterTypeMungers() {
-               if (isRawType()) getGenericType().clearInterTypeMungers();
-               interTypeMungers = new ArrayList();
-       }
-
-
-       public boolean isTopmostImplementor(ResolvedType interfaceType) {
-               if (isInterface()) return false;
-               if (!interfaceType.isAssignableFrom(this,true)) return false;
-               // check that I'm truly the topmost implementor
-               if (this.getSuperclass().isMissing()) return true; // we don't know anything about supertype, and it can't be exposed to weaver
-               if (interfaceType.isAssignableFrom(this.getSuperclass(),true)) {
-                       return false;
-               }
-               return true;
-       }
-       
-       public ResolvedType getTopmostImplementor(ResolvedType interfaceType) {
-               if (isInterface()) return null;
-               if (!interfaceType.isAssignableFrom(this)) return null;
-               // Check if my super class is an implementor?
-               ResolvedType higherType  = this.getSuperclass().getTopmostImplementor(interfaceType);
-               if (higherType!=null) return higherType;
-               return this;
-       }
-       
-       private ResolvedType findHigher(ResolvedType other) {
-        if (this == other) return this;
-     for(Iterator i = other.getDirectSupertypes(); i.hasNext(); ) {
-       ResolvedType rtx = (ResolvedType)i.next();
-       boolean b = this.isAssignableFrom(rtx);
-       if (b) return rtx;
-     }       
-     return null;
-       }
-       
-       public List getExposedPointcuts() {
-               List ret = new ArrayList();
-               if (getSuperclass() != null) ret.addAll(getSuperclass().getExposedPointcuts());
-               
-               for (Iterator i = Arrays.asList(getDeclaredInterfaces()).iterator(); i.hasNext(); ) {
-                       ResolvedType t = (ResolvedType)i.next();
-                       addPointcutsResolvingConflicts(ret, Arrays.asList(t.getDeclaredPointcuts()), false);
-               }
-               addPointcutsResolvingConflicts(ret, Arrays.asList(getDeclaredPointcuts()), true);
-               for (Iterator i = ret.iterator(); i.hasNext(); ) {
-                       ResolvedPointcutDefinition inherited = (ResolvedPointcutDefinition)i.next();
+
+        return null;
+    }
+
+    public void clearInterTypeMungers() {
+        if (isRawType()) getGenericType().clearInterTypeMungers();
+        interTypeMungers = new ArrayList();
+    }
+
+
+    public boolean isTopmostImplementor(ResolvedType interfaceType) {
+        if (isInterface()) return false;
+        if (!interfaceType.isAssignableFrom(this, true)) return false;
+        // check that I'm truly the topmost implementor
+        if (this.getSuperclass().isMissing()) return true; // we don't know anything about supertype, and it can't be exposed to weaver
+        if (interfaceType.isAssignableFrom(this.getSuperclass(), true)) {
+            return false;
+        }
+        return true;
+    }
+
+    public ResolvedType getTopmostImplementor(ResolvedType interfaceType) {
+        if (isInterface()) return null;
+        if (!interfaceType.isAssignableFrom(this)) return null;
+        // Check if my super class is an implementor?
+        ResolvedType higherType = this.getSuperclass().getTopmostImplementor(interfaceType);
+        if (higherType != null) return higherType;
+        return this;
+    }
+
+    private ResolvedType findHigher(ResolvedType other) {
+        if (this == other) return this;
+        for (Iterator i = other.getDirectSupertypes(); i.hasNext();) {
+            ResolvedType rtx = (ResolvedType) i.next();
+            boolean b = this.isAssignableFrom(rtx);
+            if (b) return rtx;
+        }
+        return null;
+    }
+
+    public List getExposedPointcuts() {
+        List ret = new ArrayList();
+        if (getSuperclass() != null) ret.addAll(getSuperclass().getExposedPointcuts());
+
+        for (Iterator i = Arrays.asList(getDeclaredInterfaces()).iterator(); i.hasNext();) {
+            ResolvedType t = (ResolvedType) i.next();
+            addPointcutsResolvingConflicts(ret, Arrays.asList(t.getDeclaredPointcuts()), false);
+        }
+        addPointcutsResolvingConflicts(ret, Arrays.asList(getDeclaredPointcuts()), true);
+        for (Iterator i = ret.iterator(); i.hasNext();) {
+            ResolvedPointcutDefinition inherited = (ResolvedPointcutDefinition) i.next();
 //                     System.err.println("looking at: " + inherited + " in " + this);
 //                     System.err.println("            " + inherited.isAbstract() + " in " + this.isAbstract());
-                       if (inherited.isAbstract()) {
-                               if (!this.isAbstract()) {
-                                       getWorld().showMessage(IMessage.ERROR,
-                                                       WeaverMessages.format(WeaverMessages.POINCUT_NOT_CONCRETE,inherited,this.getName()),
-                                                       inherited.getSourceLocation(), this.getSourceLocation());
-                               }
-                       }
-               }               
-               
-               
-               return ret;
-       }
-       
-       private void addPointcutsResolvingConflicts(List acc, List added, boolean isOverriding) {
-               for (Iterator i = added.iterator(); i.hasNext();) {
-                       ResolvedPointcutDefinition toAdd =
-                               (ResolvedPointcutDefinition) i.next();
-                               //System.err.println("adding: " + toAdd);
-                       for (Iterator j = acc.iterator(); j.hasNext();) {
-                               ResolvedPointcutDefinition existing =
-                                       (ResolvedPointcutDefinition) j.next();
-                               if (existing == toAdd) continue;
-                               if (!isVisible(existing.getModifiers(),
-                                       existing.getDeclaringType().resolve(getWorld()),
-                                       this)) {
-                                       continue;
-                               }
-                               if (conflictingSignature(existing, toAdd)) {
-                                       if (isOverriding) {
-                                               checkLegalOverride(existing, toAdd);
-                                               j.remove();
-                                       } else {
-                                               getWorld().showMessage(
-                                                       IMessage.ERROR,
-                                                       WeaverMessages.format(WeaverMessages.CONFLICTING_INHERITED_POINTCUTS,this.getName() + toAdd.getSignature()),
-                                                       existing.getSourceLocation(),
-                                                       toAdd.getSourceLocation());
-                                               j.remove();
-                                       }
-                               }
-                       }
-                       acc.add(toAdd);
-               }
-       }
-       
-       public ISourceLocation getSourceLocation() { return null; }
-       public boolean isExposedToWeaver() { return false; }
-       public WeaverStateInfo getWeaverState() {
-               return null;
-       }
-       
-       /**
-        * Overridden by ReferenceType to return a sensible answer for parameterized and raw types.
-        * @return
-        */
-       public ResolvedType getGenericType() {
-               if (!(isParameterizedType() || isRawType()))
-                       throw new BCException("The type "+getBaseName()+" is not parameterized or raw - it has no generic type");
-               return null;
-       }
-       
-       public ResolvedType parameterizedWith(UnresolvedType[] typeParameters) {
-               if (!(isGenericType() || isParameterizedType())) return this;
-               return TypeFactory.createParameterizedType(this.getGenericType(), typeParameters, getWorld());
-       }
-       
-       /**
-        * Iff I am a parameterized type, and any of my parameters are type variable
-        * references, return a version with those type parameters replaced in accordance
-        * with the passed bindings.
-        */
-       public UnresolvedType parameterize(Map typeBindings) {
-               if (!isParameterizedType()) throw new IllegalStateException("Can't parameterize a type that is not a parameterized type");
-       boolean workToDo = false;
-       for (int i = 0; i < typeParameters.length; i++) {
-                       if (typeParameters[i].isTypeVariableReference()) {
-                               workToDo = true;
-                       }
-               }
-       if (!workToDo) {
-               return this;
-       } else {
-               UnresolvedType[] newTypeParams = new UnresolvedType[typeParameters.length];
-               for (int i = 0; i < newTypeParams.length; i++) {
-                               newTypeParams[i] = typeParameters[i];
-                               if (newTypeParams[i].isTypeVariableReference()) {
-                                       TypeVariableReferenceType tvrt = (TypeVariableReferenceType) newTypeParams[i];
-                                       UnresolvedType binding = (UnresolvedType) typeBindings.get(tvrt.getTypeVariable().getName());
-                                       if (binding != null) newTypeParams[i] = binding;
-                               }
-                       }
-               return TypeFactory.createParameterizedType(getGenericType(), newTypeParams, getWorld());
-       }
-    }
-       
-       public boolean hasParameterizedSuperType() {
-               getParameterizedSuperTypes();
-               return parameterizedSuperTypes.length > 0;
-       }
-       
-       public boolean hasGenericSuperType() {
-               ResolvedType[] superTypes = getDeclaredInterfaces();
-               for (int i = 0; i < superTypes.length; i++) {
-                       if (superTypes[i].isGenericType()) return true;
-               }
-               return false;
-       }
-       
-       private ResolvedType[] parameterizedSuperTypes = null;
-       /**
-        * Similar to the above method, but accumulates the super types
-        * @return
-        */
-       public ResolvedType[] getParameterizedSuperTypes() {
-               if (parameterizedSuperTypes != null) return parameterizedSuperTypes;
-               List accumulatedTypes = new ArrayList();
-               accumulateParameterizedSuperTypes(this,accumulatedTypes);
-               ResolvedType[] ret = new ResolvedType[accumulatedTypes.size()];
-               parameterizedSuperTypes = (ResolvedType[]) accumulatedTypes.toArray(ret);
-               return parameterizedSuperTypes;
-       }
-       
-       private void accumulateParameterizedSuperTypes(ResolvedType forType, List parameterizedTypeList) {
-               if (forType.isParameterizedType()) {
-                       parameterizedTypeList.add(forType);
-               }
-               if (forType.getSuperclass() != null) {
-                       accumulateParameterizedSuperTypes(forType.getSuperclass(), parameterizedTypeList);
-               }
-               ResolvedType[] interfaces = forType.getDeclaredInterfaces();
-               for (int i = 0; i < interfaces.length; i++) {
-                       accumulateParameterizedSuperTypes(interfaces[i], parameterizedTypeList);
-               }
-       }
-
-       /**
-        * Types may have pointcuts just as they have methods and fields.
-        */
-       public ResolvedPointcutDefinition findPointcut(String name, World world) {
-           throw new UnsupportedOperationException("Not yet implemenented");
-       }
-
-       /**
-        * Determines if variables of this type could be assigned values of another
-        * with lots of help.  
-        * java.lang.Object is convertable from all types.
-        * A primitive type is convertable from X iff it's assignable from X.
-        * A reference type is convertable from X iff it's coerceable from X.
-        * In other words, X isConvertableFrom Y iff the compiler thinks that _some_ value of Y
-        * could be assignable to a variable of type X without loss of precision. 
-        * 
-        * @param other the other type
-        * @param world the {@link World} in which the possible assignment should be checked.
-        * @return true iff variables of this type could be assigned values of other with possible conversion
-        */
-     public final boolean isConvertableFrom(ResolvedType other) {
+            if (inherited.isAbstract()) {
+                if (!this.isAbstract()) {
+                    getWorld().showMessage(IMessage.ERROR,
+                            WeaverMessages.format(WeaverMessages.POINCUT_NOT_CONCRETE, inherited, this.getName()),
+                            inherited.getSourceLocation(), this.getSourceLocation());
+                }
+            }
+        }
+
+
+        return ret;
+    }
+
+    private void addPointcutsResolvingConflicts(List acc, List added, boolean isOverriding) {
+        for (Iterator i = added.iterator(); i.hasNext();) {
+            ResolvedPointcutDefinition toAdd =
+                    (ResolvedPointcutDefinition) i.next();
+            //System.err.println("adding: " + toAdd);
+            for (Iterator j = acc.iterator(); j.hasNext();) {
+                ResolvedPointcutDefinition existing =
+                        (ResolvedPointcutDefinition) j.next();
+                if (existing == toAdd) continue;
+                if (!isVisible(existing.getModifiers(),
+                        existing.getDeclaringType().resolve(getWorld()),
+                        this)) {
+                    continue;
+                }
+                if (conflictingSignature(existing, toAdd)) {
+                    if (isOverriding) {
+                        checkLegalOverride(existing, toAdd);
+                        j.remove();
+                    } else {
+                        getWorld().showMessage(
+                                IMessage.ERROR,
+                                WeaverMessages.format(WeaverMessages.CONFLICTING_INHERITED_POINTCUTS, this.getName() + toAdd.getSignature()),
+                                existing.getSourceLocation(),
+                                toAdd.getSourceLocation());
+                        j.remove();
+                    }
+                }
+            }
+            acc.add(toAdd);
+        }
+    }
+
+    public ISourceLocation getSourceLocation() {
+        return null;
+    }
+
+    public boolean isExposedToWeaver() {
+        return false;
+    }
+
+    public WeaverStateInfo getWeaverState() {
+        return null;
+    }
+
+    /**
+     * Overridden by ReferenceType to return a sensible answer for parameterized and raw types.
+     *
+     * @return
+     */
+    public ResolvedType getGenericType() {
+        if (!(isParameterizedType() || isRawType()))
+            throw new BCException("The type " + getBaseName() + " is not parameterized or raw - it has no generic type");
+        return null;
+    }
+
+    public ResolvedType parameterizedWith(UnresolvedType[] typeParameters) {
+        if (!(isGenericType() || isParameterizedType())) return this;
+        return TypeFactory.createParameterizedType(this.getGenericType(), typeParameters, getWorld());
+    }
+
+    /**
+     * Iff I am a parameterized type, and any of my parameters are type variable
+     * references, return a version with those type parameters replaced in accordance
+     * with the passed bindings.
+     */
+    public UnresolvedType parameterize(Map typeBindings) {
+        if (!isParameterizedType()) throw new IllegalStateException("Can't parameterize a type that is not a parameterized type");
+        boolean workToDo = false;
+        for (int i = 0; i < typeParameters.length; i++) {
+            if (typeParameters[i].isTypeVariableReference()) {
+                workToDo = true;
+            }
+        }
+        if (!workToDo) {
+            return this;
+        } else {
+            UnresolvedType[] newTypeParams = new UnresolvedType[typeParameters.length];
+            for (int i = 0; i < newTypeParams.length; i++) {
+                newTypeParams[i] = typeParameters[i];
+                if (newTypeParams[i].isTypeVariableReference()) {
+                    TypeVariableReferenceType tvrt = (TypeVariableReferenceType) newTypeParams[i];
+                    UnresolvedType binding = (UnresolvedType) typeBindings.get(tvrt.getTypeVariable().getName());
+                    if (binding != null) newTypeParams[i] = binding;
+                }
+            }
+            return TypeFactory.createParameterizedType(getGenericType(), newTypeParams, getWorld());
+        }
+    }
+
+    public boolean hasParameterizedSuperType() {
+        getParameterizedSuperTypes();
+        return parameterizedSuperTypes.length > 0;
+    }
+
+    public boolean hasGenericSuperType() {
+        ResolvedType[] superTypes = getDeclaredInterfaces();
+        for (int i = 0; i < superTypes.length; i++) {
+            if (superTypes[i].isGenericType()) return true;
+        }
+        return false;
+    }
+
+    private ResolvedType[] parameterizedSuperTypes = null;
+
+    /**
+     * Similar to the above method, but accumulates the super types
+     *
+     * @return
+     */
+    public ResolvedType[] getParameterizedSuperTypes() {
+        if (parameterizedSuperTypes != null) return parameterizedSuperTypes;
+        List accumulatedTypes = new ArrayList();
+        accumulateParameterizedSuperTypes(this, accumulatedTypes);
+        ResolvedType[] ret = new ResolvedType[accumulatedTypes.size()];
+        parameterizedSuperTypes = (ResolvedType[]) accumulatedTypes.toArray(ret);
+        return parameterizedSuperTypes;
+    }
+
+    private void accumulateParameterizedSuperTypes(ResolvedType forType, List parameterizedTypeList) {
+        if (forType.isParameterizedType()) {
+            parameterizedTypeList.add(forType);
+        }
+        if (forType.getSuperclass() != null) {
+            accumulateParameterizedSuperTypes(forType.getSuperclass(), parameterizedTypeList);
+        }
+        ResolvedType[] interfaces = forType.getDeclaredInterfaces();
+        for (int i = 0; i < interfaces.length; i++) {
+            accumulateParameterizedSuperTypes(interfaces[i], parameterizedTypeList);
+        }
+    }
+
+    /**
+     * Types may have pointcuts just as they have methods and fields.
+     */
+    public ResolvedPointcutDefinition findPointcut(String name, World world) {
+        throw new UnsupportedOperationException("Not yet implemenented");
+    }
+
+    /**
+     * Determines if variables of this type could be assigned values of another
+     * with lots of help.
+     * java.lang.Object is convertable from all types.
+     * A primitive type is convertable from X iff it's assignable from X.
+     * A reference type is convertable from X iff it's coerceable from X.
+     * In other words, X isConvertableFrom Y iff the compiler thinks that _some_ value of Y
+     * could be assignable to a variable of type X without loss of precision.
+     *
+     * @param other the other type
+     * @param world the {@link World} in which the possible assignment should be checked.
+     * @return true iff variables of this type could be assigned values of other with possible conversion
+     */
+    public final boolean isConvertableFrom(ResolvedType other) {
 
 //      // version from TypeX
 //      if (this.equals(OBJECT)) return true;
 //      if (this.isPrimitiveType() || other.isPrimitiveType()) return this.isAssignableFrom(other);
 //      return this.isCoerceableFrom(other);
 //      
-        
-        // version from ResolvedTypeX
-        if (this.equals(OBJECT)) return true;
-        if (world.isInJava5Mode()) {
-               if (this.isPrimitiveType()^other.isPrimitiveType()) { // If one is primitive and the other isnt
-                       if (validBoxing.contains(this.getSignature()+other.getSignature())) return true;
-               }
-        }
-        if (this.isPrimitiveType() || other.isPrimitiveType()) return this.isAssignableFrom(other);
-        return this.isCoerceableFrom(other);
-        }
-
-       /**
-        * Determines if the variables of this type could be assigned values
-        * of another type without casting.  This still allows for assignment conversion
-        * as per JLS 2ed 5.2.  For object types, this means supertypeOrEqual(THIS, OTHER).
-        * 
-        * @param other the other type
-        * @param world the {@link World} in which the possible assignment should be checked.
-        * @return true iff variables of this type could be assigned values of other without casting
-        * @exception NullPointerException if other is null
-        */
-       public abstract boolean isAssignableFrom(ResolvedType other);
-       
-       public abstract boolean isAssignableFrom(ResolvedType other, boolean allowMissing);
-
-       /**
-        * Determines if values of another type could possibly be cast to
-        * this type.  The rules followed are from JLS 2ed 5.5, "Casting Conversion".
-        *   
-        * <p> This method should be commutative, i.e., for all UnresolvedType a, b and all World w:
-        * 
-        * <blockquote><pre>
-        *    a.isCoerceableFrom(b, w) == b.isCoerceableFrom(a, w)
-        * </pre></blockquote>
-        *
-        * @param other the other type
-        * @param world the {@link World} in which the possible coersion should be checked.
-        * @return true iff values of other could possibly be cast to this type. 
-        * @exception NullPointerException if other is null.
-        */
-       public abstract boolean isCoerceableFrom(ResolvedType other);
-       
-       public boolean needsNoConversionFrom(ResolvedType o) {
-           return isAssignableFrom(o);
-       }
-       
-       /** 
+
+        // version from ResolvedTypeX
+        if (this.equals(OBJECT)) return true;
+        if (world.isInJava5Mode()) {
+            if (this.isPrimitiveType() ^ other.isPrimitiveType()) { // If one is primitive and the other isnt
+                if (validBoxing.contains(this.getSignature() + other.getSignature())) return true;
+            }
+        }
+        if (this.isPrimitiveType() || other.isPrimitiveType()) return this.isAssignableFrom(other);
+        return this.isCoerceableFrom(other);
+    }
+
+    /**
+     * Determines if the variables of this type could be assigned values
+     * of another type without casting.  This still allows for assignment conversion
+     * as per JLS 2ed 5.2.  For object types, this means supertypeOrEqual(THIS, OTHER).
+     *
+     * @param other the other type
+     * @param world the {@link World} in which the possible assignment should be checked.
+     * @return true iff variables of this type could be assigned values of other without casting
+     * @throws NullPointerException if other is null
+     */
+    public abstract boolean isAssignableFrom(ResolvedType other);
+
+    public abstract boolean isAssignableFrom(ResolvedType other, boolean allowMissing);
+
+    /**
+     * Determines if values of another type could possibly be cast to
+     * this type.  The rules followed are from JLS 2ed 5.5, "Casting Conversion".
+     * <p/>
+     * <p> This method should be commutative, i.e., for all UnresolvedType a, b and all World w:
+     * <p/>
+     * <blockquote><pre>
+     *    a.isCoerceableFrom(b, w) == b.isCoerceableFrom(a, w)
+     * </pre></blockquote>
+     *
+     * @param other the other type
+     * @param world the {@link World} in which the possible coersion should be checked.
+     * @return true iff values of other could possibly be cast to this type.
+     * @throws NullPointerException if other is null.
+     */
+    public abstract boolean isCoerceableFrom(ResolvedType other);
+
+    public boolean needsNoConversionFrom(ResolvedType o) {
+        return isAssignableFrom(o);
+    }
+
+    /**
      * Implemented by ReferenceTypes
      */
-       public String getSignatureForAttribute() {
-               throw new RuntimeException("Cannot ask this type "+this+" for a generic sig attribute");
-       }
-       
-       private FuzzyBoolean parameterizedWithAMemberTypeVariable = FuzzyBoolean.MAYBE;
-       
-       /**
-        * return true if the parameterization of this type includes a member type variable.  Member
-        * type variables occur in generic methods/ctors.
-        */
-       public boolean isParameterizedWithAMemberTypeVariable() {
-               // MAYBE means we haven't worked it out yet...
-               if (parameterizedWithAMemberTypeVariable==FuzzyBoolean.MAYBE) {
-                       
-                       // if there are no type parameters then we cant be...
-                       if (typeParameters==null || typeParameters.length==0) {
-                               parameterizedWithAMemberTypeVariable = FuzzyBoolean.NO;
-                               return false;
-                       }
-                       
-                       for (int i = 0; i < typeParameters.length; i++) {
-                               UnresolvedType aType = (ResolvedType)typeParameters[i];
-                               if (aType.isTypeVariableReference()  && ((TypeVariableReference)aType).getTypeVariable().getDeclaringElementKind()==TypeVariable.METHOD) {
-                                       parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES;
-                                       return true;
-                               }
-                               if (aType.isParameterizedType()) {
-                                       boolean b = aType.isParameterizedWithAMemberTypeVariable();
-                                       if (b) {
-                                               parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES;
-                                               return true;
-                                       }
-                               }
-                               if (aType.isGenericWildcard()) {
-                                       if (aType.isExtends()) {
-                                               boolean b = false;
-                                               UnresolvedType upperBound = aType.getUpperBound();
-                                               if (upperBound.isParameterizedType()) {
-                                                       b = upperBound.isParameterizedWithAMemberTypeVariable();
-                                               } else if (upperBound.isTypeVariableReference() && ((TypeVariableReference)upperBound).getTypeVariable().getDeclaringElementKind()==TypeVariable.METHOD) {
-                                                       b = true;
-                                               }
-                                               if (b) {
-                                                       parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES;
-                                                       return true;
-                                               }
-                                               // FIXME asc need to check additional interface bounds
-                                       }
-                                       if (aType.isSuper()) {
-                                               boolean b = false;
-                                               UnresolvedType lowerBound = aType.getLowerBound();
-                                               if (lowerBound.isParameterizedType()) {
-                                                       b = lowerBound.isParameterizedWithAMemberTypeVariable();
-                                               } else if (lowerBound.isTypeVariableReference() && ((TypeVariableReference)lowerBound).getTypeVariable().getDeclaringElementKind()==TypeVariable.METHOD) {
-                                                       b = true;
-                                               }
-                                               if (b) {
-                                                       parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES;
-                                                       return true;
-                                               }
-                                       }
-                               }
-                       }
-                       parameterizedWithAMemberTypeVariable=FuzzyBoolean.NO;
-               }
-               return parameterizedWithAMemberTypeVariable.alwaysTrue();
-       }
-           
+    public String getSignatureForAttribute() {
+        throw new RuntimeException("Cannot ask this type " + this + " for a generic sig attribute");
+    }
+
+    private FuzzyBoolean parameterizedWithAMemberTypeVariable = FuzzyBoolean.MAYBE;
+
+    /**
+     * return true if the parameterization of this type includes a member type variable.  Member
+     * type variables occur in generic methods/ctors.
+     */
+    public boolean isParameterizedWithAMemberTypeVariable() {
+        // MAYBE means we haven't worked it out yet...
+        if (parameterizedWithAMemberTypeVariable == FuzzyBoolean.MAYBE) {
+
+            // if there are no type parameters then we cant be...
+            if (typeParameters == null || typeParameters.length == 0) {
+                parameterizedWithAMemberTypeVariable = FuzzyBoolean.NO;
+                return false;
+            }
+
+            for (int i = 0; i < typeParameters.length; i++) {
+                UnresolvedType aType = (ResolvedType) typeParameters[i];
+                if (aType.isTypeVariableReference() && ((TypeVariableReference) aType).getTypeVariable().getDeclaringElementKind() == TypeVariable.METHOD) {
+                    parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES;
+                    return true;
+                }
+                if (aType.isParameterizedType()) {
+                    boolean b = aType.isParameterizedWithAMemberTypeVariable();
+                    if (b) {
+                        parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES;
+                        return true;
+                    }
+                }
+                if (aType.isGenericWildcard()) {
+                    if (aType.isExtends()) {
+                        boolean b = false;
+                        UnresolvedType upperBound = aType.getUpperBound();
+                        if (upperBound.isParameterizedType()) {
+                            b = upperBound.isParameterizedWithAMemberTypeVariable();
+                        } else if (upperBound.isTypeVariableReference() && ((TypeVariableReference) upperBound).getTypeVariable().getDeclaringElementKind() == TypeVariable.METHOD) {
+                            b = true;
+                        }
+                        if (b) {
+                            parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES;
+                            return true;
+                        }
+                        // FIXME asc need to check additional interface bounds
+                    }
+                    if (aType.isSuper()) {
+                        boolean b = false;
+                        UnresolvedType lowerBound = aType.getLowerBound();
+                        if (lowerBound.isParameterizedType()) {
+                            b = lowerBound.isParameterizedWithAMemberTypeVariable();
+                        } else if (lowerBound.isTypeVariableReference() && ((TypeVariableReference) lowerBound).getTypeVariable().getDeclaringElementKind() == TypeVariable.METHOD) {
+                            b = true;
+                        }
+                        if (b) {
+                            parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES;
+                            return true;
+                        }
+                    }
+                }
+            }
+            parameterizedWithAMemberTypeVariable = FuzzyBoolean.NO;
+        }
+        return parameterizedWithAMemberTypeVariable.alwaysTrue();
+    }
+
 }
index 6a432dd7645aebce61d6838b7b3865c9ba94a789..48af493b563fb8ec1b8b9f93c5c669aaa515ebc0 100644 (file)
@@ -7,7 +7,8 @@
  * http://www.eclipse.org/legal/cpl-v10.html 
  *  
  * Contributors: 
- *     PARC     initial implementation 
+ *     PARC     initial implementation
+ *     Alexandre Vasseur    @AspectJ ITDs
  * ******************************************************************/
 
 
@@ -246,7 +247,9 @@ public abstract class ResolvedTypeMunger {
        
        public static final Kind AnnotationOnType = new Kind("AnnotationOnType",8); // not serialized
 
-       public static final String SUPER_DISPATCH_NAME = "superDispatch";
+    public static final Kind MethodDelegate = new Kind("MethodDelegate", 9);// not serialized, @AJ ITDs
+
+    public static final String SUPER_DISPATCH_NAME = "superDispatch";
 
 
        public void setSuperMethodsCalled(Set c) {
index 87fcbf22ea2414888e2b5730ad7a17462b354078..d4ea693077f66edeb0667de56c3331647ef4ffff 100644 (file)
@@ -48,6 +48,9 @@ import org.aspectj.weaver.ResolvedPointcutDefinition;
 import org.aspectj.weaver.ResolvedType;
 import org.aspectj.weaver.UnresolvedType;
 import org.aspectj.weaver.WeaverMessages;
+import org.aspectj.weaver.ResolvedTypeMunger;
+import org.aspectj.weaver.ResolvedMember;
+import org.aspectj.weaver.MethodDelegateTypeMunger;
 import org.aspectj.weaver.patterns.AndPointcut;
 import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
 import org.aspectj.weaver.patterns.DeclarePrecedence;
@@ -68,6 +71,8 @@ import org.aspectj.weaver.patterns.PerTypeWithin;
 import org.aspectj.weaver.patterns.Pointcut;
 import org.aspectj.weaver.patterns.SimpleScope;
 import org.aspectj.weaver.patterns.TypePattern;
+import org.aspectj.weaver.patterns.DeclareParents;
+import org.aspectj.weaver.patterns.ExactTypePattern;
 
 /**
  * Annotation defined aspect reader.
@@ -151,10 +156,12 @@ public class AtAjAttributes {
     private static class AjAttributeFieldStruct extends AjAttributeStruct {
 
         final Field field;
+        final BcelField bField;
 
-        public AjAttributeFieldStruct(Field field, ResolvedType type, ISourceContext sourceContext, IMessageHandler messageHandler) {
+        public AjAttributeFieldStruct(Field field, BcelField bField, ResolvedType type, ISourceContext sourceContext, IMessageHandler messageHandler) {
             super(type, sourceContext, messageHandler);
             this.field = field;
+            this.bField = bField;
         }
     }
 
@@ -162,7 +169,7 @@ public class AtAjAttributes {
      * Annotations are RuntimeVisible only. This allow us to not visit RuntimeInvisible ones.
      *
      * @param attribute
-     * @return
+     * @return true if runtime visible annotation
      */
     public static boolean acceptAttribute(Attribute attribute) {
         return (attribute instanceof RuntimeVisibleAnnotations);
@@ -178,7 +185,7 @@ public class AtAjAttributes {
      * @return list of AjAttributes
      */
     public static List readAj5ClassAttributes(JavaClass javaClass, ReferenceType type, ISourceContext context, IMessageHandler msgHandler, boolean isCodeStyleAspect) {
-        //FIXME AV - 1.5 M3 feature limitation, kick after M3 ships
+        //FIXME AV - 1.5 feature limitation, kick after implemented
         try {
             Constant[] cpool = javaClass.getConstantPool().getConstantPool();
             for (int i = 0; i < cpool.length; i++) {
@@ -282,19 +289,21 @@ public class AtAjAttributes {
         }
 
 
-        // code style declare error / warning are class attributes
+        // code style declare error / warning / implements / parents are field attributes
         for (int i = 0; i < javaClass.getFields().length; i++) {
             Field field = javaClass.getFields()[i];
             if (field.getName().startsWith(NameMangler.PREFIX)) continue;  // already dealt with by ajc...
             //FIXME alex optimize, this method struct will gets recreated for advice extraction
-            AjAttributeFieldStruct fstruct = new AjAttributeFieldStruct(field, type, context, msgHandler);
+            AjAttributeFieldStruct fstruct = new AjAttributeFieldStruct(field, null, type, context, msgHandler);
             Attribute[] fattributes = field.getAttributes();
 
             for (int j = 0; j < fattributes.length; j++) {
                 Attribute fattribute = fattributes[j];
                 if (acceptAttribute(fattribute)) {
                     RuntimeAnnotations frvs = (RuntimeAnnotations) fattribute;
-                    if (handleDeclareErrorOrWarningAnnotation(frvs, fstruct)) {
+                    if (handleDeclareErrorOrWarningAnnotation(frvs, fstruct)
+                            || handleDeclareImplementsAnnotation(frvs, fstruct)
+                            || handleDeclareParentsAnnotation(frvs, fstruct)) {
                         // semantic check - must be in an @Aspect [remove if previous block bypassed in advance]
                         if (!type.isAnnotationStyleAspect()) {
                             msgHandler.handleMessage(
@@ -344,42 +353,42 @@ public class AtAjAttributes {
         for (int i = 0; i < attributes.length; i++) {
             Attribute attribute = attributes[i];
             try {
-                               if (acceptAttribute(attribute)) {
-                                   RuntimeAnnotations rvs = (RuntimeAnnotations) attribute;
-                                   hasAtAspectJAnnotationMustReturnVoid = hasAtAspectJAnnotationMustReturnVoid || handleBeforeAnnotation(
-                                           rvs, struct, preResolvedPointcut
-                                   );
-                                   hasAtAspectJAnnotationMustReturnVoid = hasAtAspectJAnnotationMustReturnVoid || handleAfterAnnotation(
-                                           rvs, struct, preResolvedPointcut
-                                   );
-                                   hasAtAspectJAnnotationMustReturnVoid = hasAtAspectJAnnotationMustReturnVoid || handleAfterReturningAnnotation(
-                                           rvs, struct, preResolvedPointcut, bMethod
-                                   );
-                                   hasAtAspectJAnnotationMustReturnVoid = hasAtAspectJAnnotationMustReturnVoid || handleAfterThrowingAnnotation(
-                                           rvs, struct, preResolvedPointcut, bMethod
-                                   );
-                                   hasAtAspectJAnnotation = hasAtAspectJAnnotation || handleAroundAnnotation(
-                                           rvs, struct, preResolvedPointcut
-                                   );
-                                   // there can only be one RuntimeVisible bytecode attribute
-                                   break;
-                               }
-                       } catch (ReturningFormalNotDeclaredInAdviceSignatureException e) {
-                               msgHandler.handleMessage(
-                                       new Message(
-                                                       WeaverMessages.format(WeaverMessages.RETURNING_FORMAL_NOT_DECLARED_IN_ADVICE,e.getFormalName()),
-                                                       IMessage.ERROR,
-                                                       null,
-                                                       bMethod.getSourceLocation())
-                               );
-                       } catch (ThrownFormalNotDeclaredInAdviceSignatureException e) {
-                               msgHandler.handleMessage(
-                                               new Message(
-                                                               WeaverMessages.format(WeaverMessages.THROWN_FORMAL_NOT_DECLARED_IN_ADVICE,e.getFormalName()),
-                                                               IMessage.ERROR,
-                                                               null,
-                                                               bMethod.getSourceLocation())
-                                       );                      }
+                if (acceptAttribute(attribute)) {
+                    RuntimeAnnotations rvs = (RuntimeAnnotations) attribute;
+                    hasAtAspectJAnnotationMustReturnVoid = hasAtAspectJAnnotationMustReturnVoid || handleBeforeAnnotation(
+                            rvs, struct, preResolvedPointcut
+                    );
+                    hasAtAspectJAnnotationMustReturnVoid = hasAtAspectJAnnotationMustReturnVoid || handleAfterAnnotation(
+                            rvs, struct, preResolvedPointcut
+                    );
+                    hasAtAspectJAnnotationMustReturnVoid = hasAtAspectJAnnotationMustReturnVoid || handleAfterReturningAnnotation(
+                            rvs, struct, preResolvedPointcut, bMethod
+                    );
+                    hasAtAspectJAnnotationMustReturnVoid = hasAtAspectJAnnotationMustReturnVoid || handleAfterThrowingAnnotation(
+                            rvs, struct, preResolvedPointcut, bMethod
+                    );
+                    hasAtAspectJAnnotation = hasAtAspectJAnnotation || handleAroundAnnotation(
+                            rvs, struct, preResolvedPointcut
+                    );
+                    // there can only be one RuntimeVisible bytecode attribute
+                    break;
+                }
+            } catch (ReturningFormalNotDeclaredInAdviceSignatureException e) {
+                msgHandler.handleMessage(
+                    new Message(
+                            WeaverMessages.format(WeaverMessages.RETURNING_FORMAL_NOT_DECLARED_IN_ADVICE,e.getFormalName()),
+                            IMessage.ERROR,
+                            null,
+                            bMethod.getSourceLocation())
+                );
+            } catch (ThrownFormalNotDeclaredInAdviceSignatureException e) {
+                msgHandler.handleMessage(
+                        new Message(
+                                WeaverMessages.format(WeaverMessages.THROWN_FORMAL_NOT_DECLARED_IN_ADVICE,e.getFormalName()),
+                                IMessage.ERROR,
+                                null,
+                                bMethod.getSourceLocation())
+                    );                 }
         }
         hasAtAspectJAnnotation = hasAtAspectJAnnotation || hasAtAspectJAnnotationMustReturnVoid;
 
@@ -421,7 +430,7 @@ public class AtAjAttributes {
             );
             ;// go ahead
         }
-        
+
         return struct.ajAttributes;
     }
 
@@ -434,8 +443,31 @@ public class AtAjAttributes {
      * @param msgHandler
      * @return list of AjAttributes, always empty for now
      */
-    public static List readAj5FieldAttributes(Field field, ResolvedType type, ISourceContext context, IMessageHandler msgHandler) {
-        return Collections.EMPTY_LIST;
+    public static List readAj5FieldAttributes(Field field, BcelField bField, ResolvedType type, ISourceContext context, IMessageHandler msgHandler) {
+        //TODO use ? if (field.getName().startsWith(NameMangler.PREFIX)) return Collections.EMPTY_LIST;  // already dealt with by ajc...
+//
+//        // bypass primitive type fields - useless for @DeclareParents/Implements (interface)
+//        if (bField.getType().isPrimitiveType()) return Collections.EMPTY_LIST;
+//
+//        AjAttributeFieldStruct struct = new AjAttributeFieldStruct(field, bField, type, context, msgHandler);
+//        Attribute[] attributes = field.getAttributes();
+//
+//        boolean hasAtAspectJAnnotation = false;
+//        for (int i = 0; i < attributes.length; i++) {
+//            Attribute attribute = attributes[i];
+//            try {
+//                if (acceptAttribute(attribute)) {
+//                    RuntimeAnnotations rvs = (RuntimeAnnotations) attribute;
+//                    hasAtAspectJAnnotation = hasAtAspectJAnnotation || handleDeclareImplementsAnnotation(
+//                            rvs, struct//, preResolvedPointcut//FIXME add in src layer
+//                    );
+//                }
+//            } catch (Exception e) {
+//
+//            }
+//        }
+//
+        return Collections.EMPTY_LIST;//struct.ajAttributes;
     }
 
     /**
@@ -486,10 +518,10 @@ public class AtAjAttributes {
                 FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
                 final IScope binding;
                 binding = new BindingScope(
-                               struct.enclosingType,
-                               struct.context,
-                               bindings
-                               );
+                            struct.enclosingType,
+                            struct.context,
+                            bindings
+                        );
                 perClause.resolve(binding);
                 return true;
             }
@@ -572,6 +604,106 @@ public class AtAjAttributes {
         return false;
     }
 
+    /**
+     * Read @DeclareImplements
+     *
+     * @param runtimeAnnotations
+     * @param struct
+     * @return true if found
+     */
+    private static boolean handleDeclareImplementsAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeFieldStruct struct) {//, ResolvedPointcutDefinition preResolvedPointcut) {
+        Annotation deci = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREIMPLEMENTS_ANNOTATION);
+        if (deci != null) {
+            ElementNameValuePair deciPatternNVP = getAnnotationElement(deci, VALUE);
+            String deciPattern = deciPatternNVP.getValue().stringifyValue();
+            if (deciPattern != null) {
+                TypePattern typePattern = parseTypePattern(deciPattern, struct);
+                ResolvedType fieldType = UnresolvedType.forSignature(struct.field.getSignature()).resolve(struct.enclosingType.getWorld());
+                if (fieldType.isPrimitiveType()) {
+                    return false;
+                } else if (fieldType.isInterface()) {
+                    TypePattern parent = new ExactTypePattern(UnresolvedType.forSignature(struct.field.getSignature()), false, false);
+                    parent.resolve(struct.enclosingType.getWorld());
+                    List parents = new ArrayList(1);
+                    parents.add(parent);
+                    //TODO kick ISourceLocation sl = struct.bField.getSourceLocation();    ??
+                    struct.ajAttributes.add(
+                            new AjAttribute.DeclareAttribute(
+                                    new DeclareParents(
+                                        typePattern,
+                                        parents,
+                                        false
+                                    )
+                            )
+                    );
+                    return true;
+                } else {
+                    reportError("@DeclareImplements: can only be used on field whose type is an interface", struct);
+                    return false;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Read @DeclareParents
+     *
+     * @param runtimeAnnotations
+     * @param struct
+     * @return true if found
+     */
+    private static boolean handleDeclareParentsAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeFieldStruct struct) {//, ResolvedPointcutDefinition preResolvedPointcut) {
+        Annotation decp = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREPARENTS_ANNOTATION);
+        if (decp != null) {
+            ElementNameValuePair decpPatternNVP = getAnnotationElement(decp, VALUE);
+            String decpPattern = decpPatternNVP.getValue().stringifyValue();
+            if (decpPattern != null) {
+                TypePattern typePattern = parseTypePattern(decpPattern, struct);
+                ResolvedType fieldType = UnresolvedType.forSignature(struct.field.getSignature()).resolve(struct.enclosingType.getWorld());
+                if (fieldType.isPrimitiveType()) {
+                    return false;
+                } else if (fieldType.isInterface() && (struct.field.isPublic() && struct.field.isStatic())) {
+                    TypePattern parent = new ExactTypePattern(UnresolvedType.forSignature(struct.field.getSignature()), false, false);
+                    parent.resolve(struct.enclosingType.getWorld());
+                    //TODO kick ISourceLocation sl = struct.bField.getSourceLocation();    ??
+                    // first add the declare implements like
+                    List parents = new ArrayList(1); parents.add(parent);
+                    struct.ajAttributes.add(
+                            new AjAttribute.DeclareAttribute(
+                                    new DeclareParents(
+                                        typePattern,
+                                        parents,
+                                        false
+                                    )
+                            )
+                    );
+                    // then iterate on field interface hierarchy (not object)
+                    for (Iterator it = fieldType.getMethods(); it.hasNext();) {
+                        ResolvedMember method = (ResolvedMember)it.next();
+                        if (method.isAbstract()) {
+                            struct.ajAttributes.add(
+                                    new AjAttribute.TypeMunger(
+                                            new MethodDelegateTypeMunger(
+                                                method,
+                                                struct.enclosingType,
+                                                struct.field.getName(),
+                                                typePattern
+                                            )
+                                    )
+                            );
+                        }
+                    }
+                    return true;
+                } else {
+                    reportError("@DeclareParents: can only be used on a public static field whose type is an interface", struct);
+                    return false;
+                }
+            }
+        }
+        return false;
+    }
+
     /**
      * Read @Before
      *
@@ -691,10 +823,10 @@ public class AtAjAttributes {
      * @return true if found
      */
     private static boolean handleAfterReturningAnnotation(
-               RuntimeAnnotations runtimeAnnotations, 
-               AjAttributeMethodStruct struct, 
-               ResolvedPointcutDefinition preResolvedPointcut,
-               BcelMethod owningMethod) 
+            RuntimeAnnotations runtimeAnnotations,
+            AjAttributeMethodStruct struct,
+            ResolvedPointcutDefinition preResolvedPointcut,
+            BcelMethod owningMethod)
     throws ReturningFormalNotDeclaredInAdviceSignatureException
     {
         Annotation after = getAnnotation(runtimeAnnotations, AjcMemberMaker.AFTERRETURNING_ANNOTATION);
@@ -724,8 +856,8 @@ public class AtAjAttributes {
                 if (isNullOrEmpty(returned)) {
                     returned = null;
                 } else {
-                       // check that thrownFormal exists as the last parameter in the advice
-                       String[] pNames = owningMethod.getParameterNames();
+                       // check that thrownFormal exists as the last parameter in the advice
+                    String[] pNames = owningMethod.getParameterNames();
                     if (pNames == null || pNames.length == 0 || !Arrays.asList(pNames).contains(returned)) {
                         throw new ReturningFormalNotDeclaredInAdviceSignatureException(returned);
                     }
@@ -788,10 +920,10 @@ public class AtAjAttributes {
      * @return true if found
      */
     private static boolean handleAfterThrowingAnnotation(
-               RuntimeAnnotations runtimeAnnotations, 
-               AjAttributeMethodStruct struct, 
-               ResolvedPointcutDefinition preResolvedPointcut, 
-               BcelMethod owningMethod)
+            RuntimeAnnotations runtimeAnnotations,
+            AjAttributeMethodStruct struct,
+            ResolvedPointcutDefinition preResolvedPointcut,
+            BcelMethod owningMethod)
     throws ThrownFormalNotDeclaredInAdviceSignatureException
     {
         Annotation after = getAnnotation(runtimeAnnotations, AjcMemberMaker.AFTERTHROWING_ANNOTATION);
@@ -821,11 +953,11 @@ public class AtAjAttributes {
                 if (isNullOrEmpty(thrownFormal)) {
                     thrownFormal = null;
                 } else {
-                       // check that thrownFormal exists as the last parameter in the advice
-                       String[] pNames = owningMethod.getParameterNames();
-                       if (pNames == null || pNames.length == 0 || !Arrays.asList(pNames).contains(thrownFormal)) {
-                               throw new ThrownFormalNotDeclaredInAdviceSignatureException(thrownFormal);
-                       }
+                    // check that thrownFormal exists as the last parameter in the advice
+                    String[] pNames = owningMethod.getParameterNames();
+                    if (pNames == null || pNames.length == 0 || !Arrays.asList(pNames).contains(thrownFormal)) {
+                        throw new ThrownFormalNotDeclaredInAdviceSignatureException(thrownFormal);
+                    }
                 }
             }
 
@@ -1066,7 +1198,7 @@ public class AtAjAttributes {
      * Method.toString() is not suitable.
      *
      * @param method
-     * @return
+     * @return a readable representation of a method
      */
     private static String methodToString(Method method) {
         StringBuffer sb = new StringBuffer();
@@ -1080,7 +1212,7 @@ public class AtAjAttributes {
      * Field.toString() is not suitable.
      *
      * @param field
-     * @return
+     * @return a readable representation of a field
      */
     private static String fieldToString(Field field) {
         StringBuffer sb = new StringBuffer();
@@ -1167,7 +1299,7 @@ public class AtAjAttributes {
      * Compute the flag for the xxxJoinPoint extra argument
      *
      * @param method
-     * @return
+     * @return extra arg flag
      */
     private static int extractExtraArgument(Method method) {
         Type[] methodArgs = method.getArgumentTypes();
@@ -1182,7 +1314,7 @@ public class AtAjAttributes {
      * Compute the flag for the xxxJoinPoint extra argument
      *
      * @param argumentSignatures
-     * @return
+     * @return  extra arg flag
      */
     public static int extractExtraArgument(String[] argumentSignatures) {
         int extraArgument = 0;
@@ -1205,7 +1337,7 @@ public class AtAjAttributes {
      *
      * @param rvs
      * @param annotationType
-     * @return
+     * @return annotation
      */
     private static Annotation getAnnotation(RuntimeAnnotations rvs, UnresolvedType annotationType) {
         final String annotationTypeName = annotationType.getName();
@@ -1224,7 +1356,7 @@ public class AtAjAttributes {
      *
      * @param annotation
      * @param elementName
-     * @return
+     * @return annotation NVP
      */
     private static ElementNameValuePair getAnnotationElement(Annotation annotation, String elementName) {
         for (Iterator iterator1 = annotation.getValues().iterator(); iterator1.hasNext();) {
@@ -1241,7 +1373,7 @@ public class AtAjAttributes {
      * returns an empty array upon inconsistency
      *
      * @param method
-     * @return
+     * @return method arg names as in source
      */
     private static String[] getMethodArgumentNamesAsInSource(Method method) {
         if (method.getArgumentTypes().length == 0) {
@@ -1363,7 +1495,7 @@ public class AtAjAttributes {
      * Helper to test empty strings
      *
      * @param s
-     * @return
+     * @return true if empty or null
      */
     private static boolean isNullOrEmpty(String s) {
         return (s == null || s.length() <= 0);
@@ -1437,7 +1569,7 @@ public class AtAjAttributes {
      * @param pointcutString
      * @param struct
      * @param allowIf
-     * @return
+     * @return pointcut, unresolved
      */
     private static Pointcut parsePointcut(String pointcutString, AjAttributeStruct struct, boolean allowIf) {
         try {
@@ -1465,7 +1597,7 @@ public class AtAjAttributes {
      *
      * @param patternString
      * @param location
-     * @return
+     * @return type pattern
      */
     private static TypePattern parseTypePattern(String patternString, AjAttributeStruct location) {
         try {
@@ -1509,26 +1641,26 @@ public class AtAjAttributes {
             return node;
         }
     }
-    
+
     static class ThrownFormalNotDeclaredInAdviceSignatureException extends Exception {
-       
-       private String formalName;
-       
-       public ThrownFormalNotDeclaredInAdviceSignatureException(String formalName) {
-               this.formalName = formalName;
-       }
-       
-       public String getFormalName() { return formalName; }
+
+        private String formalName;
+
+        public ThrownFormalNotDeclaredInAdviceSignatureException(String formalName) {
+            this.formalName = formalName;
+        }
+
+        public String getFormalName() { return formalName; }
     }
-    
+
     static class ReturningFormalNotDeclaredInAdviceSignatureException extends Exception {
-       
-       private String formalName;
-       
-       public ReturningFormalNotDeclaredInAdviceSignatureException(String formalName) {
-               this.formalName = formalName;
-       }
-       
-       public String getFormalName() { return formalName; }
+
+        private String formalName;
+
+        public ReturningFormalNotDeclaredInAdviceSignatureException(String formalName) {
+            this.formalName = formalName;
+        }
+
+        public String getFormalName() { return formalName; }
     }
 }
index 0e6f0f16211aa898d988d6d682b5b1525ceba369..b5346b158e0da64d88ce414798ca5241607dd9c4 100644 (file)
@@ -64,7 +64,7 @@ final class BcelField extends ResolvedMemberImpl {
        private void unpackAttributes(World world) {
                Attribute[] attrs = field.getAttributes();
         List as = BcelAttributes.readAjAttributes(getDeclaringType().getClassName(),attrs, getSourceContext(world),world.getMessageHandler(),bcelObjectType.getWeaverVersionAttribute());
-        as.addAll(AtAjAttributes.readAj5FieldAttributes(field, world.resolve(getDeclaringType()), getSourceContext(world), world.getMessageHandler()));
+        as.addAll(AtAjAttributes.readAj5FieldAttributes(field, this, world.resolve(getDeclaringType()), getSourceContext(world), world.getMessageHandler()));
 
                for (Iterator iter = as.iterator(); iter.hasNext();) {
                        AjAttribute a = (AjAttribute) iter.next();
index c6818b2bf82e133f5c108a9d2d12e7b1c25a57d4..10d116c3e5c5df777f12b87a771d5c0bd19dda7b 100644 (file)
@@ -273,7 +273,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
        }
 
 
-       private void processAttributes(List attributeList, List pointcuts, boolean fromAnnotations) {
+    private void processAttributes(List attributeList, List pointcuts, boolean fromAnnotations) {
                for (Iterator iter = attributeList.iterator(); iter.hasNext();) {
                        AjAttribute a = (AjAttribute) iter.next();
                        //System.err.println("unpacking: " + this + " and " + a);
index 32a8d36d7a7c3aad252c3a29eca05bb44e66d577..8f7e418a7b2a124268f3448bb4f928a9e1c09963 100644 (file)
@@ -7,7 +7,8 @@
  * http://www.eclipse.org/legal/cpl-v10.html 
  *  
  * Contributors: 
- *     PARC     initial implementation 
+ *     PARC     initial implementation
+ *     Alexandre Vasseur    @AspectJ ITDs
  * ******************************************************************/
 
 
@@ -58,6 +59,7 @@ import org.aspectj.weaver.TypeVariableReference;
 import org.aspectj.weaver.UnresolvedType;
 import org.aspectj.weaver.WeaverMessages;
 import org.aspectj.weaver.WeaverStateInfo;
+import org.aspectj.weaver.MethodDelegateTypeMunger;
 import org.aspectj.weaver.World;
 import org.aspectj.weaver.patterns.DeclareAnnotation;
 import org.aspectj.weaver.patterns.Pointcut;
@@ -83,6 +85,8 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                        changed = mungeNewField(weaver, (NewFieldTypeMunger)munger);
                } else if (munger.getKind() == ResolvedTypeMunger.Method) {
                        changed = mungeNewMethod(weaver, (NewMethodTypeMunger)munger);
+        } else if (munger.getKind() == ResolvedTypeMunger.MethodDelegate) {
+            changed = mungeMethodDelegate(weaver, (MethodDelegateTypeMunger)munger);
                } else if (munger.getKind() == ResolvedTypeMunger.PerObjectInterface) {
                        changed = mungePerObjectInterface(weaver, (PerObjectInterfaceTypeMunger)munger);
                        worthReporting = false;
@@ -99,7 +103,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                        changed = mungeNewParent(weaver, (NewParentTypeMunger)munger);
                } else if (munger.getKind() == ResolvedTypeMunger.AnnotationOnType) {
                        changed = mungeNewAnnotationOnType(weaver,(AnnotationOnTypeMunger)munger);
-               } else {
+        } else {
                        throw new RuntimeException("unimplemented");
                }
                
@@ -231,16 +235,18 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                         boolean satisfiedByITD = false;
                         for (Iterator ii = newParentTarget.getType().getInterTypeMungersIncludingSupers().iterator(); ii.hasNext(); ) {
                             ConcreteTypeMunger m = (ConcreteTypeMunger)ii.next();
-                            if (m.getMunger() instanceof NewMethodTypeMunger) {
-                            ResolvedMember sig = m.getSignature();
-                            if (!Modifier.isAbstract(sig.getModifiers())) {
-                                if (ResolvedType
-                                    .matches(
-                                        AjcMemberMaker.interMethod(
-                                            sig,m.getAspectType(),sig.getDeclaringType().resolve(weaver.getWorld()).isInterface()),o)) {
-                                    satisfiedByITD = true;
+                            if (m.getMunger().getKind() == ResolvedTypeMunger.Method) {//FIXME AVITD was instanceof
+                                ResolvedMember sig = m.getSignature();
+                                if (!Modifier.isAbstract(sig.getModifiers())) {
+                                    if (ResolvedType
+                                        .matches(
+                                            AjcMemberMaker.interMethod(
+                                                sig,m.getAspectType(),sig.getDeclaringType().resolve(weaver.getWorld()).isInterface()),o)) {
+                                        satisfiedByITD = true;
+                                    }
                                 }
-                            }
+                            } else if (m.getMunger().getKind() == ResolvedTypeMunger.MethodDelegate) {
+                                satisfiedByITD = true;//FIXME AVITD that should be enough, no need to check more
                             }
                         }
                         if (!satisfiedByITD) {
@@ -883,6 +889,151 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                }
        }
        
+    private boolean mungeMethodDelegate(BcelClassWeaver weaver, MethodDelegateTypeMunger munger) {
+        ResolvedMember introduced = munger.getSignature();
+
+        LazyClassGen gen = weaver.getLazyClassGen();
+        boolean mungingInterface = gen.isInterface();
+
+        ResolvedType fromType = weaver.getWorld().resolve(introduced.getDeclaringType(),munger.getSourceLocation());
+        if (fromType.isRawType()) fromType = fromType.getGenericType();
+
+        if (gen.getType().isAnnotation() || gen.getType().isEnum()) {
+            // don't signal error as it could be a consequence of a wild type pattern
+            return false;
+        }
+
+        boolean shouldApply = munger.matches(weaver.getLazyClassGen().getType(), aspectType);
+        if (shouldApply) {
+            LazyMethodGen mg = new LazyMethodGen(
+                    introduced.getModifiers() - Modifier.ABSTRACT,
+                    BcelWorld.makeBcelType(introduced.getReturnType()),
+                    introduced.getName(),
+                    BcelWorld.makeBcelTypes(introduced.getParameterTypes()),
+                    BcelWorld.makeBcelTypesAsClassNames(introduced.getExceptions()),
+                    gen
+            );
+            //FIXME AVITD annotation copy from annotation on ITD interface
+            // but need the BcelObjectType for the ITD interface..
+            // how?
+            // For copying the annotations across, we have to discover the real type
+            // which is holding them.
+//            if (weaver.getWorld().isInJava5Mode()){
+//                AnnotationX annotationsOnRealMember[] = null;
+//                //ResolvedType toLookOn = fromType;
+//                //if (fromType.isRawType()) toLookOn = fromType.getGenericType();
+//                annotationsOnRealMember = introduced.getAnnotations();
+//
+//                if (annotationsOnRealMember!=null) {
+//                    for (int i = 0; i < annotationsOnRealMember.length; i++) {
+//                        AnnotationX annotationX = annotationsOnRealMember[i];
+//                        Annotation a = annotationX.getBcelAnnotation();
+//                        AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPoolGen(),true);
+//                        mg.addAnnotation(new AnnotationX(ag.getAnnotation(),weaver.getWorld()));
+//                    }
+//                }
+////                // the below loop fixes the very special (and very stupid)
+////                // case where an aspect declares an annotation
+////                // on an ITD it declared on itself.
+////                List allDecams = weaver.getWorld().getDeclareAnnotationOnMethods();
+////                for (Iterator i = allDecams.iterator(); i.hasNext();){
+////                    DeclareAnnotation decaMC = (DeclareAnnotation) i.next();
+////                    if (decaMC.matches(unMangledInterMethod,weaver.getWorld())
+////                            && mg.getEnclosingClass().getType() == aspectType) {
+////                        mg.addAnnotation(decaMC.getAnnotationX());
+////                    }
+////                }
+//            }
+
+
+            InstructionList body = new InstructionList();
+            InstructionFactory fact = gen.getFactory();
+
+            // getstatic field from aspect
+            body.append(Utility.createGet(fact, munger.getDelegate()));
+
+            int pos = 0;
+            Type[] paramTypes = BcelWorld.makeBcelTypes(introduced.getParameterTypes());
+            for (int i = 0, len = paramTypes.length; i < len; i++) {
+                Type paramType = paramTypes[i];
+                body.append(InstructionFactory.createLoad(paramType, pos));
+                pos+=paramType.getSize();
+            }
+            body.append(Utility.createInvoke(fact, weaver.getWorld(), introduced));
+            body.append(
+                InstructionFactory.createReturn(
+                    BcelWorld.makeBcelType(introduced.getReturnType())
+                )
+            );
+
+            mg.getBody().append(body);
+            // XXX make sure to check that we set exceptions properly on this guy.
+            weaver.addLazyMethodGen(mg);
+            weaver.getLazyClassGen().warnOnAddedMethod(mg.getMethod(),getSignature().getSourceLocation());
+            return true;
+        }
+        return false;
+//        else if (onInterface && !Modifier.isAbstract(unMangledInterMethod.getModifiers())) {
+//
+//            // This means the 'gen' should be the top most implementor
+//            // - if it is *not* then something went wrong after we worked
+//            // out that it was the top most implementor (see pr49657)
+//            if (!gen.getType().isTopmostImplementor(onType)) {
+//                ResolvedType rtx = gen.getType().getTopmostImplementor(onType);
+//                if (!rtx.isExposedToWeaver()) {
+//                    ISourceLocation sLoc = munger.getSourceLocation();
+//                    weaver.getWorld().getMessageHandler().handleMessage(MessageUtil.error(
+//                            WeaverMessages.format(WeaverMessages.ITD_NON_EXPOSED_IMPLEMENTOR,rtx,getAspectType().getName()),
+//                            (sLoc==null?getAspectType().getSourceLocation():sLoc)));
+//                } else {
+//                    // XXX what does this state mean?
+//                    // We have incorrectly identified what is the top most implementor and its not because
+//                    // a type wasn't exposed to the weaver
+//                }
+//                return false;
+//            } else {
+//
+//              ResolvedMember mangledInterMethod =
+//                    AjcMemberMaker.interMethod(unMangledInterMethod, aspectType, false);
+//
+//              LazyMethodGen mg = makeMethodGen(gen, mangledInterMethod);
+//              if (mungingInterface) {
+//                // we want the modifiers of the ITD to be used for all *implementors* of the
+//                // interface, but the method itself we add to the interface must be public abstract
+//                mg.setAccessFlags(Modifier.PUBLIC | Modifier.ABSTRACT);
+//              }
+//
+//              Type[] paramTypes = BcelWorld.makeBcelTypes(mangledInterMethod.getParameterTypes());
+//              Type returnType = BcelWorld.makeBcelType(mangledInterMethod.getReturnType());
+//
+//              InstructionList body = mg.getBody();
+//              InstructionFactory fact = gen.getFactory();
+//              int pos = 0;
+//
+//              if (!mangledInterMethod.isStatic()) {
+//                body.append(InstructionFactory.createThis());
+//                pos++;
+//              }
+//              for (int i = 0, len = paramTypes.length; i < len; i++) {
+//                Type paramType = paramTypes[i];
+//                body.append(InstructionFactory.createLoad(paramType, pos));
+//                pos+=paramType.getSize();
+//              }
+//              body.append(Utility.createInvoke(fact, weaver.getWorld(), interMethodBody));
+//              body.append(InstructionFactory.createReturn(returnType));
+//              mg.definingType = onType;
+//
+//              weaver.addOrReplaceLazyMethodGen(mg);
+//
+//              addNeededSuperCallMethods(weaver, onType, munger.getSuperMethodsCalled());
+//
+//              return true;
+//            }
+//        } else {
+//            return false;
+//        }
+    }
+
        private ResolvedMember getRealMemberForITDFromAspect(ResolvedType aspectType,ResolvedMember lookingFor,boolean isCtorRelated) {
                World world = aspectType.getWorld();
                boolean debug = false;
@@ -890,6 +1041,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                        System.err.println("Searching for a member on type: "+aspectType);
                        System.err.println("Member we are looking for: "+lookingFor);
                }
+
                ResolvedMember aspectMethods[] = aspectType.getDeclaredMethods();
                UnresolvedType [] lookingForParams = lookingFor.getParameterTypes();
                
index 4676740425f09c4d6dce11ba363e603f0b29341f..0fa7fea1690e2782d8b505967d81b25711a719cb 100644 (file)
@@ -206,6 +206,14 @@ public class BcelWorld extends World implements Repository {
         return ret;
     }
 
+    static String[] makeBcelTypesAsClassNames(UnresolvedType[] types) {
+        String[] ret = new String[types.length];
+        for (int i = 0, len = types.length; i < len; i++) {
+            ret[i] = types[i].getClassName();//makeBcelType(types[i]);
+        }
+        return ret;
+    }
+
     public static UnresolvedType fromBcel(Type t) {
         return UnresolvedType.forSignature(t.getSignature());
     }