aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoracolyer <acolyer>2005-04-25 16:07:25 +0000
committeracolyer <acolyer>2005-04-25 16:07:25 +0000
commit75c1c3ea4d4cc5308cf3ba4490d18b8536b08dd2 (patch)
treed06e4c67eae3c9879eebabc6854ecf40817181d4
parent92fce1440c9017376efaf544802d8cef07546b03 (diff)
downloadaspectj-75c1c3ea4d4cc5308cf3ba4490d18b8536b08dd2.tar.gz
aspectj-75c1c3ea4d4cc5308cf3ba4490d18b8536b08dd2.zip
support in ajc for parsing and error reporting of @AspectJ style aspect definitions (aspect, pointcut, advice only at this point). Also include the AddAtAspectJAnnotationsVisitor support. Switch off using -Xdev:NoAtAspectJProcessing.
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java4
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompilerAdapter.java31
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AddAtAspectJAnnotationsVisitor.java61
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java81
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AjMethodDeclaration.java10
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java66
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AtAspectJAnnotationFactory.java146
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDeclaration.java67
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDesignator.java18
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/ValidateAtAspectJAnnotationsVisitor.java615
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java29
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java32
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java7
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java3
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java20
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AspectJBuilder.java2
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseSourceContext.java10
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CommandTestCase.java2
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjCompilerOptionsTest.java5
-rw-r--r--weaver/src/org/aspectj/weaver/ISourceContext.java1
-rw-r--r--weaver/src/org/aspectj/weaver/ataspectj/Aj5Attributes.java71
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelMethod.java16
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java38
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelSourceContext.java2
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/BasicTokenSource.java7
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/PatternNode.java4
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/PatternParser.java6
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/PerCflow.java5
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/PerClause.java2
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/PerFromSuper.java4
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/PerObject.java4
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/PerSingleton.java4
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java4
-rw-r--r--weaver/testsrc/org/aspectj/weaver/patterns/NamePatternParserTestCase.java2
34 files changed, 1271 insertions, 108 deletions
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java
index 0f8909585..af7cc30fa 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java
@@ -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);
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompilerAdapter.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompilerAdapter.java
index 9091a8c15..8085a51f4 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompilerAdapter.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompilerAdapter.java
@@ -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
index 000000000..8b4ade56e
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AddAtAspectJAnnotationsVisitor.java
@@ -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;
+ }
+
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java
index a81ad0abf..6e2d95591 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java
@@ -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);
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AjMethodDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AjMethodDeclaration.java
index bb31f5e16..efaedf2b5 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AjMethodDeclaration.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AjMethodDeclaration.java
@@ -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()));
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java
index 31eb13fe5..f9beb3f85 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java
@@ -14,23 +14,53 @@
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
index 000000000..304cd4761
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AtAspectJAnnotationFactory.java
@@ -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;
+ }
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDeclaration.java
index 870a5edc0..4c46411b8 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDeclaration.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDeclaration.java
@@ -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");
}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDesignator.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDesignator.java
index 9bede187a..9b3b2adfa 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDesignator.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDesignator.java
@@ -13,20 +13,20 @@
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
index 000000000..6da29969f
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/ValidateAtAspectJAnnotationsVisitor.java
@@ -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;
+ }
+ }
+ }
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java
index 2365ef452..197fa3376 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java
@@ -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) {
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java
index 90ed87495..826e585f2 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java
@@ -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();
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java
index 12ca5f606..cf5bcb5fb 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java
@@ -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;
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java
index c4223b8b4..1f550dd95 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java
@@ -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)
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java
index 8553ed9df..0eeb1797f 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java
@@ -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$
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AspectJBuilder.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AspectJBuilder.java
index b91aed439..5407758ff 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AspectJBuilder.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AspectJBuilder.java
@@ -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)
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseSourceContext.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseSourceContext.java
index d8219bee1..056120373 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseSourceContext.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseSourceContext.java
@@ -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));
}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CommandTestCase.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CommandTestCase.java
index a508e512c..0c972cf40 100644
--- a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CommandTestCase.java
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CommandTestCase.java
@@ -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");
}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjCompilerOptionsTest.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjCompilerOptionsTest.java
index 988209675..c19ecc33d 100644
--- a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjCompilerOptionsTest.java
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjCompilerOptionsTest.java
@@ -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();
diff --git a/weaver/src/org/aspectj/weaver/ISourceContext.java b/weaver/src/org/aspectj/weaver/ISourceContext.java
index 16cb3c8bc..d0c91a27b 100644
--- a/weaver/src/org/aspectj/weaver/ISourceContext.java
+++ b/weaver/src/org/aspectj/weaver/ISourceContext.java
@@ -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();
}
diff --git a/weaver/src/org/aspectj/weaver/ataspectj/Aj5Attributes.java b/weaver/src/org/aspectj/weaver/ataspectj/Aj5Attributes.java
index f708b6f8f..2eb120ecd 100644
--- a/weaver/src/org/aspectj/weaver/ataspectj/Aj5Attributes.java
+++ b/weaver/src/org/aspectj/weaver/ataspectj/Aj5Attributes.java
@@ -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(
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java b/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java
index 7de8b3735..a8c629992 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java
@@ -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() {
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java b/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java
index 46a7fe783..862b2a65b 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java
@@ -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() {
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelSourceContext.java b/weaver/src/org/aspectj/weaver/bcel/BcelSourceContext.java
index 8f7f4065a..8d313c4e7 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelSourceContext.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelSourceContext.java
@@ -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
diff --git a/weaver/src/org/aspectj/weaver/patterns/BasicTokenSource.java b/weaver/src/org/aspectj/weaver/patterns/BasicTokenSource.java
index c8c215a3d..dad3bccd4 100644
--- a/weaver/src/org/aspectj/weaver/patterns/BasicTokenSource.java
+++ b/weaver/src/org/aspectj/weaver/patterns/BasicTokenSource.java
@@ -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;
+ }
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/PatternNode.java b/weaver/src/org/aspectj/weaver/patterns/PatternNode.java
index c49b52923..0730538ca 100644
--- a/weaver/src/org/aspectj/weaver/patterns/PatternNode.java
+++ b/weaver/src/org/aspectj/weaver/patterns/PatternNode.java
@@ -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() {
diff --git a/weaver/src/org/aspectj/weaver/patterns/PatternParser.java b/weaver/src/org/aspectj/weaver/patterns/PatternParser.java
index ffd4446ca..ea0be3fe2 100644
--- a/weaver/src/org/aspectj/weaver/patterns/PatternParser.java
+++ b/weaver/src/org/aspectj/weaver/patterns/PatternParser.java
@@ -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));
}
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/PerCflow.java b/weaver/src/org/aspectj/weaver/patterns/PerCflow.java
index 97c06bc55..cded77643 100644
--- a/weaver/src/org/aspectj/weaver/patterns/PerCflow.java
+++ b/weaver/src/org/aspectj/weaver/patterns/PerCflow.java
@@ -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 + ")";
+ }
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/PerClause.java b/weaver/src/org/aspectj/weaver/patterns/PerClause.java
index e8fbc834a..d410436b0 100644
--- a/weaver/src/org/aspectj/weaver/patterns/PerClause.java
+++ b/weaver/src/org/aspectj/weaver/patterns/PerClause.java
@@ -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); }
diff --git a/weaver/src/org/aspectj/weaver/patterns/PerFromSuper.java b/weaver/src/org/aspectj/weaver/patterns/PerFromSuper.java
index d7841008e..87d6b61db 100644
--- a/weaver/src/org/aspectj/weaver/patterns/PerFromSuper.java
+++ b/weaver/src/org/aspectj/weaver/patterns/PerFromSuper.java
@@ -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;
diff --git a/weaver/src/org/aspectj/weaver/patterns/PerObject.java b/weaver/src/org/aspectj/weaver/patterns/PerObject.java
index b4283bc0e..79426942e 100644
--- a/weaver/src/org/aspectj/weaver/patterns/PerObject.java
+++ b/weaver/src/org/aspectj/weaver/patterns/PerObject.java
@@ -137,4 +137,8 @@ public class PerObject extends PerClause {
return "per" + (isThis ? "this" : "target") +
"(" + entry + ")";
}
+
+ public String toDeclarationString() {
+ return toString();
+ }
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/PerSingleton.java b/weaver/src/org/aspectj/weaver/patterns/PerSingleton.java
index 169e83962..f98d07980 100644
--- a/weaver/src/org/aspectj/weaver/patterns/PerSingleton.java
+++ b/weaver/src/org/aspectj/weaver/patterns/PerSingleton.java
@@ -126,5 +126,9 @@ public class PerSingleton extends PerClause {
public String toString() {
return "persingleton(" + inAspect + ")";
}
+
+ public String toDeclarationString() {
+ return "";
+ }
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java b/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java
index cdc7c3aa9..151e3f2d7 100644
--- a/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java
+++ b/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java
@@ -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)) {
diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/NamePatternParserTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/NamePatternParserTestCase.java
index b43526586..cd646b122 100644
--- a/weaver/testsrc/org/aspectj/weaver/patterns/NamePatternParserTestCase.java
+++ b/weaver/testsrc/org/aspectj/weaver/patterns/NamePatternParserTestCase.java
@@ -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);