]> source.dussan.org Git - aspectj.git/commitdiff
moved bcel things to bcel package in weaver, deow test + fix for @AJ
authoravasseur <avasseur>
Fri, 20 May 2005 12:27:59 +0000 (12:27 +0000)
committeravasseur <avasseur>
Fri, 20 May 2005 12:27:59 +0000 (12:27 +0000)
18 files changed:
docs/adk15ProgGuideDB/ataspectj.xml
tests/java5/ataspectj/ataspectj/DeowTest.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/ataspectj/Aj5Attributes.java [deleted file]
weaver/src/org/aspectj/weaver/ataspectj/Ajc5MemberMaker.java [deleted file]
weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java
weaver/src/org/aspectj/weaver/bcel/BcelField.java
weaver/src/org/aspectj/weaver/bcel/BcelMethod.java
weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java
weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
weaver/src/org/aspectj/weaver/patterns/PerCflow.java
weaver/src/org/aspectj/weaver/patterns/PerObject.java
weaver/src/org/aspectj/weaver/patterns/PerSingleton.java
weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java
weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java

index b3986ef903b8c6a1c54a38378c24d0e6d24f1655..febf50033584aecdfe840c8303e2b9c23f033946 100644 (file)
         System.out.println("phew");
       }
       
-      @AfterReturning(value="call(Foo+.new(..))",returning="f")
+      @AfterReturning(pointcut="call(Foo+.new(..))",returning="f")
       public void itsAFoo(Foo f) {
         System.out.println("It's a Foo: " + f);
       }            
       ]]></programlisting>
       
-      <para>(Note the need for the "value=" prefix in front of the pointcut
+      <para>(Note the use of the "pointcut=" prefix in front of the pointcut
       expression in the returning case).</para>
       
       <para>After throwing advice works in a similar fashion, using the 
diff --git a/tests/java5/ataspectj/ataspectj/DeowTest.java b/tests/java5/ataspectj/ataspectj/DeowTest.java
new file mode 100644 (file)
index 0000000..fc8a270
--- /dev/null
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * 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 org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.DeclareWarning;
+import org.aspectj.lang.annotation.DeclareError;
+
+/**
+ * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+ */
+public class DeowTest {
+
+    public void hello() {}
+
+    public void hi() {}
+
+    public void target() {
+        hello();
+        hi();
+    }
+
+    @Aspect
+    public static class DeowAspect {
+
+        @DeclareWarning("call(* hello()) && within(ataspectj.DeowTest)")
+        final static String onHello = "call hello";
+
+        @DeclareError("call(* hi()) && within(ataspectj.DeowTest)")
+        final static String onHi = "call hi";
+    }
+}
index 264c4693098724232542906b4a385d9cacbc2833..6c936ef4f6e4fdacb75378aed47f8fe8533f0a8d 100644 (file)
@@ -87,4 +87,8 @@ public class AtAjSyntaxTests extends XMLBasedAjcTestCase {
     public void testAroundInlineMunger2() {
         runTest("AroundInlineMunger2");
     }
+
+    public void testDeow() {
+        runTest("Deow");
+    }
 }
\ No newline at end of file
index 055567d30f3dfd3f842b3176f46790b32e408882..2a40246175872ca03c4805164e7ce6a19fc56ddd 100644 (file)
         <compile files="ataspectj/AroundInlineMungerTest2.aj,ataspectj/AroundInlineMungerTestAspects2.aj,ataspectj/TestHelper.java" options="-1.5 -Xlint:ignore"/>
         <run class="ataspectj.AroundInlineMungerTest2"/>
     </ajc-test>
+
+    <ajc-test dir="java5/ataspectj" title="Deow">
+        <compile files="ataspectj/DeowTest.java" options="-1.5">
+            <message kind="warning" line="28" text="call hello"/>
+            <message kind="error" line="29" text="call hi"/>
+        </compile>
+    </ajc-test>
 </suite>
\ No newline at end of file
index 83bab19e07dc20cdb29a25dee272b2acfff81eb1..a80e7e3a7e139dd7bc807ca1b65ba5f7610e9b35 100644 (file)
@@ -13,6 +13,9 @@
 
 package org.aspectj.weaver;
 
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+
 import java.lang.reflect.Modifier;
 
 //import org.aspectj.weaver.ResolvedTypeX.Name;
@@ -692,4 +695,22 @@ public class AjcMemberMaker {
                        "<init>",
                        "()V");
        }
+
+    //-- common types we use. Note: Java 5 dependand types are refered to as String
+    public final static TypeX ASPECT_ANNOTATION = TypeX.forName("org.aspectj.lang.annotation.Aspect");
+    public final static TypeX BEFORE_ANNOTATION = TypeX.forName("org.aspectj.lang.annotation.Before");
+    public final static TypeX AROUND_ANNOTATION = TypeX.forName("org.aspectj.lang.annotation.Around");
+    public final static TypeX AFTERRETURNING_ANNOTATION = TypeX.forName("org.aspectj.lang.annotation.AfterReturning");
+    public final static TypeX AFTERTHROWING_ANNOTATION = TypeX.forName("org.aspectj.lang.annotation.AfterThrowing");
+    public final static TypeX AFTER_ANNOTATION = TypeX.forName("org.aspectj.lang.annotation.After");
+    public final static TypeX POINTCUT_ANNOTATION = TypeX.forName("org.aspectj.lang.annotation.Pointcut");
+    public final static TypeX DECLAREERROR_ANNOTATION = TypeX.forName("org.aspectj.lang.annotation.DeclareError");
+    public final static TypeX DECLAREWARNING_ANNOTATION = TypeX.forName("org.aspectj.lang.annotation.DeclareWarning");
+    public final static TypeX DECLAREPRECEDENCE_ANNOTATION = TypeX.forName("org.aspectj.lang.annotation.DeclarePrecedence");
+
+    public final static TypeX TYPEX_JOINPOINT = TypeX.forName(JoinPoint.class.getName().replace('/','.'));
+    public final static TypeX TYPEX_PROCEEDINGJOINPOINT = TypeX.forName(ProceedingJoinPoint.class.getName().replace('/','.'));
+    public final static TypeX TYPEX_STATICJOINPOINT = TypeX.forName(JoinPoint.StaticPart.class.getName().replace('/','.'));
+    public final static TypeX TYPEX_ENCLOSINGSTATICJOINPOINT = TypeX.forName(JoinPoint.EnclosingStaticPart.class.getName().replace('/','.'));
+
 }
diff --git a/weaver/src/org/aspectj/weaver/ataspectj/Aj5Attributes.java b/weaver/src/org/aspectj/weaver/ataspectj/Aj5Attributes.java
deleted file mode 100644 (file)
index 15896cb..0000000
+++ /dev/null
@@ -1,1261 +0,0 @@
-/*******************************************************************************
- * 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              Alexandre Vasseur
- *******************************************************************************/
-package org.aspectj.weaver.ataspectj;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-
-import org.aspectj.apache.bcel.classfile.Attribute;
-import org.aspectj.apache.bcel.classfile.Field;
-import org.aspectj.apache.bcel.classfile.JavaClass;
-import org.aspectj.apache.bcel.classfile.LocalVariable;
-import org.aspectj.apache.bcel.classfile.LocalVariableTable;
-import org.aspectj.apache.bcel.classfile.Method;
-import org.aspectj.apache.bcel.classfile.annotation.Annotation;
-import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
-import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnotations;
-import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisibleAnnotations;
-import org.aspectj.apache.bcel.generic.Type;
-import org.aspectj.bridge.IMessageHandler;
-import org.aspectj.bridge.Message;
-import org.aspectj.bridge.IMessage;
-import org.aspectj.lang.JoinPoint;
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.weaver.Advice;
-import org.aspectj.weaver.AdviceKind;
-import org.aspectj.weaver.AjAttribute;
-import org.aspectj.weaver.AjcMemberMaker;
-import org.aspectj.weaver.ISourceContext;
-import org.aspectj.weaver.NameMangler;
-import org.aspectj.weaver.ResolvedPointcutDefinition;
-import org.aspectj.weaver.ResolvedTypeX;
-import org.aspectj.weaver.TypeX;
-import org.aspectj.weaver.patterns.DeclarePrecedence;
-import org.aspectj.weaver.patterns.FormalBinding;
-import org.aspectj.weaver.patterns.IScope;
-import org.aspectj.weaver.patterns.PatternParser;
-import org.aspectj.weaver.patterns.PerCflow;
-import org.aspectj.weaver.patterns.PerClause;
-import org.aspectj.weaver.patterns.PerObject;
-import org.aspectj.weaver.patterns.PerSingleton;
-import org.aspectj.weaver.patterns.PerTypeWithin;
-import org.aspectj.weaver.patterns.Pointcut;
-import org.aspectj.weaver.patterns.SimpleScope;
-import org.aspectj.weaver.patterns.ParserException;
-import org.aspectj.weaver.patterns.Declare;
-import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
-
-/**
- * Annotation defined aspect reader.
- * <p/>
- * It reads the Java 5 annotations and turns them into AjAttributes
- *
- * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
- */
-public class Aj5Attributes {
-
-    private final static List EMPTY_LIST = new ArrayList();
-    private final static String[] EMPTY_STRINGS = new String[0];
-
-    public final static TypeX TYPEX_JOINPOINT = TypeX.forName(JoinPoint.class.getName().replace('/','.'));
-    public final static TypeX TYPEX_PROCEEDINGJOINPOINT = TypeX.forName(ProceedingJoinPoint.class.getName().replace('/','.'));
-    public final static TypeX TYPEX_STATICJOINPOINT = TypeX.forName(JoinPoint.StaticPart.class.getName().replace('/','.'));
-    public final static TypeX TYPEX_ENCLOSINGSTATICJOINPOINT = TypeX.forName(JoinPoint.EnclosingStaticPart.class.getName().replace('/','.'));
-
-    /**
-     * A struct that allows to add extra arguments without always breaking the API
-     *
-     * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
-     */
-    private static class AjAttributeStruct {
-
-        /**
-         * The list of AjAttribute.XXX that we are populating from the @AJ read
-         */
-        List ajAttributes = new ArrayList();
-
-        /**
-         * The resolved type (class) for which we are reading @AJ for (be it class, method, field annotations)
-         */
-        final ResolvedTypeX enclosingType;
-
-        final ISourceContext context;
-        final IMessageHandler handler;
-
-        public AjAttributeStruct(ResolvedTypeX type, ISourceContext sourceContext, IMessageHandler messageHandler) {
-            enclosingType = type;
-            context = sourceContext;
-            handler = messageHandler;
-        }
-    }
-
-    /**
-     * A struct when we read @AJ on method
-     *
-     * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
-     */
-    private static class AjAttributeMethodStruct extends AjAttributeStruct {
-
-        /**
-         * Argument names as they appear in the SOURCE code, ordered, and lazyly populated
-         * Used to do formal binding
-         */
-        private String[] m_argumentNamesLazy = null;
-
-        final Method method;
-
-        public AjAttributeMethodStruct(Method method, ResolvedTypeX type, ISourceContext sourceContext, IMessageHandler messageHandler) {
-            super(type, sourceContext, messageHandler);
-            this.method = method;
-        }
-
-        public String[] getArgumentNames() {
-            if (m_argumentNamesLazy == null) {
-                m_argumentNamesLazy = getMethodArgumentNamesAsInSource(method);
-            }
-            return m_argumentNamesLazy;
-        }
-    }
-
-    /**
-     * A struct when we read @AJ on field
-     *
-     * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
-     */
-    private static class AjAttributeFieldStruct extends AjAttributeStruct {
-
-        final Field field;
-
-        public AjAttributeFieldStruct(Field field, ResolvedTypeX type, ISourceContext sourceContext, IMessageHandler messageHandler) {
-            super(type, sourceContext, messageHandler);
-            this.field = field;
-        }
-    }
-
-    /**
-     * Annotations are RuntimeVisible only. This allow us to not visit RuntimeInvisible ones.
-     *
-     * @param attribute
-     * @return
-     */
-    public static boolean acceptAttribute(Attribute attribute) {
-        return (attribute instanceof RuntimeVisibleAnnotations);
-    }
-
-    /**
-     * Extract class level annotations and turn them into AjAttributes.
-     *
-     * @param javaClass
-     * @param type
-     * @param context
-     * @param msgHandler
-     * @return list of AjAttributes
-     */
-    public static List readAj5ClassAttributes(JavaClass javaClass, ResolvedTypeX type, ISourceContext context,IMessageHandler msgHandler, boolean isCodeStyleAspect) {
-        AjAttributeStruct struct = new AjAttributeStruct(type, context, msgHandler);
-        Attribute[] attributes = javaClass.getAttributes();
-        boolean hasAtAspectAnnotation = false;
-        boolean hasAtPrecedenceAnnotation = false;
-
-        for (int i = 0; i < attributes.length; i++) {
-            Attribute attribute = attributes[i];
-            if (acceptAttribute(attribute)) {
-                RuntimeAnnotations rvs = (RuntimeAnnotations) attribute;
-                // we don't need to look for several attribute occurence since it cannot happen as per JSR175
-                if (!isCodeStyleAspect) {
-                    hasAtAspectAnnotation = handleAspectAnnotation(rvs, struct);
-                }
-                //TODO: below means mix style for @DeclarePrecedence - are we sure we want that ?
-                hasAtPrecedenceAnnotation = handlePrecedenceAnnotation(rvs, struct);
-                // there can only be one RuntimeVisible bytecode attribute
-                break;
-            }
-        }
-
-        // basic semantic check
-        //FIXME AV TBD could be skipped and silently ignore - TBD with Andy
-        if (hasAtPrecedenceAnnotation && !hasAtAspectAnnotation) {
-            msgHandler.handleMessage(
-                    new Message(
-                            "Found @DeclarePrecedence on a non @Aspect type '" + type.getName() + "'",
-                            IMessage.WARNING,
-                            null,
-                            type.getSourceLocation()
-                    )
-            );
-            // bypass what we have read
-            return EMPTY_LIST;
-        }
-        //FIXME turn on when ajcMightHaveAspect fixed
-//        if (hasAtAspectAnnotation && type.isInterface()) {
-//            msgHandler.handleMessage(
-//                    new Message(
-//                            "Found @Aspect on an interface type '" + type.getName() + "'",
-//                            IMessage.WARNING,
-//                            null,
-//                            type.getSourceLocation()
-//                    )
-//            );
-//            // bypass what we have read
-//            return EMPTY_LIST;
-//        }
-
-        // the following block will not detect @Pointcut in non @Aspect types for optimization purpose
-        // FIXME AV TBD with Andy
-        if (!hasAtAspectAnnotation) {
-            return EMPTY_LIST;
-        }
-
-        // code style pointcuts are class attributes
-        // we need to gather the @AJ pointcut right now and not at method level annotation extraction time
-        // in order to be able to resolve the pointcut references later on
-        //FIXME alex loop over class super class
-        //FIXME alex can that be too slow ?
-        for (int i = 0; i < javaClass.getMethods().length; i++) {
-            Method method = javaClass.getMethods()[i];
-                       if (method.getName().startsWith(NameMangler.PREFIX)) continue;  // already dealt with by ajc...
-            //FIXME alex optimize, this method struct will gets recreated for advice extraction
-            AjAttributeMethodStruct mstruct = new AjAttributeMethodStruct(method, type, context, msgHandler);
-            Attribute[] mattributes = method.getAttributes();
-
-            for (int j = 0; j < mattributes.length; j++) {
-                Attribute mattribute = mattributes[j];
-                if (acceptAttribute(mattribute)) {
-                    RuntimeAnnotations mrvs = (RuntimeAnnotations) mattribute;
-                    handlePointcutAnnotation(mrvs, mstruct);
-                    // there can only be one RuntimeVisible bytecode attribute
-                    break;
-                }
-            }
-            struct.ajAttributes.addAll(mstruct.ajAttributes);
-        }
-
-
-        // code style declare error / warning are class 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);
-            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)) {
-                        // semantic check - must be in an @Aspect [remove if previous block bypassed in advance]
-                        if (!type.isAnnotationStyleAspect()) {
-                            msgHandler.handleMessage(
-                                    new Message(
-                                            "Found @AspectJ annotations in a non @Aspect type '" + type.getName() + "'",
-                                            IMessage.WARNING,
-                                            null,
-                                            type.getSourceLocation()
-                                    )
-                            );
-                            ;// go ahead
-                        }
-                    }
-                    // there can only be one RuntimeVisible bytecode attribute
-                    break;
-                }
-            }
-            struct.ajAttributes.addAll(fstruct.ajAttributes);
-        }
-        return struct.ajAttributes;
-    }
-
-    /**
-     * Extract method level annotations and turn them into AjAttributes.
-     *
-     * @param method
-     * @param type
-     * @param context
-     * @param msgHandler
-     * @return list of AjAttributes
-     */
-    public static List readAj5MethodAttributes(Method method, ResolvedTypeX type, ResolvedPointcutDefinition preResolvedPointcut, ISourceContext context,IMessageHandler msgHandler) {
-               if (method.getName().startsWith(NameMangler.PREFIX)) return Collections.EMPTY_LIST;  // already dealt with by ajc...
-
-               AjAttributeMethodStruct struct = new AjAttributeMethodStruct(method, type, context, msgHandler);
-        Attribute[] attributes = method.getAttributes();
-
-        // we remember if we found one @AJ annotation for minimal semantic error reporting
-        // the real reporting beeing done thru AJDT and the compiler mapping @AJ to AjAtttribute
-        // or thru APT
-        // FIXME AV we could actually skip the whole thing if type is not itself an @Aspect
-        // but then we would not see any warning. TBD with Andy
-        boolean hasAtAspectJAnnotation = false;
-        boolean hasAtAspectJAnnotationMustReturnVoid = false;
-        for (int i = 0; i < attributes.length; i++) {
-            Attribute attribute = attributes[i];
-            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);
-                hasAtAspectJAnnotationMustReturnVoid = hasAtAspectJAnnotationMustReturnVoid || handleAfterThrowingAnnotation(rvs, struct, preResolvedPointcut);
-                hasAtAspectJAnnotation = hasAtAspectJAnnotation || handleAroundAnnotation(rvs, struct, preResolvedPointcut);
-                // there can only be one RuntimeVisible bytecode attribute
-                break;
-            }
-        }
-        hasAtAspectJAnnotation = hasAtAspectJAnnotation || hasAtAspectJAnnotationMustReturnVoid;
-
-        // semantic check - must be in an @Aspect [remove if previous block bypassed in advance]
-        if (hasAtAspectJAnnotation && !type.isAnnotationStyleAspect()) {
-            msgHandler.handleMessage(
-                    new Message(
-                            "Found @AspectJ annotations in a non @Aspect type '" + type.getName() + "'",
-                            IMessage.WARNING,
-                            null,
-                            type.getSourceLocation()
-                    )
-            );
-            ;// go ahead
-        }
-        // semantic check - advice must be public
-        if (hasAtAspectJAnnotation && !struct.method.isPublic()) {
-            msgHandler.handleMessage(
-                    new Message(
-                            "Found @AspectJ annotation on a non public advice '" + methodToString(struct.method) + "'",
-                            IMessage.ERROR,
-                            null,
-                            type.getSourceLocation()
-                    )
-            );
-            ;// go ahead
-        }
-        // semantic check for non around advice must return void
-        if (hasAtAspectJAnnotationMustReturnVoid && !Type.VOID.equals(struct.method.getReturnType())) {
-            msgHandler.handleMessage(
-                    new Message(
-                            "Found @AspectJ annotation on a non around advice not returning void '" + methodToString(struct.method) + "'",
-                            IMessage.ERROR,
-                            null,
-                            type.getSourceLocation()
-                    )
-            );
-            ;// go ahead
-        }
-
-
-        return struct.ajAttributes;
-    }
-
-    /**
-     * Extract field level annotations and turn them into AjAttributes.
-     *
-     * @param field
-     * @param type
-     * @param context
-     * @param msgHandler
-     * @return list of AjAttributes, always empty for now
-     */
-    public static List readAj5FieldAttributes(Field field, ResolvedTypeX type, ISourceContext context,IMessageHandler msgHandler) {
-        return Collections.EMPTY_LIST;
-    }
-
-    /**
-     * Read @Aspect
-     *
-     * @param runtimeAnnotations
-     * @param struct
-     * @return true if found
-     */
-    private static boolean handleAspectAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeStruct struct) {
-        Annotation aspect = getAnnotation(runtimeAnnotations, "org.aspectj.lang.annotation.Aspect");
-        if (aspect != null) {
-            ElementNameValuePair aspectPerClause = getAnnotationElement(aspect, "value");
-            if (aspectPerClause == null) {
-                // defaults to singleton
-                PerClause clause = new PerSingleton();
-                clause.setLocation(struct.context, -1, -1);
-                struct.ajAttributes.add(new AjAttribute.Aspect(clause));
-                return true;
-            } else {
-                String perX = aspectPerClause.getValue().stringifyValue();
-                final PerClause clause;
-                if (perX == null || perX.length()<=0) {
-                     clause = new PerSingleton();
-                } else {
-                    clause = parsePerClausePointcut(perX, struct);
-                }
-                clause.setLocation(struct.context, -1, -1);
-                struct.ajAttributes.add(new AjAttribute.Aspect(clause));
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Read a perClause
-     *
-     * @param perClause like "pertarget(.....)"
-     * @param struct for which we are parsing the per clause
-     * @return a PerClause instance
-     */
-    private static PerClause parsePerClausePointcut(String perClause, AjAttributeStruct struct) {
-        final String pointcut;
-        if (perClause.startsWith(PerClause.KindAnnotationPrefix.PERCFLOW.getName())) {
-            pointcut = PerClause.KindAnnotationPrefix.PERCFLOW.extractPointcut(perClause);
-            return new PerCflow(Pointcut.fromString(pointcut), false);
-        } else if (perClause.startsWith(PerClause.KindAnnotationPrefix.PERCFLOWBELOW.getName())) {
-            pointcut = PerClause.KindAnnotationPrefix.PERCFLOWBELOW.extractPointcut(perClause);
-            return new PerCflow(Pointcut.fromString(pointcut), true);
-        } else if (perClause.startsWith(PerClause.KindAnnotationPrefix.PERTARGET.getName())) {
-            pointcut = PerClause.KindAnnotationPrefix.PERTARGET.extractPointcut(perClause);
-            return new PerObject(Pointcut.fromString(pointcut), false);
-        } else if (perClause.startsWith(PerClause.KindAnnotationPrefix.PERTHIS.getName())) {
-            pointcut = PerClause.KindAnnotationPrefix.PERTHIS.extractPointcut(perClause);
-            return new PerObject(Pointcut.fromString(pointcut), true);
-        } else if (perClause.startsWith(PerClause.KindAnnotationPrefix.PERTYPEWITHIN.getName())) {
-            pointcut = PerClause.KindAnnotationPrefix.PERTYPEWITHIN.extractPointcut(perClause);
-            return new PerTypeWithin(new PatternParser(pointcut).parseTypePattern());
-        } else if (perClause.equalsIgnoreCase(PerClause.SINGLETON.getName() + "()")) {
-            return new PerSingleton();
-        }
-        // could not parse the @AJ perclause
-        struct.handler.handleMessage(
-                new Message(
-                        "cannot read per clause from @Aspect: " + perClause,
-                        struct.enclosingType.getSourceLocation(),
-                        true
-                )
-        );
-        throw new RuntimeException("cannot read perclause " + perClause);
-    }
-
-    /**
-     * Read @DeclarePrecedence
-     *
-     * @param runtimeAnnotations
-     * @param struct
-     * @return true if found
-     */
-    private static boolean handlePrecedenceAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeStruct struct) {
-        Annotation aspect = getAnnotation(runtimeAnnotations, "org.aspectj.lang.annotation.DeclarePrecedence");
-        if (aspect != null) {
-            ElementNameValuePair precedence = getAnnotationElement(aspect, "value");
-            if (precedence != null) {
-                String precedencePattern = precedence.getValue().stringifyValue();
-                PatternParser parser = new PatternParser(precedencePattern);
-                DeclarePrecedence ajPrecedence = parser.parseDominates();
-                struct.ajAttributes.add(new AjAttribute.DeclareAttribute(ajPrecedence));
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Read @Before
-     *
-     * @param runtimeAnnotations
-     * @param struct
-     * @return true if found
-     */
-    private static boolean handleBeforeAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) {
-        Annotation before = getAnnotation(runtimeAnnotations, "org.aspectj.lang.annotation.Before");
-        if (before != null) {
-            ElementNameValuePair beforeAdvice = getAnnotationElement(before, "value");
-            if (beforeAdvice != null) {
-                // this/target/args binding
-                FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
-                try {
-                    bindings = extractBindings(struct);
-                } catch (UnreadableDebugInfo unreadableDebugInfo) {
-                    return false;
-                }
-                IScope binding = new BindingScope(
-                        struct.enclosingType,
-                        bindings
-                );
-
-                // joinpoint, staticJoinpoint binding
-                int extraArgument = extractExtraArgument(struct.method);
-
-                               Pointcut pc = null;
-                               if (preResolvedPointcut != null) {
-                                       pc = preResolvedPointcut.getPointcut();
-                               } else {
-                  pc = Pointcut.fromString(beforeAdvice.getValue().stringifyValue()).resolve(binding);
-                               }
-                setIgnoreUnboundBindingNames(pc, bindings);
-
-                struct.ajAttributes.add(new AjAttribute.AdviceAttribute(
-                        AdviceKind.Before,
-                        pc,
-                        extraArgument,
-                        -1,
-                        -1,
-                        struct.context
-                        )
-                );
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Read @After
-     *
-     * @param runtimeAnnotations
-     * @param struct
-     * @return true if found
-     */
-    private static boolean handleAfterAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) {
-        Annotation after = getAnnotation(runtimeAnnotations, "org.aspectj.lang.annotation.After");
-        if (after != null) {
-            ElementNameValuePair afterAdvice = getAnnotationElement(after, "value");
-            if (afterAdvice != null) {
-                // this/target/args binding
-                FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
-                try {
-                    bindings = extractBindings(struct);
-                } catch (UnreadableDebugInfo unreadableDebugInfo) {
-                    return false;
-                }
-                IScope binding = new BindingScope(
-                        struct.enclosingType,
-                        bindings
-                );
-
-                // joinpoint, staticJoinpoint binding
-                int extraArgument = extractExtraArgument(struct.method);
-
-                               Pointcut pc = null;
-                               if (preResolvedPointcut != null) {
-                                       pc = preResolvedPointcut.getPointcut();
-                               } else {
-                  pc = Pointcut.fromString(afterAdvice.getValue().stringifyValue()).resolve(binding);
-                               }
-                setIgnoreUnboundBindingNames(pc, bindings);
-
-                struct.ajAttributes.add(new AjAttribute.AdviceAttribute(
-                        AdviceKind.After,
-                        pc,
-                        extraArgument,
-                        -1,
-                        -1,
-                        struct.context
-                        )
-                );
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Read @AfterReturning
-     *
-     * @param runtimeAnnotations
-     * @param struct
-     * @return true if found
-     */
-    private static boolean handleAfterReturningAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) {
-        Annotation after = getAnnotation(runtimeAnnotations, "org.aspectj.lang.annotation.AfterReturning");
-        if (after != null) {
-            ElementNameValuePair annValue = getAnnotationElement(after, "value");
-            ElementNameValuePair annPointcut = getAnnotationElement(after, "pointcut");
-            ElementNameValuePair annReturned = getAnnotationElement(after, "returning");
-
-            // extract the pointcut and returned type/binding - do some checks
-            String pointcut = null;
-            String returned = null;
-            if ((annValue!=null && annPointcut!=null) || (annValue==null && annPointcut==null)) {
-                struct.handler.handleMessage(
-                        new Message(
-                                "@AfterReturning: either 'value' or 'poincut' must be provided, not both: " + methodToString(struct.method),
-                                struct.enclosingType.getSourceLocation(),
-                                true
-                        )
-                );
-                return false;
-            }
-            if (annValue != null) {
-                pointcut = annValue.getValue().stringifyValue();
-            } else {
-                pointcut = annPointcut.getValue().stringifyValue();
-            }
-            if (isNullOrEmpty(pointcut)) {
-                struct.handler.handleMessage(
-                        new Message(
-                                "@AfterReturning: either 'value' or 'poincut' must be provided, not both: " + methodToString(struct.method),
-                                struct.enclosingType.getSourceLocation(),
-                                true
-                        )
-                );
-                return false;
-            }
-            if (annReturned!=null) {
-                returned = annReturned.getValue().stringifyValue();
-                if (isNullOrEmpty(returned))
-                    returned = null;
-            }
-
-            // this/target/args binding
-            // exclude the return binding from the pointcut binding since it is an extraArg binding
-            FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
-            try {
-                bindings = (returned==null?extractBindings(struct):extractBindings(struct, returned));
-            } catch (UnreadableDebugInfo unreadableDebugInfo) {
-                return false;
-            }
-            IScope binding = new BindingScope(
-                    struct.enclosingType,
-                    bindings
-            );
-
-            // joinpoint, staticJoinpoint binding
-            int extraArgument = extractExtraArgument(struct.method);
-
-            // return binding
-            if (returned != null) {
-                extraArgument |= Advice.ExtraArgument;
-            }
-
-                       Pointcut pc = null;
-                       if (preResolvedPointcut != null) {
-                               pc = preResolvedPointcut.getPointcut();
-                       } else {
-              pc = Pointcut.fromString(pointcut).resolve(binding);
-                       }
-            setIgnoreUnboundBindingNames(pc, bindings);
-            pc.setLocation(struct.enclosingType.getSourceContext(), 0, 0);//TODO method location ?
-
-            struct.ajAttributes.add(new AjAttribute.AdviceAttribute(
-                    AdviceKind.AfterReturning,
-                    pc,
-                    extraArgument,
-                    -1,
-                    -1,
-                    struct.context
-                    )
-            );
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Read @AfterThrowing
-     *
-     * @param runtimeAnnotations
-     * @param struct
-     * @return true if found
-     */
-    private static boolean handleAfterThrowingAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) {
-        Annotation after = getAnnotation(runtimeAnnotations, "org.aspectj.lang.annotation.AfterThrowing");
-        if (after != null) {
-            ElementNameValuePair annValue = getAnnotationElement(after, "value");
-            ElementNameValuePair annPointcut = getAnnotationElement(after, "pointcut");
-            ElementNameValuePair annThrowned = getAnnotationElement(after, "throwing");
-
-            // extract the pointcut and throwned type/binding - do some checks
-            String pointcut = null;
-            String throwned = null;
-            if ((annValue!=null && annPointcut!=null) || (annValue==null && annPointcut==null)) {
-                struct.handler.handleMessage(
-                        new Message(
-                                "@AfterThrowing: either 'value' or 'poincut' must be provided, not both: " + methodToString(struct.method),
-                                struct.enclosingType.getSourceLocation(),
-                                true
-                        )
-                );
-                return false;
-            }
-            if (annValue != null) {
-                pointcut = annValue.getValue().stringifyValue();
-            } else {
-                pointcut = annPointcut.getValue().stringifyValue();
-            }
-            if (isNullOrEmpty(pointcut)) {
-                struct.handler.handleMessage(
-                        new Message(
-                                "@AfterThrowing: either 'value' or 'poincut' must be provided, not both: " + methodToString(struct.method),
-                                struct.enclosingType.getSourceLocation(),
-                                true
-                        )
-                );
-                return false;
-            }
-            if (annThrowned!=null) {
-                throwned = annThrowned.getValue().stringifyValue();
-                if (isNullOrEmpty(throwned))
-                    throwned = null;
-            }
-
-            // this/target/args binding
-            // exclude the throwned binding from the pointcut binding since it is an extraArg binding
-            FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
-            try {
-                bindings = (throwned==null?extractBindings(struct):extractBindings(struct, throwned));
-            } catch (UnreadableDebugInfo unreadableDebugInfo) {
-                return false;
-            }
-            IScope binding = new BindingScope(
-                    struct.enclosingType,
-                    bindings
-            );
-
-            // joinpoint, staticJoinpoint binding
-            int extraArgument = extractExtraArgument(struct.method);
-
-            // return binding
-            if (throwned != null) {
-                extraArgument |= Advice.ExtraArgument;
-            }
-
-                       Pointcut pc = null;
-                       if (preResolvedPointcut != null) {
-                               pc = preResolvedPointcut.getPointcut();
-                       } else {
-              pc = Pointcut.fromString(pointcut).resolve(binding);
-                       }
-            setIgnoreUnboundBindingNames(pc, bindings);
-
-            struct.ajAttributes.add(new AjAttribute.AdviceAttribute(
-                    AdviceKind.AfterThrowing,
-                    pc,
-                    extraArgument,
-                    -1,
-                    -1,
-                    struct.context
-                    )
-            );
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Read @Around
-     *
-     * @param runtimeAnnotations
-     * @param struct
-     * @return true if found
-     */
-    private static boolean handleAroundAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) {
-        Annotation around = getAnnotation(runtimeAnnotations, "org.aspectj.lang.annotation.Around");
-        if (around != null) {
-            ElementNameValuePair aroundAdvice = getAnnotationElement(around, "value");
-            if (aroundAdvice != null) {
-                // this/target/args binding
-                FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
-                try {
-                    bindings = extractBindings(struct);
-                } catch (UnreadableDebugInfo unreadableDebugInfo) {
-                    return false;
-                }
-                IScope binding = new BindingScope(
-                        struct.enclosingType,
-                        bindings
-                );
-
-                // joinpoint, staticJoinpoint binding
-                int extraArgument = extractExtraArgument(struct.method);
-
-                               Pointcut pc = null;
-                               if (preResolvedPointcut != null) {
-                                       pc = preResolvedPointcut.getPointcut();
-                               } else {
-                    pc = Pointcut.fromString(aroundAdvice.getValue().stringifyValue()).resolve(binding);
-                               }
-                setIgnoreUnboundBindingNames(pc, bindings);
-
-                struct.ajAttributes.add(new AjAttribute.AdviceAttribute(
-                        AdviceKind.Around,
-                        pc,
-                        extraArgument,
-                        -1,
-                        -1,
-                        struct.context
-                        )
-                );
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Read @Pointcut and handle the resolving in a lazy way to deal with pointcut references
-     *
-     * @param runtimeAnnotations
-     * @param struct
-     */
-    private static void handlePointcutAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct) {
-        Annotation pointcut = getAnnotation(runtimeAnnotations, "org.aspectj.lang.annotation.Pointcut");
-        if (pointcut != null) {
-            ElementNameValuePair pointcutExpr = getAnnotationElement(pointcut, "value");
-            if (pointcutExpr != null) {
-
-                // semantic check: the method must return void
-                if (!Type.VOID.equals(struct.method.getReturnType())) {
-                    struct.handler.handleMessage(
-                            new Message(
-                                    "Found @Pointcut on a method not returning void '" + methodToString(struct.method) + "'",
-                                    IMessage.WARNING,
-                                    null,
-                                    struct.enclosingType.getSourceLocation()//TODO method loc instead how ?
-                            )
-                    );
-                    //TODO AV : Andy - should we stop ?
-                    return;
-                }
-                // semantic check: the method must not throw anything
-                if (struct.method.getExceptionTable() != null) {
-                    struct.handler.handleMessage(
-                            new Message(
-                                    "Found @Pointcut on a method throwing exception '" + methodToString(struct.method) + "'",
-                                    IMessage.WARNING,
-                                    null,
-                                    struct.enclosingType.getSourceLocation()//TODO method loc instead how ?
-                            )
-                    );
-                    //TODO AV : Andy - should we stop ?
-                    return;
-                }
-
-                // this/target/args binding
-                final IScope binding;
-                try {
-                    binding = new BindingScope(
-                            struct.enclosingType,
-                            extractBindings(struct)
-                    );
-                } catch(UnreadableDebugInfo e) {
-                    return;
-                }
-
-                TypeX[] argumentTypes = new TypeX[struct.method.getArgumentTypes().length];
-                for (int i = 0; i < argumentTypes.length; i++) {
-                    argumentTypes[i] = TypeX.forSignature(struct.method.getArgumentTypes()[i].getSignature());
-                }
-
-                // use a LazyResolvedPointcutDefinition so that the pointcut is resolved lazily
-                // since for it to be resolved, we will need other pointcuts to be registered as well
-                try {
-                    struct.ajAttributes.add(new AjAttribute.PointcutDeclarationAttribute(
-                            new LazyResolvedPointcutDefinition(
-                                    struct.enclosingType,
-                                    struct.method.getModifiers(),
-                                    struct.method.getName(),
-                                    argumentTypes,
-                                    Pointcut.fromString(pointcutExpr.getValue().stringifyValue()),
-                                    binding
-                            )
-                    ));
-                } catch (ParserException e) {
-                    struct.handler.handleMessage(
-                            new Message(
-                                    "Cannot parse @Pointcut '" + pointcutExpr.getValue().stringifyValue() + "'",
-                                    IMessage.ERROR,
-                                    e,
-                                    struct.enclosingType.getSourceLocation()//TODO method loc instead how ?
-                            )
-                    );
-                    return;
-                }
-            }
-        }
-    }
-
-    /**
-     * Read @DeclareError, @DeclareWarning
-     *
-     * @param runtimeAnnotations
-     * @param struct
-     * @return true if found
-     */
-    private static boolean handleDeclareErrorOrWarningAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeFieldStruct struct) {
-        Annotation error = getAnnotation(runtimeAnnotations, "org.aspectj.lang.annotation.DeclareError");
-        boolean hasError = false;
-        if (error != null) {
-            ElementNameValuePair declareError = getAnnotationElement(error, "value");
-            if (declareError != null) {
-                if (!"Ljava/lang/String;".equals(struct.field.getSignature()) || struct.field.getConstantValue()==null) {
-                    struct.handler.handleMessage(
-                            new Message(
-                                    "@DeclareError used on a non String constant field " + fieldToString(struct.field),
-                                    struct.enclosingType.getSourceLocation(),
-                                    true
-                    ));
-                    return false;
-                }
-                FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
-                IScope binding = new BindingScope(
-                        struct.enclosingType,
-                        bindings
-                );
-                               Pointcut pc = Pointcut.fromString(declareError.getValue().stringifyValue()).resolve(binding);
-                struct.ajAttributes.add(new AjAttribute.DeclareAttribute(
-                        new DeclareErrorOrWarning(true, pc, struct.field.getConstantValue().toString())
-                ));
-                return hasError = true;
-            }
-        }
-        Annotation warning = getAnnotation(runtimeAnnotations, "org.aspectj.lang.annotation.DeclareWarning");
-        boolean hasWarning = false;
-        if (warning != null) {
-            ElementNameValuePair declareWarning = getAnnotationElement(warning, "value");
-            if (declareWarning != null) {
-                if (!"Ljava/lang/String;".equals(struct.field.getSignature()) || struct.field.getConstantValue()==null) {
-                    struct.handler.handleMessage(
-                            new Message(
-                                    "@DeclareWarning used on a non String constant field " + fieldToString(struct.field),
-                                    struct.enclosingType.getSourceLocation(),
-                                    true
-                    ));
-                    return false;
-                }
-                FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
-                IScope binding = new BindingScope(
-                        struct.enclosingType,
-                        bindings
-                );
-                               Pointcut pc = Pointcut.fromString(declareWarning.getValue().stringifyValue()).resolve(binding);
-                struct.ajAttributes.add(new AjAttribute.DeclareAttribute(
-                        new DeclareErrorOrWarning(false, pc, struct.field.getConstantValue().toString())
-                ));
-                return hasWarning = true;
-            }
-        }
-        return hasError || hasWarning;
-    }
-
-    /**
-     * Returns a readable representation of a method.
-     * Method.toString() is not suitable.
-     *
-     * @param method
-     * @return
-     */
-    private static String methodToString(Method method) {
-        StringBuffer sb = new StringBuffer();
-        sb.append(method.getName());
-        sb.append(method.getSignature());
-        return sb.toString();
-    }
-
-    /**
-     * Returns a readable representation of a field.
-     * Field.toString() is not suitable.
-     *
-     * @param field
-     * @return
-     */
-    private static String fieldToString(Field field) {
-        StringBuffer sb = new StringBuffer();
-        sb.append(field.getName()).append(' ');
-        sb.append(field.getSignature());
-        return sb.toString();
-    }
-
-    /**
-     * Build the bindings for a given method (pointcut / advice)
-     *
-     * @param struct
-     * @return null if no debug info is available
-     */
-    private static FormalBinding[] extractBindings(AjAttributeMethodStruct struct)
-    throws UnreadableDebugInfo {
-        Method method = struct.method;
-        String[] argumentNames = struct.getArgumentNames();
-
-        // assert debug info was here
-        if (argumentNames.length != method.getArgumentTypes().length) {
-            struct.handler.handleMessage(
-                    new Message(
-                            "Cannot read debug info for @Aspect '" + struct.enclosingType.getName() + "'"
-                            + " (please compile with 'javac -g' or '<javac debug='true'.../>' in Ant)",
-                            IMessage.FAIL,
-                            null,
-                            struct.enclosingType.getSourceLocation()
-                    )
-            );
-            throw new UnreadableDebugInfo();
-        }
-
-        List bindings = new ArrayList();
-        for (int i = 0; i < argumentNames.length; i++) {
-            String argumentName = argumentNames[i];
-            TypeX argumentType = TypeX.forSignature(method.getArgumentTypes()[i].getSignature());
-
-            // do not bind JoinPoint / StaticJoinPoint / EnclosingStaticJoinPoint
-            // TODO solve me : this means that the JP/SJP/ESJP cannot appear as binding
-            // f.e. when applying advice on advice etc
-            if ((TYPEX_JOINPOINT.equals(argumentType)
-                || TYPEX_PROCEEDINGJOINPOINT.equals(argumentType)
-                || TYPEX_STATICJOINPOINT.equals(argumentType)
-                || TYPEX_ENCLOSINGSTATICJOINPOINT.equals(argumentType)
-                || AjcMemberMaker.AROUND_CLOSURE_TYPE.equals(argumentType))) {
-                //continue;// skip
-                bindings.add(new FormalBinding.ImplicitFormalBinding(argumentType, argumentName, i));
-            } else {
-                bindings.add(new FormalBinding(argumentType, argumentName, i));
-            }
-        }
-
-        return (FormalBinding[]) bindings.toArray(new FormalBinding[]{});
-    }
-
-    //FIXME alex deal with exclude index
-    private static FormalBinding[] extractBindings(AjAttributeMethodStruct struct, String excludeFormal)
-    throws UnreadableDebugInfo {
-        FormalBinding[] bindings = extractBindings(struct);
-        int excludeIndex = -1;
-        for (int i = 0; i < bindings.length; i++) {
-            FormalBinding binding = bindings[i];
-            if (binding.getName().equals(excludeFormal)) {
-                excludeIndex = i;
-                bindings[i] = new FormalBinding.ImplicitFormalBinding(binding.getType(), binding.getName(), binding.getIndex());
-                break;
-            }
-        }
-        return bindings;
-//
-//        if (excludeIndex >= 0) {
-//            FormalBinding[] bindingsFiltered = new FormalBinding[bindings.length-1];
-//            int k = 0;
-//            for (int i = 0; i < bindings.length; i++) {
-//                if (i == excludeIndex) {
-//                    ;
-//                } else {
-//                    bindingsFiltered[k] = new FormalBinding(bindings[i].getType(), bindings[i].getName(), k);
-//                    k++;
-//                }
-//            }
-//            return bindingsFiltered;
-//        } else {
-//            return bindings;
-//        }
-    }
-
-
-    /**
-     * Compute the flag for the xxxJoinPoint extra argument
-     *
-     * @param method
-     * @return
-     */
-    private static int extractExtraArgument(Method method) {
-        int extraArgument = 0;
-        Type[] methodArgs = method.getArgumentTypes();
-        for (int i = 0; i < methodArgs.length; i++) {
-            String methodArg = methodArgs[i].getSignature();
-            if (TYPEX_JOINPOINT.getSignature().equals(methodArg)) {
-                extraArgument |= Advice.ThisJoinPoint;
-            } else if (TYPEX_PROCEEDINGJOINPOINT.getSignature().equals(methodArg)) {
-                extraArgument |= Advice.ThisJoinPoint;
-            } else if (TYPEX_STATICJOINPOINT.getSignature().equals(methodArg)) {
-                extraArgument |= Advice.ThisJoinPointStaticPart;
-            } else if (TYPEX_ENCLOSINGSTATICJOINPOINT.getSignature().equals(methodArg)) {
-                extraArgument |= Advice.ThisEnclosingJoinPointStaticPart;
-            }
-        }
-        return extraArgument;
-    }
-
-    /**
-     * Returns the runtime (RV/RIV) annotation of type annotationType or null if no such annotation
-     *
-     * @param rvs
-     * @param annotationType
-     * @return
-     */
-    private static Annotation getAnnotation(RuntimeAnnotations rvs, String annotationType) {
-        for (Iterator iterator = rvs.getAnnotations().iterator(); iterator.hasNext();) {
-            Annotation rv = (Annotation) iterator.next();
-            if (annotationType.equals(rv.getTypeName())) {
-                return rv;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the value of a given element of an annotation or null if not found
-     * Caution: Does not handles default value.
-     *
-     * @param annotation
-     * @param elementName
-     * @return
-     */
-    private static ElementNameValuePair getAnnotationElement(Annotation annotation, String elementName) {
-        for (Iterator iterator1 = annotation.getValues().iterator(); iterator1.hasNext();) {
-            ElementNameValuePair element = (ElementNameValuePair) iterator1.next();
-            if (elementName.equals(element.getNameString())) {
-                return element;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Extract the method argument names as in source from debug info
-     * returns an empty array upon inconsistency
-     *
-     * @param method
-     * @return
-     */
-    private static String[] getMethodArgumentNamesAsInSource(Method method) {
-        if (method.getArgumentTypes().length == 0) {
-            return EMPTY_STRINGS;
-        }
-
-        final int startAtStackIndex = method.isStatic()?0:1;
-        final List arguments = new ArrayList();
-        LocalVariableTable lt = (LocalVariableTable) method.getLocalVariableTable();
-        if (lt != null) {
-            for (int j = 0; j < lt.getLocalVariableTable().length; j++) {
-                LocalVariable localVariable = lt.getLocalVariableTable()[j];
-                if (localVariable.getStartPC() == 0) {
-                    if (localVariable.getIndex() >= startAtStackIndex) {
-                        arguments.add(new MethodArgument(localVariable.getName(), localVariable.getIndex()));
-                    }
-                }
-            }
-        }
-
-        if (arguments.size() != method.getArgumentTypes().length) {
-            //throw new RuntimeException("cannot access debug info on " + method);
-            return EMPTY_STRINGS;
-        }
-
-        // sort by index
-        Collections.sort(arguments, new Comparator() {
-            public int compare(Object o, Object o1) {
-                MethodArgument mo = (MethodArgument)o;
-                MethodArgument mo1 = (MethodArgument) o1;
-                if (mo.indexOnStack == mo1.indexOnStack) {
-                    return 0;
-                } else if (mo.indexOnStack > mo1.indexOnStack) {
-                    return 1;
-                } else {
-                    return -1;
-                }
-            }
-        });
-        String[] argumentNames = new String[arguments.size()];
-        int i = 0;
-        for (Iterator iterator = arguments.iterator(); iterator.hasNext(); i++) {
-            MethodArgument methodArgument = (MethodArgument) iterator.next();
-            argumentNames[i] = methodArgument.name;
-        }
-        return argumentNames;
-    }
-
-    /**
-     * A method argument, used for sorting by indexOnStack (ie order in signature)
-     *
-     * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
-     */
-    private static class MethodArgument {
-        String name;
-        int indexOnStack;
-        public MethodArgument(String name, int indexOnStack) {
-            this.name = name;
-            this.indexOnStack = indexOnStack;
-        }
-    }
-
-    /**
-     * BindingScope that knows the enclosingType, which is needed for pointcut reference resolution
-     *
-     * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
-     */
-    public static class BindingScope extends SimpleScope {
-        private ResolvedTypeX m_enclosingType;
-
-        public BindingScope(ResolvedTypeX type, FormalBinding[] bindings) {
-            super(type.getWorld(), bindings);
-            m_enclosingType = type;
-        }
-
-        public ResolvedTypeX getEnclosingType() {
-            return m_enclosingType;
-        }
-    }
-
-    /**
-     * LazyResolvedPointcutDefinition lazyly resolve the pointcut so that we have time to register all
-     * pointcut referenced before pointcut resolution happens
-     *
-     * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
-     */
-    public static class LazyResolvedPointcutDefinition extends ResolvedPointcutDefinition {
-        private Pointcut m_pointcutUnresolved;
-        private IScope m_binding;
-
-        private Pointcut m_lazyPointcut = null;
-
-        public LazyResolvedPointcutDefinition(ResolvedTypeX declaringType, int modifiers, String name, TypeX[] parameterTypes,
-                                              Pointcut pointcut, IScope binding) {
-            super(declaringType, modifiers, name, parameterTypes, null);
-            m_pointcutUnresolved = pointcut;
-            m_binding = binding;
-            m_pointcutUnresolved.setLocation(declaringType.getSourceContext(), 0, 0);
-        }
-
-        public Pointcut getPointcut() {
-            if (m_lazyPointcut == null) {
-                m_lazyPointcut = m_pointcutUnresolved.resolve(m_binding);
-                m_lazyPointcut.copyLocationFrom(m_pointcutUnresolved);
-            }
-            return m_lazyPointcut;
-        }
-    }
-
-    /**
-     * Helper to test empty strings
-     * @param s
-     * @return
-     */
-    private static boolean isNullOrEmpty(String s) {
-        return (s==null || s.length()<=0);
-    }
-
-    /**
-     * Set the pointcut bindings for which to ignore unbound issues, so that we can implicitly bind
-     * xxxJoinPoint for @AJ advices
-     *
-     * @param pointcut
-     * @param bindings
-     */
-    private static void setIgnoreUnboundBindingNames(Pointcut pointcut, FormalBinding[] bindings) {
-        // register ImplicitBindings as to be ignored since unbound
-        // TODO is it likely to fail in a bad way if f.e. this(jp) etc ?
-        List ignores = new ArrayList();
-        for (int i = 0; i < bindings.length; i++) {
-            FormalBinding formalBinding = bindings[i];
-            if (formalBinding instanceof FormalBinding.ImplicitFormalBinding) {
-                ignores.add(formalBinding.getName());
-            }
-        }
-        pointcut.m_ignoreUnboundBindingForNames = (String[])ignores.toArray(new String[ignores.size()]);
-    }
-
-    /**
-     * A check exception when we cannot read debug info (needed for formal binding)
-     */
-    private static class UnreadableDebugInfo extends Exception {
-    }
-}
diff --git a/weaver/src/org/aspectj/weaver/ataspectj/Ajc5MemberMaker.java b/weaver/src/org/aspectj/weaver/ataspectj/Ajc5MemberMaker.java
deleted file mode 100644 (file)
index e6f68d7..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*******************************************************************************
- * 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              Alexandre Vasseur
- *******************************************************************************/
-package org.aspectj.weaver.ataspectj;
-
-import org.aspectj.weaver.ResolvedMember;
-import org.aspectj.weaver.TypeX;
-import org.aspectj.weaver.Member;
-import org.aspectj.weaver.ResolvedTypeX;
-
-import java.lang.reflect.Modifier;
-
-/**
- * Addition to AjcMemberMaker for @Aj aspect
- * Should end up there
- *
- * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
- */
-public class Ajc5MemberMaker {
-
-    public final static TypeX ASPECT = TypeX.forName("org.aspectj.lang.annotation.Aspect");
-
-    /**
-     * Returns true if the given aspect is an @AJ aspect
-     *
-     * @param aspectType
-     * @return
-     */
-    public static boolean isAnnotationStyleAspect(ResolvedTypeX aspectType) {
-        if (aspectType != null) {
-            if (aspectType.isAspect()) {
-                return aspectType.isAnnotationStyleAspect();
-            }
-        }
-        return false;
-    }
-
-    //temp proto code for aspectOf without pre-processing
-    public static ResolvedMember perSingletonAspectOfMethod(TypeX declaringType) {
-        return new ResolvedMember(
-                Member.METHOD,
-                TypeX.forName("alex.lang.Aspects"),
-                Modifier.PUBLIC | Modifier.STATIC,
-                "aspectOf$singleton",
-                "(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"
-        );
-
-
-    }
-
-}
diff --git a/weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java b/weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java
new file mode 100644 (file)
index 0000000..154ec27
--- /dev/null
@@ -0,0 +1,1325 @@
+/*******************************************************************************
+ * 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              Alexandre Vasseur
+ *******************************************************************************/
+package org.aspectj.weaver.bcel;
+
+import org.aspectj.apache.bcel.classfile.Attribute;
+import org.aspectj.apache.bcel.classfile.Field;
+import org.aspectj.apache.bcel.classfile.JavaClass;
+import org.aspectj.apache.bcel.classfile.LocalVariable;
+import org.aspectj.apache.bcel.classfile.LocalVariableTable;
+import org.aspectj.apache.bcel.classfile.Method;
+import org.aspectj.apache.bcel.classfile.annotation.Annotation;
+import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnotations;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisibleAnnotations;
+import org.aspectj.apache.bcel.generic.Type;
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.IMessageHandler;
+import org.aspectj.bridge.Message;
+import org.aspectj.weaver.Advice;
+import org.aspectj.weaver.AdviceKind;
+import org.aspectj.weaver.AjAttribute;
+import org.aspectj.weaver.AjcMemberMaker;
+import org.aspectj.weaver.ISourceContext;
+import org.aspectj.weaver.NameMangler;
+import org.aspectj.weaver.ResolvedPointcutDefinition;
+import org.aspectj.weaver.ResolvedTypeX;
+import org.aspectj.weaver.TypeX;
+import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
+import org.aspectj.weaver.patterns.DeclarePrecedence;
+import org.aspectj.weaver.patterns.FormalBinding;
+import org.aspectj.weaver.patterns.IScope;
+import org.aspectj.weaver.patterns.ParserException;
+import org.aspectj.weaver.patterns.PatternParser;
+import org.aspectj.weaver.patterns.PerCflow;
+import org.aspectj.weaver.patterns.PerClause;
+import org.aspectj.weaver.patterns.PerObject;
+import org.aspectj.weaver.patterns.PerSingleton;
+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 java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Annotation defined aspect reader.
+ * <p/>
+ * It reads the Java 5 annotations and turns them into AjAttributes
+ *
+ * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+ */
+public class AtAjAttributes {
+
+    private final static List EMPTY_LIST = new ArrayList();
+    private final static String[] EMPTY_STRINGS = new String[0];
+    private final static String VALUE = "value";
+    private final static String POINTCUT = "pointcut";
+    private final static String THROWING = "throwing";
+    private final static String RETURNING = "returning";
+    private final static String STRING_DESC = "Ljava/lang/String;";
+
+    /**
+     * A struct that allows to add extra arguments without always breaking the API
+     *
+     * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+     */
+    private static class AjAttributeStruct {
+
+        /**
+         * The list of AjAttribute.XXX that we are populating from the @AJ read
+         */
+        List ajAttributes = new ArrayList();
+
+        /**
+         * The resolved type (class) for which we are reading @AJ for (be it class, method, field annotations)
+         */
+        final ResolvedTypeX enclosingType;
+
+        final ISourceContext context;
+        final IMessageHandler handler;
+
+        public AjAttributeStruct(ResolvedTypeX type, ISourceContext sourceContext, IMessageHandler messageHandler) {
+            enclosingType = type;
+            context = sourceContext;
+            handler = messageHandler;
+        }
+    }
+
+    /**
+     * A struct when we read @AJ on method
+     *
+     * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+     */
+    private static class AjAttributeMethodStruct extends AjAttributeStruct {
+
+        /**
+         * Argument names as they appear in the SOURCE code, ordered, and lazyly populated
+         * Used to do formal binding
+         */
+        private String[] m_argumentNamesLazy = null;
+
+        final Method method;
+
+        public AjAttributeMethodStruct(Method method, ResolvedTypeX type, ISourceContext sourceContext, IMessageHandler messageHandler) {
+            super(type, sourceContext, messageHandler);
+            this.method = method;
+        }
+
+        public String[] getArgumentNames() {
+            if (m_argumentNamesLazy == null) {
+                m_argumentNamesLazy = getMethodArgumentNamesAsInSource(method);
+            }
+            return m_argumentNamesLazy;
+        }
+    }
+
+    /**
+     * A struct when we read @AJ on field
+     *
+     * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+     */
+    private static class AjAttributeFieldStruct extends AjAttributeStruct {
+
+        final Field field;
+
+        public AjAttributeFieldStruct(Field field, ResolvedTypeX type, ISourceContext sourceContext, IMessageHandler messageHandler) {
+            super(type, sourceContext, messageHandler);
+            this.field = field;
+        }
+    }
+
+    /**
+     * Annotations are RuntimeVisible only. This allow us to not visit RuntimeInvisible ones.
+     *
+     * @param attribute
+     * @return
+     */
+    public static boolean acceptAttribute(Attribute attribute) {
+        return (attribute instanceof RuntimeVisibleAnnotations);
+    }
+
+    /**
+     * Extract class level annotations and turn them into AjAttributes.
+     *
+     * @param javaClass
+     * @param type
+     * @param context
+     * @param msgHandler
+     * @return list of AjAttributes
+     */
+    public static List readAj5ClassAttributes(JavaClass javaClass, ResolvedTypeX type, ISourceContext context, IMessageHandler msgHandler, boolean isCodeStyleAspect) {
+        AjAttributeStruct struct = new AjAttributeStruct(type, context, msgHandler);
+        Attribute[] attributes = javaClass.getAttributes();
+        boolean hasAtAspectAnnotation = false;
+        boolean hasAtPrecedenceAnnotation = false;
+
+        for (int i = 0; i < attributes.length; i++) {
+            Attribute attribute = attributes[i];
+            if (acceptAttribute(attribute)) {
+                RuntimeAnnotations rvs = (RuntimeAnnotations) attribute;
+                // we don't need to look for several attribute occurence since it cannot happen as per JSR175
+                if (!isCodeStyleAspect) {
+                    hasAtAspectAnnotation = handleAspectAnnotation(rvs, struct);
+                }
+                //TODO: below means mix style for @DeclarePrecedence - are we sure we want that ?
+                hasAtPrecedenceAnnotation = handlePrecedenceAnnotation(rvs, struct);
+                // there can only be one RuntimeVisible bytecode attribute
+                break;
+            }
+        }
+
+        // basic semantic check
+        //FIXME AV TBD could be skipped and silently ignore - TBD with Andy
+        if (hasAtPrecedenceAnnotation && !hasAtAspectAnnotation) {
+            msgHandler.handleMessage(
+                    new Message(
+                            "Found @DeclarePrecedence on a non @Aspect type '" + type.getName() + "'",
+                            IMessage.WARNING,
+                            null,
+                            type.getSourceLocation()
+                    )
+            );
+            // bypass what we have read
+            return EMPTY_LIST;
+        }
+        //FIXME turn on when ajcMightHaveAspect fixed
+//        if (hasAtAspectAnnotation && type.isInterface()) {
+//            msgHandler.handleMessage(
+//                    new Message(
+//                            "Found @Aspect on an interface type '" + type.getName() + "'",
+//                            IMessage.WARNING,
+//                            null,
+//                            type.getSourceLocation()
+//                    )
+//            );
+//            // bypass what we have read
+//            return EMPTY_LIST;
+//        }
+
+        // the following block will not detect @Pointcut in non @Aspect types for optimization purpose
+        // FIXME AV TBD with Andy
+        if (!hasAtAspectAnnotation) {
+            return EMPTY_LIST;
+        }
+
+        // code style pointcuts are class attributes
+        // we need to gather the @AJ pointcut right now and not at method level annotation extraction time
+        // in order to be able to resolve the pointcut references later on
+        //FIXME alex loop over class super class
+        //FIXME alex can that be too slow ?
+        for (int i = 0; i < javaClass.getMethods().length; i++) {
+            Method method = javaClass.getMethods()[i];
+            if (method.getName().startsWith(NameMangler.PREFIX)) continue;  // already dealt with by ajc...
+            //FIXME alex optimize, this method struct will gets recreated for advice extraction
+            AjAttributeMethodStruct mstruct = new AjAttributeMethodStruct(method, type, context, msgHandler);
+            Attribute[] mattributes = method.getAttributes();
+
+            for (int j = 0; j < mattributes.length; j++) {
+                Attribute mattribute = mattributes[j];
+                if (acceptAttribute(mattribute)) {
+                    RuntimeAnnotations mrvs = (RuntimeAnnotations) mattribute;
+                    handlePointcutAnnotation(mrvs, mstruct);
+                    // there can only be one RuntimeVisible bytecode attribute
+                    break;
+                }
+            }
+            struct.ajAttributes.addAll(mstruct.ajAttributes);
+        }
+
+
+        // code style declare error / warning are class 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);
+            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)) {
+                        // semantic check - must be in an @Aspect [remove if previous block bypassed in advance]
+                        if (!type.isAnnotationStyleAspect()) {
+                            msgHandler.handleMessage(
+                                    new Message(
+                                            "Found @AspectJ annotations in a non @Aspect type '" + type.getName() + "'",
+                                            IMessage.WARNING,
+                                            null,
+                                            type.getSourceLocation()
+                                    )
+                            );
+                            ;// go ahead
+                        }
+                    }
+                    // there can only be one RuntimeVisible bytecode attribute
+                    break;
+                }
+            }
+            struct.ajAttributes.addAll(fstruct.ajAttributes);
+        }
+        return struct.ajAttributes;
+    }
+
+    /**
+     * Extract method level annotations and turn them into AjAttributes.
+     *
+     * @param method
+     * @param type
+     * @param context
+     * @param msgHandler
+     * @return list of AjAttributes
+     */
+    public static List readAj5MethodAttributes(Method method, ResolvedTypeX type, ResolvedPointcutDefinition preResolvedPointcut, ISourceContext context, IMessageHandler msgHandler) {
+        if (method.getName().startsWith(NameMangler.PREFIX)) return Collections.EMPTY_LIST;  // already dealt with by ajc...
+
+        AjAttributeMethodStruct struct = new AjAttributeMethodStruct(method, type, context, msgHandler);
+        Attribute[] attributes = method.getAttributes();
+
+        // we remember if we found one @AJ annotation for minimal semantic error reporting
+        // the real reporting beeing done thru AJDT and the compiler mapping @AJ to AjAtttribute
+        // or thru APT
+        // FIXME AV we could actually skip the whole thing if type is not itself an @Aspect
+        // but then we would not see any warning. TBD with Andy
+        boolean hasAtAspectJAnnotation = false;
+        boolean hasAtAspectJAnnotationMustReturnVoid = false;
+        for (int i = 0; i < attributes.length; i++) {
+            Attribute attribute = attributes[i];
+            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
+                );
+                hasAtAspectJAnnotationMustReturnVoid = hasAtAspectJAnnotationMustReturnVoid || handleAfterThrowingAnnotation(
+                        rvs, struct, preResolvedPointcut
+                );
+                hasAtAspectJAnnotation = hasAtAspectJAnnotation || handleAroundAnnotation(
+                        rvs, struct, preResolvedPointcut
+                );
+                // there can only be one RuntimeVisible bytecode attribute
+                break;
+            }
+        }
+        hasAtAspectJAnnotation = hasAtAspectJAnnotation || hasAtAspectJAnnotationMustReturnVoid;
+
+        // semantic check - must be in an @Aspect [remove if previous block bypassed in advance]
+        if (hasAtAspectJAnnotation && !type.isAnnotationStyleAspect()) {
+            msgHandler.handleMessage(
+                    new Message(
+                            "Found @AspectJ annotations in a non @Aspect type '" + type.getName() + "'",
+                            IMessage.WARNING,
+                            null,
+                            type.getSourceLocation()
+                    )
+            );
+            ;// go ahead
+        }
+        // semantic check - advice must be public
+        if (hasAtAspectJAnnotation && !struct.method.isPublic()) {
+            msgHandler.handleMessage(
+                    new Message(
+                            "Found @AspectJ annotation on a non public advice '" + methodToString(struct.method) + "'",
+                            IMessage.ERROR,
+                            null,
+                            type.getSourceLocation()
+                    )
+            );
+            ;// go ahead
+        }
+        // semantic check for non around advice must return void
+        if (hasAtAspectJAnnotationMustReturnVoid && !Type.VOID.equals(struct.method.getReturnType())) {
+            msgHandler.handleMessage(
+                    new Message(
+                            "Found @AspectJ annotation on a non around advice not returning void '" + methodToString(
+                                    struct.method
+                            ) + "'",
+                            IMessage.ERROR,
+                            null,
+                            type.getSourceLocation()
+                    )
+            );
+            ;// go ahead
+        }
+
+
+        return struct.ajAttributes;
+    }
+
+    /**
+     * Extract field level annotations and turn them into AjAttributes.
+     *
+     * @param field
+     * @param type
+     * @param context
+     * @param msgHandler
+     * @return list of AjAttributes, always empty for now
+     */
+    public static List readAj5FieldAttributes(Field field, ResolvedTypeX type, ISourceContext context, IMessageHandler msgHandler) {
+        return Collections.EMPTY_LIST;
+    }
+
+    /**
+     * Read @Aspect
+     *
+     * @param runtimeAnnotations
+     * @param struct
+     * @return true if found
+     */
+    private static boolean handleAspectAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeStruct struct) {
+        Annotation aspect = getAnnotation(runtimeAnnotations, AjcMemberMaker.ASPECT_ANNOTATION);
+        if (aspect != null) {
+            ElementNameValuePair aspectPerClause = getAnnotationElement(aspect, VALUE);
+            final PerClause perClause;
+            if (aspectPerClause == null) {
+                // defaults to singleton
+                perClause = new PerSingleton();
+            } else {
+                String perX = aspectPerClause.getValue().stringifyValue();
+                if (perX == null || perX.length() <= 0) {
+                    perClause = new PerSingleton();
+                } else {
+                    perClause = parsePerClausePointcut(perX, struct);
+                }
+            }
+            if (perClause == null) {
+                // could not parse it, ignore the aspect
+                return false;
+            } else {
+                perClause.setLocation(struct.context, -1, -1);
+                struct.ajAttributes.add(new AjAttribute.Aspect(perClause));
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Read a perClause, returns null on failure and issue messages
+     *
+     * @param perClauseString like "pertarget(.....)"
+     * @param struct    for which we are parsing the per clause
+     * @return a PerClause instance
+     */
+    private static PerClause parsePerClausePointcut(String perClauseString, AjAttributeStruct struct) {
+        final String pointcutString;
+        Pointcut poincut = null;
+        TypePattern typePattern = null;
+        final PerClause perClause;
+        if (perClauseString.startsWith(PerClause.KindAnnotationPrefix.PERCFLOW.getName())) {
+            pointcutString = PerClause.KindAnnotationPrefix.PERCFLOW.extractPointcut(perClauseString);
+            poincut = parsePointcut(pointcutString, struct);
+            perClause = new PerCflow(poincut, false);
+        } else if (perClauseString.startsWith(PerClause.KindAnnotationPrefix.PERCFLOWBELOW.getName())) {
+            pointcutString = PerClause.KindAnnotationPrefix.PERCFLOWBELOW.extractPointcut(perClauseString);
+            poincut = parsePointcut(pointcutString, struct);
+            perClause = new PerCflow(poincut, true);
+        } else if (perClauseString.startsWith(PerClause.KindAnnotationPrefix.PERTARGET.getName())) {
+            pointcutString = PerClause.KindAnnotationPrefix.PERTARGET.extractPointcut(perClauseString);
+            poincut = parsePointcut(pointcutString, struct);
+            perClause = new PerObject(poincut, false);
+        } else if (perClauseString.startsWith(PerClause.KindAnnotationPrefix.PERTHIS.getName())) {
+            pointcutString = PerClause.KindAnnotationPrefix.PERTHIS.extractPointcut(perClauseString);
+            poincut = parsePointcut(pointcutString, struct);
+            perClause = new PerObject(poincut, true);
+        } else if (perClauseString.startsWith(PerClause.KindAnnotationPrefix.PERTYPEWITHIN.getName())) {
+            pointcutString = PerClause.KindAnnotationPrefix.PERTYPEWITHIN.extractPointcut(perClauseString);
+            typePattern = parseTypePattern(pointcutString, struct);
+            perClause = new PerTypeWithin(typePattern);
+        } else if (perClauseString.equalsIgnoreCase(PerClause.SINGLETON.getName() + "()")) {
+            perClause = new PerSingleton();
+        } else {
+            // could not parse the @AJ perclause - fallback to singleton and issue an error
+            reportError("@Aspect per clause cannot be read '" + perClauseString + "'", struct);
+            return null;
+        }
+
+        if (!PerClause.SINGLETON.equals(perClause.getKind())
+                && !PerClause.PERTYPEWITHIN.equals(perClause.getKind())
+                && poincut == null) {
+            // we could not parse the pointcut
+            return null;
+        }
+        if (PerClause.PERTYPEWITHIN.equals(perClause.getKind()) && typePattern == null) {
+            // we could not parse the type pattern
+            return null;
+        }
+        return perClause;
+    }
+
+    /**
+     * Read @DeclarePrecedence
+     *
+     * @param runtimeAnnotations
+     * @param struct
+     * @return true if found
+     */
+    private static boolean handlePrecedenceAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeStruct struct) {
+        Annotation aspect = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREPRECEDENCE_ANNOTATION);
+        if (aspect != null) {
+            ElementNameValuePair precedence = getAnnotationElement(aspect, VALUE);
+            if (precedence != null) {
+                String precedencePattern = precedence.getValue().stringifyValue();
+                PatternParser parser = new PatternParser(precedencePattern);
+                DeclarePrecedence ajPrecedence = parser.parseDominates();
+                struct.ajAttributes.add(new AjAttribute.DeclareAttribute(ajPrecedence));
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Read @Before
+     *
+     * @param runtimeAnnotations
+     * @param struct
+     * @return true if found
+     */
+    private static boolean handleBeforeAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) {
+        Annotation before = getAnnotation(runtimeAnnotations, AjcMemberMaker.BEFORE_ANNOTATION);
+        if (before != null) {
+            ElementNameValuePair beforeAdvice = getAnnotationElement(before, VALUE);
+            if (beforeAdvice != null) {
+                // this/target/args binding
+                FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
+                try {
+                    bindings = extractBindings(struct);
+                } catch (UnreadableDebugInfoException unreadableDebugInfoException) {
+                    return false;
+                }
+                IScope binding = new BindingScope(
+                        struct.enclosingType,
+                        bindings
+                );
+
+                // joinpoint, staticJoinpoint binding
+                int extraArgument = extractExtraArgument(struct.method);
+
+                Pointcut pc = null;
+                if (preResolvedPointcut != null) {
+                    pc = preResolvedPointcut.getPointcut();
+                } else {
+                    pc = parsePointcut(beforeAdvice.getValue().stringifyValue(), struct);
+                    if (pc == null) return false;//parse error
+                    pc.resolve(binding);
+                }
+                setIgnoreUnboundBindingNames(pc, bindings);
+
+                struct.ajAttributes.add(
+                        new AjAttribute.AdviceAttribute(
+                                AdviceKind.Before,
+                                pc,
+                                extraArgument,
+                                -1,
+                                -1,
+                                struct.context
+                        )
+                );
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Read @After
+     *
+     * @param runtimeAnnotations
+     * @param struct
+     * @return true if found
+     */
+    private static boolean handleAfterAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) {
+        Annotation after = getAnnotation(runtimeAnnotations, AjcMemberMaker.AFTER_ANNOTATION);
+        if (after != null) {
+            ElementNameValuePair afterAdvice = getAnnotationElement(after, VALUE);
+            if (afterAdvice != null) {
+                // this/target/args binding
+                FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
+                try {
+                    bindings = extractBindings(struct);
+                } catch (UnreadableDebugInfoException unreadableDebugInfoException) {
+                    return false;
+                }
+                IScope binding = new BindingScope(
+                        struct.enclosingType,
+                        bindings
+                );
+
+                // joinpoint, staticJoinpoint binding
+                int extraArgument = extractExtraArgument(struct.method);
+
+                Pointcut pc = null;
+                if (preResolvedPointcut != null) {
+                    pc = preResolvedPointcut.getPointcut();
+                } else {
+                    pc = parsePointcut(afterAdvice.getValue().stringifyValue(), struct);
+                    if (pc == null) return false;//parse error
+                    pc.resolve(binding);
+                }
+                setIgnoreUnboundBindingNames(pc, bindings);
+
+                struct.ajAttributes.add(
+                        new AjAttribute.AdviceAttribute(
+                                AdviceKind.After,
+                                pc,
+                                extraArgument,
+                                -1,
+                                -1,
+                                struct.context
+                        )
+                );
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Read @AfterReturning
+     *
+     * @param runtimeAnnotations
+     * @param struct
+     * @return true if found
+     */
+    private static boolean handleAfterReturningAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) {
+        Annotation after = getAnnotation(runtimeAnnotations, AjcMemberMaker.AFTERRETURNING_ANNOTATION);
+        if (after != null) {
+            ElementNameValuePair annValue = getAnnotationElement(after, VALUE);
+            ElementNameValuePair annPointcut = getAnnotationElement(after, POINTCUT);
+            ElementNameValuePair annReturned = getAnnotationElement(after, RETURNING);
+
+            // extract the pointcut and returned type/binding - do some checks
+            String pointcut = null;
+            String returned = null;
+            if ((annValue != null && annPointcut != null) || (annValue == null && annPointcut == null)) {
+                reportError("@AfterReturning: either 'value' or 'poincut' must be provided, not both", struct);
+                return false;
+            }
+            if (annValue != null) {
+                pointcut = annValue.getValue().stringifyValue();
+            } else {
+                pointcut = annPointcut.getValue().stringifyValue();
+            }
+            if (isNullOrEmpty(pointcut)) {
+                reportError("@AfterReturning: either 'value' or 'poincut' must be provided, not both", struct);
+                return false;
+            }
+            if (annReturned != null) {
+                returned = annReturned.getValue().stringifyValue();
+                if (isNullOrEmpty(returned))
+                    returned = null;
+            }
+
+            // this/target/args binding
+            // exclude the return binding from the pointcut binding since it is an extraArg binding
+            FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
+            try {
+                bindings = (returned == null ? extractBindings(struct) : extractBindings(struct, returned));
+            } catch (UnreadableDebugInfoException unreadableDebugInfoException) {
+                return false;
+            }
+            IScope binding = new BindingScope(
+                    struct.enclosingType,
+                    bindings
+            );
+
+            // joinpoint, staticJoinpoint binding
+            int extraArgument = extractExtraArgument(struct.method);
+
+            // return binding
+            if (returned != null) {
+                extraArgument |= Advice.ExtraArgument;
+            }
+
+            Pointcut pc = null;
+            if (preResolvedPointcut != null) {
+                pc = preResolvedPointcut.getPointcut();
+            } else {
+                pc = parsePointcut(pointcut, struct);
+                if (pc == null) return false;//parse error
+                pc.resolve(binding);
+            }
+            setIgnoreUnboundBindingNames(pc, bindings);
+
+            struct.ajAttributes.add(
+                    new AjAttribute.AdviceAttribute(
+                            AdviceKind.AfterReturning,
+                            pc,
+                            extraArgument,
+                            -1,
+                            -1,
+                            struct.context
+                    )
+            );
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Read @AfterThrowing
+     *
+     * @param runtimeAnnotations
+     * @param struct
+     * @return true if found
+     */
+    private static boolean handleAfterThrowingAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) {
+        Annotation after = getAnnotation(runtimeAnnotations, AjcMemberMaker.AFTERTHROWING_ANNOTATION);
+        if (after != null) {
+            ElementNameValuePair annValue = getAnnotationElement(after, VALUE);
+            ElementNameValuePair annPointcut = getAnnotationElement(after, POINTCUT);
+            ElementNameValuePair annThrowned = getAnnotationElement(after, THROWING);
+
+            // extract the pointcut and throwned type/binding - do some checks
+            String pointcut = null;
+            String throwned = null;
+            if ((annValue != null && annPointcut != null) || (annValue == null && annPointcut == null)) {
+                reportError("@AfterThrowing: either 'value' or 'poincut' must be provided, not both", struct);
+                return false;
+            }
+            if (annValue != null) {
+                pointcut = annValue.getValue().stringifyValue();
+            } else {
+                pointcut = annPointcut.getValue().stringifyValue();
+            }
+            if (isNullOrEmpty(pointcut)) {
+                reportError("@AfterThrowing: either 'value' or 'poincut' must be provided, not both", struct);
+                return false;
+            }
+            if (annThrowned != null) {
+                throwned = annThrowned.getValue().stringifyValue();
+                if (isNullOrEmpty(throwned))
+                    throwned = null;
+            }
+
+            // this/target/args binding
+            // exclude the throwned binding from the pointcut binding since it is an extraArg binding
+            FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
+            try {
+                bindings = (throwned == null ? extractBindings(struct) : extractBindings(struct, throwned));
+            } catch (UnreadableDebugInfoException unreadableDebugInfoException) {
+                return false;
+            }
+            IScope binding = new BindingScope(
+                    struct.enclosingType,
+                    bindings
+            );
+
+            // joinpoint, staticJoinpoint binding
+            int extraArgument = extractExtraArgument(struct.method);
+
+            // return binding
+            if (throwned != null) {
+                extraArgument |= Advice.ExtraArgument;
+            }
+
+            Pointcut pc = null;
+            if (preResolvedPointcut != null) {
+                pc = preResolvedPointcut.getPointcut();
+            } else {
+                pc = parsePointcut(pointcut, struct);
+                if (pc == null) return false;//parse error
+                pc.resolve(binding);
+            }
+            setIgnoreUnboundBindingNames(pc, bindings);
+
+            struct.ajAttributes.add(
+                    new AjAttribute.AdviceAttribute(
+                            AdviceKind.AfterThrowing,
+                            pc,
+                            extraArgument,
+                            -1,
+                            -1,
+                            struct.context
+                    )
+            );
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Read @Around
+     *
+     * @param runtimeAnnotations
+     * @param struct
+     * @return true if found
+     */
+    private static boolean handleAroundAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) {
+        Annotation around = getAnnotation(runtimeAnnotations, AjcMemberMaker.AROUND_ANNOTATION);
+        if (around != null) {
+            ElementNameValuePair aroundAdvice = getAnnotationElement(around, VALUE);
+            if (aroundAdvice != null) {
+                // this/target/args binding
+                FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
+                try {
+                    bindings = extractBindings(struct);
+                } catch (UnreadableDebugInfoException unreadableDebugInfoException) {
+                    return false;
+                }
+                IScope binding = new BindingScope(
+                        struct.enclosingType,
+                        bindings
+                );
+
+                // joinpoint, staticJoinpoint binding
+                int extraArgument = extractExtraArgument(struct.method);
+
+                Pointcut pc = null;
+                if (preResolvedPointcut != null) {
+                    pc = preResolvedPointcut.getPointcut();
+                } else {
+                    pc = parsePointcut(aroundAdvice.getValue().stringifyValue(), struct);
+                    if (pc == null) return false;//parse error
+                    pc.resolve(binding);
+                }
+                setIgnoreUnboundBindingNames(pc, bindings);
+
+                struct.ajAttributes.add(
+                        new AjAttribute.AdviceAttribute(
+                                AdviceKind.Around,
+                                pc,
+                                extraArgument,
+                                -1,
+                                -1,
+                                struct.context
+                        )
+                );
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Read @Pointcut and handle the resolving in a lazy way to deal with pointcut references
+     *
+     * @param runtimeAnnotations
+     * @param struct
+     */
+    private static void handlePointcutAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct) {
+        Annotation pointcut = getAnnotation(runtimeAnnotations, AjcMemberMaker.POINTCUT_ANNOTATION);
+        if (pointcut != null) {
+            ElementNameValuePair pointcutExpr = getAnnotationElement(pointcut, VALUE);
+            if (pointcutExpr != null) {
+
+                // semantic check: the method must return void
+                if (!Type.VOID.equals(struct.method.getReturnType())) {
+                    reportWarning("Found @Pointcut on a method not returning void", struct);
+                    ;//no need to stop
+                }
+                // semantic check: the method must not throw anything
+                if (struct.method.getExceptionTable() != null) {
+                    reportWarning("Found @Pointcut on a method throwing exception", struct);
+                    ;// no need to stop
+                }
+
+                // this/target/args binding
+                final IScope binding;
+                try {
+                    binding = new BindingScope(
+                            struct.enclosingType,
+                            extractBindings(struct)
+                    );
+                } catch (UnreadableDebugInfoException e) {
+                    return;
+                }
+
+                TypeX[] argumentTypes = new TypeX[struct.method.getArgumentTypes().length];
+                for (int i = 0; i < argumentTypes.length; i++) {
+                    argumentTypes[i] = TypeX.forSignature(struct.method.getArgumentTypes()[i].getSignature());
+                }
+
+                // use a LazyResolvedPointcutDefinition so that the pointcut is resolved lazily
+                // since for it to be resolved, we will need other pointcuts to be registered as well
+                Pointcut pc = parsePointcut(pointcutExpr.getValue().stringifyValue(), struct);
+                if (pc == null) return;//parse error
+                // do not resolve binding now but lazily
+                pc.setLocation(struct.context, -1, -1);
+                struct.ajAttributes.add(
+                        new AjAttribute.PointcutDeclarationAttribute(
+                                new LazyResolvedPointcutDefinition(
+                                        struct.enclosingType,
+                                        struct.method.getModifiers(),
+                                        struct.method.getName(),
+                                        argumentTypes,
+                                        pc,
+                                        binding
+                                )
+                        )
+                );
+            }
+        }
+    }
+
+    /**
+     * Read @DeclareError, @DeclareWarning
+     *
+     * @param runtimeAnnotations
+     * @param struct
+     * @return true if found
+     */
+    private static boolean handleDeclareErrorOrWarningAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeFieldStruct struct) {
+        Annotation error = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREERROR_ANNOTATION);
+        boolean hasError = false;
+        if (error != null) {
+            ElementNameValuePair declareError = getAnnotationElement(error, VALUE);
+            if (declareError != null) {
+                if (!STRING_DESC.equals(struct.field.getSignature()) || struct.field.getConstantValue() == null) {
+                    reportError("@DeclareError used on a non String constant field", struct);
+                    return false;
+                }
+                FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
+                IScope binding = new BindingScope(
+                        struct.enclosingType,
+                        bindings
+                );
+                Pointcut pc = parsePointcut(declareError.getValue().stringifyValue(), struct);
+                if (pc == null) {
+                    hasError = false;//cannot parse pointcut
+                } else {
+                    pc .resolve(binding);
+                    DeclareErrorOrWarning deow = new DeclareErrorOrWarning(true, pc, struct.field.getConstantValue().toString());
+                    deow.setLocation(struct.context, -1, -1);
+                    struct.ajAttributes.add(new AjAttribute.DeclareAttribute(deow));
+                    hasError = true;
+                }
+            }
+        }
+        Annotation warning = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREWARNING_ANNOTATION);
+        boolean hasWarning = false;
+        if (warning != null) {
+            ElementNameValuePair declareWarning = getAnnotationElement(warning, VALUE);
+            if (declareWarning != null) {
+                if (!STRING_DESC.equals(struct.field.getSignature()) || struct.field.getConstantValue() == null) {
+                    reportError("@DeclareWarning used on a non String constant field", struct);
+                    return false;
+                }
+                FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
+                IScope binding = new BindingScope(
+                        struct.enclosingType,
+                        bindings
+                );
+                Pointcut pc = parsePointcut(declareWarning.getValue().stringifyValue(), struct);
+                if (pc == null) {
+                    hasWarning = false;//cannot parse pointcut
+                } else {
+                    pc.resolve(binding);
+                    DeclareErrorOrWarning deow = new DeclareErrorOrWarning(false, pc, struct.field.getConstantValue().toString());
+                    deow.setLocation(struct.context, -1, -1);
+                    struct.ajAttributes.add(new AjAttribute.DeclareAttribute(deow));
+                    return hasWarning = true;
+                }
+            }
+        }
+        return hasError || hasWarning;
+    }
+
+    /**
+     * Returns a readable representation of a method.
+     * Method.toString() is not suitable.
+     *
+     * @param method
+     * @return
+     */
+    private static String methodToString(Method method) {
+        StringBuffer sb = new StringBuffer();
+        sb.append(method.getName());
+        sb.append(method.getSignature());
+        return sb.toString();
+    }
+
+    /**
+     * Returns a readable representation of a field.
+     * Field.toString() is not suitable.
+     *
+     * @param field
+     * @return
+     */
+    private static String fieldToString(Field field) {
+        StringBuffer sb = new StringBuffer();
+        sb.append(field.getName()).append(' ');
+        sb.append(field.getSignature());
+        return sb.toString();
+    }
+
+    /**
+     * Build the bindings for a given method (pointcut / advice)
+     *
+     * @param struct
+     * @return null if no debug info is available
+     */
+    private static FormalBinding[] extractBindings(AjAttributeMethodStruct struct)
+            throws UnreadableDebugInfoException {
+        Method method = struct.method;
+        String[] argumentNames = struct.getArgumentNames();
+
+        // assert debug info was here
+        if (argumentNames.length != method.getArgumentTypes().length) {
+            reportError("Cannot read debug info for @Aspect to handle formal binding in pointcuts (please compile with 'javac -g' or '<javac debug='true'.../>' in Ant)", struct);
+            throw new UnreadableDebugInfoException();
+        }
+
+        List bindings = new ArrayList();
+        for (int i = 0; i < argumentNames.length; i++) {
+            String argumentName = argumentNames[i];
+            TypeX argumentType = TypeX.forSignature(method.getArgumentTypes()[i].getSignature());
+
+            // do not bind JoinPoint / StaticJoinPoint / EnclosingStaticJoinPoint
+            // TODO solve me : this means that the JP/SJP/ESJP cannot appear as binding
+            // f.e. when applying advice on advice etc
+            if ((AjcMemberMaker.TYPEX_JOINPOINT.equals(argumentType)
+                    || AjcMemberMaker.TYPEX_PROCEEDINGJOINPOINT.equals(argumentType)
+                    || AjcMemberMaker.TYPEX_STATICJOINPOINT.equals(argumentType)
+                    || AjcMemberMaker.TYPEX_ENCLOSINGSTATICJOINPOINT.equals(argumentType)
+                    || AjcMemberMaker.AROUND_CLOSURE_TYPE.equals(argumentType))) {
+                //continue;// skip
+                bindings.add(new FormalBinding.ImplicitFormalBinding(argumentType, argumentName, i));
+            } else {
+                bindings.add(new FormalBinding(argumentType, argumentName, i));
+            }
+        }
+
+        return (FormalBinding[]) bindings.toArray(new FormalBinding[]{});
+    }
+
+    //FIXME alex deal with exclude index
+    private static FormalBinding[] extractBindings(AjAttributeMethodStruct struct, String excludeFormal)
+            throws UnreadableDebugInfoException {
+        FormalBinding[] bindings = extractBindings(struct);
+        int excludeIndex = -1;
+        for (int i = 0; i < bindings.length; i++) {
+            FormalBinding binding = bindings[i];
+            if (binding.getName().equals(excludeFormal)) {
+                excludeIndex = i;
+                bindings[i] = new FormalBinding.ImplicitFormalBinding(
+                        binding.getType(), binding.getName(), binding.getIndex()
+                );
+                break;
+            }
+        }
+        return bindings;
+//
+//        if (excludeIndex >= 0) {
+//            FormalBinding[] bindingsFiltered = new FormalBinding[bindings.length-1];
+//            int k = 0;
+//            for (int i = 0; i < bindings.length; i++) {
+//                if (i == excludeIndex) {
+//                    ;
+//                } else {
+//                    bindingsFiltered[k] = new FormalBinding(bindings[i].getType(), bindings[i].getName(), k);
+//                    k++;
+//                }
+//            }
+//            return bindingsFiltered;
+//        } else {
+//            return bindings;
+//        }
+    }
+
+
+    /**
+     * Compute the flag for the xxxJoinPoint extra argument
+     *
+     * @param method
+     * @return
+     */
+    private static int extractExtraArgument(Method method) {
+        int extraArgument = 0;
+        Type[] methodArgs = method.getArgumentTypes();
+        for (int i = 0; i < methodArgs.length; i++) {
+            String methodArg = methodArgs[i].getSignature();
+            if (AjcMemberMaker.TYPEX_JOINPOINT.getSignature().equals(methodArg)) {
+                extraArgument |= Advice.ThisJoinPoint;
+            } else if (AjcMemberMaker.TYPEX_PROCEEDINGJOINPOINT.getSignature().equals(methodArg)) {
+                extraArgument |= Advice.ThisJoinPoint;
+            } else if (AjcMemberMaker.TYPEX_STATICJOINPOINT.getSignature().equals(methodArg)) {
+                extraArgument |= Advice.ThisJoinPointStaticPart;
+            } else if (AjcMemberMaker.TYPEX_ENCLOSINGSTATICJOINPOINT.getSignature().equals(methodArg)) {
+                extraArgument |= Advice.ThisEnclosingJoinPointStaticPart;
+            }
+        }
+        return extraArgument;
+    }
+
+    /**
+     * Returns the runtime (RV/RIV) annotation of type annotationType or null if no such annotation
+     *
+     * @param rvs
+     * @param annotationType
+     * @return
+     */
+    private static Annotation getAnnotation(RuntimeAnnotations rvs, TypeX annotationType) {
+        final String annotationTypeName = annotationType.getName();
+        for (Iterator iterator = rvs.getAnnotations().iterator(); iterator.hasNext();) {
+            Annotation rv = (Annotation) iterator.next();
+            if (annotationTypeName.equals(rv.getTypeName())) {
+                return rv;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the value of a given element of an annotation or null if not found
+     * Caution: Does not handles default value.
+     *
+     * @param annotation
+     * @param elementName
+     * @return
+     */
+    private static ElementNameValuePair getAnnotationElement(Annotation annotation, String elementName) {
+        for (Iterator iterator1 = annotation.getValues().iterator(); iterator1.hasNext();) {
+            ElementNameValuePair element = (ElementNameValuePair) iterator1.next();
+            if (elementName.equals(element.getNameString())) {
+                return element;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Extract the method argument names as in source from debug info
+     * returns an empty array upon inconsistency
+     *
+     * @param method
+     * @return
+     */
+    private static String[] getMethodArgumentNamesAsInSource(Method method) {
+        if (method.getArgumentTypes().length == 0) {
+            return EMPTY_STRINGS;
+        }
+
+        final int startAtStackIndex = method.isStatic() ? 0 : 1;
+        final List arguments = new ArrayList();
+        LocalVariableTable lt = (LocalVariableTable) method.getLocalVariableTable();
+        if (lt != null) {
+            for (int j = 0; j < lt.getLocalVariableTable().length; j++) {
+                LocalVariable localVariable = lt.getLocalVariableTable()[j];
+                if (localVariable.getStartPC() == 0) {
+                    if (localVariable.getIndex() >= startAtStackIndex) {
+                        arguments.add(new MethodArgument(localVariable.getName(), localVariable.getIndex()));
+                    }
+                }
+            }
+        }
+
+        if (arguments.size() != method.getArgumentTypes().length) {
+            return EMPTY_STRINGS;
+        }
+
+        // sort by index
+        Collections.sort(
+                arguments, new Comparator() {
+                    public int compare(Object o, Object o1) {
+                        MethodArgument mo = (MethodArgument) o;
+                        MethodArgument mo1 = (MethodArgument) o1;
+                        if (mo.indexOnStack == mo1.indexOnStack) {
+                            return 0;
+                        } else if (mo.indexOnStack > mo1.indexOnStack) {
+                            return 1;
+                        } else {
+                            return -1;
+                        }
+                    }
+                }
+        );
+        String[] argumentNames = new String[arguments.size()];
+        int i = 0;
+        for (Iterator iterator = arguments.iterator(); iterator.hasNext(); i++) {
+            MethodArgument methodArgument = (MethodArgument) iterator.next();
+            argumentNames[i] = methodArgument.name;
+        }
+        return argumentNames;
+    }
+
+    /**
+     * A method argument, used for sorting by indexOnStack (ie order in signature)
+     *
+     * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+     */
+    private static class MethodArgument {
+        String name;
+        int indexOnStack;
+
+        public MethodArgument(String name, int indexOnStack) {
+            this.name = name;
+            this.indexOnStack = indexOnStack;
+        }
+    }
+
+    /**
+     * BindingScope that knows the enclosingType, which is needed for pointcut reference resolution
+     *
+     * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+     */
+    public static class BindingScope extends SimpleScope {
+        private ResolvedTypeX m_enclosingType;
+
+        public BindingScope(ResolvedTypeX type, FormalBinding[] bindings) {
+            super(type.getWorld(), bindings);
+            m_enclosingType = type;
+        }
+
+        public ResolvedTypeX getEnclosingType() {
+            return m_enclosingType;
+        }
+    }
+
+    /**
+     * LazyResolvedPointcutDefinition lazyly resolve the pointcut so that we have time to register all
+     * pointcut referenced before pointcut resolution happens
+     *
+     * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+     */
+    public static class LazyResolvedPointcutDefinition extends ResolvedPointcutDefinition {
+        private Pointcut m_pointcutUnresolved;
+        private IScope m_binding;
+
+        private Pointcut m_lazyPointcut = null;
+
+        public LazyResolvedPointcutDefinition(ResolvedTypeX declaringType, int modifiers, String name, TypeX[] parameterTypes,
+                                              Pointcut pointcut, IScope binding) {
+            super(declaringType, modifiers, name, parameterTypes, null);
+            m_pointcutUnresolved = pointcut;
+            m_binding = binding;
+        }
+
+        public Pointcut getPointcut() {
+            if (m_lazyPointcut == null) {
+                m_lazyPointcut = m_pointcutUnresolved.resolve(m_binding);
+                m_lazyPointcut.copyLocationFrom(m_pointcutUnresolved);
+            }
+            return m_lazyPointcut;
+        }
+    }
+
+    /**
+     * Helper to test empty strings
+     *
+     * @param s
+     * @return
+     */
+    private static boolean isNullOrEmpty(String s) {
+        return (s == null || s.length() <= 0);
+    }
+
+    /**
+     * Set the pointcut bindings for which to ignore unbound issues, so that we can implicitly bind
+     * xxxJoinPoint for @AJ advices
+     *
+     * @param pointcut
+     * @param bindings
+     */
+    private static void setIgnoreUnboundBindingNames(Pointcut pointcut, FormalBinding[] bindings) {
+        // register ImplicitBindings as to be ignored since unbound
+        // TODO is it likely to fail in a bad way if f.e. this(jp) etc ?
+        List ignores = new ArrayList();
+        for (int i = 0; i < bindings.length; i++) {
+            FormalBinding formalBinding = bindings[i];
+            if (formalBinding instanceof FormalBinding.ImplicitFormalBinding) {
+                ignores.add(formalBinding.getName());
+            }
+        }
+        pointcut.m_ignoreUnboundBindingForNames = (String[]) ignores.toArray(new String[ignores.size()]);
+    }
+
+    /**
+     * A check exception when we cannot read debug info (needed for formal binding)
+     */
+    private static class UnreadableDebugInfoException extends Exception {
+    }
+
+    /**
+     * Report an error
+     *
+     * @param message
+     * @param location
+     */
+    private static void reportError(String message, AjAttributeStruct location) {
+        if (!location.handler.isIgnoring(IMessage.ERROR)) {
+            location.handler.handleMessage(
+                    new Message(
+                            message,
+                            location.enclosingType.getSourceLocation(),
+                            true
+                    )
+            );
+        }
+    }
+
+    /**
+     * Report a warning
+     *
+     * @param message
+     * @param location
+     */
+    private static void reportWarning(String message, AjAttributeStruct location) {
+        if (!location.handler.isIgnoring(IMessage.WARNING)) {
+            location.handler.handleMessage(
+                    new Message(
+                            message,
+                            location.enclosingType.getSourceLocation(),
+                            false
+                    )
+            );
+        }
+    }
+
+    /**
+     * Parse the given pointcut, return null on failure and issue an error
+     *
+     * @param pointcutString
+     * @param location
+     * @return
+     */
+    private static Pointcut parsePointcut(String pointcutString, AjAttributeStruct location) {
+        try {
+            Pointcut pointcut = Pointcut.fromString(pointcutString);
+            pointcut.setLocation(location.context, -1, -1);//FIXME -1,-1 is not good enough
+            return pointcut;
+        } catch (ParserException e) {
+            reportError("Invalid pointcut '" + pointcutString + "' : " + e.getLocation(), location);
+            return null;
+        }
+    }
+
+    /**
+     * Parse the given type pattern, return null on failure and issue an error
+     *
+     * @param patternString
+     * @param location
+     * @return
+     */
+    private static TypePattern parseTypePattern(String patternString, AjAttributeStruct location) {
+        try {
+            TypePattern typePattern = new PatternParser(patternString).parseTypePattern();
+            typePattern.setLocation(location.context, -1, -1);//FIXME -1,-1 is not good enough
+            return typePattern;
+        } catch (ParserException e) {
+            reportError("Invalid type pattern'" + patternString + "' : " + e.getLocation(), location);
+            return null;
+        }
+    }
+}
index 1fa87d1b0091d77c19016dd00043ba33e00788ad..3dc4878535c561f185cfa6521b1da1eb22d14342 100644 (file)
@@ -37,7 +37,6 @@ import org.aspectj.weaver.TypeX;
 import org.aspectj.weaver.WeaverMessages;
 import org.aspectj.weaver.World;
 import org.aspectj.weaver.PerObjectInterfaceTypeMunger;
-import org.aspectj.weaver.ataspectj.Ajc5MemberMaker;
 import org.aspectj.weaver.ast.Literal;
 import org.aspectj.weaver.ast.Test;
 import org.aspectj.weaver.patterns.ExactTypePattern;
@@ -362,7 +361,7 @@ public class BcelAdvice extends Advice {
 
             if (v == null) {
                 // if not @AJ aspect, go on with the regular binding handling
-               if (!Ajc5MemberMaker.isAnnotationStyleAspect(getConcreteAspect())) {
+               if (!getConcreteAspect().isAnnotationStyleAspect()) {
                        continue;
                } else {
                     // ATAJ: for @AJ aspects, handle implicit binding of xxJoinPoint
@@ -408,7 +407,7 @@ public class BcelAdvice extends Advice {
         
         // ATAJ: for code style aspect, handles the extraFlag as usual ie not
         // in the middle of the formal bindings but at the end, in a rock solid ordering
-        if (!Ajc5MemberMaker.isAnnotationStyleAspect(getConcreteAspect())) {
+        if (!getConcreteAspect().isAnnotationStyleAspect()) {
             if (getKind() == AdviceKind.Around) {
                 il.append(closureInstantiation);
             } else if (hasExtraParameter()) {
index ee8d51bc5f4151d1b3f35095fb8338a2a8037057..98789df085fd41b56a4d9d56590d9da061cd1109 100644 (file)
@@ -27,7 +27,6 @@ import org.aspectj.weaver.ResolvedMember;
 import org.aspectj.weaver.ResolvedTypeX;
 import org.aspectj.weaver.TypeX;
 import org.aspectj.weaver.World;
-import org.aspectj.weaver.ataspectj.Aj5Attributes;
 
 final class BcelField extends ResolvedMember {
 
@@ -56,7 +55,7 @@ final class BcelField extends ResolvedMember {
        private void unpackAttributes(World world) {
                Attribute[] attrs = field.getAttributes();
         List as = BcelAttributes.readAjAttributes(getDeclaringType().getClassName(),attrs, getSourceContext(world),world.getMessageHandler());
-        as.addAll(Aj5Attributes.readAj5FieldAttributes(field, world.resolve(getDeclaringType()), getSourceContext(world), world.getMessageHandler()));
+        as.addAll(AtAjAttributes.readAj5FieldAttributes(field, world.resolve(getDeclaringType()), getSourceContext(world), world.getMessageHandler()));
 
                for (Iterator iter = as.iterator(); iter.hasNext();) {
                        AjAttribute a = (AjAttribute) iter.next();
index a8c62999298b1164a04b93f4a0e5b07494f973aa..ca4dfaaa41ae0f0f08ab478b2a0a80fba35f0d7a 100644 (file)
@@ -34,7 +34,6 @@ import org.aspectj.weaver.ResolvedTypeX;
 import org.aspectj.weaver.ShadowMunger;
 import org.aspectj.weaver.TypeX;
 import org.aspectj.weaver.World;
-import org.aspectj.weaver.ataspectj.Aj5Attributes;
 
 final class BcelMethod extends ResolvedMember {
 
@@ -101,7 +100,7 @@ final class BcelMethod extends ResolvedMember {
                associatedShadowMunger = null;
         List as = BcelAttributes.readAjAttributes(getDeclaringType().getClassName(),method.getAttributes(), getSourceContext(world),world.getMessageHandler());
                processAttributes(world, as);
-               as = Aj5Attributes.readAj5MethodAttributes(method, world.resolve(getDeclaringType()), preResolvedPointcut,getSourceContext(world), world.getMessageHandler());
+               as = AtAjAttributes.readAj5MethodAttributes(method, world.resolve(getDeclaringType()), preResolvedPointcut,getSourceContext(world), world.getMessageHandler());
                processAttributes(world,as);
        }
 
index 862b2a65bbe0b61a285e2d02970baafb31988699..75c46d5ddcd37f1047d691bcb554cc3832540187 100644 (file)
@@ -36,9 +36,8 @@ import org.aspectj.weaver.ResolvedPointcutDefinition;
 import org.aspectj.weaver.ResolvedTypeX;
 import org.aspectj.weaver.TypeX;
 import org.aspectj.weaver.WeaverStateInfo;
+import org.aspectj.weaver.AjcMemberMaker;
 import org.aspectj.weaver.patterns.PerClause;
-import org.aspectj.weaver.ataspectj.Aj5Attributes;
-import org.aspectj.weaver.ataspectj.Ajc5MemberMaker;
 
 
 // ??? exposed for testing
@@ -186,7 +185,7 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName {
     public boolean isAnnotationStyleAspect() {
                if (!discoveredWhetherAnnotationStyle) {
                        discoveredWhetherAnnotationStyle = true;
-                       isAnnotationStyleAspect = !isCodeStyleAspect && hasAnnotation(Ajc5MemberMaker.ASPECT);
+                       isAnnotationStyleAspect = !isCodeStyleAspect && hasAnnotation(AjcMemberMaker.ASPECT_ANNOTATION);
                }
         return isAnnotationStyleAspect;
     }
@@ -198,7 +197,7 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName {
                // Pass in empty list that can store things for readAj5 to process
         List l = BcelAttributes.readAjAttributes(javaClass.getClassName(),javaClass.getAttributes(), getResolvedTypeX().getSourceContext(),getResolvedTypeX().getWorld().getMessageHandler());
                processAttributes(l,pointcuts,false);
-               l = Aj5Attributes.readAj5ClassAttributes(javaClass, getResolvedTypeX(), getResolvedTypeX().getSourceContext(), getResolvedTypeX().getWorld().getMessageHandler(),isCodeStyleAspect);
+               l = AtAjAttributes.readAj5ClassAttributes(javaClass, getResolvedTypeX(), getResolvedTypeX().getSourceContext(), getResolvedTypeX().getWorld().getMessageHandler(),isCodeStyleAspect);
                processAttributes(l,pointcuts,true);
                
                this.pointcuts = (ResolvedPointcutDefinition[]) 
index f41cce9658fb588c5e0290c31c38350206bc6da8..4bc3daf92c00e8bdb296233d7458a1383030e39b 100644 (file)
@@ -74,7 +74,6 @@ import org.aspectj.weaver.TypeX;
 import org.aspectj.weaver.WeaverMessages;
 import org.aspectj.weaver.World;
 import org.aspectj.weaver.ast.Var;
-import org.aspectj.weaver.ataspectj.Ajc5MemberMaker;
 
 
 /*
@@ -2549,8 +2548,7 @@ public class BcelShadow extends Shadow {
                }
 
         // ATAJ for @AJ aspect we need to link the closure with the joinpoint instance
-        if (Ajc5MemberMaker.isAnnotationStyleAspect(munger.getConcreteAspect())) {
-            //advice.append(new POP());
+        if (munger.getConcreteAspect().isAnnotationStyleAspect()) {
             closureInstantiation.append(Utility.createInvoke(
                     getFactory(),
                     getWorld(),
@@ -2563,12 +2561,9 @@ public class BcelShadow extends Shadow {
                             )
             ));
         }
-        //System.err.println(closureInstantiation);
-
 
         InstructionList advice = new InstructionList();
         advice.append(munger.getAdviceArgSetup(this, null, closureInstantiation));
-//        advice.append(closureInstantiation);
 
         // invoke the advice
         advice.append(munger.getNonTestAdviceInstructions(this));
index f9d97a936f6a6a208723d648dfdab250b5b64c68..73eef47d7e24aa66b4ba598cc3e82f479ad08011 100644 (file)
@@ -35,7 +35,6 @@ import org.aspectj.weaver.TypeX;
 import org.aspectj.weaver.VersionedDataInputStream;
 import org.aspectj.weaver.World;
 import org.aspectj.weaver.bcel.BcelAccessForInlineMunger;
-import org.aspectj.weaver.ataspectj.Ajc5MemberMaker;
 import org.aspectj.weaver.ast.Expr;
 import org.aspectj.weaver.ast.Test;
 
@@ -106,7 +105,7 @@ public class PerCflow extends PerClause {
         }
 
         //ATAJ inline around advice support - don't use a late munger to allow around inling for itself
-        if (Ajc5MemberMaker.isAnnotationStyleAspect(inAspect)) {
+        if (inAspect.isAnnotationStyleAspect()) {
             inAspect.crosscuttingMembers.addTypeMunger(new BcelAccessForInlineMunger(inAspect));
         }
 
index 3ec3addebe7da924bc6a85a8f5002409667112b3..31eef9adefed8e5fdf36a9c3ab6db6ad5b90cb4f 100644 (file)
@@ -30,7 +30,6 @@ import org.aspectj.weaver.Shadow;
 import org.aspectj.weaver.VersionedDataInputStream;
 import org.aspectj.weaver.World;
 import org.aspectj.weaver.bcel.BcelAccessForInlineMunger;
-import org.aspectj.weaver.ataspectj.Ajc5MemberMaker;
 import org.aspectj.weaver.ast.Expr;
 import org.aspectj.weaver.ast.Test;
 import org.aspectj.weaver.ast.Var;
@@ -119,7 +118,7 @@ public class PerObject extends PerClause {
         }
 
         //ATAJ inline around advice support - don't use a late munger to allow around inling for itself
-        if (Ajc5MemberMaker.isAnnotationStyleAspect(inAspect)) {
+        if (inAspect.isAnnotationStyleAspect()) {
             inAspect.crosscuttingMembers.addTypeMunger(new BcelAccessForInlineMunger(inAspect));
         }
 
index bf390fa6e67c858118ff6477b94759999febedc4..385f9175c6a2c8b464851375ab5b61141dacde69 100644 (file)
@@ -27,7 +27,6 @@ import org.aspectj.weaver.bcel.BcelAccessForInlineMunger;
 import org.aspectj.weaver.ast.Expr;
 import org.aspectj.weaver.ast.Literal;
 import org.aspectj.weaver.ast.Test;
-import org.aspectj.weaver.ataspectj.Ajc5MemberMaker;
 
 public class PerSingleton extends PerClause {
        public PerSingleton() {
@@ -97,7 +96,7 @@ public class PerSingleton extends PerClause {
                ret.inAspect = inAspect;
 
         //ATAJ: add a munger to add the aspectOf(..) to the @AJ aspects
-        if (!inAspect.isAbstract() && Ajc5MemberMaker.isAnnotationStyleAspect(inAspect)) {
+        if (!inAspect.isAbstract() && inAspect.isAnnotationStyleAspect()) {
             //TODO will those change be ok if we add a serializable aspect ?
             // dig: "can't be Serializable/Cloneable unless -XserializableAspects"
             inAspect.crosscuttingMembers.addLateTypeMunger(
@@ -106,7 +105,7 @@ public class PerSingleton extends PerClause {
         }
 
         //ATAJ inline around advice support
-        if (Ajc5MemberMaker.isAnnotationStyleAspect(inAspect)) {
+        if (inAspect.isAnnotationStyleAspect()) {
             inAspect.crosscuttingMembers.addTypeMunger(new BcelAccessForInlineMunger(inAspect));
         }
 
index 59c4169b7a87fc8b9994c6c67eb8a1e3dcaeee9b..651d192a306ed15df26f46f6457f856545319e84 100644 (file)
@@ -33,7 +33,6 @@ import org.aspectj.weaver.Shadow;
 import org.aspectj.weaver.VersionedDataInputStream;
 import org.aspectj.weaver.World;
 import org.aspectj.weaver.bcel.BcelAccessForInlineMunger;
-import org.aspectj.weaver.ataspectj.Ajc5MemberMaker;
 import org.aspectj.weaver.ast.Expr;
 import org.aspectj.weaver.ast.Literal;
 import org.aspectj.weaver.ast.Test;
@@ -156,7 +155,7 @@ public class PerTypeWithin extends PerClause {
         }
 
         //ATAJ inline around advice support - don't use a late munger to allow around inling for itself
-        if (Ajc5MemberMaker.isAnnotationStyleAspect(inAspect)) {
+        if (inAspect.isAnnotationStyleAspect()) {
             inAspect.crosscuttingMembers.addTypeMunger(new BcelAccessForInlineMunger(inAspect));
         }
 
index a1bf961cd5322987d4e6af2b2444d969b820bec4..67bd70f3c98e7a2fb6892afbf656c8fd57e2ece1 100644 (file)
@@ -37,7 +37,6 @@ import org.aspectj.util.FileUtil;
 import org.aspectj.weaver.IClassFileProvider;
 import org.aspectj.weaver.IWeaveRequestor;
 import org.aspectj.weaver.ResolvedTypeX;
-import org.aspectj.weaver.ataspectj.Ajc5MemberMaker;
 import org.aspectj.weaver.bcel.BcelWeaver;
 import org.aspectj.weaver.bcel.BcelWorld;
 import org.aspectj.weaver.bcel.UnwovenClassFile;
@@ -209,7 +208,7 @@ public class WeavingAdaptor {
      */
        private boolean shouldWeaveAspect (String name) {
                ResolvedTypeX type = bcelWorld.resolve(name);
-        return (type == null || !type.isAspect() || Ajc5MemberMaker.isAnnotationStyleAspect(type));
+        return (type == null || !type.isAspect() || type.isAnnotationStyleAspect());
        }
 
        /**