]> source.dussan.org Git - aspectj.git/commitdiff
support in ajc for parsing and error reporting of @AspectJ style aspect definitions...
authoracolyer <acolyer>
Mon, 25 Apr 2005 16:07:25 +0000 (16:07 +0000)
committeracolyer <acolyer>
Mon, 25 Apr 2005 16:07:25 +0000 (16:07 +0000)
34 files changed:
org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompilerAdapter.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AddAtAspectJAnnotationsVisitor.java [new file with mode: 0644]
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AjMethodDeclaration.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AtAspectJAnnotationFactory.java [new file with mode: 0644]
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDeclaration.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDesignator.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/ValidateAtAspectJAnnotationsVisitor.java [new file with mode: 0644]
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AspectJBuilder.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseSourceContext.java
org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CommandTestCase.java
org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjCompilerOptionsTest.java
weaver/src/org/aspectj/weaver/ISourceContext.java
weaver/src/org/aspectj/weaver/ataspectj/Aj5Attributes.java
weaver/src/org/aspectj/weaver/bcel/BcelMethod.java
weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java
weaver/src/org/aspectj/weaver/bcel/BcelSourceContext.java
weaver/src/org/aspectj/weaver/patterns/BasicTokenSource.java
weaver/src/org/aspectj/weaver/patterns/PatternNode.java
weaver/src/org/aspectj/weaver/patterns/PatternParser.java
weaver/src/org/aspectj/weaver/patterns/PerCflow.java
weaver/src/org/aspectj/weaver/patterns/PerClause.java
weaver/src/org/aspectj/weaver/patterns/PerFromSuper.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/testsrc/org/aspectj/weaver/patterns/NamePatternParserTestCase.java

index 0f89095854b25a42078cb406235e14f58c373c09..af7cc30fa0d7f30458bb4f9999fc7f06915f400e 100644 (file)
@@ -511,7 +511,9 @@ public class BuildArgParser extends Main {
                        } else if (arg.equals("-XjavadocsInModel")) {
                                buildConfig.setGenerateModelMode(true);
                                buildConfig.setGenerateJavadocsInModelMode(true);
-                       } else if (arg.equals("-noweave") || arg.equals( "-XnoWeave")) {
+                       } else if (arg.equals("-Xdev:NoAtAspectJProcessing")) { 
+                               buildConfig.setNoAtAspectJAnnotationProcessing(true);
+               }else if (arg.equals("-noweave") || arg.equals( "-XnoWeave")) {
                                buildConfig.setNoWeave(true);
                        } else if (arg.equals("-XserializableAspects")) {
                                buildConfig.setXserializableAspects(true);
index 9091a8c15705e4af5ab7f9af31eae8046c4923cd..8085a51f41fce8082df63379931da058af494179 100644 (file)
@@ -19,20 +19,24 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
+import org.aspectj.ajdt.internal.compiler.ast.AddAtAspectJAnnotationsVisitor;
+import org.aspectj.ajdt.internal.compiler.ast.ValidateAtAspectJAnnotationsVisitor;
 import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
+import org.aspectj.ajdt.internal.core.builder.AjCompilerOptions;
 import org.aspectj.bridge.IMessage;
 import org.aspectj.bridge.IMessageHandler;
 import org.aspectj.bridge.IProgressListener;
-import org.aspectj.weaver.bcel.BcelWeaver;
-import org.aspectj.weaver.bcel.BcelWorld;
-import org.aspectj.weaver.patterns.CflowPointcut;
 import org.aspectj.org.eclipse.jdt.core.compiler.IProblem;
 import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
 import org.aspectj.org.eclipse.jdt.internal.compiler.Compiler;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ICompilerAdapter;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
 import org.aspectj.org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.aspectj.org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.aspectj.weaver.bcel.BcelWeaver;
+import org.aspectj.weaver.bcel.BcelWorld;
+import org.aspectj.weaver.patterns.CflowPointcut;
 
 /**
  * @author colyer
@@ -48,6 +52,8 @@ public class AjCompilerAdapter implements ICompilerAdapter {
        private boolean reportedErrors;
        private boolean isXNoWeave;
        private boolean proceedOnError;
+       private boolean inJava5Mode;
+       private boolean noAtAspectJAnnotationProcessing;
        private IIntermediateResultsRequestor intermediateResultsRequestor;
        private IProgressListener progressListener;
        private IOutputClassFileNameProvider outputFileNameProvider;
@@ -55,7 +61,6 @@ public class AjCompilerAdapter implements ICompilerAdapter {
        private WeaverMessageHandler weaverMessageHandler;
        private Map /* fileName |-> List<UnwovenClassFile> */ binarySourceSetForFullWeave = new HashMap();
        private Collection /*InterimCompilationResult*/ resultSetForFullWeave = Collections.EMPTY_LIST;
-
        
        List /*InterimResult*/ resultsPendingWeave = new ArrayList();
 
@@ -86,7 +91,8 @@ public class AjCompilerAdapter implements ICompilerAdapter {
                                                         Map fullBinarySourceEntries, /* fileName |-> List<UnwovenClassFile> */
                                                         Collection /* InterimCompilationResult */ resultSetForFullWeave,
                                                         boolean isXNoWeave,
-                                                        boolean proceedOnError) {
+                                                        boolean proceedOnError,
+                                                        boolean noAtAspectJProcessing) {
                this.compiler = compiler;
                this.isBatchCompile = isBatchCompile;
                this.weaver = weaver;
@@ -99,6 +105,10 @@ public class AjCompilerAdapter implements ICompilerAdapter {
                this.binarySourceSetForFullWeave = fullBinarySourceEntries;
                this.resultSetForFullWeave = resultSetForFullWeave;
                this.eWorld = eFactory;
+               this.inJava5Mode = false;
+               this.noAtAspectJAnnotationProcessing = noAtAspectJProcessing;
+               
+               if (compiler.options.complianceLevel == CompilerOptions.JDK1_5) inJava5Mode = true;
                
                IMessageHandler msgHandler = world.getMessageHandler();
                weaverMessageHandler = new WeaverMessageHandler(msgHandler, compiler);
@@ -133,6 +143,17 @@ public class AjCompilerAdapter implements ICompilerAdapter {
 
        public void beforeProcessing(CompilationUnitDeclaration unit) {
                eWorld.showMessage(IMessage.INFO, "compiling " + new String(unit.getFileName()), null, null);
+               if (inJava5Mode && !noAtAspectJAnnotationProcessing) {
+                       AddAtAspectJAnnotationsVisitor atAspectJVisitor = new AddAtAspectJAnnotationsVisitor(unit);
+                       unit.traverse(atAspectJVisitor, unit.scope);
+               }               
+       }
+       
+       public void beforeAnalysing(CompilationUnitDeclaration unit) {
+               if (inJava5Mode && !noAtAspectJAnnotationProcessing) {
+                       ValidateAtAspectJAnnotationsVisitor atAspectJVisitor = new ValidateAtAspectJAnnotationsVisitor(unit);
+                       unit.traverse(atAspectJVisitor, unit.scope);
+               }               
        }
 
        public void afterProcessing(CompilationUnitDeclaration unit, int unitIndex) {
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AddAtAspectJAnnotationsVisitor.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AddAtAspectJAnnotationsVisitor.java
new file mode 100644 (file)
index 0000000..8b4ade5
--- /dev/null
@@ -0,0 +1,61 @@
+/* *******************************************************************
+ * Copyright (c) 2005 IBM Corporation Ltd
+ * 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://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Adrian Colyer  initial implementation 
+ * ******************************************************************/
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import org.aspectj.org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
+
+public class AddAtAspectJAnnotationsVisitor extends ASTVisitor {
+
+       private CompilationUnitDeclaration unit;
+       
+       public AddAtAspectJAnnotationsVisitor(CompilationUnitDeclaration unit) {
+               this.unit = unit;
+       }
+       
+       public boolean visit(TypeDeclaration localTypeDeclaration, BlockScope scope) {
+               if (localTypeDeclaration instanceof AspectDeclaration) {
+                       ((AspectDeclaration) localTypeDeclaration).addAtAspectJAnnotations();
+               }
+               return true;
+       }
+       
+       
+       public boolean visit(TypeDeclaration memberTypeDeclaration,ClassScope scope) {
+               if (memberTypeDeclaration instanceof AspectDeclaration) {
+                       ((AspectDeclaration) memberTypeDeclaration).addAtAspectJAnnotations();
+               }
+               return true;
+       }
+       
+       public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
+               if (typeDeclaration instanceof AspectDeclaration) {
+                       ((AspectDeclaration) typeDeclaration).addAtAspectJAnnotations();
+               }
+               return true;
+       }
+       public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
+               if (methodDeclaration instanceof AdviceDeclaration) {
+                       ((AdviceDeclaration)methodDeclaration).addAtAspectJAnnotations();
+               } else if (methodDeclaration instanceof PointcutDeclaration) {
+                       ((PointcutDeclaration)methodDeclaration).addAtAspectJAnnotations();
+               } 
+               return false;
+       }
+       
+
+}
index a81ad0abf55428a1d41be15ae1f225e8cb9fc198..6e2d955911defab6ca2980c75e0309489780fdbb 100644 (file)
@@ -20,14 +20,10 @@ import java.util.List;
 import org.aspectj.ajdt.internal.compiler.lookup.AjTypeConstants;
 import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
 import org.aspectj.ajdt.internal.compiler.lookup.PrivilegedHandler;
-import org.aspectj.weaver.Advice;
-import org.aspectj.weaver.AdviceKind;
-import org.aspectj.weaver.AjAttribute;
-import org.aspectj.weaver.NameMangler;
-import org.aspectj.weaver.ResolvedMember;
-import org.aspectj.weaver.TypeX;
+import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile;
 import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Argument;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeReference;
@@ -37,7 +33,12 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ClassScope;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
+import org.aspectj.weaver.Advice;
+import org.aspectj.weaver.AdviceKind;
+import org.aspectj.weaver.AjAttribute;
+import org.aspectj.weaver.NameMangler;
+import org.aspectj.weaver.ResolvedMember;
+import org.aspectj.weaver.TypeX;
 
 /**
  * Represents before, after and around advice in an aspect.
@@ -47,22 +48,21 @@ import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
  * @author Jim Hugunin
  */
 public class AdviceDeclaration extends AjMethodDeclaration {
-       public PointcutDesignator pointcutDesignator;
-       int baseArgumentCount;
+       public PointcutDesignator pointcutDesignator;  // set during parsing
+       int baseArgumentCount;                               // referenced by IfPseudoToken.makeArguments
        
-       public Argument extraArgument;
+       public Argument extraArgument;                    // set during parsing, referenced by Proceed
        
-       public AdviceKind kind;
+       public AdviceKind kind;                                                                 // set during parsing, referenced by Proceed and AsmElementFormatter
        private int extraArgumentFlags = 0;
        
-       public MethodBinding proceedMethodBinding;
-       
+       public MethodBinding proceedMethodBinding;   // set during this.resolveStaments, referenced by Proceed
+       public List proceedCalls = new ArrayList(2);    // populated during Proceed.findEnclosingAround
        
-       public List proceedCalls = new ArrayList(2);
-       public boolean proceedInInners;
-       public ResolvedMember[] proceedCallSignatures;
-       public boolean[] formalsUnchangedToProceed;
-       public TypeX[] declaredExceptions;
+       private boolean proceedInInners;
+       private ResolvedMember[] proceedCallSignatures;
+       private boolean[] formalsUnchangedToProceed;
+       private TypeX[] declaredExceptions;
        
        
        public AdviceDeclaration(CompilationResult result, AdviceKind kind) {
@@ -71,7 +71,7 @@ public class AdviceDeclaration extends AjMethodDeclaration {
                this.kind = kind;
        }
 
-       
+       // override
        protected int generateInfoAttributes(ClassFile classFile) {
                List l = new ArrayList(1);
                l.add(new EclipseAttributeAdapter(makeAttribute()));
@@ -80,7 +80,7 @@ public class AdviceDeclaration extends AjMethodDeclaration {
                return classFile.generateMethodInfoAttribute(binding, false, l);
        }
        
-       public AjAttribute makeAttribute() {
+       private AjAttribute makeAttribute() {
                if (kind == AdviceKind.Around) {
                        return new AjAttribute.AdviceAttribute(kind, pointcutDesignator.getPointcut(), 
                                        extraArgumentFlags, sourceStart, sourceEnd, null,
@@ -92,6 +92,7 @@ public class AdviceDeclaration extends AjMethodDeclaration {
                }
        }
 
+       // override
        public void resolveStatements() {
                if (binding == null || ignoreFurtherInvestigation) return;
                
@@ -172,14 +173,14 @@ public class AdviceDeclaration extends AjMethodDeclaration {
                }
        }
 
-
+     // called by Proceed.resolveType
        public int getDeclaredParameterCount() {
                // this only works before code generation
                return this.arguments.length - 3 - ((extraArgument == null) ? 0 : 1);
                //Advice.countOnes(extraArgumentFlags);
        }
 
-       public void generateProceedMethod(ClassScope classScope, ClassFile classFile) {
+       private void generateProceedMethod(ClassScope classScope, ClassFile classFile) {
                MethodBinding binding = (MethodBinding)proceedMethodBinding;
                
                classFile.generateMethodInfoHeader(binding);
@@ -243,7 +244,7 @@ public class AdviceDeclaration extends AjMethodDeclaration {
        }
 
 
-
+       // override
        public void generateCode(ClassScope classScope, ClassFile classFile) {
                if (ignoreFurtherInvestigation) return;
                
@@ -268,7 +269,39 @@ public class AdviceDeclaration extends AjMethodDeclaration {
                return ret;
        }
 
+       /**
+        * Add either the @Before, @After, @Around, @AfterReturning or @AfterThrowing annotation
+        */
+       public void addAtAspectJAnnotations() {
+               Annotation adviceAnnotation = null;
+               String pointcutExpression = pointcutDesignator.getPointcut().toString();
+               String extraArgumentName = "";
+               if (extraArgument != null) {
+                       extraArgumentName = new String(extraArgument.name);
+               }
+               
+               if (kind == AdviceKind.Before) {
+                       adviceAnnotation = AtAspectJAnnotationFactory.createBeforeAnnotation(pointcutExpression,declarationSourceStart);
+               } else if (kind == AdviceKind.After) {
+                       adviceAnnotation = AtAspectJAnnotationFactory.createAfterAnnotation(pointcutExpression,declarationSourceStart);                 
+               } else if (kind == AdviceKind.AfterReturning) {
+                       adviceAnnotation = AtAspectJAnnotationFactory.createAfterReturningAnnotation(pointcutExpression,extraArgumentName,declarationSourceStart);
+               } else if (kind == AdviceKind.AfterThrowing) {
+                       adviceAnnotation = AtAspectJAnnotationFactory.createAfterThrowingAnnotation(pointcutExpression,extraArgumentName,declarationSourceStart);
+               } else if (kind == AdviceKind.Around) {
+                       adviceAnnotation = AtAspectJAnnotationFactory.createAroundAnnotation(pointcutExpression,declarationSourceStart);
+               }
+               if (annotations == null) {
+                       annotations = new Annotation[] { adviceAnnotation };
+               } else {
+                       Annotation[] old = annotations;
+                       annotations = new Annotation[old.length +1];
+                       System.arraycopy(old,0,annotations,0,old.length);
+                       annotations[old.length] = adviceAnnotation;
+               }
+       }
        
+       // override, Called by ClassScope.postParse
        public void postParse(TypeDeclaration typeDec) {
                int adviceSequenceNumberInType = ((AspectDeclaration)typeDec).adviceCounter++;
                
@@ -321,7 +354,7 @@ public class AdviceDeclaration extends AjMethodDeclaration {
                }
        }
 
-       
+       // called by IfPseudoToken
        public static Argument[]  addTjpArguments(Argument[] arguments) {
                int index = arguments.length;
                arguments = extendArgumentsLength(arguments, 3);
index bb31f5e16c24be1897ecd063b04a1f4671561cc8..efaedf2b573378cf480574c45f949e6aca963ca4 100644 (file)
@@ -25,6 +25,8 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
  */
 public class AjMethodDeclaration extends MethodDeclaration {
 
+       private List attributes = new ArrayList();
+       
        /**
         * @param compilationResult
         */
@@ -32,12 +34,18 @@ public class AjMethodDeclaration extends MethodDeclaration {
                super(compilationResult);
        }
 
+       // general purpose hook to add an AjAttribute to this method
+       // used by @AspectJ visitor to add pointcut attribute to @Advice
+       protected void addAttribute(EclipseAttributeAdapter eaa) {
+               attributes.add(eaa);
+       }
+       
        /**
         * Overridden to add extra AJ stuff, also adds synthetic if boolean is true.
         */
        protected int generateInfoAttributes(ClassFile classFile,boolean addAjSynthetic) {
                // add extra attributes into list then call 2-arg version of generateInfoAttributes...
-               List extras = new ArrayList();
+               List extras = attributes;
                addDeclarationStartLineAttribute(extras,classFile);
                if (addAjSynthetic) {
                        extras.add(new EclipseAttributeAdapter(new AjAttribute.AjSynthetic()));
index 31eb13fe5a87f82e1ad304726eb6cc74e9aa1ebf..f9beb3f85020ed98a2482823ae660960b3d957ca 100644 (file)
 package org.aspectj.ajdt.internal.compiler.ast;
 
 import java.lang.reflect.Modifier;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
-import org.aspectj.ajdt.internal.compiler.lookup.*;
-import org.aspectj.weaver.*;
-import org.aspectj.weaver.patterns.*;
+import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
+import org.aspectj.ajdt.internal.compiler.lookup.EclipseScope;
+import org.aspectj.ajdt.internal.compiler.lookup.EclipseSourceType;
+import org.aspectj.ajdt.internal.compiler.lookup.EclipseTypeMunger;
+import org.aspectj.ajdt.internal.compiler.lookup.HelperInterfaceBinding;
+import org.aspectj.ajdt.internal.compiler.lookup.InlineAccessFieldBinding;
+import org.aspectj.ajdt.internal.compiler.lookup.PrivilegedHandler;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile;
 import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
-//import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Clinit;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
-//import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.CodeStream;
 import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel;
 import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.Label;
 import org.aspectj.org.eclipse.jdt.internal.compiler.env.IGenericType;
-import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.*;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BaseTypes;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.aspectj.weaver.AjAttribute;
+import org.aspectj.weaver.AjcMemberMaker;
+import org.aspectj.weaver.NameMangler;
+import org.aspectj.weaver.ResolvedMember;
+import org.aspectj.weaver.ResolvedTypeX;
+import org.aspectj.weaver.Shadow;
+import org.aspectj.weaver.TypeX;
+import org.aspectj.weaver.patterns.Declare;
+import org.aspectj.weaver.patterns.FormalBinding;
+import org.aspectj.weaver.patterns.PerClause;
+import org.aspectj.weaver.patterns.PerFromSuper;
+import org.aspectj.weaver.patterns.PerSingleton;
+import org.aspectj.weaver.patterns.TypePattern;
 //import org.aspectj.org.eclipse.jdt.internal.compiler.parser.Parser;
 
 
@@ -158,6 +188,28 @@ public class AspectDeclaration extends TypeDeclaration {
        
        private FieldBinding initFailureField= null;
        
+       /**
+        * AMC - this method is called by the AtAspectJVisitor during beforeCompilation processing in
+        * the AjCompiler adapter. We use this hook to add in the @AspectJ annotations.
+        */
+       public void addAtAspectJAnnotations() {         
+               Annotation atAspectAnnotation = AtAspectJAnnotationFactory.createAspectAnnotation(perClause.toDeclarationString(), declarationSourceStart);
+               Annotation privilegedAnnotation = null;
+               if (isPrivileged) privilegedAnnotation = AtAspectJAnnotationFactory.createPrivilegedAnnotation(declarationSourceStart);
+               Annotation[] toAdd = new Annotation[isPrivileged ? 2 : 1];
+               toAdd[0] = atAspectAnnotation;
+               if (isPrivileged) toAdd[1] = privilegedAnnotation;
+               if (annotations == null) {
+                       annotations = toAdd;
+               } else {
+                       Annotation[] old = annotations;
+                       annotations = new Annotation[annotations.length + toAdd.length];
+                       System.arraycopy(old,0,annotations,0,old.length);
+                       System.arraycopy(toAdd,0,annotations,old.length,toAdd.length);
+               }               
+       }
+       
+       
        public void generateCode(ClassFile enclosingClassFile) {
                if (ignoreFurtherInvestigation) {
                        if (binding == null)
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AtAspectJAnnotationFactory.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AtAspectJAnnotationFactory.java
new file mode 100644 (file)
index 0000000..304cd47
--- /dev/null
@@ -0,0 +1,146 @@
+/* *******************************************************************
+ * 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: 
+ *   Adrian Colyer                     Initial implementation
+ * ******************************************************************/
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.StringLiteral;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeReference;
+
+/**
+ * @author colyer
+ * Creates @AspectJ annotations for use by AtAspectJVisitor
+ */
+public class AtAspectJAnnotationFactory {
+       
+       static final char[] org = "org".toCharArray();
+       static final char[] aspectj = "aspectj".toCharArray();
+       static final char[] lang = "lang".toCharArray();
+       static final char[] internal = "internal".toCharArray();
+       static final char[] annotation = "annotation".toCharArray();
+       static final char[] value = "value".toCharArray();
+       
+       static final char[] aspect = "Aspect".toCharArray();
+       static final char[] privileged = "ajcPrivileged".toCharArray();
+       static final char[] before = "Before".toCharArray();
+       static final char[] after = "After".toCharArray();
+       static final char[] afterReturning = "AfterReturning".toCharArray();
+       static final char[] afterThrowing = "AfterThrowing".toCharArray();
+       static final char[] around = "Around".toCharArray();
+    static final char[] pointcut = "Pointcut".toCharArray(); 
+
+       /**
+        * Create an @Aspect annotation for a code style aspect declaration starting at
+        * the given position in the source file
+        */
+       public static Annotation createAspectAnnotation(String perclause, int pos) {
+               char[][] typeName = new char[][] {org,aspectj,lang,annotation,aspect};
+               long[] positions = new long[] {pos,pos,pos,pos,pos};
+               TypeReference orgAspectJLangAnnotationAspect = new QualifiedTypeReference(typeName,positions);
+               NormalAnnotation atAspectAnnotation = new NormalAnnotation(orgAspectJLangAnnotationAspect,pos);
+               if (!perclause.equals("")) {
+                       // we have to set the value
+                       Expression perclauseExpr = new StringLiteral(perclause.toCharArray(),pos,pos);
+                       MemberValuePair[] mvps = new MemberValuePair[1];
+                       mvps[0] = new MemberValuePair(value,pos,pos,perclauseExpr);
+                       atAspectAnnotation.memberValuePairs = mvps;
+               }
+               return atAspectAnnotation;
+       }
+       
+       public static Annotation createPrivilegedAnnotation(int pos) {
+               char[][] typeName = new char[][] {org,aspectj,internal,lang,annotation,privileged};
+               long[] positions = new long[] {pos,pos,pos,pos,pos,pos};
+               TypeReference annType = new QualifiedTypeReference(typeName,positions);
+               NormalAnnotation ann = new NormalAnnotation(annType,pos);
+               return ann;
+       }
+
+       public static Annotation createBeforeAnnotation(String pointcutExpression, int pos) {
+               char[][] typeName = new char[][] {org,aspectj,lang,annotation,before};
+               long[] positions = new long[] {pos,pos,pos,pos,pos};
+               TypeReference annType = new QualifiedTypeReference(typeName,positions);
+               NormalAnnotation ann = new NormalAnnotation(annType,pos);
+               Expression pcExpr = new StringLiteral(pointcutExpression.toCharArray(),pos,pos);
+               MemberValuePair[] mvps = new MemberValuePair[1];
+               mvps[0] = new MemberValuePair(value,pos,pos,pcExpr);
+               ann.memberValuePairs = mvps;
+               return ann;
+       }
+
+       public static Annotation createAfterAnnotation(String pointcutExpression, int pos) {
+               char[][] typeName = new char[][] {org,aspectj,lang,annotation,after};
+               long[] positions = new long[] {pos,pos,pos,pos,pos};
+               TypeReference annType = new QualifiedTypeReference(typeName,positions);
+               NormalAnnotation ann = new NormalAnnotation(annType,pos);
+               Expression pcExpr = new StringLiteral(pointcutExpression.toCharArray(),pos,pos);
+               MemberValuePair[] mvps = new MemberValuePair[1];
+               mvps[0] = new MemberValuePair(value,pos,pos,pcExpr);
+               ann.memberValuePairs = mvps;
+               return ann;
+       }
+
+       public static Annotation createAfterReturningAnnotation(String pointcutExpression, String extraArgumentName, int pos) {
+               char[][] typeName = new char[][] {org,aspectj,lang,annotation,afterReturning};
+               long[] positions = new long[] {pos,pos,pos,pos,pos};
+               TypeReference annType = new QualifiedTypeReference(typeName,positions);
+               NormalAnnotation ann = new NormalAnnotation(annType,pos);
+               Expression pcExpr = new StringLiteral(pointcutExpression.toCharArray(),pos,pos);
+               MemberValuePair[] mvps = new MemberValuePair[2];
+               mvps[0] = new MemberValuePair("pointcut".toCharArray(),pos,pos,pcExpr);
+               Expression argExpr = new StringLiteral(extraArgumentName.toCharArray(),pos,pos);
+               mvps[1] = new MemberValuePair("returning".toCharArray(),pos,pos,argExpr);
+               ann.memberValuePairs = mvps;
+               return ann;
+       }
+
+       public static Annotation createAfterThrowingAnnotation(String pointcutExpression, String extraArgumentName, int pos) {
+               char[][] typeName = new char[][] {org,aspectj,lang,annotation,afterThrowing};
+               long[] positions = new long[] {pos,pos,pos,pos,pos};
+               TypeReference annType = new QualifiedTypeReference(typeName,positions);
+               NormalAnnotation ann = new NormalAnnotation(annType,pos);
+               Expression pcExpr = new StringLiteral(pointcutExpression.toCharArray(),pos,pos);
+               MemberValuePair[] mvps = new MemberValuePair[2];
+               mvps[0] = new MemberValuePair("pointcut".toCharArray(),pos,pos,pcExpr);
+               Expression argExpr = new StringLiteral(extraArgumentName.toCharArray(),pos,pos);
+               mvps[1] = new MemberValuePair("throwing".toCharArray(),pos,pos,argExpr);
+               ann.memberValuePairs = mvps;
+               return ann;
+       }
+
+       public static Annotation createAroundAnnotation(String pointcutExpression, int pos) {
+               char[][] typeName = new char[][] {org,aspectj,lang,annotation,around};
+               long[] positions = new long[] {pos,pos,pos,pos,pos};
+               TypeReference annType = new QualifiedTypeReference(typeName,positions);
+               NormalAnnotation ann = new NormalAnnotation(annType,pos);
+               Expression pcExpr = new StringLiteral(pointcutExpression.toCharArray(),pos,pos);
+               MemberValuePair[] mvps = new MemberValuePair[1];
+               mvps[0] = new MemberValuePair(value,pos,pos,pcExpr);
+               ann.memberValuePairs = mvps;
+               return ann;
+       }
+
+       public static Annotation createPointcutAnnotation(String pointcutExpression, int pos) {
+               char[][] typeName = new char[][] {org,aspectj,lang,annotation,pointcut};
+               long[] positions = new long[] {pos,pos,pos,pos,pos};
+               TypeReference annType = new QualifiedTypeReference(typeName,positions);
+               NormalAnnotation ann = new NormalAnnotation(annType,pos);
+               Expression pcExpr = new StringLiteral(pointcutExpression.toCharArray(),pos,pos);
+               MemberValuePair[] mvps = new MemberValuePair[1];
+               mvps[0] = new MemberValuePair(value,pos,pos,pcExpr);
+               ann.memberValuePairs = mvps;
+               return ann;
+       }
+}
index 870a5edc0cdf0f087096d833ba6e9455063deed3..4c46411b8198c74de926f05e702321e762ec0878 100644 (file)
@@ -17,20 +17,22 @@ import java.lang.reflect.Modifier;
 
 import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
 import org.aspectj.ajdt.internal.core.builder.EclipseSourceContext;
-import org.aspectj.weaver.AjAttribute;
-import org.aspectj.weaver.ResolvedPointcutDefinition;
-//import org.aspectj.weaver.ResolvedTypeX;
-//import org.aspectj.weaver.TypeX;
-import org.aspectj.weaver.patterns.Pointcut;
+import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile;
 import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Argument;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.aspectj.org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.aspectj.org.eclipse.jdt.internal.compiler.flow.InitializationFlowContext;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits;
 import org.aspectj.org.eclipse.jdt.internal.compiler.parser.Parser;
-import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
+import org.aspectj.weaver.AjAttribute;
+import org.aspectj.weaver.ResolvedPointcutDefinition;
+import org.aspectj.weaver.patterns.Pointcut;
 
 /**
  * pointcut [declaredModifiers] [declaredName]([arguments]): [pointcutDesignator];
@@ -46,6 +48,8 @@ public class PointcutDeclaration extends AjMethodDeclaration {
        public PointcutDesignator pointcutDesignator;
        private int declaredModifiers;
        private String declaredName;
+       private boolean generateSyntheticPointcutMethod = false;
+       //private boolean mangleSelector = true;
     
     private ResolvedPointcutDefinition resolvedPointcutDeclaration = null;
 
@@ -73,8 +77,14 @@ public class PointcutDeclaration extends AjMethodDeclaration {
                if (arguments == null) arguments = new Argument[0];
                this.declaredModifiers = modifiers;
                this.declaredName = new String(selector);
-               selector = CharOperation.concat(mangledPrefix, '$', selector, '$',
-                               Integer.toHexString(sourceStart).toCharArray());
+               // amc - if we set mangle selector to false, then the generated bytecode has the 
+               // pointcut method name that the user of an @Pointcut would expect.
+               // But then we will unpack it again in the weaver which may cause redundant
+               // error messages to be issued. This seems the better trade-off...
+               //if (mangleSelector) {  
+                       selector = CharOperation.concat(mangledPrefix, '$', selector, '$',
+                                                                        Integer.toHexString(sourceStart).toCharArray());
+               //}
                                
                if (Modifier.isAbstract(this.declaredModifiers)) {
                        if (!(typeDec instanceof AspectDeclaration)) {
@@ -98,8 +108,39 @@ public class PointcutDeclaration extends AjMethodDeclaration {
                }
        }
     
+       
+       /**
+        * Called from the AtAspectJVisitor to create the @Pointcut annotation
+        * (and corresponding method) for this pointcut
+        *
+        */
+       public void addAtAspectJAnnotations() {
+               Annotation pcutAnnotation = AtAspectJAnnotationFactory.createPointcutAnnotation(getPointcut().toString(),declarationSourceStart);;
+               if (annotations == null) {
+                       annotations = new Annotation[] { pcutAnnotation };
+               } else {
+                       Annotation[] old = annotations;
+                       annotations = new Annotation[old.length +1];
+                       System.arraycopy(old,0,annotations,0,old.length);
+                       annotations[old.length] = pcutAnnotation;
+               }               
+               generateSyntheticPointcutMethod = true;
+       }
+       
+       // coming from an @Pointcut declaration
+       public void setGenerateSyntheticPointcutMethod() {
+               generateSyntheticPointcutMethod = true;
+               //mangleSelector = false;
+       }
+       
     public void resolve(ClassScope upperScope) {
-        // this method should do nothing, use the entry point below...
+               // we attempted to resolve annotations below, but that was too early, so we do it again
+               // now at the 'right' time.
+               if (binding!= null) {
+                       binding.tagBits -= TagBits.AnnotationResolved;
+                       resolveAnnotations(scope, this.annotations, this.binding);
+               }
+        // for the rest of the resolution process, this method should do nothing, use the entry point below...
     }
 
     public void resolvePointcut(ClassScope upperScope) {
@@ -152,6 +193,7 @@ public class PointcutDeclaration extends AjMethodDeclaration {
        public AjAttribute makeAttribute() {
                return new AjAttribute.PointcutDeclarationAttribute(makeResolvedPointcutDefinition());
        }
+
        
        /**
         * A pointcut declaration exists in a classfile only as an attibute on the
@@ -161,9 +203,16 @@ public class PointcutDeclaration extends AjMethodDeclaration {
        public void generateCode(ClassScope classScope, ClassFile classFile) {
                if (ignoreFurtherInvestigation) return ;
                classFile.extraAttributes.add(new EclipseAttributeAdapter(makeAttribute()));
+               if (generateSyntheticPointcutMethod) {
+                       super.generateCode(classScope,classFile);
+               }
                return;
        }
        
+       protected int generateInfoAttributes(ClassFile classFile) {
+               return super.generateInfoAttributes(classFile,true);
+       }
+       
        public StringBuffer printReturnType(int indent, StringBuffer output) {
                return output.append("pointcut");
        }
index 9bede187a4ee620c2857f7bda56f427a0563c42f..9b3b2adfa7e10009f2fd73a3427e16125aeec32d 100644 (file)
 
 package org.aspectj.ajdt.internal.compiler.ast;
 
-import org.aspectj.ajdt.internal.compiler.lookup.EclipseScope;
 import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
-import org.aspectj.weaver.TypeX;
-import org.aspectj.weaver.patterns.FormalBinding;
-import org.aspectj.weaver.patterns.Pointcut;
+import org.aspectj.ajdt.internal.compiler.lookup.EclipseScope;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ASTNode;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Argument;
-import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ASTNode;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 import org.aspectj.org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.aspectj.weaver.TypeX;
+import org.aspectj.weaver.patterns.FormalBinding;
+import org.aspectj.weaver.patterns.Pointcut;
 
 public class PointcutDesignator extends ASTNode {
        private Pointcut pointcut;
@@ -46,8 +46,14 @@ public class PointcutDesignator extends ASTNode {
                pointcut = pc;
        }
        
+       // called by AtAspectJVisitor
+       public PointcutDesignator(Pointcut pc) {
+               this.pointcut = pc;
+       }
+       
        public void postParse(TypeDeclaration typeDec, MethodDeclaration enclosingDec) {
-               tokens.postParse(typeDec, enclosingDec);
+               if (tokens != null)
+                       tokens.postParse(typeDec, enclosingDec);
        }
 
 
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/ValidateAtAspectJAnnotationsVisitor.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/ValidateAtAspectJAnnotationsVisitor.java
new file mode 100644 (file)
index 0000000..6da2996
--- /dev/null
@@ -0,0 +1,615 @@
+/* *******************************************************************
+ * Copyright (c) 2005 IBM Corporation Ltd
+ * 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://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Adrian Colyer  initial implementation 
+ * ******************************************************************/
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
+import org.aspectj.ajdt.internal.compiler.lookup.EclipseScope;
+import org.aspectj.ajdt.internal.core.builder.EclipseSourceContext;
+import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.StringLiteral;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.aspectj.weaver.AdviceKind;
+import org.aspectj.weaver.AjAttribute;
+import org.aspectj.weaver.ISourceContext;
+import org.aspectj.weaver.ResolvedPointcutDefinition;
+import org.aspectj.weaver.TypeX;
+import org.aspectj.weaver.patterns.FormalBinding;
+import org.aspectj.weaver.patterns.ParserException;
+import org.aspectj.weaver.patterns.PatternParser;
+import org.aspectj.weaver.patterns.Pointcut;
+
+public class ValidateAtAspectJAnnotationsVisitor extends ASTVisitor {
+
+       private static final char[] beforeAdviceSig = "Lorg/aspectj/lang/annotation/Before;".toCharArray();
+       private static final char[] afterAdviceSig = "Lorg/aspectj/lang/annotation/After;".toCharArray();
+       private static final char[] afterReturningAdviceSig = "Lorg/aspectj/lang/annotation/AfterReturning;".toCharArray();
+       private static final char[] afterThrowingAdviceSig = "Lorg/aspectj/lang/annotation/AfterThrowing;".toCharArray();
+       private static final char[] aroundAdviceSig = "Lorg/aspectj/lang/annotation/Around;".toCharArray();
+       private static final char[] pointcutSig = "Lorg/aspectj/lang/annotation/Pointcut;".toCharArray();
+       private static final char[] aspectSig = "Lorg/aspectj/lang/annotation/Aspect;".toCharArray();
+       private static final char[] adviceNameSig = "Lorg/aspectj/lang/annotation/AdviceName;".toCharArray();
+       private static final char[] orgAspectJLangAnnotation = "org/aspectj/lang/annotation/".toCharArray();
+       private static final char[] voidType = "void".toCharArray();
+       private static final char[] joinPoint = "Lorg/aspectj/lang/JoinPoint;".toCharArray();
+       private static final char[] joinPointStaticPart = "Lorg/aspectj/lang/JoinPoint$StaticPart;".toCharArray();
+       private static final char[] joinPointEnclosingStaticPart = "Lorg/aspectj/lang/JoinPoint$EnclosingStaticPart;".toCharArray();
+       private static final char[] proceedingJoinPoint = "Lorg/aspectj/lang/ProceedingJoinPoint;".toCharArray();
+       private static final char[][] adviceSigs = new char[][] {beforeAdviceSig,afterAdviceSig,afterReturningAdviceSig,afterThrowingAdviceSig,aroundAdviceSig};
+       
+       
+       private CompilationUnitDeclaration unit;
+       private Stack typeStack = new Stack();
+       
+       public ValidateAtAspectJAnnotationsVisitor(CompilationUnitDeclaration unit) {
+               this.unit = unit;
+       }
+       
+       public boolean visit(TypeDeclaration localTypeDeclaration, BlockScope scope) {
+               typeStack.push(localTypeDeclaration);
+               checkTypeDeclaration(localTypeDeclaration);
+               return true;
+       }
+       
+       public void endVisit(TypeDeclaration localTypeDeclaration,BlockScope scope) {
+               typeStack.pop();
+       }
+       
+       public boolean visit(TypeDeclaration memberTypeDeclaration,ClassScope scope) {
+               typeStack.push(memberTypeDeclaration);
+               checkTypeDeclaration(memberTypeDeclaration);
+               return true;
+       }
+       
+       public void endVisit(TypeDeclaration memberTypeDeclaration,ClassScope scope) {
+               typeStack.pop();
+       }
+       
+       public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
+               typeStack.push(typeDeclaration);
+               checkTypeDeclaration(typeDeclaration);
+               return true;
+       }
+       
+       public void endVisit(TypeDeclaration typeDeclaration,CompilationUnitScope scope) {
+               typeStack.pop();
+       }
+       
+       private void checkTypeDeclaration(TypeDeclaration typeDecl) {
+               if (!(typeDecl instanceof AspectDeclaration)) {
+                       if (insideAspect()) {
+                               validateAspectDeclaration(typeDecl);
+                       } else {
+                               // check that class doesn't extend aspect
+                               TypeReference parentRef = typeDecl.superclass;
+                               if (parentRef != null) {
+                                       TypeBinding parentBinding = parentRef.resolvedType;
+                                       if (parentBinding instanceof SourceTypeBinding) {
+                                               SourceTypeBinding parentSTB = (SourceTypeBinding) parentBinding;
+                                               if (parentSTB.scope != null) {
+                                                       TypeDeclaration parentDecl = parentSTB.scope.referenceContext;
+                                                       if (isAspect(parentDecl)) {
+                                                               typeDecl.scope.problemReporter().signalError(typeDecl.sourceStart,typeDecl.sourceEnd,"a class cannot extend an aspect");
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               } else {
+                       // check that aspect doesn't have @Aspect annotation
+                       boolean foundAspectAnnotation = false;
+                       for (int i = 0; i < typeDecl.annotations.length; i++) {
+                               if (typeDecl.annotations[i].resolvedType == null) continue;
+                               char[] sig = typeDecl.annotations[i].resolvedType.signature();
+                               if (CharOperation.equals(aspectSig,sig)) {
+                                       if (!foundAspectAnnotation) {
+                                               foundAspectAnnotation = true; // this is the one we added in the first visitor pass
+                                       } else {
+                                               //a second @Aspect annotation, user must have declared one...
+                                               typeDecl.scope.problemReporter().signalError(
+                                                               typeDecl.sourceStart,
+                                                               typeDecl.sourceEnd,
+                                                               "aspects cannot have @Aspect annotation"
+                                                               );
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
+               if (!methodDeclaration.getClass().equals(AjMethodDeclaration.class)) {
+                       // simply test for innapropriate use of annotations on code-style members
+                       if (!hasAspectJAnnotation(methodDeclaration)) return false;
+                       int numPointcutAnnotations = 0;
+                       int numAdviceAnnotations = 0;
+                       int numAdviceNameAnnotations = 0;
+                       for (int i=0; i < methodDeclaration.annotations.length; i++) {
+                               if (isAspectJAnnotation(methodDeclaration.annotations[i])) {
+                                       if (CharOperation.equals(adviceNameSig,methodDeclaration.annotations[i].resolvedType.signature())) {
+                                               numAdviceNameAnnotations++;
+                                       } else if (CharOperation.equals(pointcutSig,methodDeclaration.annotations[i].resolvedType.signature())) {
+                                               numPointcutAnnotations++;
+                                       } else {
+                                               for (int j = 0; j < adviceSigs.length; j++) { 
+                                                       if (CharOperation.equals(adviceSigs[j],methodDeclaration.annotations[i].resolvedType.signature())) {
+                                                               numAdviceAnnotations++;                                                         
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       if (methodDeclaration instanceof PointcutDeclaration) {
+                               if (numPointcutAnnotations > 1 || numAdviceAnnotations > 0 || numAdviceNameAnnotations > 0) {
+                                       methodDeclaration.scope.problemReporter().signalError(
+                                                       methodDeclaration.sourceStart,
+                                                       methodDeclaration.sourceEnd,
+                                                       "@AspectJ annotations cannot be declared on this aspect member");
+                               }
+                       } else if (methodDeclaration instanceof AdviceDeclaration) {
+                               if (numPointcutAnnotations > 0 || numAdviceAnnotations > 1) {
+                                       methodDeclaration.scope.problemReporter().signalError(
+                                                                               methodDeclaration.sourceStart,
+                                                                               methodDeclaration.sourceEnd,
+                                                                               "Only @AdviceName AspectJ annotation allowed on advice");
+                               }                               
+                       } else {
+                               if (numPointcutAnnotations > 0 || numAdviceAnnotations > 0 || numAdviceNameAnnotations > 0) {
+                                       methodDeclaration.scope.problemReporter().signalError(
+                                                       methodDeclaration.sourceStart,
+                                                       methodDeclaration.sourceEnd,
+                                                       "@AspectJ annotations cannot be declared on this aspect member");                                       
+                               }
+                       }
+                       return false;
+               }
+               if (isAnnotationStyleAdvice(methodDeclaration.annotations)) {
+                       validateAdvice(methodDeclaration);
+               } else if (isAnnotationStylePointcut(methodDeclaration.annotations)) {
+                       convertToPointcutDeclaration(methodDeclaration,scope);
+               }
+               return false;
+       }
+       
+       
+
+       private boolean isAnnotationStyleAdvice(Annotation[] annotations) {
+               if (annotations == null) return false;
+               for (int i = 0; i < annotations.length; i++) {
+                       if (annotations[i].resolvedType == null) continue;
+                       char[] sig = annotations[i].resolvedType.signature();
+                       if (CharOperation.equals(beforeAdviceSig,sig) ||
+                               CharOperation.equals(afterAdviceSig,sig) ||
+                               CharOperation.equals(afterReturningAdviceSig,sig) ||
+                               CharOperation.equals(aroundAdviceSig,sig) ||
+                               CharOperation.equals(afterThrowingAdviceSig,sig)) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+       
+       private boolean isAnnotationStylePointcut(Annotation[] annotations) {
+               if (annotations == null) return false;
+               for (int i = 0; i < annotations.length; i++) {
+                       if (annotations[i].resolvedType == null) continue;
+                       char[] sig = annotations[i].resolvedType.signature();
+                       if (CharOperation.equals(pointcutSig,sig)) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       private boolean hasAspectJAnnotation(MethodDeclaration methodDecl) {
+               if (methodDecl.annotations == null) return false;
+               for (int i=0; i < methodDecl.annotations.length; i++) {
+                       if (isAspectJAnnotation(methodDecl.annotations[i])) return true;
+               }
+               return false;
+       }
+       
+       private boolean isAspectJAnnotation(Annotation ann) {
+               if (ann.resolvedType == null) return false;
+               char[] sig = ann.resolvedType.signature();
+               return CharOperation.contains(orgAspectJLangAnnotation, sig);
+       }
+       
+       private boolean insideAspect() {
+               if (typeStack.empty()) return false;
+               TypeDeclaration typeDecl = (TypeDeclaration) typeStack.peek();
+               return isAspect(typeDecl);
+       }
+       
+       private boolean isAspect(TypeDeclaration typeDecl) {
+               if (typeDecl instanceof AspectDeclaration) return true;
+               return hasAspectAnnotation(typeDecl);                   
+       }
+
+       private boolean hasAspectAnnotation(TypeDeclaration typeDecl) {
+               if (typeDecl.annotations == null) return false;
+               for (int i = 0; i < typeDecl.annotations.length; i++) {
+                       if (typeDecl.annotations[i].resolvedType == null) continue;
+                       char[] sig = typeDecl.annotations[i].resolvedType.signature();
+                       if (CharOperation.equals(aspectSig,sig)) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+       
+       /**
+        * nested aspect must be static
+        * cannot extend a concrete aspect
+        * pointcut in perclause must be good.
+        */
+       private void validateAspectDeclaration(TypeDeclaration typeDecl) {
+               if (typeStack.size() > 1) {
+                       // it's a nested aspect
+                       if (!Modifier.isStatic(typeDecl.modifiers)) {
+                               typeDecl.scope.problemReporter().signalError(typeDecl.sourceStart, typeDecl.sourceEnd, "inner aspects must be static");
+                               return;
+                       }
+               }
+               
+               SourceTypeBinding binding = typeDecl.binding;
+               if (binding != null) {
+                       if (binding.isEnum() || binding.isInterface() || binding.isAnnotationType()) {
+                               typeDecl.scope.problemReporter().signalError(typeDecl.sourceStart,typeDecl.sourceEnd,"only classes can have an @Aspect annotation");
+                       }
+               }
+               
+               TypeReference parentRef = typeDecl.superclass;
+               if (parentRef != null) {
+                       TypeBinding parentBinding = parentRef.resolvedType;
+                       if (parentBinding instanceof SourceTypeBinding) {
+                               SourceTypeBinding parentSTB = (SourceTypeBinding) parentBinding;
+                               TypeDeclaration parentDecl = parentSTB.scope.referenceContext;
+                               if (isAspect(parentDecl) && !Modifier.isAbstract(parentDecl.modifiers)) {
+                                       typeDecl.scope.problemReporter().signalError(typeDecl.sourceStart,typeDecl.sourceEnd,"cannot extend a concrete aspect");
+                               }                       
+                       }
+               }
+
+               Annotation aspectAnnotation = null;
+               for (int i = 0; i < typeDecl.annotations.length; i++) {
+                       if (typeDecl.annotations[i].resolvedType == null) continue;
+                       char[] sig = typeDecl.annotations[i].resolvedType.signature();
+                       if (CharOperation.equals(aspectSig,sig)) {
+                               aspectAnnotation = typeDecl.annotations[i];
+                               break;
+                       }
+               }
+
+               int[] pcLoc = new int[2];
+               String perClause = getStringLiteralFor("value", aspectAnnotation, pcLoc);
+               AspectDeclaration aspectDecl = new AspectDeclaration(typeDecl.compilationResult);
+
+               try {
+                       if (perClause != null && !perClause.equals("")) {
+                               ISourceContext context = new EclipseSourceContext(unit.compilationResult,pcLoc[0]);
+                               Pointcut pc = new PatternParser(perClause,context).maybeParsePerClause();
+                           FormalBinding[] bindings = new FormalBinding[0];
+                               if (pc != null) pc.resolve(new EclipseScope(bindings,typeDecl.scope));
+                       }
+               } catch(ParserException pEx) {
+                       typeDecl.scope.problemReporter().parseError(
+                                       pcLoc[0] + pEx.getLocation().getStart(),
+                                       pcLoc[0] + pEx.getLocation().getEnd() ,
+                                       -1, 
+                                       perClause.toCharArray(), 
+                                       perClause, 
+                                       new String[] {pEx.getMessage()});
+               }
+       }
+       
+       /**
+        * 1) Advice must be public
+        * 2) Advice must have a void return type if not around advice
+        * 3) Advice must not have any other @AspectJ annotations
+        */
+       private void validateAdvice(MethodDeclaration methodDeclaration) {
+               
+               if (!insideAspect()) {
+                       methodDeclaration.scope.problemReporter().signalError(methodDeclaration.sourceStart,
+                                         methodDeclaration.sourceEnd, 
+                                         "Advice must be declared inside an aspect type");                     
+               }
+               
+               if (!Modifier.isPublic(methodDeclaration.modifiers)) {
+                       methodDeclaration.scope.problemReporter()
+                               .signalError(methodDeclaration.sourceStart,methodDeclaration.sourceEnd,"advice must be public");
+               }
+                               
+               AdviceKind kind = null;
+               Annotation adviceAnn = null;
+               Annotation duplicateAnn = null;
+               for(int i = 0; i < methodDeclaration.annotations.length; i++) {
+                       Annotation ann = methodDeclaration.annotations[i];
+                       if (isAspectJAnnotation(ann)) {
+                               if (adviceAnn != null) {
+                                       duplicateAnn = ann;
+                                       break;
+                               }
+                               if (CharOperation.equals(afterAdviceSig,ann.resolvedType.signature())) {
+                                       kind = AdviceKind.After;
+                                       adviceAnn = ann;
+                               } else if (CharOperation.equals(afterReturningAdviceSig,ann.resolvedType.signature())) {
+                                       kind = AdviceKind.AfterReturning;
+                                       adviceAnn = ann;
+                               } else if (CharOperation.equals(afterThrowingAdviceSig,ann.resolvedType.signature())) {
+                                       kind = AdviceKind.AfterThrowing;
+                                       adviceAnn = ann;
+                               } else if (CharOperation.equals(beforeAdviceSig,ann.resolvedType.signature())) {
+                                       kind = AdviceKind.Before;
+                                       adviceAnn = ann;
+                               } else if (CharOperation.equals(aroundAdviceSig,ann.resolvedType.signature())) {
+                                       kind = AdviceKind.Around;
+                                       adviceAnn = ann;
+                               } else if (CharOperation.equals(adviceNameSig,ann.resolvedType.signature())) {
+                                       methodDeclaration.scope.problemReporter().signalError(
+                                                       ann.sourceStart,ann.sourceEnd, "AdviceName annotation cannot be used for advice defined using annotation style");
+                               }
+                       }
+               }
+
+               if (duplicateAnn != null) {
+                       methodDeclaration.scope.problemReporter().disallowedTargetForAnnotation(duplicateAnn);
+               }
+
+               if (kind != AdviceKind.Around) {
+                       ensureVoidReturnType(methodDeclaration);
+               }         
+
+               resolveAndSetPointcut(methodDeclaration, adviceAnn);
+               
+       }
+
+       private void resolveAndSetPointcut(MethodDeclaration methodDeclaration, Annotation adviceAnn) {
+               int[] pcLocation = new int[2];
+               String pointcutExpression = getStringLiteralFor("pointcut",adviceAnn,pcLocation);
+               if (pointcutExpression == null) pointcutExpression = getStringLiteralFor("value",adviceAnn,pcLocation);
+               try {
+                       ISourceContext context = new EclipseSourceContext(unit.compilationResult,pcLocation[0]);
+                       Pointcut pc = new PatternParser(pointcutExpression,context).parsePointcut();
+                       FormalBinding[] bindings = buildFormalAdviceBindingsFrom(methodDeclaration);
+                       pc.resolve(new EclipseScope(bindings,methodDeclaration.scope));
+                       // now create a ResolvedPointcutDefinition,make an attribute out of it, and add it to the method
+                       TypeX[] paramTypes = new TypeX[bindings.length];
+                       for (int i = 0; i < paramTypes.length; i++) paramTypes[i] = bindings[i].getType();
+                       ResolvedPointcutDefinition resPcutDef = 
+                               new ResolvedPointcutDefinition(
+                                               EclipseFactory.fromBinding(((TypeDeclaration)typeStack.peek()).binding),
+                                               methodDeclaration.modifiers,
+                                               "anonymous",
+                                               paramTypes,
+                                               pc
+                               );
+                       AjAttribute attr = new AjAttribute.PointcutDeclarationAttribute(resPcutDef);
+                       ((AjMethodDeclaration)methodDeclaration).addAttribute(new EclipseAttributeAdapter(attr));
+               } catch(ParserException pEx) {
+                       methodDeclaration.scope.problemReporter().parseError(
+                                       pcLocation[0] + pEx.getLocation().getStart(),
+                                       pcLocation[0] + pEx.getLocation().getEnd() ,
+                                       -1, 
+                                       pointcutExpression.toCharArray(), 
+                                       pointcutExpression, 
+                                       new String[] {pEx.getMessage()});
+               }
+       }
+
+       private void ensureVoidReturnType(MethodDeclaration methodDeclaration) {
+               boolean returnsVoid = true;
+               if ((methodDeclaration.returnType instanceof SingleTypeReference)) {
+                       SingleTypeReference retType = (SingleTypeReference) methodDeclaration.returnType;
+                       if (!CharOperation.equals(voidType,retType.token)) {
+                               returnsVoid = false;
+                       }
+               } else {
+                       returnsVoid = false;
+               }
+               if (!returnsVoid) {
+                       methodDeclaration.scope.problemReporter().signalError(methodDeclaration.returnType.sourceStart,
+                                                                                                                                                                         methodDeclaration.returnType.sourceEnd, 
+                                                                                                                                                                         "This advice must return void");
+               }
+       }
+       
+       private FormalBinding[] buildFormalAdviceBindingsFrom(MethodDeclaration mDecl) {
+               if (mDecl.arguments == null) return new FormalBinding[0];
+               FormalBinding[] ret = new FormalBinding[mDecl.arguments.length];
+               for (int i = 0; i < mDecl.arguments.length; i++) {
+            Argument arg = mDecl.arguments[i];
+            String name = new String(arg.name);
+                       TypeBinding argTypeBinding = mDecl.binding.parameters[i];
+            TypeX type = EclipseFactory.fromBinding(argTypeBinding);
+                       if  (CharOperation.equals(joinPoint,argTypeBinding.signature()) ||
+                                CharOperation.equals(joinPointStaticPart,argTypeBinding.signature()) ||
+                                CharOperation.equals(joinPointEnclosingStaticPart,argTypeBinding.signature()) ||
+                                CharOperation.equals(proceedingJoinPoint,argTypeBinding.signature())) {
+                               ret[i] = new FormalBinding.ImplicitFormalBinding(type,name,i);
+                       } else {
+                   ret[i] = new FormalBinding(type, name, i, arg.sourceStart, arg.sourceEnd, "unknown");                                               
+                       }
+               }
+               return ret;
+       }
+
+       private String getStringLiteralFor(String memberName, Annotation inAnnotation, int[] location) {
+               if (inAnnotation instanceof SingleMemberAnnotation && memberName.equals("value")) {
+                       SingleMemberAnnotation sma = (SingleMemberAnnotation) inAnnotation;
+                       if (sma.memberValue instanceof StringLiteral) {
+                               StringLiteral sv = (StringLiteral) sma.memberValue;
+                               location[0] = sv.sourceStart;
+                               location[1] = sv.sourceEnd;
+                               return new String(sv.source());
+                       }
+               }
+               if (! (inAnnotation instanceof NormalAnnotation)) return null;
+               NormalAnnotation ann = (NormalAnnotation) inAnnotation;
+               MemberValuePair[] mvps = ann.memberValuePairs;
+               if (mvps == null) return null;
+               for (int i = 0; i < mvps.length; i++) {
+                       if (CharOperation.equals(memberName.toCharArray(),mvps[i].name)) {
+                               if (mvps[i].value instanceof StringLiteral) {
+                                       StringLiteral sv = (StringLiteral) mvps[i].value;
+                                       location[0] = sv.sourceStart;
+                                       location[1] = sv.sourceEnd;
+                                       return new String(sv.source());
+                               }
+                       }
+               }
+               return null;
+       }
+       
+       private void convertToPointcutDeclaration(MethodDeclaration methodDeclaration, ClassScope scope) {
+               TypeDeclaration typeDecl = (TypeDeclaration) typeStack.peek();
+               if (typeDecl.binding != null) {
+                       if (!typeDecl.binding.isClass()) {
+                               methodDeclaration.scope.problemReporter()
+                                       .signalError(methodDeclaration.sourceStart,methodDeclaration.sourceEnd,"pointcuts can only be declared in a class or an aspect");
+                       }
+               }
+               
+               if (methodDeclaration.thrownExceptions != null && methodDeclaration.thrownExceptions.length > 0) {
+                       methodDeclaration.scope.problemReporter()
+                               .signalError(methodDeclaration.sourceStart,methodDeclaration.sourceEnd,"pointcuts cannot throw exceptions!");
+               }
+               
+               PointcutDeclaration pcDecl = new PointcutDeclaration(unit.compilationResult);
+               copyAllFields(methodDeclaration,pcDecl);
+
+               Annotation pcutAnn = null;
+               Annotation duplicateAnn = null;
+               for(int i = 0; i < methodDeclaration.annotations.length; i++) {
+                       Annotation ann = methodDeclaration.annotations[i];
+                       if (isAspectJAnnotation(ann)) {
+                               if (pcutAnn != null) {
+                                       duplicateAnn = ann;
+                                       break;
+                               }
+                               if (CharOperation.equals(pointcutSig,ann.resolvedType.signature())) {
+                                       pcutAnn = ann;
+                               } 
+                       }
+               }
+
+               if (duplicateAnn != null && !CharOperation.equals(pointcutSig,duplicateAnn.resolvedType.signature())) {
+                       // (duplicate annotations of same type are already reported)
+                       methodDeclaration.scope.problemReporter().disallowedTargetForAnnotation(duplicateAnn);
+               }
+
+               boolean returnsVoid = true;
+               if ((methodDeclaration.returnType instanceof SingleTypeReference)) {
+                       SingleTypeReference retType = (SingleTypeReference) methodDeclaration.returnType;
+                       if (!CharOperation.equals(voidType,retType.token)) {
+                               returnsVoid = false;
+                       }
+               } else {
+                       returnsVoid = false;
+               }
+               if (!returnsVoid) {
+                       methodDeclaration.scope.problemReporter().signalError(methodDeclaration.returnType.sourceStart,
+                                                                                                                                                                         methodDeclaration.returnType.sourceEnd, 
+                                                                                                                                                                         "Methods annotated with @Pointcut must return void");
+               }
+               
+               if (methodDeclaration.statements != null && methodDeclaration.statements.length > 0) {
+                       methodDeclaration.scope.problemReporter().signalError(methodDeclaration.returnType.sourceStart,
+                                         methodDeclaration.returnType.sourceEnd, 
+                                         "Pointcuts should have an empty method body");                        
+               }
+               
+               int[] pcLocation = new int[2];
+               String pointcutExpression = getStringLiteralFor("value",pcutAnn,pcLocation);
+               try {
+                       ISourceContext context = new EclipseSourceContext(unit.compilationResult,pcLocation[0]);
+                       Pointcut pc = new PatternParser(pointcutExpression,context).parsePointcut();
+                       pcDecl.pointcutDesignator = new PointcutDesignator(pc);
+                       pcDecl.setGenerateSyntheticPointcutMethod();
+                       TypeDeclaration onType = (TypeDeclaration) typeStack.peek();
+                       pcDecl.postParse(onType);
+                       int argsLength = methodDeclaration.arguments == null ? 0 : methodDeclaration.arguments.length;
+                   FormalBinding[] bindings = new FormalBinding[argsLength];
+               for (int i = 0, len = bindings.length; i < len; i++) {
+                   Argument arg = methodDeclaration.arguments[i];
+                   String name = new String(arg.name);
+                   TypeX type = EclipseFactory.fromBinding(methodDeclaration.binding.parameters[i]);
+                   bindings[i] = new FormalBinding(type, name, i, arg.sourceStart, arg.sourceEnd, "unknown");
+               }
+                       swap(onType,methodDeclaration,pcDecl);
+                       pc.resolve(new EclipseScope(bindings,methodDeclaration.scope));
+               } catch(ParserException pEx) {
+                       methodDeclaration.scope.problemReporter().parseError(
+                                       pcLocation[0] + pEx.getLocation().getStart(),
+                                       pcLocation[0] + pEx.getLocation().getEnd() ,
+                                       -1, 
+                                       pointcutExpression.toCharArray(), 
+                                       pointcutExpression, 
+                                       new String[] {pEx.getMessage()});
+               }
+       }
+       
+       private void copyAllFields(MethodDeclaration from, MethodDeclaration to) {
+               to.annotations = from.annotations;
+               to.arguments = from.arguments;
+               to.binding = from.binding;
+               to.bits = from.bits;
+               to.bodyEnd = from.bodyEnd;
+               to.bodyStart = from.bodyStart;
+               to.declarationSourceEnd = from.declarationSourceEnd;
+               to.declarationSourceStart = from.declarationSourceStart;
+               to.errorInSignature = from.errorInSignature;
+               to.explicitDeclarations = from.explicitDeclarations;
+               to.ignoreFurtherInvestigation = from.ignoreFurtherInvestigation;
+               to.javadoc = from.javadoc;
+               to.modifiers = from.modifiers;
+               to.modifiersSourceStart = from.modifiersSourceStart;
+               to.needFreeReturn = from.needFreeReturn;
+               to.returnType = from.returnType;
+               to.scope = from.scope;
+               to.selector = from.selector;
+               to.sourceEnd = from.sourceEnd;
+               to.sourceStart = from.sourceStart;
+               to.statements = from.statements;
+               to.thrownExceptions = from.thrownExceptions;
+               to.typeParameters = from.typeParameters;
+       }
+       
+       private void swap(TypeDeclaration inType, MethodDeclaration thisDeclaration, MethodDeclaration forThatDeclaration) {
+               for (int i = 0; i < inType.methods.length; i++) {
+                       if (inType.methods[i]  == thisDeclaration) {
+                               inType.methods[i] = forThatDeclaration;
+                               break;
+                       }
+               }
+       }
+}
index 2365ef4524c2c339d2409edd002a3c592490eb4f..197fa33766f1f492b0d9384e75b6db5b8c3b86f2 100644 (file)
@@ -29,6 +29,8 @@ import org.aspectj.bridge.WeaveMessage;
 import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 import org.aspectj.org.eclipse.jdt.internal.compiler.env.AccessRestriction;
 import org.aspectj.org.eclipse.jdt.internal.compiler.env.IBinaryType;
@@ -307,7 +309,7 @@ public class AjLookupEnvironment extends LookupEnvironment {
                // test classes don't extend aspects
                if (sourceType.superclass != null) {
                        ResolvedTypeX parent = factory.fromEclipse(sourceType.superclass);
-                       if (parent.isAspect() && !(dec instanceof AspectDeclaration)) {
+                       if (parent.isAspect() && !isAspect(dec)) {
                                factory.showMessage(IMessage.ERROR, "class \'" + new String(sourceType.sourceName) + 
                                                "\' can not extend aspect \'" + parent.getName() + "\'",
                                                factory.fromEclipse(sourceType).getSourceLocation(), null);
@@ -319,6 +321,31 @@ public class AjLookupEnvironment extends LookupEnvironment {
                        buildInterTypeAndPerClause(((SourceTypeBinding) memberTypes[i]).scope);
                }
        }
+       
+       private boolean isAspect(TypeDeclaration decl) {
+               if ((decl instanceof AspectDeclaration)) {
+                       return true;
+               } else if (decl.annotations == null) {
+                       return false;
+               } else {
+                       for (int i = 0; i < decl.annotations.length; i++) {
+                               Annotation ann = decl.annotations[i];
+                               if (ann.type instanceof SingleTypeReference) {
+                                       if (CharOperation.equals("Aspect".toCharArray(),((SingleTypeReference)ann.type).token)) return true;
+                               } else if (ann.type instanceof QualifiedTypeReference) {
+                                       QualifiedTypeReference qtr = (QualifiedTypeReference) ann.type;
+                                       if (qtr.tokens.length != 5) return false;
+                                       if (!CharOperation.equals("org".toCharArray(),qtr.tokens[0])) return false;
+                                       if (!CharOperation.equals("aspectj".toCharArray(),qtr.tokens[1])) return false;
+                                       if (!CharOperation.equals("lang".toCharArray(),qtr.tokens[2])) return false;
+                                       if (!CharOperation.equals("annotation".toCharArray(),qtr.tokens[3])) return false;
+                                       if (!CharOperation.equals("Aspect".toCharArray(),qtr.tokens[4])) return false;
+                                       return true;
+                               }
+                       }
+               }
+               return false;           
+       }
                
        private void weaveInterTypeDeclarations(CompilationUnitScope unit, Collection typeMungers, 
                                                        Collection declareParents, Collection declareAnnotationOnTypes) {
index 90ed87495e069311379196fe9322422301d01344..826e585f2155959776bd67c21f65db1e59a14d3d 100644 (file)
@@ -34,6 +34,7 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.*;
  * @author Jim Hugunin
  */
 public class EclipseSourceType extends ResolvedTypeX.ConcreteName {
+       private static final char[] pointcutSig = "Lorg/aspectj/lang/annotation/Pointcut;".toCharArray();
        protected ResolvedPointcutDefinition[] declaredPointcuts = null;
        protected ResolvedMember[] declaredMethods = null;
        protected ResolvedMember[] declaredFields = null;
@@ -83,6 +84,19 @@ public class EclipseSourceType extends ResolvedTypeX.ConcreteName {
         return false;
     }
 
+       private boolean isAnnotationStylePointcut(Annotation[] annotations) {
+               if (annotations == null) return false;
+               for (int i = 0; i < annotations.length; i++) {
+                       if (annotations[i].resolvedType == null) continue; // XXX happens if we do this very early from buildInterTypeandPerClause
+                                                                                            // may prevent us from resolving references made in @Pointcuts to
+                                                                                            // an @Pointcut in a code-style aspect
+                       char[] sig = annotations[i].resolvedType.signature();
+                       if (CharOperation.equals(pointcutSig,sig)) {
+                               return true;
+                       }
+               }
+               return false;
+       }
        public WeaverStateInfo getWeaverState() {
                return null;
        }
@@ -113,7 +127,7 @@ public class EclipseSourceType extends ResolvedTypeX.ConcreteName {
                                        PointcutDeclaration d = (PointcutDeclaration)amd;
                                        ResolvedPointcutDefinition df = d.makeResolvedPointcutDefinition();
                                        declaredPointcuts.add(df);
-                               } else if (amd instanceof InterTypeDeclaration) {
+                               } else if (amd instanceof InterTypeDeclaration) {                               
                                        // these are handled in a separate pass
                                        continue;
                                } else if (amd instanceof DeclareDeclaration && 
@@ -123,6 +137,10 @@ public class EclipseSourceType extends ResolvedTypeX.ConcreteName {
                                } else if (amd instanceof AdviceDeclaration) {
                                        // these are ignored during compilation and only used during weaving
                                        continue;
+                               }  else if ((amd.annotations != null) && isAnnotationStylePointcut(amd.annotations)) {
+                                       // consider pointcuts defined via annotations
+                                       ResolvedPointcutDefinition df = makeResolvedPointcutDefinition(amd);
+                                       declaredPointcuts.add(df);
                                } else {
                                        if (amd.binding == null || !amd.binding.isValidBinding()) continue;
                                        declaredMethods.add(EclipseFactory.makeResolvedMember(amd.binding));
@@ -144,6 +162,18 @@ public class EclipseSourceType extends ResolvedTypeX.ConcreteName {
                        declaredFields.toArray(new ResolvedMember[declaredFields.size()]);
        }
 
+       private ResolvedPointcutDefinition makeResolvedPointcutDefinition(AbstractMethodDeclaration md) {
+               ResolvedPointcutDefinition resolvedPointcutDeclaration = new ResolvedPointcutDefinition(
+            EclipseFactory.fromBinding(md.binding.declaringClass), 
+            md.modifiers, 
+            new String(md.selector),
+                       EclipseFactory.fromBindings(md.binding.parameters),
+                       null); //??? might want to use null 
+                       
+               resolvedPointcutDeclaration.setPosition(md.sourceStart, md.sourceEnd);
+               resolvedPointcutDeclaration.setSourceContext(new EclipseSourceContext(md.compilationResult));
+               return resolvedPointcutDeclaration;
+       }
 
        public ResolvedMember[] getDeclaredFields() {
                if (declaredFields == null) fillDeclaredMembers();
index 12ca5f606aee4ef4251acdb52d823f63f6e08b87..cf5bcb5fb0745e93c81f5e0ddb0334e9773df1cb 100644 (file)
@@ -508,6 +508,13 @@ public class AjBuildConfig {
                options.generateModel = structureModelMode;
        }
        
+       public boolean isNoAtAspectJAnnotationProcessing() {
+               return options.noAtAspectJProcessing;
+       }
+       
+       public void setNoAtAspectJAnnotationProcessing(boolean noProcess) {
+               options.noAtAspectJProcessing = noProcess;
+       }
        
        public void setShowWeavingInformation(boolean b) {
                options.showWeavingInformation = true;
index c4223b8b40fa01e6561765f2af22b5a7db8924cb..1f550dd95b687594107420684cdd52e3316c591d 100644 (file)
@@ -974,7 +974,8 @@ public class AjBuildManager implements IOutputClassFileNameProvider,IBinarySourc
                                                state.binarySourceFiles,
                                                state.resultsFromFile.values(),
                                                buildConfig.isNoWeave(),
-                                               buildConfig.getProceedOnError());
+                                               buildConfig.getProceedOnError(),
+                                               buildConfig.isNoAtAspectJAnnotationProcessing());
        }
 
        /* (non-Javadoc)
index 8553ed9dfff152524807b5085ac9c79ece0a0197..0eeb1797f02f80b06ccc5f16e43de9dd608c50f9 100644 (file)
@@ -41,8 +41,9 @@ public class AjCompilerOptions extends CompilerOptions {
        public static final String OPTION_XNoInline               = "org.aspectj.ajdt.core.compiler.weaver.XNoInline";
        public static final String OPTION_XReweavable             = "org.aspectj.ajdt.core.compiler.weaver.XReweavable";
        public static final String OPTION_XReweavableCompress     = "org.aspectj.ajdt.core.compiler.weaver.XReweavableCompress";
-
-       // these next three not exposed by IDEs
+       
+       // these next four not exposed by IDEs
+       public static final String OPTION_XDevNoAtAspectJProcessing = "org.aspectj.ajdt.core.compiler.ast.NoAtAspectJProcessing";
     public static final String OPTION_GenerateModel           = "org.aspectj.ajdt.core.compiler.model.GenerateModel";
     public static final String OPTION_GenerateJavaDocsInModel = "org.aspectj.ajdt.core.compiler.model.GenerateJavaDocsInModel";
     public static final String OPTION_Emacssym                = "org.aspectj.ajdt.core.compiler.model.Emacssym";
@@ -69,10 +70,12 @@ public class AjCompilerOptions extends CompilerOptions {
        // If true - autoboxing behaves differently ...
        public boolean behaveInJava5Way = false;
        
-       // these next three not exposed by IDEs
+       // these next four not exposed by IDEs
        public boolean generateModel = false;
        public boolean generateJavaDocsInModel = false;
        public boolean generateEmacsSymFiles = false;
+       public boolean noAtAspectJProcessing = false;
+       
        public boolean proceedOnError = false;
 
        
@@ -119,6 +122,7 @@ public class AjCompilerOptions extends CompilerOptions {
                map.put(OPTION_GenerateModel,this.generateModel ? ENABLED : DISABLED);
                map.put(OPTION_GenerateJavaDocsInModel,this.generateJavaDocsInModel ? ENABLED : DISABLED);
                map.put(OPTION_Emacssym,this.generateEmacsSymFiles ? ENABLED : DISABLED);
+               map.put(OPTION_XDevNoAtAspectJProcessing,this.noAtAspectJProcessing ? ENABLED : DISABLED);
                
                return map;
        }
@@ -203,6 +207,13 @@ public class AjCompilerOptions extends CompilerOptions {
                                this.generateEmacsSymFiles = false;
                        }
                }
+               if ((optionValue = optionsMap.get(OPTION_XDevNoAtAspectJProcessing)) != null) {
+                       if (ENABLED.equals(optionValue)) {
+                               this.noAtAspectJProcessing = true;
+                       } else if (DISABLED.equals(optionValue)) {
+                               this.noAtAspectJProcessing = false;
+                       }
+               }
                
        }
        
@@ -235,7 +246,8 @@ public class AjCompilerOptions extends CompilerOptions {
 
                buf.append("\n\t- generate AJDE model: ").append(this.generateModel ? ENABLED : DISABLED); //$NON-NLS-1$                
                buf.append("\n\t- generate Javadocs in AJDE model: ").append(this.generateJavaDocsInModel ? ENABLED : DISABLED); //$NON-NLS-1$          
-               buf.append("\n\t- generate Emacs symbol files: ").append(this.generateEmacsSymFiles ? ENABLED : DISABLED); //$NON-NLS-1$                
+               buf.append("\n\t- generate Emacs symbol files: ").append(this.generateEmacsSymFiles ? ENABLED : DISABLED); //$NON-NLS-1$
+               buf.append("\n\t- suppress @AspectJ processing: ").append(this.noAtAspectJProcessing ? ENABLED : DISABLED); //$NON-NLS-1$
                
                buf.append("\n\t- invalid absolute type name (XLint): ").append(getSeverityString(InvalidAbsoluteTypeName)); //$NON-NLS-1$
                buf.append("\n\t- invalid wildcard type name (XLint): ").append(getSeverityString(InvalidWildCardTypeName)); //$NON-NLS-1$
index b91aed439bbd7b57d5a3a06e3e23cc603e359a39..5407758fff76e4a109ec8a3f17555d09f1a47b6b 100644 (file)
@@ -139,7 +139,7 @@ public class AspectJBuilder extends JavaBuilder implements ICompilerAdapterFacto
                return new AjCompilerAdapter(forCompiler,isBatchBuild,myBcelWorld,
                                     myWeaver,eFactory,unwovenResultCollector,ajNotifier,fileNameProvider,bsProvider,
                                         fullBinarySourceEntries,resultSetForFullWeave,
-                                        ajOptions.noWeave,ajOptions.proceedOnError);
+                                        ajOptions.noWeave,ajOptions.proceedOnError,ajOptions.noAtAspectJProcessing);
        }               
        
        /* (non-Javadoc)
index d8219bee137f0f492256f78d1511ed432f4fb58c..0561203734511b9a429d84fdfa79de0ce0e4cf53 100644 (file)
@@ -27,11 +27,21 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
 public class EclipseSourceContext implements ISourceContext {
        
        CompilationResult result;
+       int offset = 0;
 
        public EclipseSourceContext(CompilationResult result) {
                this.result = result;
        }
        
+       public EclipseSourceContext(CompilationResult result, int offset) {
+               this.result = result;
+               this.offset = offset;
+       }
+       
+       public int getOffset() {
+               return offset;
+       }
+       
        private File getSourceFile() {
                return new File(new String(result.fileName));
        }
index a508e512c3cf3c358ed549a51f1c3a4810654524..0c972cf40ed2b605a0126b50289e97a1dde4b06a 100644 (file)
@@ -166,7 +166,7 @@ public abstract class CommandTestCase extends TestCase {
 
        /** get the location of the org.aspectj.lang & runtime classes */
        protected static String getRuntimeClasspath() {
-               return "../runtime/bin" + File.pathSeparator + 
+               return "../runtime/bin" + File.pathSeparator + "../aspectj5rt/bin" + File.pathSeparator + 
                           System.getProperty("aspectjrt.path");
                
        }
index 988209675337c1b5c414a399ab3f8871a3df9aea..c19ecc33d186ce560d9d41a1ecd797414f4015a7 100644 (file)
@@ -45,6 +45,7 @@ public class AjCompilerOptionsTest extends TestCase {
                assertFalse(options.generateModel);
                assertFalse(options.generateJavaDocsInModel);
                assertFalse(options.generateEmacsSymFiles);
+               assertFalse(options.noAtAspectJProcessing);
                
                Map map = options.getMap();
                assertEquals(CompilerOptions.WARNING,map.get(AjCompilerOptions.OPTION_ReportInvalidAbsoluteTypeName));
@@ -68,6 +69,7 @@ public class AjCompilerOptionsTest extends TestCase {
                options.generateModel = true;
                options.generateJavaDocsInModel = true;
                options.generateEmacsSymFiles = true;
+               options.noAtAspectJProcessing = true;
 
                Map map = options.getMap();
                assertEquals(CompilerOptions.ENABLED,map.get(AjCompilerOptions.OPTION_NoWeave));
@@ -79,6 +81,7 @@ public class AjCompilerOptionsTest extends TestCase {
                assertEquals(CompilerOptions.ENABLED,map.get(AjCompilerOptions.OPTION_GenerateModel));
                assertEquals(CompilerOptions.ENABLED,map.get(AjCompilerOptions.OPTION_GenerateJavaDocsInModel));
                assertEquals(CompilerOptions.ENABLED,map.get(AjCompilerOptions.OPTION_Emacssym));
+               assertEquals(CompilerOptions.ENABLED,map.get(AjCompilerOptions.OPTION_XDevNoAtAspectJProcessing));
        }
 
        
@@ -103,6 +106,7 @@ public class AjCompilerOptionsTest extends TestCase {
                map.put(AjCompilerOptions.OPTION_GenerateModel,CompilerOptions.ENABLED);
                map.put(AjCompilerOptions.OPTION_GenerateJavaDocsInModel,CompilerOptions.ENABLED);
                map.put(AjCompilerOptions.OPTION_Emacssym,CompilerOptions.ENABLED);
+               map.put(AjCompilerOptions.OPTION_XDevNoAtAspectJProcessing,CompilerOptions.ENABLED);
                
                options.set(map);
                
@@ -115,6 +119,7 @@ public class AjCompilerOptionsTest extends TestCase {
                assertTrue(options.generateModel);
                assertTrue(options.generateJavaDocsInModel);
                assertTrue(options.generateEmacsSymFiles);
+               assertTrue(options.noAtAspectJProcessing);
                
                Map newMap = options.getMap();
                
index 16cb3c8bcb7db34f05e80214a50253822188bbf9..d0c91a27b0f113362086e20a0f67b25ca47c86ea 100644 (file)
@@ -18,4 +18,5 @@ import org.aspectj.bridge.ISourceLocation;
 public interface ISourceContext {
        public ISourceLocation makeSourceLocation(IHasPosition position);
        public ISourceLocation makeSourceLocation(int line);
+       public int getOffset();
 }
index f708b6f8f27fac776354fec5b255f8d6226463d8..2eb120ecdc29baab96ad5b9d85fe1a148e129ab7 100644 (file)
@@ -27,7 +27,6 @@ import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
 import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnotations;
 import org.aspectj.apache.bcel.generic.Type;
 import org.aspectj.bridge.IMessageHandler;
-import org.aspectj.bridge.IMessage;
 import org.aspectj.bridge.Message;
 import org.aspectj.lang.JoinPoint;
 import org.aspectj.lang.ProceedingJoinPoint;
@@ -36,6 +35,7 @@ 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;
@@ -142,14 +142,14 @@ public class Aj5Attributes {
      * @param msgHandler
      * @return list of AjAttributes
      */
-    public static List readAj5ClassAttributes(JavaClass javaClass, ResolvedTypeX type, ISourceContext context,IMessageHandler msgHandler) {
+    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();
         for (int i = 0; i < attributes.length; i++) {
             Attribute attribute = attributes[i];
             if (acceptAttribute(attribute)) {
                 RuntimeAnnotations rvs = (RuntimeAnnotations) attribute;
-                handleAspectAnnotation(rvs, struct);
+                if (!isCodeStyleAspect) handleAspectAnnotation(rvs, struct);
                 handlePrecedenceAnnotation(rvs, struct);
             }
         }
@@ -161,6 +161,7 @@ public class Aj5Attributes {
         //FIXME alex can that be too slow ?
         for (int m = 0; m < javaClass.getMethods().length; m++) {
             Method method = javaClass.getMethods()[m];
+                       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();
@@ -187,19 +188,21 @@ public class Aj5Attributes {
      * @param msgHandler
      * @return list of AjAttributes
      */
-    public static List readAj5MethodAttributes(Method method, ResolvedTypeX type, ISourceContext context,IMessageHandler msgHandler) {
-        AjAttributeMethodStruct struct = new AjAttributeMethodStruct(method, type, context, msgHandler);
+    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();
 
         for (int i = 0; i < attributes.length; i++) {
             Attribute attribute = attributes[i];
             if (acceptAttribute(attribute)) {
                 RuntimeAnnotations rvs = (RuntimeAnnotations) attribute;
-                handleBeforeAnnotation(rvs, struct);
-                handleAfterAnnotation(rvs, struct);
-                handleAfterReturningAnnotation(rvs, struct);
-                handleAfterThrowingAnnotation(rvs, struct);
-                handleAroundAnnotation(rvs, struct);
+                handleBeforeAnnotation(rvs, struct, preResolvedPointcut);
+                handleAfterAnnotation(rvs, struct, preResolvedPointcut);
+                handleAfterReturningAnnotation(rvs, struct, preResolvedPointcut);
+                handleAfterThrowingAnnotation(rvs, struct, preResolvedPointcut);
+                handleAroundAnnotation(rvs, struct, preResolvedPointcut);
             }
         }
         return struct.ajAttributes;
@@ -215,6 +218,7 @@ public class Aj5Attributes {
      * @return list of AjAttributes, always empty for now
      */
     public static List readAj5FieldAttributes(Field field, ResolvedTypeX type, ISourceContext context,IMessageHandler msgHandler) {
+               if (field.getName().startsWith(NameMangler.PREFIX)) return Collections.EMPTY_LIST;  // already dealt with by ajc...
         return EMPTY_LIST;
     }
 
@@ -271,7 +275,7 @@ public class Aj5Attributes {
         } 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())) {
+        } else if (perClause.equalsIgnoreCase(PerClause.SINGLETON.getName() + "()")) {
             return new PerSingleton();
         }
         // could not parse the @AJ perclause
@@ -310,7 +314,7 @@ public class Aj5Attributes {
      * @param runtimeAnnotations
      * @param struct
      */
-    private static void handleBeforeAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct) {
+    private static void handleBeforeAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) {
         Annotation before = getAnnotation(runtimeAnnotations, "org.aspectj.lang.annotation.Before");
         if (before != null) {
             ElementNameValuePair beforeAdvice = getAnnotationElement(before, "value");
@@ -325,7 +329,12 @@ public class Aj5Attributes {
                 // joinpoint, staticJoinpoint binding
                 int extraArgument = extractExtraArgument(struct.method);
 
-                Pointcut pc = Pointcut.fromString(beforeAdvice.getValue().stringifyValue()).resolve(binding);
+                               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(
@@ -347,7 +356,7 @@ public class Aj5Attributes {
      * @param runtimeAnnotations
      * @param struct
      */
-    private static void handleAfterAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct) {
+    private static void handleAfterAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) {
         Annotation after = getAnnotation(runtimeAnnotations, "org.aspectj.lang.annotation.After");
         if (after != null) {
             ElementNameValuePair afterAdvice = getAnnotationElement(after, "value");
@@ -362,7 +371,12 @@ public class Aj5Attributes {
                 // joinpoint, staticJoinpoint binding
                 int extraArgument = extractExtraArgument(struct.method);
 
-                Pointcut pc = Pointcut.fromString(afterAdvice.getValue().stringifyValue()).resolve(binding);
+                               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(
@@ -384,7 +398,7 @@ public class Aj5Attributes {
      * @param runtimeAnnotations
      * @param struct
      */
-    private static void handleAfterReturningAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct) {
+    private static void handleAfterReturningAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) {
         Annotation after = getAnnotation(runtimeAnnotations, "org.aspectj.lang.annotation.AfterReturning");
         if (after != null) {
             ElementNameValuePair annValue = getAnnotationElement(after, "value");
@@ -427,7 +441,12 @@ public class Aj5Attributes {
                 extraArgument |= Advice.ExtraArgument;
             }
 
-            Pointcut pc = Pointcut.fromString(pointcut).resolve(binding);
+                       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(
@@ -448,7 +467,7 @@ public class Aj5Attributes {
      * @param runtimeAnnotations
      * @param struct
      */
-    private static void handleAfterThrowingAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct) {
+    private static void handleAfterThrowingAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) {
         Annotation after = getAnnotation(runtimeAnnotations, "org.aspectj.lang.annotation.AfterThrowing");
         if (after != null) {
             ElementNameValuePair annValue = getAnnotationElement(after, "value");
@@ -491,7 +510,12 @@ public class Aj5Attributes {
                 extraArgument |= Advice.ExtraArgument;
             }
 
-            Pointcut pc = Pointcut.fromString(pointcut).resolve(binding);
+                       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(
@@ -512,7 +536,7 @@ public class Aj5Attributes {
      * @param runtimeAnnotations
      * @param struct
      */
-    private static void handleAroundAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct) {
+    private static void handleAroundAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) {
         Annotation around = getAnnotation(runtimeAnnotations, "org.aspectj.lang.annotation.Around");
         if (around != null) {
             ElementNameValuePair aroundAdvice = getAnnotationElement(around, "value");
@@ -527,7 +551,12 @@ public class Aj5Attributes {
                 // joinpoint, staticJoinpoint binding
                 int extraArgument = extractExtraArgument(struct.method);
 
-                Pointcut pc = Pointcut.fromString(aroundAdvice.getValue().stringifyValue()).resolve(binding);
+                               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(
index 7de8b373558f66a53d81933f04b836782dd995ab..a8c62999298b1164a04b93f4a0e5b07494f973aa 100644 (file)
@@ -29,6 +29,7 @@ import org.aspectj.weaver.AnnotationX;
 import org.aspectj.weaver.BCException;
 import org.aspectj.weaver.ISourceContext;
 import org.aspectj.weaver.ResolvedMember;
+import org.aspectj.weaver.ResolvedPointcutDefinition;
 import org.aspectj.weaver.ResolvedTypeX;
 import org.aspectj.weaver.ShadowMunger;
 import org.aspectj.weaver.TypeX;
@@ -40,6 +41,7 @@ final class BcelMethod extends ResolvedMember {
        private Method method;
        private boolean isAjSynthetic;
        private ShadowMunger associatedShadowMunger;
+       private ResolvedPointcutDefinition preResolvedPointcut;  // used when ajc has pre-resolved the pointcut of some @Advice
        
     private ResolvedTypeX[] annotationTypes = null;
     private AnnotationX[] annotations = null;
@@ -96,27 +98,33 @@ final class BcelMethod extends ResolvedMember {
        }
 
        private void unpackAjAttributes(World world) {
+               associatedShadowMunger = null;
         List as = BcelAttributes.readAjAttributes(getDeclaringType().getClassName(),method.getAttributes(), getSourceContext(world),world.getMessageHandler());
-        as.addAll(Aj5Attributes.readAj5MethodAttributes(method, world.resolve(getDeclaringType()), getSourceContext(world), world.getMessageHandler()));
+               processAttributes(world, as);
+               as = Aj5Attributes.readAj5MethodAttributes(method, world.resolve(getDeclaringType()), preResolvedPointcut,getSourceContext(world), world.getMessageHandler());
+               processAttributes(world,as);
+       }
 
-               //System.out.println("unpack: " + this + ", " + as);
+       private void processAttributes(World world, List as) {
                for (Iterator iter = as.iterator(); iter.hasNext();) {
                        AjAttribute a = (AjAttribute) iter.next();
                        if (a instanceof AjAttribute.MethodDeclarationLineNumberAttribute) {
                                declarationLineNumber = (AjAttribute.MethodDeclarationLineNumberAttribute)a;
                        } else if (a instanceof AjAttribute.AdviceAttribute) {
                                associatedShadowMunger = ((AjAttribute.AdviceAttribute)a).reify(this, world);
-                               return;
+                               // return;
                        } else if (a instanceof AjAttribute.AjSynthetic) {
                                isAjSynthetic = true;
                        } else if (a instanceof AjAttribute.EffectiveSignatureAttribute) {
                                //System.out.println("found effective: " + this);
                                effectiveSignature = (AjAttribute.EffectiveSignatureAttribute)a;
+                       } else if (a instanceof AjAttribute.PointcutDeclarationAttribute) {
+                               // this is an @AspectJ annotated advice method, with pointcut pre-resolved by ajc
+                               preResolvedPointcut = ((AjAttribute.PointcutDeclarationAttribute)a).reify();
                        } else {
                                throw new BCException("weird method attribute " + a);
                        }
                }
-               associatedShadowMunger = null;
        }
 
        public boolean isAjSynthetic() {
index 46a7fe783c18bd2e2097c3dce139087998d3e836..862b2a65bbe0b61a285e2d02970baafb31988699 100644 (file)
@@ -66,6 +66,7 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName {
 
        private boolean discoveredWhetherAnnotationStyle = false;
     private boolean isAnnotationStyleAspect = false;// set upon construction
+       private boolean isCodeStyleAspect = false; // not redundant with field above!
 
 
        public Collection getTypeMungers() {
@@ -185,7 +186,7 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName {
     public boolean isAnnotationStyleAspect() {
                if (!discoveredWhetherAnnotationStyle) {
                        discoveredWhetherAnnotationStyle = true;
-                       isAnnotationStyleAspect = hasAnnotation(Ajc5MemberMaker.ASPECT);
+                       isAnnotationStyleAspect = !isCodeStyleAspect && hasAnnotation(Ajc5MemberMaker.ASPECT);
                }
         return isAnnotationStyleAspect;
     }
@@ -196,13 +197,32 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName {
                declares = new ArrayList();
                // 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());
-        l.addAll(Aj5Attributes.readAj5ClassAttributes(javaClass, getResolvedTypeX(), getResolvedTypeX().getSourceContext(), getResolvedTypeX().getWorld().getMessageHandler()));
+               processAttributes(l,pointcuts,false);
+               l = Aj5Attributes.readAj5ClassAttributes(javaClass, getResolvedTypeX(), getResolvedTypeX().getSourceContext(), getResolvedTypeX().getWorld().getMessageHandler(),isCodeStyleAspect);
+               processAttributes(l,pointcuts,true);
+               
+               this.pointcuts = (ResolvedPointcutDefinition[]) 
+                       pointcuts.toArray(new ResolvedPointcutDefinition[pointcuts.size()]);
+               // Test isn't quite right, leaving this out for now...
+//             if (isAspect() && wvInfo.getMajorVersion() == WeaverVersionInfo.UNKNOWN.getMajorVersion()) {
+//                     throw new BCException("Unable to continue, this version of AspectJ cannot use aspects as input that were built "+
+//                                     "with an AspectJ earlier than version 1.2.1.  Please rebuild class: "+javaClass.getClassName());
+//             }
+               
+//             this.typeMungers = (BcelTypeMunger[]) 
+//                     typeMungers.toArray(new BcelTypeMunger[typeMungers.size()]);
+//             this.declares = (Declare[])
+//                     declares.toArray(new Declare[declares.size()]); 
+       }
 
-               for (Iterator iter = l.iterator(); iter.hasNext();) {
+
+       private void processAttributes(List attributeList, List pointcuts, boolean fromAnnotations) {
+               for (Iterator iter = attributeList.iterator(); iter.hasNext();) {
                        AjAttribute a = (AjAttribute) iter.next();
                        //System.err.println("unpacking: " + this + " and " + a);
                        if (a instanceof AjAttribute.Aspect) {
                                perClause = ((AjAttribute.Aspect)a).reify(this.getResolvedTypeX());
+                               if (!fromAnnotations) isCodeStyleAspect = true;
                        } else if (a instanceof AjAttribute.PointcutDeclarationAttribute) {
                                pointcuts.add(((AjAttribute.PointcutDeclarationAttribute)a).reify());
                        } else if (a instanceof AjAttribute.WeaverState) {
@@ -223,18 +243,6 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName {
                                throw new BCException("bad attribute " + a);
                        }
                }
-               this.pointcuts = (ResolvedPointcutDefinition[]) 
-                       pointcuts.toArray(new ResolvedPointcutDefinition[pointcuts.size()]);
-               // Test isn't quite right, leaving this out for now...
-//             if (isAspect() && wvInfo.getMajorVersion() == WeaverVersionInfo.UNKNOWN.getMajorVersion()) {
-//                     throw new BCException("Unable to continue, this version of AspectJ cannot use aspects as input that were built "+
-//                                     "with an AspectJ earlier than version 1.2.1.  Please rebuild class: "+javaClass.getClassName());
-//             }
-               
-//             this.typeMungers = (BcelTypeMunger[]) 
-//                     typeMungers.toArray(new BcelTypeMunger[typeMungers.size()]);
-//             this.declares = (Declare[])
-//                     declares.toArray(new Declare[declares.size()]); 
        }
 
        public PerClause getPerClause() {
index 8f7f4065a9887069dfce1863a7a020edc9f663e3..8d313c4e7192586647099a2ce37b7dc949813616 100644 (file)
@@ -51,6 +51,8 @@ public class BcelSourceContext implements ISourceContext {
                
                return new File(fileName);
        }
+       
+       public int getOffset() { return 0; }
                
                /*
                // AMC - a temporary "fudge" to give as much information as possible about the identity of the
index c8c215a3d65722e60d1b326c9347e5f8038010be..dad3bccd4edd7299a112622a9a60a2b07984fbc7 100644 (file)
@@ -80,7 +80,7 @@ public class BasicTokenSource implements ITokenSource {
        
        //////////////////////////////////////////////////////
        // Convenience, maybe just for testing
-       static ITokenSource makeTokenSource(String input) {
+       static ITokenSource makeTokenSource(String input, ISourceContext context) {
                char[] chars = input.toCharArray();
                
                int i = 0;
@@ -136,7 +136,7 @@ public class BasicTokenSource implements ITokenSource {
 
                //System.out.println(tokens);
                
-               return new BasicTokenSource((IToken[])tokens.toArray(new IToken[tokens.size()]), null);
+               return new BasicTokenSource((IToken[])tokens.toArray(new IToken[tokens.size()]), context);
        }
 
        private static String makeString(char ch) {
@@ -153,5 +153,8 @@ public class BasicTokenSource implements ITokenSource {
        public ISourceContext getSourceContext() {
                return sourceContext;
        }
+       public void setSourceContext(ISourceContext context) {
+               this.sourceContext = context;
+       }
 
 }
index c49b529231929acbd1f572c3a8a48e2339c94d40..0730538caa7e9fa9827bf74d613e698433dfb8b7 100644 (file)
@@ -31,11 +31,11 @@ public abstract class PatternNode implements IHasSourceLocation {
        }
 
        public int getStart() {
-               return start;
+               return start + (sourceContext != null ? sourceContext.getOffset() : 0);
        }
 
        public int getEnd() {
-               return end;
+               return end + (sourceContext != null ? sourceContext.getOffset() : 0);
        }
        
        public ISourceContext getSourceContext() {
index ffd4446ca1dad757cc7f4e746a656fa6fd4391c9..ea0be3fe2988498db5960bd53e8d2fa99796b0dd 100644 (file)
@@ -1160,6 +1160,10 @@ public class PatternParser {
 
        
        public PatternParser(String data) {
-               this(BasicTokenSource.makeTokenSource(data));
+               this(BasicTokenSource.makeTokenSource(data,null));
+       }
+       
+       public PatternParser(String data, ISourceContext context) {
+               this(BasicTokenSource.makeTokenSource(data,context));
        }
 }
index 97c06bc554ed28d0da82305fa4bc0d94de75f8c9..cded77643de0e296cf1dffc95f2c2f9ed2972542 100644 (file)
@@ -126,4 +126,9 @@ public class PerCflow extends PerClause {
        public String toString() {
                return "percflow(" + inAspect + " on " + entry + ")";
        }
+       
+       public String toDeclarationString() {
+               if (isBelow) return  "percflowbelow(" + entry + ")";
+               return "percflow(" + entry + ")";
+       }
 }
index e8fbc834a97e89ccfe3b57c72cc5e2bb888d8d37..d410436b046b2da4067a023581928d4f7c447969 100644 (file)
@@ -41,6 +41,8 @@ public abstract class PerClause extends Pointcut {
        
        public abstract PerClause.Kind getKind();
        
+       public abstract String toDeclarationString();
+       
        public static class Kind extends TypeSafeEnum {
         public Kind(String name, int key) { super(name, key); }
         
index d7841008efc20e9326cd931c65f5a6ade6e103e7..87d6b61db997b3030192d06b91d4cd8eb8ce41fd 100644 (file)
@@ -97,6 +97,10 @@ public class PerFromSuper extends PerClause {
        public String toString() {
                return "perFromSuper(" + kind + ", " + inAspect + ")";
        }
+       
+       public String toDeclarationString() {
+               return "";
+       }
 
        public PerClause.Kind getKind() {
                return kind;
index b4283bc0ecbc98cc60c1150cbbee63ae4fe22b0c..79426942e56f3738cb0a6ab8c47d0d0937d39633 100644 (file)
@@ -137,4 +137,8 @@ public class PerObject extends PerClause {
                return "per" + (isThis ? "this" : "target") +
                        "(" + entry + ")";
        }
+       
+       public String toDeclarationString() {
+               return toString();
+       }
 }
index 169e8396290c958b13ab39c1106368ac55f87a24..f98d07980e7ba13f1f9e932e591cbbbe6ee48373 100644 (file)
@@ -126,5 +126,9 @@ public class PerSingleton extends PerClause {
        public String toString() {
                return "persingleton(" + inAspect + ")";
        }
+       
+       public String toDeclarationString() {
+               return "";
+       }
 
 }
index cdc7c3aa9173ecef6c8295e96896e2ca3e44bfa1..151e3f2d708e1450507209918f713938eb044b79 100644 (file)
@@ -169,6 +169,10 @@ public class PerTypeWithin extends PerClause {
                return "pertypewithin("+typePattern+")";
        }
        
+       public String toDeclarationString() {
+               return toString();
+       }
+       
        private FuzzyBoolean isWithinType(ResolvedTypeX type) {
                while (type != null) {
                        if (typePattern.matchesStatically(type)) {
index b4352658678f6cfc274919116fe3d414205027ee..cd646b122ad9616b7c89d1513f375d0609830559 100644 (file)
@@ -51,7 +51,7 @@ public class NamePatternParserTestCase extends TestCase {
        private void checkMatch(String[] patterns) {
                for (int i=0, len=patterns.length; i < len; i++) {
                        String pattern = patterns[i];
-                       ITokenSource tokenSource = BasicTokenSource.makeTokenSource(pattern);
+                       ITokenSource tokenSource = BasicTokenSource.makeTokenSource(pattern,null);
                        NamePattern p1 = new PatternParser(tokenSource).parseNamePattern();
                        NamePattern p2 = new NamePattern(pattern);
                        assertEquals("pattern: " + pattern, p2, p1);