--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * ******************************************************************/
+
+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;
+
+/**
+ * @annotation(@Foo) or @annotation(foo)
+ *
+ * Matches any join point where the subject of the join point has an
+ * annotation matching the annotationTypePattern:
+ *
+ * Join Point Kind Subject
+ * ================================
+ * method call the target method
+ * method execution the method
+ * constructor call the constructor
+ * constructor execution the constructor
+ * get the target field
+ * set the target field
+ * adviceexecution the advice
+ * initialization the constructor
+ * preinitialization the constructor
+ * staticinitialization the type being initialized
+ * handler the declared type of the handled exception
+ */
+public class AnnotationPointcut extends NameBindingPointcut {
+
+ private ExactAnnotationTypePattern annotationTypePattern;
+ private ShadowMunger munger = null; // only set after concretization
+
+ public AnnotationPointcut(ExactAnnotationTypePattern type) {
+ super();
+ this.annotationTypePattern = type;
+ this.pointcutKind = Pointcut.ANNOTATION;
+ }
+
+ public AnnotationPointcut(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) {
+ if (info.getKind() == Shadow.StaticInitialization) {
+ return annotationTypePattern.matches(info.getType());
+ } else {
+ return FuzzyBoolean.MAYBE;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow)
+ */
+ public FuzzyBoolean match(Shadow shadow) {
+ AnnotatedElement toMatchAgainst = null;
+ Member member = shadow.getSignature();
+ 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;
+ }
+
+ Shadow.Kind kind = shadow.getKind();
+ if (kind == Shadow.StaticInitialization) {
+ toMatchAgainst = rMember.getType();
+ } else if ( (kind == Shadow.ExceptionHandler)) {
+ toMatchAgainst = TypeX.forName(rMember.getSignature()).resolve(shadow.getIWorld());
+ } else {
+ toMatchAgainst = rMember;
+ }
+
+ 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) {
+ annotationTypePattern = (ExactAnnotationTypePattern) annotationTypePattern.resolveBindings(scope,bindings,true);
+ // must be either a Var, or an annotation type pattern
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.Pointcut#resolveBindingsFromRTTI()
+ */
+ 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) {
+ ExactAnnotationTypePattern newType = (ExactAnnotationTypePattern) annotationTypePattern.remapAdviceFormals(bindings);
+ Pointcut ret = new AnnotationPointcut(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) {
+
+ if (annotationTypePattern instanceof BindingAnnotationTypePattern) {
+ BindingAnnotationTypePattern btp = (BindingAnnotationTypePattern)annotationTypePattern;
+ TypeX annotationType = btp.annotationType;
+ Var var = shadow.getKindedAnnotationVar(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 {
+ s.writeByte(Pointcut.ANNOTATION);
+ annotationTypePattern.write(s);
+ writeLocation(s);
+ }
+
+ public static Pointcut read(DataInputStream s, ISourceContext context) throws IOException {
+ AnnotationTypePattern type = AnnotationTypePattern.read(s, context);
+ AnnotationPointcut ret = new AnnotationPointcut((ExactAnnotationTypePattern)type);
+ ret.readLocation(context, s);
+ return ret;
+ }
+
+ public boolean equals(Object other) {
+ if (!(other instanceof AnnotationPointcut)) return false;
+ AnnotationPointcut o = (AnnotationPointcut)other;
+ return o.annotationTypePattern.equals(this.annotationTypePattern);
+ }
+
+ public int hashCode() {
+ int result = 17;
+ result = 37*result + annotationTypePattern.hashCode();
+ return result;
+ }
+
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ buf.append("@annotation(");
+ buf.append(annotationTypePattern.toString());
+ buf.append(")");
+ return buf.toString();
+ }
+
+}
+++ /dev/null
-/* *******************************************************************
- * Copyright (c) 2004 IBM Corporation.
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Common Public License v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * ******************************************************************/
-
-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.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;
-
-/**
- * A KindedAnnotationPointcut matches iff the kind of a join point
- * matches the kind of the pointcut (with no distinction between
- * method and constructor for call and execution), AND if the
- * member (field, method or constructor) has an annotation of the
- * given type.
- */
-public class KindedAnnotationPointcut extends NameBindingPointcut {
-
- private Shadow.Kind kind;
- private AnnotationTypePattern type;
- private ShadowMunger munger = null; // only set after concretization
-
- public KindedAnnotationPointcut(Shadow.Kind kind, AnnotationTypePattern type) {
- super();
- this.kind = kind;
- this.type = type;
- this.pointcutKind = Pointcut.ATKINDED;
- }
-
- public KindedAnnotationPointcut(Shadow.Kind kind, AnnotationTypePattern type, ShadowMunger munger) {
- this(kind,type);
- this.munger = munger;
- }
-
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.Pointcut#fastMatch(org.aspectj.weaver.patterns.FastMatchInfo)
- */
- public FuzzyBoolean fastMatch(FastMatchInfo info) {
- if (info.getKind() != null) {
- if (info.getKind() != kind) {
- // no distinction between method and constructors
- if ((info.getKind() == Shadow.ConstructorExecution) &&
- kind == Shadow.MethodExecution) {
- return FuzzyBoolean.MAYBE;
- }
- if ((info.getKind() == Shadow.ConstructorCall) &&
- kind == Shadow.MethodCall) {
- return FuzzyBoolean.MAYBE;
- }
- } else {
- return FuzzyBoolean.NO;
- }
- }
- return FuzzyBoolean.MAYBE;
- }
-
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow)
- */
- public FuzzyBoolean match(Shadow shadow) {
- if (!couldMatch(shadow)) return FuzzyBoolean.NO;
- Member member = shadow.getSignature();
- 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;
- }
- return type.matches(rMember);
- }
-
- private boolean couldMatch(Shadow shadow) {
- Shadow.Kind kindToMatch = shadow.getKind();
- if (kindToMatch == Shadow.ConstructorExecution) kindToMatch = Shadow.MethodExecution;
- if (kindToMatch == Shadow.ConstructorCall) kindToMatch = Shadow.MethodCall;
- return (kindToMatch == kind);
- }
-
- /* (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) {
- type = type.resolveBindings(scope,bindings,true);
- // must be either a Var, or an annotation type pattern
- }
-
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.Pointcut#resolveBindingsFromRTTI()
- */
- 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) {
- AnnotationTypePattern newType = type.remapAdviceFormals(bindings);
- Pointcut ret = new KindedAnnotationPointcut(kind, 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) {
- if (!couldMatch(shadow)) return Literal.FALSE;
-
- if (type instanceof BindingAnnotationTypePattern) {
- BindingAnnotationTypePattern btp = (BindingAnnotationTypePattern)type;
- TypeX annotationType = btp.annotationType;
- Var var = shadow.getKindedAnnotationVar(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 {
- s.writeByte(Pointcut.ATKINDED);
- kind.write(s);
- type.write(s);
- writeLocation(s);
- }
-
- public static Pointcut read(DataInputStream s, ISourceContext context) throws IOException {
- Shadow.Kind kind = Shadow.Kind.read(s);
- AnnotationTypePattern type = AnnotationTypePattern.read(s, context);
- KindedAnnotationPointcut ret = new KindedAnnotationPointcut(kind, type);
- ret.readLocation(context, s);
- return ret;
- }
-
- public boolean equals(Object other) {
- if (!(other instanceof KindedAnnotationPointcut)) return false;
- KindedAnnotationPointcut o = (KindedAnnotationPointcut)other;
- return o.kind == this.kind && o.type.equals(this.type);
- }
-
- public int hashCode() {
- int result = 17;
- result = 37*result + kind.hashCode();
- result = 37*result + type.hashCode();
- return result;
- }
-
- public String toString() {
- StringBuffer buf = new StringBuffer();
- buf.append(kind.getSimpleName());
- buf.append("(");
- buf.append(type.toString());
- buf.append(")");
- return buf.toString();
- }
-
-}
IToken t = tokenSource.peek();
String kind = parseIdentifier();
tokenSource.setIndex(start);
- if (kind.equals("execution") || kind.equals("call") ||
- kind.equals("get") || kind.equals("set") ||
- kind.equals("adviceexecution") ||
- kind.equals("initialization") ||
- kind.equals("preinitialization") ||
- kind.equals("staticinitialization")) {
- return parseKindedAnnotationPointcut();
+ if (kind.equals("annotation")) {
+ return parseAtAnnotationPointcut();
} else if (kind.equals("args")) {
return parseArgsAnnotationPointcut();
} else if (kind.equals("this") || kind.equals("target")) {
} throw new ParserException("@pointcut name expected, but found " + kind, t);
}
- private Pointcut parseKindedAnnotationPointcut() {
- String kind = parseIdentifier();
- Shadow.Kind shadowKind = null;
- if (kind.equals("execution")) {
- shadowKind = Shadow.MethodExecution; // also matches cons execution
- } else if (kind.equals("call")) {
- shadowKind = Shadow.MethodCall; // also matches cons call
- } else if (kind.equals("get")) {
- shadowKind = Shadow.FieldGet;
- } else if (kind.equals("set")) {
- shadowKind = Shadow.FieldSet;
- } else if (kind.equals("adviceexecution")) {
- shadowKind = Shadow.AdviceExecution;
- } else if (kind.equals("initialization")) {
- shadowKind = Shadow.Initialization;
- } else if (kind.equals("preinitialization")) {
- shadowKind = Shadow.PreInitialization;
- } else if (kind.equals("staticinitialization")) {
- shadowKind = Shadow.StaticInitialization;
- } else {
- throw new ParserException(("bad kind: " + kind), tokenSource.peek());
- }
+ private Pointcut parseAtAnnotationPointcut() {
+ parseIdentifier();
eat("(");
if (maybeEat(")")) {
- throw new ParserException("expecting @AnnotationName or parameter, but found ')'", tokenSource.peek());
+ throw new ParserException("@AnnotationName or parameter", tokenSource.peek());
}
- AnnotationTypePattern type = parseAnnotationNameOrVarTypePattern();
+ ExactAnnotationTypePattern type = parseAnnotationNameOrVarTypePattern();
eat(")");
- return new KindedAnnotationPointcut(shadowKind,type);
+ return new AnnotationPointcut(type);
}
// }
- protected AnnotationTypePattern parseAnnotationNameOrVarTypePattern() {
- AnnotationTypePattern p = null;
+ protected ExactAnnotationTypePattern parseAnnotationNameOrVarTypePattern() {
+ ExactAnnotationTypePattern p = null;
int startPos = tokenSource.peek().getStart();
if (maybeEat("@")) {
p = parseSimpleAnnotationName();
/**
* @return
*/
- private AnnotationTypePattern parseSimpleAnnotationName() {
+ private ExactAnnotationTypePattern parseSimpleAnnotationName() {
// the @ has already been eaten...
- AnnotationTypePattern p;
+ ExactAnnotationTypePattern p;
StringBuffer annotationName = new StringBuffer();
annotationName.append(parseIdentifier());
while (maybeEat(".")) {
public static final byte HANDLER = 13;
public static final byte IF_TRUE = 14;
public static final byte IF_FALSE = 15;
- public static final byte ATKINDED = 16;
+ public static final byte ANNOTATION = 16;
public static final byte NONE = 20;
case HANDLER: ret = HandlerPointcut.read(s, context); break;
case IF_TRUE: ret = IfPointcut.makeIfTruePointcut(RESOLVED); break;
case IF_FALSE: ret = IfPointcut.makeIfFalsePointcut(RESOLVED); break;
- case ATKINDED: ret = KindedAnnotationPointcut.read(s, context); break;
+ case ANNOTATION: ret = AnnotationPointcut.read(s, context); break;
case NONE: ret = makeMatchesNothing(RESOLVED); break;
default:
throw new BCException("unknown kind: " + kind);