import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.AnnotatedElement;
import org.aspectj.weaver.ISourceContext;
+import org.aspectj.weaver.World;
/**
* @author colyer
return left.matches(annotated).and(right.matches(annotated));
}
+ public void resolve(World world) {
+ left.resolve(world);
+ right.resolve(world);
+ }
+
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.AnnotationTypePattern#resolveBindings(org.aspectj.weaver.patterns.IScope, org.aspectj.weaver.patterns.Bindings, boolean)
*/
import java.io.IOException;
import java.util.List;
+import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.IntMap;
+import org.aspectj.weaver.ResolvedTypeX;
+import org.aspectj.weaver.World;
/**
* @author colyer
public AnnotationPatternList(List l) {
this((AnnotationTypePattern[]) l.toArray(new AnnotationTypePattern[l.size()]));
}
+
+ public void resolve(World inWorld) {
+ for (int i = 0; i < typePatterns.length; i++) {
+ typePatterns[i].resolve(inWorld);
+ }
+ }
+
+ public FuzzyBoolean matches(ResolvedTypeX[] someArgs) {
+ // do some quick length tests first
+ int numArgsMatchedByEllipsis = (someArgs.length + ellipsisCount) - typePatterns.length;
+ if (numArgsMatchedByEllipsis < 0) return FuzzyBoolean.NO;
+ if ((numArgsMatchedByEllipsis > 0) && (ellipsisCount == 0)) {
+ return FuzzyBoolean.NO;
+ }
+ // now work through the args and the patterns, skipping at ellipsis
+ FuzzyBoolean ret = FuzzyBoolean.YES;
+ int argsIndex = 0;
+ for (int i = 0; i < typePatterns.length; i++) {
+ if (typePatterns[i] == AnnotationTypePattern.ELLIPSIS) {
+ // match ellipsisMatchCount args
+ argsIndex += numArgsMatchedByEllipsis;
+ } else if (typePatterns[i] == AnnotationTypePattern.ANY) {
+ argsIndex++;
+ } else {
+ // match the argument type at argsIndex with the ExactAnnotationTypePattern
+ // we know it is exact because nothing else is allowed in args
+ ExactAnnotationTypePattern ap = (ExactAnnotationTypePattern)typePatterns[i];
+ FuzzyBoolean matches = ap.matches(someArgs[argsIndex]);
+ if (matches == FuzzyBoolean.NO) {
+ return FuzzyBoolean.NO;
+ } else {
+ argsIndex++;
+ ret = ret.and(matches);
+ }
+ }
+ }
+ return ret;
+ }
public int size() { return typePatterns.length; }
*/
public FuzzyBoolean fastMatch(FastMatchInfo info) {
if (info.getKind() == Shadow.StaticInitialization) {
- return annotationTypePattern.matches(info.getType());
+ return annotationTypePattern.fastMatches(info.getType());
} else {
return FuzzyBoolean.MAYBE;
}
toMatchAgainst = rMember;
}
+ annotationTypePattern.resolve(shadow.getIWorld());
return annotationTypePattern.matches(toMatchAgainst);
}
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.IntMap;
+import org.aspectj.weaver.World;
public abstract class AnnotationTypePattern extends PatternNode {
public abstract FuzzyBoolean matches(AnnotatedElement annotated);
+ public FuzzyBoolean fastMatches(AnnotatedElement annotated) {
+ return FuzzyBoolean.MAYBE;
+ }
+
public AnnotationTypePattern remapAdviceFormals(IntMap bindings) {
return this;
}
+ public abstract void resolve(World world);
+
/**
* This can modify in place, or return a new TypePattern if the type changes.
*/
s.writeByte(AnnotationTypePattern.ANY_KEY);
}
+ public void resolve(World world) {
+ }
+
public String toString() { return "@ANY"; }
}
public void write(DataOutputStream s) throws IOException {
s.writeByte(AnnotationTypePattern.ELLIPSIS_KEY);
}
-
+
+ public void resolve(World world) {
+ }
+
public String toString() { return ".."; }
}
\ No newline at end of file
* ******************************************************************/
package org.aspectj.weaver.patterns;
+import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.bridge.Message;
import org.aspectj.util.FuzzyBoolean;
+import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.IntMap;
import org.aspectj.weaver.ResolvedTypeX;
import org.aspectj.weaver.Shadow;
+import org.aspectj.weaver.TypeX;
+import org.aspectj.weaver.WeaverMessages;
+import org.aspectj.weaver.ast.Literal;
import org.aspectj.weaver.ast.Test;
/**
public class ArgsAnnotationPointcut extends NameBindingPointcut {
private AnnotationPatternList arguments;
+
/**
*
*/
super();
this.arguments = arguments;
}
-
+
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.Pointcut#fastMatch(org.aspectj.weaver.patterns.FastMatchInfo)
*/
public FuzzyBoolean fastMatch(FastMatchInfo info) {
- // TODO Auto-generated method stub
- return null;
+ return FuzzyBoolean.MAYBE;
}
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow)
*/
public FuzzyBoolean match(Shadow shadow) {
- // TODO Auto-generated method stub
- return null;
+ arguments.resolve(shadow.getIWorld());
+ FuzzyBoolean ret =
+ arguments.matches(shadow.getIWorld().resolve(shadow.getArgTypes()));
+ return ret;
}
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.Pointcut#resolveBindings(org.aspectj.weaver.patterns.IScope, org.aspectj.weaver.patterns.Bindings)
*/
protected void resolveBindings(IScope scope, Bindings bindings) {
- // TODO Auto-generated method stub
-
+ arguments.resolveBindings(scope, bindings, true);
+ if (arguments.ellipsisCount > 1) {
+ scope.message(IMessage.ERROR, this,
+ "uses more than one .. in args (compiler limitation)");
+ }
}
/* (non-Javadoc)
*/
protected void resolveBindingsFromRTTI() {
// TODO Auto-generated method stub
-
}
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.Pointcut#concretize1(org.aspectj.weaver.ResolvedTypeX, org.aspectj.weaver.IntMap)
*/
protected Pointcut concretize1(ResolvedTypeX inAspect, IntMap bindings) {
- // TODO Auto-generated method stub
- return null;
+ if (isDeclare(bindings.getEnclosingAdvice())) {
+ // Enforce rule about which designators are supported in declare
+ inAspect.getWorld().showMessage(IMessage.ERROR,
+ WeaverMessages.format(WeaverMessages.ARGS_IN_DECLARE),
+ bindings.getEnclosingAdvice().getSourceLocation(), null);
+ return Pointcut.makeMatchesNothing(Pointcut.CONCRETE);
+ }
+ AnnotationPatternList list = arguments.resolveReferences(bindings);
+ return new ArgsAnnotationPointcut(list);
}
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.Pointcut#findResidue(org.aspectj.weaver.Shadow, org.aspectj.weaver.patterns.ExposedState)
*/
public Test findResidue(Shadow shadow, ExposedState state) {
- // TODO Auto-generated method stub
- return null;
+ int len = shadow.getArgCount();
+
+ // do some quick length tests first
+ int numArgsMatchedByEllipsis = (len + arguments.ellipsisCount) - arguments.size();
+ if (numArgsMatchedByEllipsis < 0) return Literal.FALSE; // should never happen
+ if ((numArgsMatchedByEllipsis > 0) && (arguments.ellipsisCount == 0)) {
+ return Literal.FALSE; // should never happen
+ }
+ // now work through the args and the patterns, skipping at ellipsis
+ Test ret = Literal.TRUE;
+ int argsIndex = 0;
+ for (int i = 0; i < arguments.size(); i++) {
+ if (arguments.get(i) == AnnotationTypePattern.ELLIPSIS) {
+ // match ellipsisMatchCount args
+ argsIndex += numArgsMatchedByEllipsis;
+ } else if (arguments.get(i) == AnnotationTypePattern.ANY) {
+ argsIndex++;
+ } else {
+ // match the argument type at argsIndex with the ExactAnnotationTypePattern
+ // we know it is exact because nothing else is allowed in args
+ ExactAnnotationTypePattern ap = (ExactAnnotationTypePattern)arguments.get(i);
+ TypeX argType = shadow.getArgType(i);
+ ResolvedTypeX rArgType = argType.resolve(shadow.getIWorld());
+ if (rArgType == ResolvedTypeX.MISSING) {
+ IMessage msg = new Message(
+ WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE_ARG_TYPE,argType.getName()),
+ "",IMessage.ERROR,shadow.getSourceLocation(),null,new ISourceLocation[]{getSourceLocation()});
+ }
+ if (ap.matches(rArgType).alwaysTrue()) {
+ continue;
+ } else {
+ // we need a test...
+ // TODO: binding
+ ResolvedTypeX rAnnType = ap.annotationType.resolve(shadow.getIWorld());
+ ret = Test.makeAnd(ret,Test.makeHasAnnotation(shadow.getArgVar(i),rAnnType));
+ }
+ }
+ }
+ return ret;
}
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.PatternNode#write(java.io.DataOutputStream)
*/
public void write(DataOutputStream s) throws IOException {
- // TODO Auto-generated method stub
-
+ s.writeByte(Pointcut.ATARGS);
+ arguments.write(s);
+ writeLocation(s);
+ }
+
+ public static Pointcut read(DataInputStream s, ISourceContext context) throws IOException {
+ AnnotationPatternList annotationPatternList = AnnotationPatternList.read(s,context);
+ ArgsAnnotationPointcut ret = new ArgsAnnotationPointcut(annotationPatternList);
+ ret.readLocation(context, s);
+ return ret;
}
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object obj) {
+ if (!(obj instanceof ArgsAnnotationPointcut)) return false;
+ ArgsAnnotationPointcut other = (ArgsAnnotationPointcut) obj;
+ return other.arguments.equals(arguments);
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return 17 + 37*arguments.hashCode();
+ }
+
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
this(binding.getType(),binding.getIndex());
}
- public AnnotationTypePattern resolve(World world) {
+ public void resolveBinding(World world) {
// For 1.5.0 M1
IMessage lim = MessageUtil.error("Binding not supported in @pcds (1.5.0 M1 limitation): " +
getSourceLocation());
world.getMessageHandler().handleMessage(lim);
// End of 1.5.0 M1
- if (resolved) return this;
+ if (resolved) return;
resolved = true;
annotationType = annotationType.resolve(world);
if (!annotationType.isAnnotation(world)) {
// TO DO... get the retention policy annotation, and check the value is
// RetentionPolicy.RUNTIME;
}
- return this;
}
import org.aspectj.weaver.ResolvedTypeX;
import org.aspectj.weaver.TypeX;
import org.aspectj.weaver.WeaverMessages;
+import org.aspectj.weaver.World;
/**
* Matches an annotation of a given type
// will be turned into BindingAnnotationTypePattern during resolution
}
+ public FuzzyBoolean fastMatches(AnnotatedElement annotated) {
+ if (annotated.hasAnnotation(annotationType)) {
+ return FuzzyBoolean.YES;
+ } else {
+ // could be inherited, but we don't know that until we are
+ // resolved, and we're not yet...
+ return FuzzyBoolean.MAYBE;
+ }
+ }
+
public FuzzyBoolean matches(AnnotatedElement annotated) {
- return (annotated.hasAnnotation(annotationType) ?
- FuzzyBoolean.YES : FuzzyBoolean.NO);
+ boolean checkSupers = false;
+ if (annotationType.hasAnnotation(TypeX.AT_INHERITED)) {
+ if (annotated instanceof ResolvedTypeX) {
+ checkSupers = true;
+ }
+ }
+
+ if (annotated.hasAnnotation(annotationType)) {
+ return FuzzyBoolean.YES;
+ } else if (checkSupers) {
+ ResolvedTypeX toMatchAgainst = ((ResolvedTypeX) annotated).getSuperclass();
+ while (toMatchAgainst != null) {
+ if (toMatchAgainst.hasAnnotation(annotationType)) return FuzzyBoolean.YES;
+ toMatchAgainst = toMatchAgainst.getSuperclass();
+ }
+ }
+ return FuzzyBoolean.NO;
}
+ public void resolve(World world) {
+ annotationType = annotationType.resolve(world);
+ }
+
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.AnnotationTypePattern#resolveBindings(org.aspectj.weaver.patterns.IScope, org.aspectj.weaver.patterns.Bindings, boolean)
*/
BindingAnnotationTypePattern binding = new BindingAnnotationTypePattern(formalBinding);
binding.copyLocationFrom(this);
bindings.register(binding, scope);
- binding.resolve(scope.getWorld());
+ binding.resolveBinding(scope.getWorld());
return binding;
} else {
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.AnnotatedElement;
import org.aspectj.weaver.ISourceContext;
+import org.aspectj.weaver.World;
public class NotAnnotationTypePattern extends AnnotationTypePattern {
public FuzzyBoolean matches(AnnotatedElement annotated) {
return negatedPattern.matches(annotated).not();
}
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.AnnotationTypePattern#resolve(org.aspectj.weaver.World)
+ */
+ public void resolve(World world) {
+ negatedPattern.resolve(world);
+ }
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.AnnotationTypePattern#resolveBindings(org.aspectj.weaver.patterns.IScope, org.aspectj.weaver.patterns.Bindings, boolean)
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.AnnotatedElement;
import org.aspectj.weaver.ISourceContext;
+import org.aspectj.weaver.World;
public class OrAnnotationTypePattern extends AnnotationTypePattern {
public FuzzyBoolean matches(AnnotatedElement annotated) {
return left.matches(annotated).or(right.matches(annotated));
}
+
+ public void resolve(World world) {
+ left.resolve(world);
+ right.resolve(world);
+ }
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.AnnotationTypePattern#resolveBindings(org.aspectj.weaver.patterns.IScope, org.aspectj.weaver.patterns.Bindings, boolean)
public static final byte ATWITHIN = 17;
public static final byte ATWITHINCODE = 18;
public static final byte ATTHIS_OR_TARGET = 19;
+ public static final byte ATARGS = 20;
- public static final byte NONE = 20;
+ public static final byte NONE = 40;
public byte getPointcutKind() { return pointcutKind; }
case ATWITHIN: ret = WithinAnnotationPointcut.read(s, context); break;
case ATWITHINCODE: ret = WithinCodeAnnotationPointcut.read(s, context); break;
case ATTHIS_OR_TARGET: ret = ThisOrTargetAnnotationPointcut.read(s, context); break;
+ case ATARGS: ret = ArgsAnnotationPointcut.read(s,context); break;
case NONE: ret = makeMatchesNothing(RESOLVED); break;
default:
throw new BCException("unknown kind: " + kind);
world.getLint().unresolvableMember.signal(member.toString(), getSourceLocation());
return false;
}
+ annotationPattern.resolve(world);
return annotationPattern.matches(rMember).alwaysTrue();
}
*/
public FuzzyBoolean match(Shadow shadow) {
if (!couldMatch(shadow)) return FuzzyBoolean.NO;
- TypeX annotationType = annotationTypePattern.annotationType;
- annotationType = annotationType.resolve(shadow.getIWorld());
- if (annotationType.hasAnnotation(TypeX.AT_INHERITED)) {
- // we can attempt to match now
- ResolvedTypeX toMatchAgainst =
- (isThis ? shadow.getThisType() : shadow.getTargetType() ).resolve(shadow.getIWorld());
- if (toMatchAgainst.hasAnnotation(annotationType)) {
- return FuzzyBoolean.YES;
- } else {
- ResolvedTypeX superC = toMatchAgainst;
- while ((superC = superC.getSuperclass()) != null) {
- if (superC.hasAnnotation(annotationType)) return FuzzyBoolean.YES;
-// if (superC.getName().equals("java.lang.Object")) return FuzzyBoolean.NO;
- }
- return FuzzyBoolean.NO;
- }
- }
- // else we can only do matching via a runtime test
- return FuzzyBoolean.MAYBE;
+ ResolvedTypeX toMatchAgainst =
+ (isThis ? shadow.getThisType() : shadow.getTargetType() ).resolve(shadow.getIWorld());
+ annotationTypePattern.resolve(shadow.getIWorld());
+ if (annotationTypePattern.matches(toMatchAgainst).alwaysTrue()) {
+ return FuzzyBoolean.YES;
+ } else {
+ // a subtype may match at runtime
+ return FuzzyBoolean.MAYBE;
+ }
}
public boolean isThis() { return isThis; }
* @see org.aspectj.weaver.patterns.Pointcut#concretize1(org.aspectj.weaver.ResolvedTypeX, org.aspectj.weaver.IntMap)
*/
protected Pointcut concretize1(ResolvedTypeX inAspect, IntMap bindings) {
+ if (isDeclare(bindings.getEnclosingAdvice())) {
+ // Enforce rule about which designators are supported in declare
+ inAspect.getWorld().showMessage(IMessage.ERROR,
+ WeaverMessages.format(WeaverMessages.THIS_OR_TARGET_IN_DECLARE,isThis?"this":"target"),
+ bindings.getEnclosingAdvice().getSourceLocation(), null);
+ return Pointcut.makeMatchesNothing(Pointcut.CONCRETE);
+ }
+
ExactAnnotationTypePattern newType = (ExactAnnotationTypePattern) annotationTypePattern.remapAdviceFormals(bindings);
Pointcut ret = new ThisOrTargetAnnotationPointcut(isThis, newType, bindings.getEnclosingAdvice());
ret.copyLocationFrom(this);
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.ResolvedTypeX;
import org.aspectj.weaver.WeaverMessages;
+import org.aspectj.weaver.World;
/**
* @author colyer
return FuzzyBoolean.NO;
}
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.AnnotationTypePattern#resolve(org.aspectj.weaver.World)
+ */
+ public void resolve(World world) {
+ // nothing to do...
+ }
+
/**
* This can modify in place, or return a new TypePattern if the type changes.
*/
* @see org.aspectj.weaver.patterns.Pointcut#fastMatch(org.aspectj.weaver.patterns.FastMatchInfo)
*/
public FuzzyBoolean fastMatch(FastMatchInfo info) {
- return annotationTypePattern.matches(info.getType());
+ return annotationTypePattern.fastMatches(info.getType());
}
/* (non-Javadoc)
shadow.getSourceLocation(),true,new ISourceLocation[]{getSourceLocation()});
shadow.getIWorld().getMessageHandler().handleMessage(msg);
}
+ annotationTypePattern.resolve(shadow.getIWorld());
return annotationTypePattern.matches(enclosingType);
}
}
toMatchAgainst = TypeX.forName(rMember.getSignature()).resolve(shadow.getIWorld());
-
+
+ annotationTypePattern.resolve(shadow.getIWorld());
return annotationTypePattern.matches(toMatchAgainst);
}