diff options
author | acolyer <acolyer> | 2004-12-08 17:10:18 +0000 |
---|---|---|
committer | acolyer <acolyer> | 2004-12-08 17:10:18 +0000 |
commit | 4f6a0fd6989d2de4d41b485f7775a600c95c35a2 (patch) | |
tree | cff3c72e2faf12ad600a54a581e652d554c281ad /weaver | |
parent | 0d07deaa99a6454cd2d5fbc6aea1fce0c737df62 (diff) | |
download | aspectj-4f6a0fd6989d2de4d41b485f7775a600c95c35a2.tar.gz aspectj-4f6a0fd6989d2de4d41b485f7775a600c95c35a2.zip |
@within, @withincode impl (non-binding)
Diffstat (limited to 'weaver')
5 files changed, 181 insertions, 41 deletions
diff --git a/weaver/src/org/aspectj/weaver/patterns/PatternParser.java b/weaver/src/org/aspectj/weaver/patterns/PatternParser.java index ae6f0cbc2..684377120 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PatternParser.java +++ b/weaver/src/org/aspectj/weaver/patterns/PatternParser.java @@ -373,7 +373,7 @@ public class PatternParser { if (maybeEat(")")) { throw new ParserException("expecting @AnnotationName or parameter, but found ')'", tokenSource.peek()); } - AnnotationTypePattern type = parseAnnotationNameOrVarTypePattern(); + ExactAnnotationTypePattern type = parseAnnotationNameOrVarTypePattern(); eat(")"); return new WithinCodeAnnotationPointcut(type); } diff --git a/weaver/src/org/aspectj/weaver/patterns/Pointcut.java b/weaver/src/org/aspectj/weaver/patterns/Pointcut.java index e85db612f..e29b80c44 100644 --- a/weaver/src/org/aspectj/weaver/patterns/Pointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/Pointcut.java @@ -125,6 +125,8 @@ public abstract class Pointcut extends PatternNode implements PointcutExpression public static final byte IF_TRUE = 14; public static final byte IF_FALSE = 15; public static final byte ANNOTATION = 16; + public static final byte ATWITHIN = 17; + public static final byte ATWITHINCODE = 18; public static final byte NONE = 20; @@ -243,6 +245,8 @@ public abstract class Pointcut extends PatternNode implements PointcutExpression case IF_TRUE: ret = IfPointcut.makeIfTruePointcut(RESOLVED); break; case IF_FALSE: ret = IfPointcut.makeIfFalsePointcut(RESOLVED); break; case ANNOTATION: ret = AnnotationPointcut.read(s, context); break; + case ATWITHIN: ret = WithinAnnotationPointcut.read(s, context); break; + case ATWITHINCODE: ret = WithinCodeAnnotationPointcut.read(s, context); break; case NONE: ret = makeMatchesNothing(RESOLVED); break; default: throw new BCException("unknown kind: " + kind); diff --git a/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetAnnotationPointcut.java b/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetAnnotationPointcut.java index de488dc17..7c1a30264 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetAnnotationPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetAnnotationPointcut.java @@ -104,5 +104,6 @@ public class ThisOrTargetAnnotationPointcut extends NameBindingPointcut { buf.append(isThis ? "@this(" : "@target("); buf.append(type.toString()); buf.append(")"); - return buf.toString(); } + return buf.toString(); + } } diff --git a/weaver/src/org/aspectj/weaver/patterns/WithinAnnotationPointcut.java b/weaver/src/org/aspectj/weaver/patterns/WithinAnnotationPointcut.java index 71937aadf..e5242d7d1 100644 --- a/weaver/src/org/aspectj/weaver/patterns/WithinAnnotationPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/WithinAnnotationPointcut.java @@ -9,14 +9,24 @@ * ******************************************************************/ 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.ShadowMunger; +import org.aspectj.weaver.TypeX; +import org.aspectj.weaver.WeaverMessages; +import org.aspectj.weaver.ast.Literal; import org.aspectj.weaver.ast.Test; +import org.aspectj.weaver.ast.Var; /** * @author colyer @@ -26,37 +36,50 @@ import org.aspectj.weaver.ast.Test; */ public class WithinAnnotationPointcut extends NameBindingPointcut { - private AnnotationTypePattern type; + private AnnotationTypePattern annotationTypePattern; + private ShadowMunger munger; + /** * */ public WithinAnnotationPointcut(AnnotationTypePattern type) { super(); - this.type = type; + this.annotationTypePattern = type; + } + + public WithinAnnotationPointcut(AnnotationTypePattern type, ShadowMunger munger) { + this(type); + this.munger = munger; } /* (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 annotationTypePattern.matches(info.getType()); } /* (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; + ResolvedTypeX enclosingType = shadow.getIWorld().resolve(shadow.getEnclosingType(),true); + if (enclosingType == ResolvedTypeX.MISSING) { + IMessage msg = new Message( + WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE_WITHINPCD, + shadow.getEnclosingType().getName()), + shadow.getSourceLocation(),true,new ISourceLocation[]{getSourceLocation()}); + shadow.getIWorld().getMessageHandler().handleMessage(msg); + } + return annotationTypePattern.matches(enclosingType); } /* (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 - + annotationTypePattern = (ExactAnnotationTypePattern) annotationTypePattern.resolveBindings(scope,bindings,true); + // must be either a Var, or an annotation type pattern } /* (non-Javadoc) @@ -71,33 +94,77 @@ public class WithinAnnotationPointcut extends NameBindingPointcut { * @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; + ExactAnnotationTypePattern newType = (ExactAnnotationTypePattern) annotationTypePattern.remapAdviceFormals(bindings); + Pointcut ret = new WithinAnnotationPointcut(newType, bindings.getEnclosingAdvice()); + ret.copyLocationFrom(this); + return ret; } /* (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; + if (annotationTypePattern instanceof BindingAnnotationTypePattern) { + BindingAnnotationTypePattern btp = (BindingAnnotationTypePattern)annotationTypePattern; + TypeX annotationType = btp.annotationType; + Var var = shadow.getWithinAnnotationVar(annotationType); + if (var == null) return Literal.FALSE; + // Check if we have already bound something to this formal + if (state.get(btp.getFormalIndex())!=null) { + ISourceLocation pcdSloc = getSourceLocation(); + ISourceLocation shadowSloc = shadow.getSourceLocation(); + Message errorMessage = new Message( + "Cannot use @pointcut to match at this location and bind a formal to type '"+var.getType()+ + "' - the formal is already bound to type '"+state.get(btp.getFormalIndex()).getType()+"'"+ + ". The secondary source location points to the problematic binding.", + shadowSloc,true,new ISourceLocation[]{pcdSloc}); + shadow.getIWorld().getMessageHandler().handleMessage(errorMessage); + state.setErroneousVar(btp.getFormalIndex()); + } + state.set(btp.getFormalIndex(),var); + } + return Literal.TRUE; } /* (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.ATWITHIN); + annotationTypePattern.write(s); + writeLocation(s); } + public static Pointcut read(DataInputStream s, ISourceContext context) throws IOException { + AnnotationTypePattern type = AnnotationTypePattern.read(s, context); + WithinAnnotationPointcut ret = new WithinAnnotationPointcut((ExactAnnotationTypePattern)type); + ret.readLocation(context, s); + return ret; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object obj) { + if (!(obj instanceof WithinAnnotationPointcut)) return false; + WithinAnnotationPointcut other = (WithinAnnotationPointcut) obj; + return other.annotationTypePattern.equals(this.annotationTypePattern); + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return 17 + 19*annotationTypePattern.hashCode(); + } + /* (non-Javadoc) * @see java.lang.Object#toString() */ public String toString() { StringBuffer buf = new StringBuffer(); buf.append("@within("); - buf.append(type.toString()); + buf.append(annotationTypePattern.toString()); buf.append(")"); return buf.toString(); } diff --git a/weaver/src/org/aspectj/weaver/patterns/WithinCodeAnnotationPointcut.java b/weaver/src/org/aspectj/weaver/patterns/WithinCodeAnnotationPointcut.java index 2ebff9be9..b28011718 100644 --- a/weaver/src/org/aspectj/weaver/patterns/WithinCodeAnnotationPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/WithinCodeAnnotationPointcut.java @@ -9,14 +9,26 @@ * ******************************************************************/ package org.aspectj.weaver.patterns; +import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import org.aspectj.bridge.ISourceLocation; +import org.aspectj.bridge.Message; import org.aspectj.util.FuzzyBoolean; +import org.aspectj.weaver.AnnotatedElement; +import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.IntMap; +import org.aspectj.weaver.Member; +import org.aspectj.weaver.NameMangler; +import org.aspectj.weaver.ResolvedMember; import org.aspectj.weaver.ResolvedTypeX; import org.aspectj.weaver.Shadow; +import org.aspectj.weaver.ShadowMunger; +import org.aspectj.weaver.TypeX; +import org.aspectj.weaver.ast.Literal; import org.aspectj.weaver.ast.Test; +import org.aspectj.weaver.ast.Var; /** * @author colyer @@ -26,37 +38,55 @@ import org.aspectj.weaver.ast.Test; */ public class WithinCodeAnnotationPointcut extends NameBindingPointcut { - private AnnotationTypePattern type; - /** - * - */ - public WithinCodeAnnotationPointcut(AnnotationTypePattern type) { + private ExactAnnotationTypePattern annotationTypePattern; + private ShadowMunger munger = null; // only set after concretization + + public WithinCodeAnnotationPointcut(ExactAnnotationTypePattern type) { super(); - this.type = type; + this.annotationTypePattern = type; + this.pointcutKind = Pointcut.ANNOTATION; + } + + public WithinCodeAnnotationPointcut(ExactAnnotationTypePattern type, ShadowMunger munger) { + this(type); + this.munger = munger; } /* (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; + AnnotatedElement toMatchAgainst = null; + Member member = shadow.getEnclosingCodeSignature(); + ResolvedMember rMember = member.resolve(shadow.getIWorld()); + + if (rMember == null) { + if (member.getName().startsWith(NameMangler.PREFIX)) { + return FuzzyBoolean.NO; + } + shadow.getIWorld().getLint().unresolvableMember.signal(member.toString(), getSourceLocation()); + return FuzzyBoolean.NO; + } + + toMatchAgainst = TypeX.forName(rMember.getSignature()).resolve(shadow.getIWorld()); + + return annotationTypePattern.matches(toMatchAgainst); } + /* (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 - + annotationTypePattern = (ExactAnnotationTypePattern) annotationTypePattern.resolveBindings(scope,bindings,true); + // must be either a Var, or an annotation type pattern } /* (non-Javadoc) @@ -71,34 +101,72 @@ public class WithinCodeAnnotationPointcut extends NameBindingPointcut { * @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; + ExactAnnotationTypePattern newType = (ExactAnnotationTypePattern) annotationTypePattern.remapAdviceFormals(bindings); + Pointcut ret = new WithinCodeAnnotationPointcut(newType, bindings.getEnclosingAdvice()); + ret.copyLocationFrom(this); + return ret; } /* (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; + + if (annotationTypePattern instanceof BindingAnnotationTypePattern) { + BindingAnnotationTypePattern btp = (BindingAnnotationTypePattern)annotationTypePattern; + TypeX annotationType = btp.annotationType; + Var var = shadow.getWithinCodeAnnotationVar(annotationType); + if (var == null) return Literal.FALSE; + // Check if we have already bound something to this formal + if (state.get(btp.getFormalIndex())!=null) { + ISourceLocation pcdSloc = getSourceLocation(); + ISourceLocation shadowSloc = shadow.getSourceLocation(); + Message errorMessage = new Message( + "Cannot use @pointcut to match at this location and bind a formal to type '"+var.getType()+ + "' - the formal is already bound to type '"+state.get(btp.getFormalIndex()).getType()+"'"+ + ". The secondary source location points to the problematic binding.", + shadowSloc,true,new ISourceLocation[]{pcdSloc}); + shadow.getIWorld().getMessageHandler().handleMessage(errorMessage); + state.setErroneousVar(btp.getFormalIndex()); + } + state.set(btp.getFormalIndex(),var); + } + return Literal.TRUE; } /* (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.ATWITHINCODE); + annotationTypePattern.write(s); + writeLocation(s); + } + public static Pointcut read(DataInputStream s, ISourceContext context) throws IOException { + AnnotationTypePattern type = AnnotationTypePattern.read(s, context); + WithinCodeAnnotationPointcut ret = new WithinCodeAnnotationPointcut((ExactAnnotationTypePattern)type); + ret.readLocation(context, s); + return ret; } - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - public String toString() { - StringBuffer buf = new StringBuffer(); + public boolean equals(Object other) { + if (!(other instanceof WithinCodeAnnotationPointcut)) return false; + WithinCodeAnnotationPointcut o = (WithinCodeAnnotationPointcut)other; + return o.annotationTypePattern.equals(this.annotationTypePattern); + } + + public int hashCode() { + int result = 17; + result = 23*result + annotationTypePattern.hashCode(); + return result; + } + + public String toString() { + StringBuffer buf = new StringBuffer(); buf.append("@withincode("); - buf.append(type.toString()); + buf.append(annotationTypePattern.toString()); buf.append(")"); return buf.toString(); - } + } } |