private static final char[] aspectSig = "Lorg/aspectj/lang/annotation/Aspect;".toCharArray();
private static final char[] declareParentsSig = "Lorg/aspectj/lang/annotation/DeclareParents;".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[] orgAspectJLangAnnotation =
+ // "org/aspectj/lang/annotation/".toCharArray();
private static final char[] voidType = "void".toCharArray();
private static final char[] booleanType = "boolean".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,
+ // private static final char[][] adviceSigs = new char[][] {
+ // beforeAdviceSig, afterAdviceSig, afterReturningAdviceSig,
// afterThrowingAdviceSig, aroundAdviceSig };
- private CompilationUnitDeclaration unit;
- private Stack typeStack = new Stack();
+ private final CompilationUnitDeclaration unit;
+ private final Stack typeStack = new Stack();
private AspectJAnnotations ajAnnotations;
public ValidateAtAspectJAnnotationsVisitor(CompilationUnitDeclaration unit) {
}
}
} else {
- // check that aspect doesn't have @Aspect annotation, we've already added on ourselves.
+ // check that aspect doesn't have @Aspect annotation, we've already
+ // added on ourselves.
if (ajAnnotations.hasMultipleAspectAnnotations) {
typeDecl.scope.problemReporter().signalError(typeDecl.sourceStart, typeDecl.sourceEnd,
"aspects cannot have @Aspect annotation");
CompilationAndWeavingContext.VALIDATING_AT_ASPECTJ_ANNOTATIONS, methodDeclaration.selector);
ajAnnotations = new AspectJAnnotations(methodDeclaration.annotations);
if (!methodDeclaration.getClass().equals(AjMethodDeclaration.class)) {
- // simply test for innapropriate use of annotations on code-style members
+ // simply test for innapropriate use of annotations on code-style
+ // members
if (methodDeclaration instanceof PointcutDeclaration) {
if (ajAnnotations.hasMultiplePointcutAnnotations || ajAnnotations.hasAdviceAnnotation
|| ajAnnotations.hasAspectAnnotation || ajAnnotations.hasAdviceNameAnnotation) {
}
/**
- * aspect must be public nested aspect must be static cannot extend a concrete aspect pointcut in perclause must be good.
+ * aspect must be public 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) {
// FIXME AV - do we really want that
// if (!Modifier.isPublic(typeDecl.modifiers)) {
- // typeDecl.scope.problemReporter().signalError(typeDecl.sourceStart,typeDecl.sourceEnd,"@Aspect class must be public");
+ // typeDecl.scope.problemReporter().signalError(typeDecl.sourceStart,
+ // typeDecl.sourceEnd,"@Aspect class must be public");
// }
TypeReference parentRef = typeDecl.superclass;
TypeBinding parentBinding = parentRef.resolvedType;
if (parentBinding instanceof SourceTypeBinding) {
SourceTypeBinding parentSTB = (SourceTypeBinding) parentBinding;
- if (parentSTB.scope != null) { // scope is null if its a binarytypebinding (in AJ world, thats a subclass of
+ if (parentSTB.scope != null) { // scope is null if its a
+ // binarytypebinding (in AJ
+ // world, thats a subclass of
// SourceTypeBinding)
TypeDeclaration parentDecl = parentSTB.scope.referenceContext;
if (isAspect(parentDecl) && !Modifier.isAbstract(parentDecl.modifiers)) {
int[] pcLoc = new int[2];
String perClause = getStringLiteralFor("value", aspectAnnotation, pcLoc);
- // AspectDeclaration aspectDecl = new AspectDeclaration(typeDecl.compilationResult);
+ // AspectDeclaration aspectDecl = new
+ // AspectDeclaration(typeDecl.compilationResult);
try {
if (perClause != null && !perClause.equals("")) {
}
/**
- * 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 4) After throwing advice must declare the thrown formal 5) After returning advice must declare the returning
- * formal 6) Advice must not be static
+ * 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 4)
+ * After throwing advice must declare the thrown formal 5) After returning
+ * advice must declare the returning formal 6) Advice must not be static
*/
private void validateAdvice(MethodDeclaration methodDeclaration) {
FormalBinding[] bindings = buildFormalAdviceBindingsFrom(methodDeclaration);
pc.resolve(new EclipseScope(bindings, methodDeclaration.scope));
EclipseFactory factory = EclipseFactory.fromScopeLookupEnvironment(methodDeclaration.scope);
- // now create a ResolvedPointcutDefinition,make an attribute out of it, and add it to the method
+ // now create a ResolvedPointcutDefinition,make an attribute out of
+ // it, and add it to the method
UnresolvedType[] paramTypes = new UnresolvedType[bindings.length];
for (int i = 0; i < paramTypes.length; i++)
paramTypes[i] = bindings[i].getType();
pcDecl.setGenerateSyntheticPointcutMethod();
TypeDeclaration onType = (TypeDeclaration) typeStack.peek();
pcDecl.postParse(onType);
- // EclipseFactory factory = EclipseFactory.fromScopeLookupEnvironment(methodDeclaration.scope);
- // int argsLength = methodDeclaration.arguments == null ? 0 : methodDeclaration.arguments.length;
+ // EclipseFactory factory =
+ // EclipseFactory.fromScopeLookupEnvironment
+ // (methodDeclaration.scope);
+ // int argsLength = methodDeclaration.arguments == null ? 0 :
+ // methodDeclaration.arguments.length;
FormalBinding[] bindings = buildFormalAdviceBindingsFrom(methodDeclaration);
// 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);
- // UnresolvedType type = factory.fromBinding(methodDeclaration.binding.parameters[i]);
- // bindings[i] = new FormalBinding(type, name, i, arg.sourceStart, arg.sourceEnd, "unknown");
+ // UnresolvedType type =
+ // factory.fromBinding(methodDeclaration.binding.parameters[i]);
+ // bindings[i] = new FormalBinding(type, name, i, arg.sourceStart,
+ // arg.sourceEnd, "unknown");
// }
swap(onType, methodDeclaration, pcDecl);
if (pc != null) {
// has an expression
- pc.resolve(new EclipseScope(bindings, methodDeclaration.scope));
+ EclipseScope eScope = new EclipseScope(bindings, methodDeclaration.scope);
+ char[] packageName = null;
+ if (typeDecl.binding != null && typeDecl.binding.getPackage() != null) {
+ packageName = typeDecl.binding.getPackage().readableName();
+ }
+ eScope.setLimitedImports(packageName);
+ pc.resolve(eScope);
HasIfPCDVisitor ifFinder = new HasIfPCDVisitor();
pc.traverse(ifFinder, null);
containsIfPcd = ifFinder.containsIfPcd;
}
if (pcDecl.pointcutDesignator == null) {
- if (Modifier.isAbstract(methodDeclaration.modifiers) || noValueSupplied // this is a matches nothing pointcut
- // those 2 checks makes sense for aop.xml concretization but NOT for regular abstraction of pointcut
+ if (Modifier.isAbstract(methodDeclaration.modifiers) || noValueSupplied // this
+ // is
+ // a
+ // matches
+ // nothing
+ // pointcut
+ // those 2 checks makes sense for aop.xml concretization but NOT for
+ // regular abstraction of pointcut
// && returnsVoid
- // && (methodDeclaration.arguments == null || methodDeclaration.arguments.length == 0)) {
+ // && (methodDeclaration.arguments == null ||
+ // methodDeclaration.arguments.length == 0)) {
) {
// fine
} else {
* PARC initial implementation
* ******************************************************************/
-
package org.aspectj.ajdt.internal.compiler.lookup;
import java.util.ArrayList;
import org.aspectj.bridge.IMessageHandler;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.Message;
-import org.aspectj.weaver.IHasPosition;
-import org.aspectj.weaver.ResolvedType;
-import org.aspectj.weaver.UnresolvedType;
-import org.aspectj.weaver.World;
-import org.aspectj.weaver.patterns.*;
+import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
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.ImportBinding;
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.TypeBinding;
-import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
+import org.aspectj.weaver.IHasPosition;
+import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.UnresolvedType;
+import org.aspectj.weaver.World;
+import org.aspectj.weaver.patterns.FormalBinding;
+import org.aspectj.weaver.patterns.IScope;
+import org.aspectj.weaver.patterns.WildTypePattern;
/**
- * Adaptor from org.eclipse.jdt.internal.compiler.lookup.Scope to org.aspectj.weaver.IScope
+ * Adaptor from org.eclipse.jdt.internal.compiler.lookup.Scope to
+ * org.aspectj.weaver.IScope
*
* @author Jim Hugunin
*/
public class EclipseScope implements IScope {
- private Scope scope;
- private EclipseFactory world;
- private ResolvedType enclosingType;
- private FormalBinding[] bindings;
-
+ private static final char[] javaLang = "java.lang".toCharArray();
+ private static final String[] JL = new String[] { "java.lang." };
+ private static final String[] NONE = new String[0];
+ private final Scope scope;
+ private final EclipseFactory world;
+ private final ResolvedType enclosingType;
+ private final FormalBinding[] bindings;
+
private String[] importedPrefixes = null;
private String[] importedNames = null;
-
public EclipseScope(FormalBinding[] bindings, Scope scope) {
this.bindings = bindings;
-
+
this.scope = scope;
- this.world = EclipseFactory.fromScopeLookupEnvironment(scope);
-
- this.enclosingType = world.fromEclipse(scope.enclosingSourceType());
+ world = EclipseFactory.fromScopeLookupEnvironment(scope);
+
+ enclosingType = world.fromEclipse(scope.enclosingSourceType());
}
-
-
+
public UnresolvedType lookupType(String name, IHasPosition location) {
- char[][] splitName = WildTypePattern.splitNames(name,true);
- TypeBinding b = scope.getType(splitName,splitName.length);
- //FIXME ??? need reasonable error handling...
+ char[][] splitName = WildTypePattern.splitNames(name, true);
+ TypeBinding b = scope.getType(splitName, splitName.length);
+ // FIXME ??? need reasonable error handling...
if (!b.isValidBinding()) {
return ResolvedType.MISSING;
}
-
- //System.err.println("binding: " + b);
- // Binding(tokens, bits & RestrictiveFlagMASK, this)
- return world.fromBinding(b);
-
- /*
- computeImports();
-
-// System.out.println("lookup: " + name + " in " +
-// Arrays.asList(importedPrefixes));
-
- ResolvedType ret = null;
- String dotName = "." + name;
- for (int i=0; i<importedNames.length; i++) {
- String importedName = importedNames[i];
- //??? can this be right
- if (importedName.endsWith(name) &&
- ((importedName.length() == name.length()) ||
- (importedName.endsWith(dotName))))
- {
- ResolvedType found = resolveVisible(importedName);
- if (found == ResolvedType.MISSING) continue;
- if (ret != null) {
- message(IMessage.ERROR, location,
- "ambiguous type reference, both " + ret.getName() + " and " + importedName);
- return ResolvedType.MISSING;
- } else {
- ret = found;
+
+ if (referenceFromAnnotationStylePointcut) { // pr265360
+ // it must be fully qualified in the pointcut text or in the same
+ // package as the type containing the pointcut
+ char[] qualifiedPackageName = b.qualifiedPackageName();
+ if (!CharOperation.equals(qualifiedPackageName, javaLang)) {
+ String packagePrefix = new String(qualifiedPackageName);
+ if (!name.startsWith(packagePrefix)) {
+ if (validPackage != null && CharOperation.equals(validPackage, qualifiedPackageName)) {
+ // it is OK, found in same package as the aspect
+ } else {
+ return ResolvedType.MISSING;
+ }
}
}
}
-
- if (ret != null) return ret;
-
- //XXX need to handle ambiguous references here
- for (int i=0; i<importedPrefixes.length; i++) {
- String importedPrefix = importedPrefixes[i];
- ResolvedType tryType = resolveVisible(importedPrefix + name);
- if (tryType != ResolvedType.MISSING) {
- return tryType;
- }
- }
- return resolveVisible(name);
- */
+ // System.err.println("binding: " + b);
+ // Binding(tokens, bits & RestrictiveFlagMASK, this)
+ return world.fromBinding(b);
+
+ /*
+ * computeImports();
+ *
+ * // System.out.println("lookup: " + name + " in " + //
+ * Arrays.asList(importedPrefixes));
+ *
+ * ResolvedType ret = null; String dotName = "." + name; for (int i=0;
+ * i<importedNames.length; i++) { String importedName =
+ * importedNames[i]; //??? can this be right if
+ * (importedName.endsWith(name) && ((importedName.length() ==
+ * name.length()) || (importedName.endsWith(dotName)))) { ResolvedType
+ * found = resolveVisible(importedName); if (found ==
+ * ResolvedType.MISSING) continue; if (ret != null) {
+ * message(IMessage.ERROR, location, "ambiguous type reference, both " +
+ * ret.getName() + " and " + importedName); return ResolvedType.MISSING;
+ * } else { ret = found; } } }
+ *
+ * if (ret != null) return ret;
+ *
+ * //XXX need to handle ambiguous references here for (int i=0;
+ * i<importedPrefixes.length; i++) { String importedPrefix =
+ * importedPrefixes[i]; ResolvedType tryType =
+ * resolveVisible(importedPrefix + name); if (tryType !=
+ * ResolvedType.MISSING) { return tryType; } }
+ *
+ * return resolveVisible(name);
+ */
}
-
-
-// private ResolvedType resolveVisible(String name) {
-// ResolvedType found = world.getWorld().resolve(UnresolvedType.forName(name), true);
-// if (found == ResolvedType.MISSING) return found;
-// if (ResolvedType.isVisible(found.getModifiers(), found, enclosingType)) return found;
-// return ResolvedType.MISSING;
-// }
-
-
-// public UnresolvedType lookupType(String name, IHasPosition location) {
-// char[][] namePieces = CharOperation.splitOn('.', name.toCharArray());
-// TypeBinding binding;
-// if (namePieces.length == 1) {
-// binding = scope.getType(namePieces[0]);
-// } else {
-// binding = scope.getType(namePieces);
-// }
-//
-//
-// if (!binding.isValidBinding()) {
-// //XXX do we do this always or sometimes
-// System.err.println("error: " + binding);
-// scope.problemReporter().invalidType(EclipseWorld.astForLocation(location), binding);
-// return ResolvedType.MISSING;
-// }
-// //??? do we want this too
-//// if (AstNode.isTypeUseDeprecated(binding, scope))
-//// scope.problemReporter().deprecatedType(binding, EclipseWorld.astForLocation(location));
-//
-// return EclipseWorld.fromBinding(binding);
-// }
-
-
-
+
+ // private ResolvedType resolveVisible(String name) {
+ // ResolvedType found =
+ // world.getWorld().resolve(UnresolvedType.forName(name), true);
+ // if (found == ResolvedType.MISSING) return found;
+ // if (ResolvedType.isVisible(found.getModifiers(), found, enclosingType))
+ // return found;
+ // return ResolvedType.MISSING;
+ // }
+
+ // public UnresolvedType lookupType(String name, IHasPosition location) {
+ // char[][] namePieces = CharOperation.splitOn('.', name.toCharArray());
+ // TypeBinding binding;
+ // if (namePieces.length == 1) {
+ // binding = scope.getType(namePieces[0]);
+ // } else {
+ // binding = scope.getType(namePieces);
+ // }
+ //
+ //
+ // if (!binding.isValidBinding()) {
+ // //XXX do we do this always or sometimes
+ // System.err.println("error: " + binding);
+ //scope.problemReporter().invalidType(EclipseWorld.astForLocation(location),
+ // binding);
+ // return ResolvedType.MISSING;
+ // }
+ // //??? do we want this too
+ // // if (AstNode.isTypeUseDeprecated(binding, scope))
+ // // scope.problemReporter().deprecatedType(binding,
+ // EclipseWorld.astForLocation(location));
+ //
+ // return EclipseWorld.fromBinding(binding);
+ // }
+
private void computeImports() {
- if (importedNames != null) return;
-
+ if (importedNames != null)
+ return;
+
List importedNamesList = new ArrayList();
List importedPrefixesList = new ArrayList();
-
-
+
Scope currentScope = scope;
- //add any enclosing types to this list
+ // add any enclosing types to this list
while (!(currentScope instanceof CompilationUnitScope)) {
if (currentScope == null) {
throw new RuntimeException("unimplemented");
}
if (currentScope instanceof ClassScope) {
- addClassAndParentsToPrefixes(((ClassScope)currentScope).referenceType().binding, importedPrefixesList);
+ addClassAndParentsToPrefixes(((ClassScope) currentScope).referenceType().binding, importedPrefixesList);
}
currentScope = currentScope.parent;
}
-
- CompilationUnitScope cuScope = (CompilationUnitScope)currentScope;
- String packageName =
- new String(CharOperation.concatWith(cuScope.currentPackageName, '.'));
- //System.err.println("package: " + packageName);
+ CompilationUnitScope cuScope = (CompilationUnitScope) currentScope;
+
+ String packageName = new String(CharOperation.concatWith(cuScope.currentPackageName, '.'));
+ // System.err.println("package: " + packageName);
if (packageName.length() > 0) {
importedPrefixesList.add(packageName + ".");
}
-
ImportBinding[] imports = cuScope.imports;
for (int i = 0; i < imports.length; i++) {
ImportBinding importBinding = imports[i];
- String importName =
- new String(CharOperation.concatWith(importBinding.compoundName, '.'));
-
- //XXX wrong behavior for java.util.Map.*
+ String importName = new String(CharOperation.concatWith(importBinding.compoundName, '.'));
+
+ // XXX wrong behavior for java.util.Map.*
if (importBinding.onDemand) {
importedPrefixesList.add(importName + ".");
} else {
importedNamesList.add(importName);
}
}
-
+
TypeBinding[] topTypes = cuScope.topLevelTypes;
for (int i = 0; i < topTypes.length; i++) {
importedNamesList.add(world.fromBinding(topTypes[i]).getName());
}
-
- importedNames =
- (String[])importedNamesList.toArray(new String[importedNamesList.size()]);
-
- importedPrefixes =
- (String[])importedPrefixesList.toArray(new String[importedPrefixesList.size()]);
+
+ importedNames = (String[]) importedNamesList.toArray(new String[importedNamesList.size()]);
+
+ importedPrefixes = (String[]) importedPrefixesList.toArray(new String[importedPrefixesList.size()]);
}
- private void addClassAndParentsToPrefixes(
- ReferenceBinding binding,
- List importedPrefixesList)
- {
- if (binding == null) return;
- importedPrefixesList.add(world.fromBinding(binding).getName()+"$");
-
+ private void addClassAndParentsToPrefixes(ReferenceBinding binding, List importedPrefixesList) {
+ if (binding == null)
+ return;
+ importedPrefixesList.add(world.fromBinding(binding).getName() + "$");
+
addClassAndParentsToPrefixes(binding.superclass(), importedPrefixesList);
ReferenceBinding[] superinterfaces = binding.superInterfaces();
if (superinterfaces != null) {
}
}
}
-
public String[] getImportedNames() {
computeImports();
public String[] getImportedPrefixes() {
computeImports();
- //System.err.println("prefixes: " + Arrays.asList(importedPrefixes));
+ // System.err.println("prefixes: " + Arrays.asList(importedPrefixes));
return importedPrefixes;
}
-
- //XXX add good errors when would bind to extra parameters
- public FormalBinding lookupFormal(String name) {
- for (int i = 0, len = bindings.length; i < len; i++) {
- if (bindings[i].getName().equals(name)) return bindings[i];
- }
- return null;
- }
-
+ // XXX add good errors when would bind to extra parameters
+ public FormalBinding lookupFormal(String name) {
+ for (int i = 0, len = bindings.length; i < len; i++) {
+ if (bindings[i].getName().equals(name))
+ return bindings[i];
+ }
+ return null;
+ }
public FormalBinding getFormal(int i) {
return bindings[i];
}
- public int getFormalCount() {
- return bindings.length;
- }
+ public int getFormalCount() {
+ return bindings.length;
+ }
public ISourceLocation makeSourceLocation(IHasPosition location) {
- return new EclipseSourceLocation(scope.problemReporter().referenceContext.compilationResult(),
- location.getStart(), location.getEnd());
+ return new EclipseSourceLocation(scope.problemReporter().referenceContext.compilationResult(), location.getStart(),
+ location.getEnd());
}
public IMessageHandler getMessageHandler() {
return world.getWorld().getMessageHandler();
}
-
- public void message(
- IMessage.Kind kind,
- IHasPosition location1,
- IHasPosition location2,
- String message) {
- message(kind, location1, message);
- message(kind, location2, message);
+ public void message(IMessage.Kind kind, IHasPosition location1, IHasPosition location2, String message) {
+ message(kind, location1, message);
+ message(kind, location2, message);
}
- public void message(
- IMessage.Kind kind,
- IHasPosition location,
- String message) {
- //System.out.println("message: " + message + " loc: " + makeSourceLocation(location));
- getMessageHandler()
- .handleMessage(new Message(message, kind, null, makeSourceLocation(location)));
+ public void message(IMessage.Kind kind, IHasPosition location, String message) {
+ // System.out.println("message: " + message + " loc: " +
+ // makeSourceLocation(location));
+ getMessageHandler().handleMessage(new Message(message, kind, null, makeSourceLocation(location)));
}
-
+
public void message(IMessage aMessage) {
getMessageHandler().handleMessage(aMessage);
}
return enclosingType;
}
+ private boolean referenceFromAnnotationStylePointcut = false;
+ private char[] validPackage;
+
+ /**
+ * Mark this scope as only allowing limited support for imports. This is to
+ * ensure that references in annotation style pointcuts are accidentally
+ * resolved against import statements. They won't be if javac is used (and
+ * the resulting .class file will contain 'bad pointcuts') so this method
+ * enables it to also be policed when compiling with ajc.
+ *
+ * @param validPackage unqualified references can be resolved if the type is
+ * in the same package as the type containing the pointcut
+ * declaration.
+ */
+ public void setLimitedImports(char[] validPackage) {
+ referenceFromAnnotationStylePointcut = true;
+ this.validPackage = validPackage;
+ importedPrefixes = JL; // Consider only java.lang. as an import
+ importedNames = NONE; // No imported names
+ }
+
}