### Eclipse Workspace Patch 1.0 #P org.aspectj.matcher Index: src/org/aspectj/weaver/patterns/TypePattern.java =================================================================== RCS file: /cvsroot/tools/org.aspectj/modules/org.aspectj.matcher/src/org/aspectj/weaver/patterns/TypePattern.java,v retrieving revision 1.1 diff -u -r1.1 TypePattern.java --- src/org/aspectj/weaver/patterns/TypePattern.java 22 Oct 2008 05:45:52 -0000 1.1 +++ src/org/aspectj/weaver/patterns/TypePattern.java 9 Dec 2008 19:24:29 -0000 @@ -10,7 +10,6 @@ * PARC initial implementation * ******************************************************************/ - package org.aspectj.weaver.patterns; import java.io.DataOutputStream; @@ -30,90 +29,98 @@ import org.aspectj.weaver.VersionedDataInputStream; import org.aspectj.weaver.WeaverMessages; import org.aspectj.weaver.World; + /** - * On creation, type pattern only contains WildTypePattern nodes, not BindingType or ExactType. + * On creation, type pattern only contains WildTypePattern nodes, not BindingType or ExactType. + * + *

+ * Then we call resolveBindings() during compilation During concretization of enclosing pointcuts, we call remapAdviceFormals * - *

Then we call resolveBindings() during compilation - * During concretization of enclosing pointcuts, we call remapAdviceFormals - * * @author Erik Hilsdale * @author Jim Hugunin */ public abstract class TypePattern extends PatternNode { public static class MatchKind { private String name; - public MatchKind(String name) { this.name = name; } - public String toString() { return name; } + + public MatchKind(String name) { + this.name = name; + } + + public String toString() { + return name; + } } - + public static final MatchKind STATIC = new MatchKind("STATIC"); public static final MatchKind DYNAMIC = new MatchKind("DYNAMIC"); - + public static final TypePattern ELLIPSIS = new EllipsisTypePattern(); public static final TypePattern ANY = new AnyTypePattern(); public static final TypePattern NO = new NoTypePattern(); - - + protected boolean includeSubtypes; protected boolean isVarArgs = false; protected AnnotationTypePattern annotationPattern = AnnotationTypePattern.ANY; protected TypePatternList typeParameters = TypePatternList.EMPTY; - - protected TypePattern(boolean includeSubtypes,boolean isVarArgs,TypePatternList typeParams) { + + protected TypePattern(boolean includeSubtypes, boolean isVarArgs, TypePatternList typeParams) { this.includeSubtypes = includeSubtypes; this.isVarArgs = isVarArgs; this.typeParameters = (typeParams == null ? TypePatternList.EMPTY : typeParams); } - + protected TypePattern(boolean includeSubtypes, boolean isVarArgs) { - this(includeSubtypes,isVarArgs,null); + this(includeSubtypes, isVarArgs, null); } - public AnnotationTypePattern getAnnotationPattern() { - return annotationPattern; - } + public AnnotationTypePattern getAnnotationPattern() { + return annotationPattern; + } - public boolean isVarArgs() { - return isVarArgs; - } + public boolean isVarArgs() { + return isVarArgs; + } public boolean isStarAnnotation() { return annotationPattern == AnnotationTypePattern.ANY; } - + public boolean isArray() { return false; } - + protected TypePattern(boolean includeSubtypes) { - this(includeSubtypes,false); + this(includeSubtypes, false); } - + public void setAnnotationTypePattern(AnnotationTypePattern annPatt) { this.annotationPattern = annPatt; } - + public void setTypeParameters(TypePatternList typeParams) { this.typeParameters = typeParams; } - + public TypePatternList getTypeParameters() { return this.typeParameters; } - + public void setIsVarArgs(boolean isVarArgs) { this.isVarArgs = isVarArgs; } - + // answer conservatively... protected boolean couldEverMatchSameTypesAs(TypePattern other) { - if (this.includeSubtypes || other.includeSubtypes) return true; - if (this.annotationPattern != AnnotationTypePattern.ANY) return true; - if (other.annotationPattern != AnnotationTypePattern.ANY) return true; + if (this.includeSubtypes || other.includeSubtypes) + return true; + if (this.annotationPattern != AnnotationTypePattern.ANY) + return true; + if (other.annotationPattern != AnnotationTypePattern.ANY) + return true; return false; } - - //XXX non-final for Not, && and || + public boolean matchesStatically(ResolvedType type) { if (includeSubtypes) { return matchesSubtypes(type); @@ -121,64 +128,68 @@ return matchesExactly(type); } } - public abstract FuzzyBoolean matchesInstanceof(ResolvedType type); - + + public abstract FuzzyBoolean matchesInstanceof(ResolvedType type); + public final FuzzyBoolean matches(ResolvedType type, MatchKind kind) { -// FuzzyBoolean typeMatch = null; - //??? This is part of gracefully handling missing references - if (type.isMissing()) return FuzzyBoolean.NO; - + // FuzzyBoolean typeMatch = null; + // ??? This is part of gracefully handling missing references + if (type.isMissing()) + return FuzzyBoolean.NO; + if (kind == STATIC) { -// typeMatch = FuzzyBoolean.fromBoolean(matchesStatically(type)); -// return typeMatch.and(annotationPattern.matches(type)); - return FuzzyBoolean.fromBoolean(matchesStatically(type)); + // typeMatch = FuzzyBoolean.fromBoolean(matchesStatically(type)); + // return typeMatch.and(annotationPattern.matches(type)); + return FuzzyBoolean.fromBoolean(matchesStatically(type)); } else if (kind == DYNAMIC) { - //System.err.println("matching: " + this + " with " + type); -// typeMatch = matchesInstanceof(type); - //System.err.println(" got: " + ret); -// return typeMatch.and(annotationPattern.matches(type)); - return matchesInstanceof(type); + // System.err.println("matching: " + this + " with " + type); + // typeMatch = matchesInstanceof(type); + // System.err.println(" got: " + ret); + // return typeMatch.and(annotationPattern.matches(type)); + return matchesInstanceof(type); } else { throw new IllegalArgumentException("kind must be DYNAMIC or STATIC"); } } - + protected abstract boolean matchesExactly(ResolvedType type); - + protected abstract boolean matchesExactly(ResolvedType type, ResolvedType annotatedType); protected boolean matchesSubtypes(ResolvedType type) { - //System.out.println("matching: " + this + " to " + type); + // System.out.println("matching: " + this + " to " + type); if (matchesExactly(type)) { - //System.out.println(" true"); + // System.out.println(" true"); return true; } // pr124808 Iterator typesIterator = null; if (type.isTypeVariableReference()) { - typesIterator = ((TypeVariableReference)type).getTypeVariable().getFirstBound().resolve(type.getWorld()).getDirectSupertypes(); + typesIterator = ((TypeVariableReference) type).getTypeVariable().getFirstBound().resolve(type.getWorld()) + .getDirectSupertypes(); } else { - // pr223605 - if (type.isRawType()) { - type = type.getGenericType(); - } - typesIterator = type.getDirectSupertypes(); + // pr223605 + if (type.isRawType()) { + type = type.getGenericType(); + } + typesIterator = type.getDirectSupertypes(); } - + // FuzzyBoolean ret = FuzzyBoolean.NO; // ??? -eh - for (Iterator i = typesIterator; i.hasNext(); ) { - ResolvedType superType = (ResolvedType)i.next(); + for (Iterator i = typesIterator; i.hasNext();) { + ResolvedType supertype = (ResolvedType) i.next(); // TODO asc generics, temporary whilst matching isnt aware.. - //if (superType.isParameterizedType()) superType = superType.getRawType().resolve(superType.getWorld()); - if (matchesSubtypes(superType,type)) return true; + // if (superType.isParameterizedType()) superType = superType.getRawType().resolve(superType.getWorld()); + if (matchesSubtypes(supertype, type)) + return true; } return false; } - + protected boolean matchesSubtypes(ResolvedType superType, ResolvedType annotatedType) { - //System.out.println("matching: " + this + " to " + type); - if (matchesExactly(superType,annotatedType)) { - //System.out.println(" true"); + // System.out.println("matching: " + this + " to " + type); + if (matchesExactly(superType, annotatedType)) { + // System.out.println(" true"); return true; } // If an ITD is applied, it will be put onto the generic type, not the parameterized or raw form @@ -186,95 +197,94 @@ superType = superType.getGenericType(); } // FuzzyBoolean ret = FuzzyBoolean.NO; // ??? -eh - for (Iterator i = superType.getDirectSupertypes(); i.hasNext(); ) { - ResolvedType superSuperType = (ResolvedType)i.next(); - if (matchesSubtypes(superSuperType,annotatedType)) return true; + for (Iterator i = superType.getDirectSupertypes(); i.hasNext();) { + ResolvedType superSuperType = (ResolvedType) i.next(); + if (matchesSubtypes(superSuperType, annotatedType)) + return true; } return false; } - + public UnresolvedType resolveExactType(IScope scope, Bindings bindings) { TypePattern p = resolveBindings(scope, bindings, false, true); - if (!(p instanceof ExactTypePattern)) return ResolvedType.MISSING; - return ((ExactTypePattern)p).getType(); + if (!(p instanceof ExactTypePattern)) + return ResolvedType.MISSING; + return ((ExactTypePattern) p).getType(); } - + public UnresolvedType getExactType() { - if (this instanceof ExactTypePattern) return ((ExactTypePattern)this).getType(); - else return ResolvedType.MISSING; + if (this instanceof ExactTypePattern) + return ((ExactTypePattern) this).getType(); + else + return ResolvedType.MISSING; } - + protected TypePattern notExactType(IScope s) { - s.getMessageHandler().handleMessage(MessageUtil.error( - WeaverMessages.format(WeaverMessages.EXACT_TYPE_PATTERN_REQD), getSourceLocation())); + s.getMessageHandler().handleMessage( + MessageUtil.error(WeaverMessages.format(WeaverMessages.EXACT_TYPE_PATTERN_REQD), getSourceLocation())); return NO; } - -// public boolean assertExactType(IMessageHandler m) { -// if (this instanceof ExactTypePattern) return true; -// -// //XXX should try harder to avoid multiple errors for one problem -// m.handleMessage(MessageUtil.error("exact type pattern required", getSourceLocation())); -// return false; -// } + + // public boolean assertExactType(IMessageHandler m) { + // if (this instanceof ExactTypePattern) return true; + // + // //XXX should try harder to avoid multiple errors for one problem + // m.handleMessage(MessageUtil.error("exact type pattern required", getSourceLocation())); + // return false; + // } /** * This can modify in place, or return a new TypePattern if the type changes. */ - public TypePattern resolveBindings(IScope scope, Bindings bindings, - boolean allowBinding, boolean requireExactType) - { - annotationPattern = annotationPattern.resolveBindings(scope,bindings,allowBinding); - return this; - } - - public void resolve(World world) { - annotationPattern.resolve(world); - } - - /** - * return a version of this type pattern in which all type variable references have been - * replaced by their corresponding entry in the map. - */ - public abstract TypePattern parameterizeWith(Map typeVariableMap,World w); - + public TypePattern resolveBindings(IScope scope, Bindings bindings, boolean allowBinding, boolean requireExactType) { + annotationPattern = annotationPattern.resolveBindings(scope, bindings, allowBinding); + return this; + } + + public void resolve(World world) { + annotationPattern.resolve(world); + } + + /** + * return a version of this type pattern in which all type variable references have been replaced by their corresponding entry + * in the map. + */ + public abstract TypePattern parameterizeWith(Map typeVariableMap, World w); + public void postRead(ResolvedType enclosingType) { } - + public boolean isStar() { return false; } - - - /** - * This is called during concretization of pointcuts, it is used by BindingTypePattern - * to return a new BindingTypePattern with a formal index appropiate for the advice, - * rather than for the lexical declaration, i.e. this handles transforamtions through - * named pointcuts. - *

-     * pointcut foo(String name): args(name);
-     * --> This makes a BindingTypePattern(0) pointing to the 0th formal
-     * 
-     * before(Foo f, String n): this(f) && foo(n) { ... }
-     * --> when resolveReferences is called on the args from the above, it
-     *     will return a BindingTypePattern(1)
-     * 
-     * before(Foo f): this(f) && foo(*) { ... }
-     * --> when resolveReferences is called on the args from the above, it
-     *     will return an ExactTypePattern(String)
-     * 
- */ + /** + * This is called during concretization of pointcuts, it is used by BindingTypePattern to return a new BindingTypePattern with a + * formal index appropiate for the advice, rather than for the lexical declaration, i.e. this handles transforamtions through + * named pointcuts. + * + *
+	 * pointcut foo(String name): args(name);
+	 * --> This makes a BindingTypePattern(0) pointing to the 0th formal
+	 * 
+	 * before(Foo f, String n): this(f) && foo(n) { ... }
+	 * --> when resolveReferences is called on the args from the above, it
+	 *     will return a BindingTypePattern(1)
+	 * 
+	 * before(Foo f): this(f) && foo(*) { ... }
+	 * --> when resolveReferences is called on the args from the above, it
+	 *     will return an ExactTypePattern(String)
+	 * 
+ */ public TypePattern remapAdviceFormals(IntMap bindings) { return this; } - public static final byte WILD = 1; public static final byte EXACT = 2; public static final byte BINDING = 3; - public static final byte ELLIPSIS_KEY = 4; - public static final byte ANY_KEY = 5; + public static final byte ELLIPSIS_KEY = 4; + public static final byte ANY_KEY = 5; public static final byte NOT = 6; public static final byte OR = 7; public static final byte AND = 8; @@ -284,18 +294,29 @@ public static TypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException { byte key = s.readByte(); - switch(key) { - case WILD: return WildTypePattern.read(s, context); - case EXACT: return ExactTypePattern.read(s, context); - case BINDING: return BindingTypePattern.read(s, context); - case ELLIPSIS_KEY: return ELLIPSIS; - case ANY_KEY: return ANY; - case NO_KEY: return NO; - case NOT: return NotTypePattern.read(s, context); - case OR: return OrTypePattern.read(s, context); - case AND: return AndTypePattern.read(s, context); - case ANY_WITH_ANNO: return AnyWithAnnotationTypePattern.read(s,context); - case HAS_MEMBER: return HasMemberTypePattern.read(s,context); + switch (key) { + case WILD: + return WildTypePattern.read(s, context); + case EXACT: + return ExactTypePattern.read(s, context); + case BINDING: + return BindingTypePattern.read(s, context); + case ELLIPSIS_KEY: + return ELLIPSIS; + case ANY_KEY: + return ANY; + case NO_KEY: + return NO; + case NOT: + return NotTypePattern.read(s, context); + case OR: + return OrTypePattern.read(s, context); + case AND: + return AndTypePattern.read(s, context); + case ANY_WITH_ANNO: + return AnyWithAnnotationTypePattern.read(s, context); + case HAS_MEMBER: + return HasMemberTypePattern.read(s, context); } throw new BCException("unknown TypePattern kind: " + key); } @@ -307,28 +328,32 @@ } class EllipsisTypePattern extends TypePattern { - + /** * Constructor for EllipsisTypePattern. + * * @param includeSubtypes */ public EllipsisTypePattern() { - super(false,false,new TypePatternList()); + super(false, false, new TypePatternList()); } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.aspectj.weaver.patterns.TypePattern#couldEverMatchSameTypesAs(org.aspectj.weaver.patterns.TypePattern) */ protected boolean couldEverMatchSameTypesAs(TypePattern other) { return true; } + /** * @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType) */ protected boolean matchesExactly(ResolvedType type) { return false; } - + protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) { return false; } @@ -346,50 +371,59 @@ public void write(DataOutputStream s) throws IOException { s.writeByte(ELLIPSIS_KEY); } - - public String toString() { return ".."; } - - /* (non-Javadoc) + + public String toString() { + return ".."; + } + + /* + * (non-Javadoc) + * * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object obj) { return (obj instanceof EllipsisTypePattern); } - - /* (non-Javadoc) + + /* + * (non-Javadoc) + * * @see java.lang.Object#hashCode() */ public int hashCode() { return 17 * 37; } - public Object accept(PatternNodeVisitor visitor, Object data) { - return visitor.visit(this, data); - } - - public TypePattern parameterizeWith(Map typeVariableMap,World w) { - return this; - } + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this, data); + } + public TypePattern parameterizeWith(Map typeVariableMap, World w) { + return this; + } } class AnyTypePattern extends TypePattern { - + /** * Constructor for EllipsisTypePattern. + * * @param includeSubtypes */ public AnyTypePattern() { - super(false,false,new TypePatternList()); + super(false, false, new TypePatternList()); } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.aspectj.weaver.patterns.TypePattern#couldEverMatchSameTypesAs(org.aspectj.weaver.patterns.TypePattern) */ protected boolean couldEverMatchSameTypesAs(TypePattern other) { return true; } + /** * @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType) */ @@ -400,7 +434,7 @@ protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) { return true; } - + /** * @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(IType) */ @@ -418,56 +452,55 @@ /** * @see org.aspectj.weaver.patterns.TypePattern#matches(IType, MatchKind) */ -// public FuzzyBoolean matches(IType type, MatchKind kind) { -// return FuzzyBoolean.YES; -// } - + // public FuzzyBoolean matches(IType type, MatchKind kind) { + // return FuzzyBoolean.YES; + // } /** * @see org.aspectj.weaver.patterns.TypePattern#matchesSubtypes(IType) */ protected boolean matchesSubtypes(ResolvedType type) { return true; } - - + public boolean isStar() { return true; } - - public String toString() { return "*"; } - + + public String toString() { + return "*"; + } + public boolean equals(Object obj) { return (obj instanceof AnyTypePattern); } - + public int hashCode() { return 37; } - public Object accept(PatternNodeVisitor visitor, Object data) { - return visitor.visit(this, data); - } - - public TypePattern parameterizeWith(Map arg0,World w) { - return this; - } + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this, data); + } + + public TypePattern parameterizeWith(Map arg0, World w) { + return this; + } } /** - * This type represents a type pattern of '*' but with an annotation specified, - * e.g. '@Color *' + * This type represents a type pattern of '*' but with an annotation specified, e.g. '@Color *' */ class AnyWithAnnotationTypePattern extends TypePattern { - + public AnyWithAnnotationTypePattern(AnnotationTypePattern atp) { - super(false,false); + super(false, false); annotationPattern = atp; } public Object accept(PatternNodeVisitor visitor, Object data) { - return visitor.visit(this,data); + return visitor.visit(this, data); } - + protected boolean couldEverMatchSameTypesAs(TypePattern other) { return true; } @@ -475,18 +508,71 @@ protected boolean matchesExactly(ResolvedType type) { annotationPattern.resolve(type.getWorld()); boolean b = false; - if (type.temporaryAnnotationTypes!=null) { - b = annotationPattern.matches(type,type.temporaryAnnotationTypes).alwaysTrue(); + if (type.temporaryAnnotationTypes != null) { + b = annotationPattern.matches(type, type.temporaryAnnotationTypes).alwaysTrue(); } else { b = annotationPattern.matches(type).alwaysTrue(); } return b; } - - + + /** + * Coming in here means we are looking at a pattern like "(@SomeAnnotation *)+" - so a type or any subtype that has the + * annotation SomeAnnotation (pr128664). + * + * If we are matching on some type X, we first see if X is an exact match for our pattern. Then we look at the direct supertypes + * of X. The variant matchSubtypes() that involves two parameters is for when the type to match is different to the type against + * which the annotations are stored. This happens for parameter annotations where, temporarily during matching, the + * annotatedType is marked with any parameter annotations it has. That doesn't apply in the case we are dealing with here + * (AnyWithAnnotationTypePattern) + * + */ + protected boolean matchesSubtypes(ResolvedType type) { + if (matchesExactly(type)) { + return true; + } + // pr124808 + Iterator typesIterator = null; + if (type.isTypeVariableReference()) { + typesIterator = ((TypeVariableReference) type).getTypeVariable().getFirstBound().resolve(type.getWorld()) + .getDirectSupertypes(); + } else { + // pr223605 + if (type.isRawType()) { + type = type.getGenericType(); + } + typesIterator = type.getDirectSupertypes(); + } + + for (Iterator i = typesIterator; i.hasNext();) { + ResolvedType supertype = (ResolvedType) i.next(); + if (matchesSubtypes(supertype, supertype)) { + return true; + } + } + return false; + } + + protected boolean matchesSubtypes(ResolvedType superType, ResolvedType annotatedType) { + if (matchesExactly(superType, annotatedType)) { + return true; + } + // If an ITD is applied, it will be put onto the generic type, not the parameterized or raw form + if (superType.isParameterizedType() || superType.isRawType()) { + superType = superType.getGenericType(); + } + // FuzzyBoolean ret = FuzzyBoolean.NO; // ??? -eh + for (Iterator i = superType.getDirectSupertypes(); i.hasNext();) { + ResolvedType superSuperType = (ResolvedType) i.next(); + if (matchesSubtypes(superSuperType, superSuperType)) + return true; + } + return false; + } + protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) { annotationPattern.resolve(type.getWorld()); - return annotationPattern.matches(annotatedType).alwaysTrue(); + return annotationPattern.matches(annotatedType).alwaysTrue(); } public FuzzyBoolean matchesInstanceof(ResolvedType type) { @@ -496,70 +582,74 @@ return FuzzyBoolean.MAYBE; } - public TypePattern parameterizeWith(Map typeVariableMap,World w) { - AnyWithAnnotationTypePattern ret = new AnyWithAnnotationTypePattern(this.annotationPattern.parameterizeWith(typeVariableMap,w)); + public TypePattern parameterizeWith(Map typeVariableMap, World w) { + AnyWithAnnotationTypePattern ret = new AnyWithAnnotationTypePattern(this.annotationPattern.parameterizeWith( + typeVariableMap, w)); ret.copyLocationFrom(this); return ret; } - + public void write(DataOutputStream s) throws IOException { s.writeByte(TypePattern.ANY_WITH_ANNO); annotationPattern.write(s); writeLocation(s); + s.writeBoolean(includeSubtypes); } - - public static TypePattern read(VersionedDataInputStream s,ISourceContext c) throws IOException { - AnnotationTypePattern annPatt = AnnotationTypePattern.read(s,c); - AnyWithAnnotationTypePattern ret = new AnyWithAnnotationTypePattern(annPatt); - ret.readLocation(c, s); - return ret; + + public static TypePattern read(VersionedDataInputStream s, ISourceContext c) throws IOException { + AnnotationTypePattern annPatt = AnnotationTypePattern.read(s, c); + AnyWithAnnotationTypePattern ret = new AnyWithAnnotationTypePattern(annPatt); + ret.readLocation(c, s); + ret.includeSubtypes = s.readBoolean(); + return ret; } -// public FuzzyBoolean matches(IType type, MatchKind kind) { -// return FuzzyBoolean.YES; -// } + // public FuzzyBoolean matches(IType type, MatchKind kind) { + // return FuzzyBoolean.YES; + // } - protected boolean matchesSubtypes(ResolvedType type) { - return true; - } - public boolean isStar() { return false; } - - public String toString() { return annotationPattern+" *"; } - + + public String toString() { + return annotationPattern + " *"; + } + public boolean equals(Object obj) { - if (!(obj instanceof AnyWithAnnotationTypePattern)) return false; + if (!(obj instanceof AnyWithAnnotationTypePattern)) + return false; AnyWithAnnotationTypePattern awatp = (AnyWithAnnotationTypePattern) obj; return (annotationPattern.equals(awatp.annotationPattern)); } - + public int hashCode() { return annotationPattern.hashCode(); } } class NoTypePattern extends TypePattern { - + public NoTypePattern() { - super(false,false,new TypePatternList()); + super(false, false, new TypePatternList()); } - - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.aspectj.weaver.patterns.TypePattern#couldEverMatchSameTypesAs(org.aspectj.weaver.patterns.TypePattern) */ protected boolean couldEverMatchSameTypesAs(TypePattern other) { return false; } + /** * @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType) */ protected boolean matchesExactly(ResolvedType type) { return false; } - + protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) { return false; } @@ -581,44 +671,47 @@ /** * @see org.aspectj.weaver.patterns.TypePattern#matches(IType, MatchKind) */ -// public FuzzyBoolean matches(IType type, MatchKind kind) { -// return FuzzyBoolean.YES; -// } - + // public FuzzyBoolean matches(IType type, MatchKind kind) { + // return FuzzyBoolean.YES; + // } /** * @see org.aspectj.weaver.patterns.TypePattern#matchesSubtypes(IType) */ protected boolean matchesSubtypes(ResolvedType type) { return false; } - - + public boolean isStar() { return false; } - - public String toString() { return ""; }//FIXME AV - bad! toString() cannot be parsed back (not idempotent) - - /* (non-Javadoc) + + public String toString() { + return ""; + }// FIXME AV - bad! toString() cannot be parsed back (not idempotent) + + /* + * (non-Javadoc) + * * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object obj) { return (obj instanceof NoTypePattern); } - - /* (non-Javadoc) + + /* + * (non-Javadoc) + * * @see java.lang.Object#hashCode() */ public int hashCode() { return 17 * 37 * 37; } - public Object accept(PatternNodeVisitor visitor, Object data) { - return visitor.visit(this, data); - } - - public TypePattern parameterizeWith(Map arg0,World w) { - return this; - } -} + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this, data); + } + public TypePattern parameterizeWith(Map arg0, World w) { + return this; + } +} Index: src/org/aspectj/weaver/patterns/SignaturePattern.java =================================================================== RCS file: /cvsroot/tools/org.aspectj/modules/org.aspectj.matcher/src/org/aspectj/weaver/patterns/SignaturePattern.java,v retrieving revision 1.1 diff -u -r1.1 SignaturePattern.java --- src/org/aspectj/weaver/patterns/SignaturePattern.java 22 Oct 2008 05:45:52 -0000 1.1 +++ src/org/aspectj/weaver/patterns/SignaturePattern.java 9 Dec 2008 19:24:29 -0000 @@ -10,7 +10,6 @@ * PARC initial implementation * ******************************************************************/ - package org.aspectj.weaver.patterns; import java.io.DataOutputStream; @@ -25,7 +24,7 @@ import org.aspectj.bridge.ISourceLocation; import org.aspectj.util.FuzzyBoolean; -import org.aspectj.weaver.AjAttribute; +import org.aspectj.weaver.AjAttribute; import org.aspectj.weaver.AjcMemberMaker; import org.aspectj.weaver.AnnotationTargetKind; import org.aspectj.weaver.ConcreteTypeMunger; @@ -40,23 +39,19 @@ import org.aspectj.weaver.VersionedDataInputStream; import org.aspectj.weaver.World; - public class SignaturePattern extends PatternNode { private MemberKind kind; private ModifiersPattern modifiers; private TypePattern returnType; - private TypePattern declaringType; + private TypePattern declaringType; private NamePattern name; - private TypePatternList parameterTypes; - private ThrowsPattern throwsPattern; - private AnnotationTypePattern annotationPattern; - private transient int hashcode = -1; - - public SignaturePattern(MemberKind kind, ModifiersPattern modifiers, - TypePattern returnType, TypePattern declaringType, - NamePattern name, TypePatternList parameterTypes, - ThrowsPattern throwsPattern, - AnnotationTypePattern annotationPattern) { + private TypePatternList parameterTypes; + private ThrowsPattern throwsPattern; + private AnnotationTypePattern annotationPattern; + private transient int hashcode = -1; + + public SignaturePattern(MemberKind kind, ModifiersPattern modifiers, TypePattern returnType, TypePattern declaringType, + NamePattern name, TypePatternList parameterTypes, ThrowsPattern throwsPattern, AnnotationTypePattern annotationPattern) { this.kind = kind; this.modifiers = modifiers; this.returnType = returnType; @@ -66,84 +61,84 @@ this.throwsPattern = throwsPattern; this.annotationPattern = annotationPattern; } - - - public SignaturePattern resolveBindings(IScope scope, Bindings bindings) { + + public SignaturePattern resolveBindings(IScope scope, Bindings bindings) { if (returnType != null) { returnType = returnType.resolveBindings(scope, bindings, false, false); - checkForIncorrectTargetKind(returnType,scope,false); - } + checkForIncorrectTargetKind(returnType, scope, false); + } if (declaringType != null) { declaringType = declaringType.resolveBindings(scope, bindings, false, false); - checkForIncorrectTargetKind(declaringType,scope,false); + checkForIncorrectTargetKind(declaringType, scope, false); } if (parameterTypes != null) { parameterTypes = parameterTypes.resolveBindings(scope, bindings, false, false); - checkForIncorrectTargetKind(parameterTypes,scope,false,true); + checkForIncorrectTargetKind(parameterTypes, scope, false, true); } if (throwsPattern != null) { throwsPattern = throwsPattern.resolveBindings(scope, bindings); - if (throwsPattern.getForbidden().getTypePatterns().length > 0 + if (throwsPattern.getForbidden().getTypePatterns().length > 0 || throwsPattern.getRequired().getTypePatterns().length > 0) { - checkForIncorrectTargetKind(throwsPattern,scope,false); + checkForIncorrectTargetKind(throwsPattern, scope, false); } } if (annotationPattern != null) { - annotationPattern = annotationPattern.resolveBindings(scope,bindings,false); - checkForIncorrectTargetKind(annotationPattern,scope,true); + annotationPattern = annotationPattern.resolveBindings(scope, bindings, false); + checkForIncorrectTargetKind(annotationPattern, scope, true); } - hashcode =-1; - return this; - } - private void checkForIncorrectTargetKind(PatternNode patternNode, IScope scope, boolean targetsOtherThanTypeAllowed) { - checkForIncorrectTargetKind(patternNode, scope, targetsOtherThanTypeAllowed, false); - - } - - // bug 115252 - adding an xlint warning if the annnotation target type is - // wrong. This logic, or similar, may have to be applied elsewhere in the case - // of pointcuts which don't go through SignaturePattern.resolveBindings(..) - private void checkForIncorrectTargetKind(PatternNode patternNode, IScope scope, boolean targetsOtherThanTypeAllowed, boolean parameterTargettingAnnotationsAllowed) { - // return if we're not in java5 mode, if the unmatchedTargetKind Xlint - // warning has been turned off, or if the patternNode is * - if (!scope.getWorld().isInJava5Mode() - || scope.getWorld().getLint().unmatchedTargetKind == null - || (patternNode instanceof AnyTypePattern)) { + hashcode = -1; + return this; + } + + private void checkForIncorrectTargetKind(PatternNode patternNode, IScope scope, boolean targetsOtherThanTypeAllowed) { + checkForIncorrectTargetKind(patternNode, scope, targetsOtherThanTypeAllowed, false); + + } + + // bug 115252 - adding an xlint warning if the annnotation target type is + // wrong. This logic, or similar, may have to be applied elsewhere in the case + // of pointcuts which don't go through SignaturePattern.resolveBindings(..) + private void checkForIncorrectTargetKind(PatternNode patternNode, IScope scope, boolean targetsOtherThanTypeAllowed, + boolean parameterTargettingAnnotationsAllowed) { + // return if we're not in java5 mode, if the unmatchedTargetKind Xlint + // warning has been turned off, or if the patternNode is * + if (!scope.getWorld().isInJava5Mode() || scope.getWorld().getLint().unmatchedTargetKind == null + || (patternNode instanceof AnyTypePattern)) { return; } if (patternNode instanceof ExactAnnotationTypePattern) { - ResolvedType resolvedType = ((ExactAnnotationTypePattern)patternNode).getAnnotationType().resolve(scope.getWorld()); + ResolvedType resolvedType = ((ExactAnnotationTypePattern) patternNode).getAnnotationType().resolve(scope.getWorld()); if (targetsOtherThanTypeAllowed) { AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds(); - if (targetKinds == null) return; - reportUnmatchedTargetKindMessage(targetKinds,patternNode,scope,true); + if (targetKinds == null) + return; + reportUnmatchedTargetKindMessage(targetKinds, patternNode, scope, true); } else if (!targetsOtherThanTypeAllowed && !resolvedType.canAnnotationTargetType()) { // everything is incorrect since we've already checked whether we have the TYPE target annotation AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds(); - if (targetKinds == null) return; - reportUnmatchedTargetKindMessage(targetKinds,patternNode,scope,false); + if (targetKinds == null) + return; + reportUnmatchedTargetKindMessage(targetKinds, patternNode, scope, false); } } else { - TypePatternVisitor visitor = new TypePatternVisitor(scope,targetsOtherThanTypeAllowed,parameterTargettingAnnotationsAllowed); - patternNode.traverse(visitor,null); + TypePatternVisitor visitor = new TypePatternVisitor(scope, targetsOtherThanTypeAllowed, + parameterTargettingAnnotationsAllowed); + patternNode.traverse(visitor, null); if (visitor.containedIncorrectTargetKind()) { - Set keys = visitor.getIncorrectTargetKinds().keySet(); + Set keys = visitor.getIncorrectTargetKinds().keySet(); for (Iterator iter = keys.iterator(); iter.hasNext();) { - PatternNode node = (PatternNode)iter.next(); - AnnotationTargetKind[] targetKinds = (AnnotationTargetKind[]) visitor.getIncorrectTargetKinds().get(node); - reportUnmatchedTargetKindMessage(targetKinds,node,scope,false); + PatternNode node = (PatternNode) iter.next(); + AnnotationTargetKind[] targetKinds = (AnnotationTargetKind[]) visitor.getIncorrectTargetKinds().get(node); + reportUnmatchedTargetKindMessage(targetKinds, node, scope, false); } } } - } - - private void reportUnmatchedTargetKindMessage( - AnnotationTargetKind[] annotationTargetKinds, - PatternNode node, - IScope scope, - boolean checkMatchesMemberKindName) { - StringBuffer targetNames = new StringBuffer("{"); - for (int i = 0; i < annotationTargetKinds.length; i++) { + } + + private void reportUnmatchedTargetKindMessage(AnnotationTargetKind[] annotationTargetKinds, PatternNode node, IScope scope, + boolean checkMatchesMemberKindName) { + StringBuffer targetNames = new StringBuffer("{"); + for (int i = 0; i < annotationTargetKinds.length; i++) { AnnotationTargetKind targetKind = annotationTargetKinds[i]; if (checkMatchesMemberKindName && kind.getName().equals(targetKind.getName())) { return; @@ -154,112 +149,112 @@ targetNames.append("ElementType." + targetKind.getName() + "}"); } } - scope.getWorld().getLint().unmatchedTargetKind.signal(new String[] {node.toString(),targetNames.toString()}, getSourceLocation(), new ISourceLocation[0]); - } - - /** - * Class which visits the nodes in the TypePattern tree until an - * ExactTypePattern is found. Once this is found it creates a new - * ExactAnnotationTypePattern and checks whether the targetKind - * (created via the @Target annotation) matches ElementType.TYPE if - * this is the only target kind which is allowed, or matches the - * signature pattern kind if there is no restriction. - */ - private class TypePatternVisitor extends AbstractPatternNodeVisitor { - - private IScope scope; - private Map incorrectTargetKinds /* PatternNode -> AnnotationTargetKind[] */ = new HashMap(); - private boolean targetsOtherThanTypeAllowed; + scope.getWorld().getLint().unmatchedTargetKind.signal(new String[] { node.toString(), targetNames.toString() }, + getSourceLocation(), new ISourceLocation[0]); + } + + /** + * Class which visits the nodes in the TypePattern tree until an ExactTypePattern is found. Once this is found it creates a new + * ExactAnnotationTypePattern and checks whether the targetKind (created via the @Target annotation) matches ElementType.TYPE if + * this is the only target kind which is allowed, or matches the signature pattern kind if there is no restriction. + */ + private class TypePatternVisitor extends AbstractPatternNodeVisitor { + + private IScope scope; + private Map incorrectTargetKinds /* PatternNode -> AnnotationTargetKind[] */= new HashMap(); + private boolean targetsOtherThanTypeAllowed; private boolean parameterTargettingAnnotationsAllowed; - /** - * @param requiredTarget - the signature pattern Kind - * @param scope - * @param parameterTargettingAnnotationsAllowed - */ - public TypePatternVisitor(IScope scope, boolean targetsOtherThanTypeAllowed, boolean parameterTargettingAnnotationsAllowed) { - this.scope = scope; - this.targetsOtherThanTypeAllowed = targetsOtherThanTypeAllowed; - this.parameterTargettingAnnotationsAllowed = parameterTargettingAnnotationsAllowed; - } - - public Object visit(WildAnnotationTypePattern node, Object data) { - node.getTypePattern().accept(this,data); - return node; - } - - /** - * Do the ExactAnnotationTypePatterns have the incorrect target? - */ - public Object visit(ExactAnnotationTypePattern node, Object data) { - ResolvedType resolvedType = node.getAnnotationType().resolve(scope.getWorld()); + /** + * @param requiredTarget - the signature pattern Kind + * @param scope + * @param parameterTargettingAnnotationsAllowed + */ + public TypePatternVisitor(IScope scope, boolean targetsOtherThanTypeAllowed, boolean parameterTargettingAnnotationsAllowed) { + this.scope = scope; + this.targetsOtherThanTypeAllowed = targetsOtherThanTypeAllowed; + this.parameterTargettingAnnotationsAllowed = parameterTargettingAnnotationsAllowed; + } + + public Object visit(WildAnnotationTypePattern node, Object data) { + node.getTypePattern().accept(this, data); + return node; + } + + /** + * Do the ExactAnnotationTypePatterns have the incorrect target? + */ + public Object visit(ExactAnnotationTypePattern node, Object data) { + ResolvedType resolvedType = node.getAnnotationType().resolve(scope.getWorld()); if (targetsOtherThanTypeAllowed) { AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds(); - if (targetKinds == null) return data; + if (targetKinds == null) + return data; List incorrectTargets = new ArrayList(); for (int i = 0; i < targetKinds.length; i++) { - if (targetKinds[i].getName().equals(kind.getName()) || - (targetKinds[i].getName().equals("PARAMETER") && node.isForParameterAnnotationMatch()) - ) { + if (targetKinds[i].getName().equals(kind.getName()) + || (targetKinds[i].getName().equals("PARAMETER") && node.isForParameterAnnotationMatch())) { return data; } incorrectTargets.add(targetKinds[i]); } - if (incorrectTargets.isEmpty()) return data; + if (incorrectTargets.isEmpty()) + return data; AnnotationTargetKind[] kinds = new AnnotationTargetKind[incorrectTargets.size()]; - incorrectTargetKinds.put(node,(AnnotationTargetKind[]) incorrectTargets.toArray(kinds)); + incorrectTargetKinds.put(node, (AnnotationTargetKind[]) incorrectTargets.toArray(kinds)); } else if (!targetsOtherThanTypeAllowed && !resolvedType.canAnnotationTargetType()) { AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds(); - if (targetKinds == null) return data; + if (targetKinds == null) + return data; // exception here is if parameter annotations are allowed if (parameterTargettingAnnotationsAllowed) { for (int i = 0; i < targetKinds.length; i++) { AnnotationTargetKind annotationTargetKind = targetKinds[i]; - if (annotationTargetKind.getName().equals("PARAMETER") && node.isForParameterAnnotationMatch()) return data; + if (annotationTargetKind.getName().equals("PARAMETER") && node.isForParameterAnnotationMatch()) + return data; } } - incorrectTargetKinds.put(node,targetKinds); + incorrectTargetKinds.put(node, targetKinds); } - return data; - } - - public Object visit(ExactTypePattern node, Object data) { - ExactAnnotationTypePattern eatp = new ExactAnnotationTypePattern(node.getExactType().resolve(scope.getWorld()),null); - eatp.accept(this,data); - return data; - } - - public Object visit(AndTypePattern node, Object data) { - node.getLeft().accept(this,data); - node.getRight().accept(this,data); - return node; - } - - public Object visit(OrTypePattern node, Object data) { - node.getLeft().accept(this,data); - node.getRight().accept(this,data); - return node; - } - - public Object visit(AnyWithAnnotationTypePattern node, Object data) { - node.getAnnotationPattern().accept(this,data); - return node; - } - - public boolean containedIncorrectTargetKind() { - return (incorrectTargetKinds.size() != 0); - } - - public Map getIncorrectTargetKinds() { - return incorrectTargetKinds; - } - } - - + return data; + } + + public Object visit(ExactTypePattern node, Object data) { + ExactAnnotationTypePattern eatp = new ExactAnnotationTypePattern(node.getExactType().resolve(scope.getWorld()), null); + eatp.accept(this, data); + return data; + } + + public Object visit(AndTypePattern node, Object data) { + node.getLeft().accept(this, data); + node.getRight().accept(this, data); + return node; + } + + public Object visit(OrTypePattern node, Object data) { + node.getLeft().accept(this, data); + node.getRight().accept(this, data); + return node; + } + + public Object visit(AnyWithAnnotationTypePattern node, Object data) { + node.getAnnotationPattern().accept(this, data); + return node; + } + + public boolean containedIncorrectTargetKind() { + return (incorrectTargetKinds.size() != 0); + } + + public Map getIncorrectTargetKinds() { + return incorrectTargetKinds; + } + } + public void postRead(ResolvedType enclosingType) { if (returnType != null) { returnType.postRead(enclosingType); - } + } if (declaringType != null) { declaringType.postRead(enclosingType); } @@ -267,37 +262,34 @@ parameterTypes.postRead(enclosingType); } } - + /** - * return a copy of this signature pattern in which every type variable reference - * is replaced by the corresponding entry in the map. + * return a copy of this signature pattern in which every type variable reference is replaced by the corresponding entry in the + * map. */ - public SignaturePattern parameterizeWith(Map typeVariableMap,World w) { - SignaturePattern ret = new SignaturePattern( - kind, - modifiers, - returnType.parameterizeWith(typeVariableMap,w), - declaringType.parameterizeWith(typeVariableMap,w), - name, - parameterTypes.parameterizeWith(typeVariableMap,w), - throwsPattern.parameterizeWith(typeVariableMap,w), - annotationPattern.parameterizeWith(typeVariableMap,w)); + public SignaturePattern parameterizeWith(Map typeVariableMap, World w) { + SignaturePattern ret = new SignaturePattern(kind, modifiers, returnType.parameterizeWith(typeVariableMap, w), declaringType + .parameterizeWith(typeVariableMap, w), name, parameterTypes.parameterizeWith(typeVariableMap, w), throwsPattern + .parameterizeWith(typeVariableMap, w), annotationPattern.parameterizeWith(typeVariableMap, w)); ret.copyLocationFrom(this); return ret; } - + public boolean matches(Member joinPointSignature, World world, boolean allowBridgeMethods) { // fail (or succeed!) fast tests... - if (joinPointSignature == null) return false; - if (kind != joinPointSignature.getKind()) return false; - if (kind == Member.ADVICE) return true; - + if (joinPointSignature == null) + return false; + if (kind != joinPointSignature.getKind()) + return false; + if (kind == Member.ADVICE) + return true; + // do the hard work then... boolean subjectMatch = true; Iterator candidateMatches = joinPointSignature.getJoinPointSignatures(world); - while(candidateMatches.hasNext()) { + while (candidateMatches.hasNext()) { JoinPointSignature aSig = (JoinPointSignature) candidateMatches.next(); - FuzzyBoolean matchResult = matchesExactly(aSig,world,allowBridgeMethods,subjectMatch); + FuzzyBoolean matchResult = matchesExactly(aSig, world, allowBridgeMethods, subjectMatch); if (matchResult.alwaysTrue()) { return true; } else if (matchResult.alwaysFalse()) { @@ -308,62 +300,63 @@ } return false; } - + // Does this pattern match this exact signature (no declaring type mucking about // or chasing up the hierarchy) // return YES if it does, NO if it doesn't and no ancester member could match either, // and MAYBE if it doesn't but an ancester member could. - private FuzzyBoolean matchesExactly(JoinPointSignature aMember, World inAWorld, boolean allowBridgeMethods,boolean subjectMatch) { + private FuzzyBoolean matchesExactly(JoinPointSignature aMember, World inAWorld, boolean allowBridgeMethods, boolean subjectMatch) { // Java5 introduces bridge methods, we match a call to them but nothing else... if (aMember.isBridgeMethod() && !allowBridgeMethods) { return FuzzyBoolean.MAYBE; } - + // modifiers match on the *subject* if (subjectMatch && !modifiers.matches(aMember.getModifiers())) { return FuzzyBoolean.NO; -// if (aMember.isPrivate()) return FuzzyBoolean.NO; -// else return FuzzyBoolean.MAYBE; + // if (aMember.isPrivate()) return FuzzyBoolean.NO; + // else return FuzzyBoolean.MAYBE; } - - + FuzzyBoolean matchesIgnoringAnnotations = FuzzyBoolean.YES; if (kind == Member.STATIC_INITIALIZATION) { matchesIgnoringAnnotations = matchesExactlyStaticInitialization(aMember, inAWorld); } else if (kind == Member.FIELD) { - matchesIgnoringAnnotations = matchesExactlyField(aMember,inAWorld); + matchesIgnoringAnnotations = matchesExactlyField(aMember, inAWorld); } else if (kind == Member.METHOD) { - matchesIgnoringAnnotations = matchesExactlyMethod(aMember,inAWorld, subjectMatch); + matchesIgnoringAnnotations = matchesExactlyMethod(aMember, inAWorld, subjectMatch); } else if (kind == Member.CONSTRUCTOR) { matchesIgnoringAnnotations = matchesExactlyConstructor(aMember, inAWorld); } - if (matchesIgnoringAnnotations.alwaysFalse()) return FuzzyBoolean.NO; - + if (matchesIgnoringAnnotations.alwaysFalse()) + return FuzzyBoolean.NO; + // why did Adrian put this comment in: - // annotations match on the *subject* + // annotations match on the *subject* // surely you never want execution(@Something * *(..)) to match something just because // it is a secondary join point signature for a join point and doesn't have the annotation? // pr239441 if (matchesIgnoringAnnotations.alwaysTrue()) { - return matchesAnnotations(aMember,inAWorld); + return matchesAnnotations(aMember, inAWorld); } else { return matchesIgnoringAnnotations; } - + } - + /** * Matches on declaring type */ - private FuzzyBoolean matchesExactlyStaticInitialization(JoinPointSignature aMember,World world) { + private FuzzyBoolean matchesExactlyStaticInitialization(JoinPointSignature aMember, World world) { return FuzzyBoolean.fromBoolean(declaringType.matchesStatically(aMember.getDeclaringType().resolve(world))); } - + /** * Matches on name, declaring type, field type */ private FuzzyBoolean matchesExactlyField(JoinPointSignature aField, World world) { - if (!name.matches(aField.getName())) return FuzzyBoolean.NO; + if (!name.matches(aField.getName())) + return FuzzyBoolean.NO; ResolvedType fieldDeclaringType = aField.getDeclaringType().resolve(world); if (!declaringType.matchesStatically(fieldDeclaringType)) { return FuzzyBoolean.MAYBE; @@ -378,16 +371,19 @@ // passed all the guards... return FuzzyBoolean.YES; } - + /** * Matches on name, declaring type, return type, parameter types, throws types */ private FuzzyBoolean matchesExactlyMethod(JoinPointSignature aMethod, World world, boolean subjectMatch) { - if (!name.matches(aMethod.getName())) return FuzzyBoolean.NO; + if (!name.matches(aMethod.getName())) + return FuzzyBoolean.NO; // Check the throws pattern - if (subjectMatch && !throwsPattern.matches(aMethod.getExceptions(), world)) return FuzzyBoolean.NO; - - if (!declaringType.matchesStatically(aMethod.getDeclaringType().resolve(world))) return FuzzyBoolean.MAYBE; + if (subjectMatch && !throwsPattern.matches(aMethod.getExceptions(), world)) + return FuzzyBoolean.NO; + + if (!declaringType.matchesStatically(aMethod.getDeclaringType().resolve(world))) + return FuzzyBoolean.MAYBE; if (!returnType.matchesStatically(aMethod.getReturnType().resolve(world))) { // looking bad, but there might be parameterization to consider... if (!returnType.matchesStatically(aMethod.getGenericReturnType().resolve(world))) { @@ -395,276 +391,294 @@ return FuzzyBoolean.MAYBE; } } - if (!parameterTypes.canMatchSignatureWithNParameters(aMethod.getParameterTypes().length)) return FuzzyBoolean.NO; + if (!parameterTypes.canMatchSignatureWithNParameters(aMethod.getParameterTypes().length)) + return FuzzyBoolean.NO; ResolvedType[] resolvedParameters = world.resolve(aMethod.getParameterTypes()); ResolvedType[][] parameterAnnotationTypes = aMethod.getParameterAnnotationTypes(); - if (parameterAnnotationTypes==null || parameterAnnotationTypes.length==0) parameterAnnotationTypes=null; - if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC,parameterAnnotationTypes).alwaysTrue()) { + if (parameterAnnotationTypes == null || parameterAnnotationTypes.length == 0) + parameterAnnotationTypes = null; + if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC, parameterAnnotationTypes).alwaysTrue()) { // It could still be a match based on the generic sig parameter types of a parameterized type - if (!parameterTypes.matches(world.resolve(aMethod.getGenericParameterTypes()),TypePattern.STATIC,parameterAnnotationTypes).alwaysTrue()) { + if (!parameterTypes.matches(world.resolve(aMethod.getGenericParameterTypes()), TypePattern.STATIC, + parameterAnnotationTypes).alwaysTrue()) { return FuzzyBoolean.MAYBE; // It could STILL be a match based on the erasure of the parameter types?? // to be determined via test cases... } } - + // check that varargs specifications match - if (!matchesVarArgs(aMethod,world)) return FuzzyBoolean.MAYBE; - + if (!matchesVarArgs(aMethod, world)) + return FuzzyBoolean.MAYBE; + // passed all the guards.. return FuzzyBoolean.YES; } - - /** * match on declaring type, parameter types, throws types */ private FuzzyBoolean matchesExactlyConstructor(JoinPointSignature aConstructor, World world) { - if (!declaringType.matchesStatically(aConstructor.getDeclaringType().resolve(world))) return FuzzyBoolean.NO; + if (!declaringType.matchesStatically(aConstructor.getDeclaringType().resolve(world))) + return FuzzyBoolean.NO; - if (!parameterTypes.canMatchSignatureWithNParameters(aConstructor.getParameterTypes().length)) return FuzzyBoolean.NO; + if (!parameterTypes.canMatchSignatureWithNParameters(aConstructor.getParameterTypes().length)) + return FuzzyBoolean.NO; ResolvedType[] resolvedParameters = world.resolve(aConstructor.getParameterTypes()); - + ResolvedType[][] parameterAnnotationTypes = aConstructor.getParameterAnnotationTypes(); - if (parameterAnnotationTypes==null || parameterAnnotationTypes.length==0) parameterAnnotationTypes=null; + if (parameterAnnotationTypes == null || parameterAnnotationTypes.length == 0) + parameterAnnotationTypes = null; - if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC,parameterAnnotationTypes).alwaysTrue()) { + if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC, parameterAnnotationTypes).alwaysTrue()) { // It could still be a match based on the generic sig parameter types of a parameterized type - if (!parameterTypes.matches(world.resolve(aConstructor.getGenericParameterTypes()),TypePattern.STATIC).alwaysTrue()) { + if (!parameterTypes.matches(world.resolve(aConstructor.getGenericParameterTypes()), TypePattern.STATIC).alwaysTrue()) { return FuzzyBoolean.MAYBE; // It could STILL be a match based on the erasure of the parameter types?? // to be determined via test cases... } } - + // check that varargs specifications match - if (!matchesVarArgs(aConstructor,world)) return FuzzyBoolean.NO; - + if (!matchesVarArgs(aConstructor, world)) + return FuzzyBoolean.NO; + // Check the throws pattern - if (!throwsPattern.matches(aConstructor.getExceptions(), world)) return FuzzyBoolean.NO; - + if (!throwsPattern.matches(aConstructor.getExceptions(), world)) + return FuzzyBoolean.NO; + // passed all the guards.. - return FuzzyBoolean.YES; + return FuzzyBoolean.YES; } - + /** - * We've matched against this method or constructor so far, but without considering - * varargs (which has been matched as a simple array thus far). Now we do the additional - * checks to see if the parties agree on whether the last parameter is varargs or a - * straight array. + * We've matched against this method or constructor so far, but without considering varargs (which has been matched as a simple + * array thus far). Now we do the additional checks to see if the parties agree on whether the last parameter is varargs or a + * straight array. */ private boolean matchesVarArgs(JoinPointSignature aMethodOrConstructor, World inAWorld) { - if (parameterTypes.size() == 0) return true; - - TypePattern lastPattern = parameterTypes.get(parameterTypes.size()-1); - boolean canMatchVarArgsSignature = lastPattern.isStar() || - lastPattern.isVarArgs() || - (lastPattern == TypePattern.ELLIPSIS); - + if (parameterTypes.size() == 0) + return true; + + TypePattern lastPattern = parameterTypes.get(parameterTypes.size() - 1); + boolean canMatchVarArgsSignature = lastPattern.isStar() || lastPattern.isVarArgs() || (lastPattern == TypePattern.ELLIPSIS); + if (aMethodOrConstructor.isVarargsMethod()) { // we have at least one parameter in the pattern list, and the method has a varargs signature if (!canMatchVarArgsSignature) { // XXX - Ideally the shadow would be included in the msg but we don't know it... - inAWorld.getLint().cantMatchArrayTypeOnVarargs.signal(aMethodOrConstructor.toString(),getSourceLocation()); + inAWorld.getLint().cantMatchArrayTypeOnVarargs.signal(aMethodOrConstructor.toString(), getSourceLocation()); return false; } } else { // the method ends with an array type, check that we don't *require* a varargs - if (lastPattern.isVarArgs()) return false; + if (lastPattern.isVarArgs()) + return false; } return true; } - - private FuzzyBoolean matchesAnnotations(ResolvedMember member,World world) { - if (member == null) { - // world.getLint().unresolvableMember.signal(member.toString(), getSourceLocation()); - return FuzzyBoolean.NO; - } - annotationPattern.resolve(world); - - // optimization before we go digging around for annotations on ITDs - if (annotationPattern instanceof AnyAnnotationTypePattern) return FuzzyBoolean.YES; - - // fake members represent ITD'd fields - for their annotations we should go and look up the - // relevant member in the original aspect - if (member.isAnnotatedElsewhere() && member.getKind()==Member.FIELD) { - // FIXME asc duplicate of code in AnnotationPointcut.matchInternal()? same fixmes apply here. -// ResolvedMember [] mems = member.getDeclaringType().resolve(world).getDeclaredFields(); // FIXME asc should include supers with getInterTypeMungersIncludingSupers? - List mungers = member.getDeclaringType().resolve(world).getInterTypeMungers(); - for (Iterator iter = mungers.iterator(); iter.hasNext();) { - ConcreteTypeMunger typeMunger = (ConcreteTypeMunger) iter.next(); - if (typeMunger.getMunger() instanceof NewFieldTypeMunger) { - ResolvedMember fakerm = typeMunger.getSignature(); - ResolvedMember ajcMethod = AjcMemberMaker.interFieldInitializer(fakerm,typeMunger.getAspectType()); - ResolvedMember rmm = findMethod(typeMunger.getAspectType(),ajcMethod); - if (fakerm.equals(member)) { - member = rmm; - } - } - } - } - - if (annotationPattern.matches(member).alwaysTrue()) { - return FuzzyBoolean.YES; - } else { - return FuzzyBoolean.NO; // do NOT look at ancestor members... - } + + private FuzzyBoolean matchesAnnotations(ResolvedMember member, World world) { + if (member == null) { + // world.getLint().unresolvableMember.signal(member.toString(), getSourceLocation()); + return FuzzyBoolean.NO; + } + annotationPattern.resolve(world); + + // optimization before we go digging around for annotations on ITDs + if (annotationPattern instanceof AnyAnnotationTypePattern) + return FuzzyBoolean.YES; + + // fake members represent ITD'd fields - for their annotations we should go and look up the + // relevant member in the original aspect + if (member.isAnnotatedElsewhere() && member.getKind() == Member.FIELD) { + // FIXME asc duplicate of code in AnnotationPointcut.matchInternal()? same fixmes apply here. + // ResolvedMember [] mems = member.getDeclaringType().resolve(world).getDeclaredFields(); // FIXME asc should include + // supers with getInterTypeMungersIncludingSupers? + List mungers = member.getDeclaringType().resolve(world).getInterTypeMungers(); + for (Iterator iter = mungers.iterator(); iter.hasNext();) { + ConcreteTypeMunger typeMunger = (ConcreteTypeMunger) iter.next(); + if (typeMunger.getMunger() instanceof NewFieldTypeMunger) { + ResolvedMember fakerm = typeMunger.getSignature(); + ResolvedMember ajcMethod = AjcMemberMaker.interFieldInitializer(fakerm, typeMunger.getAspectType()); + ResolvedMember rmm = findMethod(typeMunger.getAspectType(), ajcMethod); + if (fakerm.equals(member)) { + member = rmm; + } + } + } + } + + if (annotationPattern.matches(member).alwaysTrue()) { + return FuzzyBoolean.YES; + } else { + return FuzzyBoolean.NO; // do NOT look at ancestor members... + } } - + private ResolvedMember findMethod(ResolvedType aspectType, ResolvedMember ajcMethod) { - ResolvedMember decMethods[] = aspectType.getDeclaredMethods(); - for (int i = 0; i < decMethods.length; i++) { + ResolvedMember decMethods[] = aspectType.getDeclaredMethods(); + for (int i = 0; i < decMethods.length; i++) { ResolvedMember member = decMethods[i]; - if (member.equals(ajcMethod)) return member; - } - return null; - } - - public boolean declaringTypeMatchAllowingForCovariance(Member member, UnresolvedType shadowDeclaringType, World world,TypePattern returnTypePattern,ResolvedType sigReturn) { - + if (member.equals(ajcMethod)) + return member; + } + return null; + } + + public boolean declaringTypeMatchAllowingForCovariance(Member member, UnresolvedType shadowDeclaringType, World world, + TypePattern returnTypePattern, ResolvedType sigReturn) { + ResolvedType onType = shadowDeclaringType.resolve(world); - + // fastmatch - if (declaringType.matchesStatically(onType) && returnTypePattern.matchesStatically(sigReturn)) + if (declaringType.matchesStatically(onType) && returnTypePattern.matchesStatically(sigReturn)) return true; - + Collection declaringTypes = member.getDeclaringTypes(world); - + boolean checkReturnType = true; - // XXX Possible enhancement? Doesn't seem to speed things up - // if (returnTypePattern.isStar()) { - // if (returnTypePattern instanceof WildTypePattern) { - // if (((WildTypePattern)returnTypePattern).getDimensions()==0) checkReturnType = false; - // } - // } - + // XXX Possible enhancement? Doesn't seem to speed things up + // if (returnTypePattern.isStar()) { + // if (returnTypePattern instanceof WildTypePattern) { + // if (((WildTypePattern)returnTypePattern).getDimensions()==0) checkReturnType = false; + // } + // } + // Sometimes that list includes types that don't explicitly declare the member we are after - // they are on the list because their supertype is on the list, that's why we use // lookupMethod rather than lookupMemberNoSupers() - for (Iterator i = declaringTypes.iterator(); i.hasNext(); ) { - ResolvedType type = (ResolvedType)i.next(); + for (Iterator i = declaringTypes.iterator(); i.hasNext();) { + ResolvedType type = (ResolvedType) i.next(); if (declaringType.matchesStatically(type)) { - if (!checkReturnType) return true; - ResolvedMember rm = type.lookupMethod(member); - if (rm==null) rm = type.lookupMethodInITDs(member); // It must be in here, or we have *real* problems - if (rm==null) continue; // might be currently looking at the generic type and we need to continue searching in case we hit a parameterized version of this same type... - UnresolvedType returnTypeX = rm.getReturnType(); - ResolvedType returnType = returnTypeX.resolve(world); - if (returnTypePattern.matchesStatically(returnType)) return true; + if (!checkReturnType) + return true; + ResolvedMember rm = type.lookupMethod(member); + if (rm == null) + rm = type.lookupMethodInITDs(member); // It must be in here, or we have *real* problems + if (rm == null) + continue; // might be currently looking at the generic type and we need to continue searching in case we hit a + // parameterized version of this same type... + UnresolvedType returnTypeX = rm.getReturnType(); + ResolvedType returnType = returnTypeX.resolve(world); + if (returnTypePattern.matchesStatically(returnType)) + return true; } } return false; } - -// private Collection getDeclaringTypes(Signature sig) { -// List l = new ArrayList(); -// Class onType = sig.getDeclaringType(); -// String memberName = sig.getName(); -// if (sig instanceof FieldSignature) { -// Class fieldType = ((FieldSignature)sig).getFieldType(); -// Class superType = onType; -// while(superType != null) { -// try { -// Field f = (superType.getDeclaredField(memberName)); -// if (f.getType() == fieldType) { -// l.add(superType); -// } -// } catch (NoSuchFieldException nsf) {} -// superType = superType.getSuperclass(); -// } -// } else if (sig instanceof MethodSignature) { -// Class[] paramTypes = ((MethodSignature)sig).getParameterTypes(); -// Class superType = onType; -// while(superType != null) { -// try { -// superType.getDeclaredMethod(memberName,paramTypes); -// l.add(superType); -// } catch (NoSuchMethodException nsm) {} -// superType = superType.getSuperclass(); -// } -// } -// return l; -// } - - public NamePattern getName() { return name; } - public TypePattern getDeclaringType() { return declaringType; } - - public MemberKind getKind() { - return kind; - } - - public String toString() { - StringBuffer buf = new StringBuffer(); - - if (annotationPattern != AnnotationTypePattern.ANY) { + + // private Collection getDeclaringTypes(Signature sig) { + // List l = new ArrayList(); + // Class onType = sig.getDeclaringType(); + // String memberName = sig.getName(); + // if (sig instanceof FieldSignature) { + // Class fieldType = ((FieldSignature)sig).getFieldType(); + // Class superType = onType; + // while(superType != null) { + // try { + // Field f = (superType.getDeclaredField(memberName)); + // if (f.getType() == fieldType) { + // l.add(superType); + // } + // } catch (NoSuchFieldException nsf) {} + // superType = superType.getSuperclass(); + // } + // } else if (sig instanceof MethodSignature) { + // Class[] paramTypes = ((MethodSignature)sig).getParameterTypes(); + // Class superType = onType; + // while(superType != null) { + // try { + // superType.getDeclaredMethod(memberName,paramTypes); + // l.add(superType); + // } catch (NoSuchMethodException nsm) {} + // superType = superType.getSuperclass(); + // } + // } + // return l; + // } + + public NamePattern getName() { + return name; + } + + public TypePattern getDeclaringType() { + return declaringType; + } + + public MemberKind getKind() { + return kind; + } + + public String toString() { + StringBuffer buf = new StringBuffer(); + + if (annotationPattern != AnnotationTypePattern.ANY) { buf.append(annotationPattern.toString()); buf.append(' '); - } - - if (modifiers != ModifiersPattern.ANY) { - buf.append(modifiers.toString()); - buf.append(' '); - } - - if (kind == Member.STATIC_INITIALIZATION) { - buf.append(declaringType.toString()); - buf.append(".()");//FIXME AV - bad, cannot be parsed again - } else if (kind == Member.HANDLER) { - buf.append("handler("); - buf.append(parameterTypes.get(0)); - buf.append(")"); - } else { - if (!(kind == Member.CONSTRUCTOR)) { - buf.append(returnType.toString()); - buf.append(' '); - } - if (declaringType != TypePattern.ANY) { - buf.append(declaringType.toString()); - buf.append('.'); - } - if (kind == Member.CONSTRUCTOR) { - buf.append("new"); - } else { - buf.append(name.toString()); - } - if (kind == Member.METHOD || kind == Member.CONSTRUCTOR) { - buf.append(parameterTypes.toString()); - } - //FIXME AV - throws is not printed here, weird - } - return buf.toString(); - } - - public boolean equals(Object other) { - if (!(other instanceof SignaturePattern)) return false; - SignaturePattern o = (SignaturePattern)other; - return o.kind.equals(this.kind) - && o.modifiers.equals(this.modifiers) - && o.returnType.equals(this.returnType) - && o.declaringType.equals(this.declaringType) - && o.name.equals(this.name) - && o.parameterTypes.equals(this.parameterTypes) - && o.throwsPattern.equals(this.throwsPattern) - && o.annotationPattern.equals(this.annotationPattern); - } - public int hashCode() { - if (hashcode==-1) { - hashcode = 17; - hashcode = 37*hashcode + kind.hashCode(); - hashcode = 37*hashcode + modifiers.hashCode(); - hashcode = 37*hashcode + returnType.hashCode(); - hashcode = 37*hashcode + declaringType.hashCode(); - hashcode = 37*hashcode + name.hashCode(); - hashcode = 37*hashcode + parameterTypes.hashCode(); - hashcode = 37*hashcode + throwsPattern.hashCode(); - hashcode = 37*hashcode + annotationPattern.hashCode(); - } - return hashcode; - } - + } + + if (modifiers != ModifiersPattern.ANY) { + buf.append(modifiers.toString()); + buf.append(' '); + } + + if (kind == Member.STATIC_INITIALIZATION) { + buf.append(declaringType.toString()); + buf.append(".()");// FIXME AV - bad, cannot be parsed again + } else if (kind == Member.HANDLER) { + buf.append("handler("); + buf.append(parameterTypes.get(0)); + buf.append(")"); + } else { + if (!(kind == Member.CONSTRUCTOR)) { + buf.append(returnType.toString()); + buf.append(' '); + } + if (declaringType != TypePattern.ANY) { + buf.append(declaringType.toString()); + buf.append('.'); + } + if (kind == Member.CONSTRUCTOR) { + buf.append("new"); + } else { + buf.append(name.toString()); + } + if (kind == Member.METHOD || kind == Member.CONSTRUCTOR) { + buf.append(parameterTypes.toString()); + } + // FIXME AV - throws is not printed here, weird + } + return buf.toString(); + } + + public boolean equals(Object other) { + if (!(other instanceof SignaturePattern)) + return false; + SignaturePattern o = (SignaturePattern) other; + return o.kind.equals(this.kind) && o.modifiers.equals(this.modifiers) && o.returnType.equals(this.returnType) + && o.declaringType.equals(this.declaringType) && o.name.equals(this.name) + && o.parameterTypes.equals(this.parameterTypes) && o.throwsPattern.equals(this.throwsPattern) + && o.annotationPattern.equals(this.annotationPattern); + } + + public int hashCode() { + if (hashcode == -1) { + hashcode = 17; + hashcode = 37 * hashcode + kind.hashCode(); + hashcode = 37 * hashcode + modifiers.hashCode(); + hashcode = 37 * hashcode + returnType.hashCode(); + hashcode = 37 * hashcode + declaringType.hashCode(); + hashcode = 37 * hashcode + name.hashCode(); + hashcode = 37 * hashcode + parameterTypes.hashCode(); + hashcode = 37 * hashcode + throwsPattern.hashCode(); + hashcode = 37 * hashcode + annotationPattern.hashCode(); + } + return hashcode; + } + public void write(DataOutputStream s) throws IOException { kind.write(s); modifiers.write(s); @@ -685,15 +699,15 @@ NamePattern name = NamePattern.read(s); TypePatternList parameterTypes = TypePatternList.read(s, context); ThrowsPattern throwsPattern = ThrowsPattern.read(s, context); - + AnnotationTypePattern annotationPattern = AnnotationTypePattern.ANY; - - if (s.getMajorVersion()>=AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) { - annotationPattern = AnnotationTypePattern.read(s,context); + + if (s.getMajorVersion() >= AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) { + annotationPattern = AnnotationTypePattern.read(s, context); } - SignaturePattern ret = new SignaturePattern(kind, modifiers, returnType, declaringType, - name, parameterTypes, throwsPattern,annotationPattern); + SignaturePattern ret = new SignaturePattern(kind, modifiers, returnType, declaringType, name, parameterTypes, + throwsPattern, annotationPattern); ret.readLocation(context, s); return ret; } @@ -725,30 +739,28 @@ public ThrowsPattern getThrowsPattern() { return throwsPattern; } - + /** - * return true if last argument in params is an Object[] but the modifiers say this method - * was declared with varargs (Object...). We shouldn't be matching if this is the case. + * return true if last argument in params is an Object[] but the modifiers say this method was declared with varargs + * (Object...). We shouldn't be matching if this is the case. */ -// private boolean matchedArrayAgainstVarArgs(TypePatternList params,int modifiers) { -// if (params.size()>0 && (modifiers & Constants.ACC_VARARGS)!=0) { -// // we have at least one parameter in the pattern list, and the method has a varargs signature -// TypePattern lastPattern = params.get(params.size()-1); -// if (lastPattern.isArray() && !lastPattern.isVarArgs) return true; -// } -// return false; -// } - + // private boolean matchedArrayAgainstVarArgs(TypePatternList params,int modifiers) { + // if (params.size()>0 && (modifiers & Constants.ACC_VARARGS)!=0) { + // // we have at least one parameter in the pattern list, and the method has a varargs signature + // TypePattern lastPattern = params.get(params.size()-1); + // if (lastPattern.isArray() && !lastPattern.isVarArgs) return true; + // } + // return false; + // } public AnnotationTypePattern getAnnotationPattern() { return annotationPattern; } - public boolean isStarAnnotation() { return annotationPattern == AnnotationTypePattern.ANY; } - public Object accept(PatternNodeVisitor visitor, Object data) { - return visitor.visit(this, data); - } + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this, data); + } } Index: src/org/aspectj/weaver/patterns/WildTypePattern.java =================================================================== RCS file: /cvsroot/tools/org.aspectj/modules/org.aspectj.matcher/src/org/aspectj/weaver/patterns/WildTypePattern.java,v retrieving revision 1.2 diff -u -r1.2 WildTypePattern.java --- src/org/aspectj/weaver/patterns/WildTypePattern.java 28 Oct 2008 20:33:13 -0000 1.2 +++ src/org/aspectj/weaver/patterns/WildTypePattern.java 9 Dec 2008 19:24:29 -0000 @@ -655,6 +655,7 @@ } else if (!isVarArgs) { annotationPattern = annotationPattern.resolveBindings(scope, bindings, allowBinding); AnyWithAnnotationTypePattern ret = new AnyWithAnnotationTypePattern(annotationPattern); + ret.includeSubtypes = includeSubtypes; ret.setLocation(sourceContext, start, end); return ret; }