From: aclement Date: Fri, 25 Jan 2008 20:05:55 +0000 (+0000) Subject: paramannos: ResolvedType can hold 'temporary annotations' during a match (parameter... X-Git-Tag: V1_6_0M2~70 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=83d584dded49ec0861ad0fe1e6f5f15658bc477b;p=aspectj.git paramannos: ResolvedType can hold 'temporary annotations' during a match (parameter annos). PatternParser supports distinction between parameter and type annos. --- diff --git a/weaver/src/org/aspectj/weaver/ResolvedType.java b/weaver/src/org/aspectj/weaver/ResolvedType.java index 65fa61ac9..6a01e3ca1 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedType.java +++ b/weaver/src/org/aspectj/weaver/ResolvedType.java @@ -39,6 +39,9 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl public static final ResolvedType[] EMPTY_RESOLVED_TYPE_ARRAY = new ResolvedType[0]; public static final String PARAMETERIZED_TYPE_IDENTIFIER = "P"; + // Set during a type pattern match call - this currently used to hold the annotations + // that may be attached to a type when it used as a parameter + public ResolvedType[] temporaryAnnotationTypes; private ResolvedType[] resolvedTypeParams; private String binaryPath; diff --git a/weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java index 9f2a98a49..45664babe 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java @@ -26,6 +26,7 @@ import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.VersionedDataInputStream; import org.aspectj.weaver.WeaverMessages; import org.aspectj.weaver.World; +import org.aspectj.weaver.AjAttribute.WeaverVersionInfo; /** * Matches an annotation of a given type @@ -72,30 +73,48 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern { } public FuzzyBoolean matches(AnnotatedElement annotated) { - boolean checkSupers = false; - if (getResolvedAnnotationType().hasAnnotation(UnresolvedType.AT_INHERITED)) { - if (annotated instanceof ResolvedType) { - checkSupers = true; - } - } - - if (annotated.hasAnnotation(annotationType)) { - if (annotationType instanceof ReferenceType) { - ReferenceType rt = (ReferenceType)annotationType; - if (rt.getRetentionPolicy()!=null && rt.getRetentionPolicy().equals("SOURCE")) { - rt.getWorld().getMessageHandler().handleMessage( - MessageUtil.warn(WeaverMessages.format(WeaverMessages.NO_MATCH_BECAUSE_SOURCE_RETENTION,annotationType,annotated),getSourceLocation())); - return FuzzyBoolean.NO; + return matches(annotated,null); + } + + public FuzzyBoolean matches(AnnotatedElement annotated,ResolvedType[] parameterAnnotations) { + if (!isForParameterAnnotationMatch()) { + boolean checkSupers = false; + if (getResolvedAnnotationType().hasAnnotation(UnresolvedType.AT_INHERITED)) { + if (annotated instanceof ResolvedType) { + checkSupers = true; } } - return FuzzyBoolean.YES; - } else if (checkSupers) { - ResolvedType toMatchAgainst = ((ResolvedType) annotated).getSuperclass(); - while (toMatchAgainst != null) { - if (toMatchAgainst.hasAnnotation(annotationType)) return FuzzyBoolean.YES; - toMatchAgainst = toMatchAgainst.getSuperclass(); + + if (annotated.hasAnnotation(annotationType)) { + if (annotationType instanceof ReferenceType) { + ReferenceType rt = (ReferenceType)annotationType; + if (rt.getRetentionPolicy()!=null && rt.getRetentionPolicy().equals("SOURCE")) { + rt.getWorld().getMessageHandler().handleMessage( + MessageUtil.warn(WeaverMessages.format(WeaverMessages.NO_MATCH_BECAUSE_SOURCE_RETENTION,annotationType,annotated),getSourceLocation())); + return FuzzyBoolean.NO; + } + } + return FuzzyBoolean.YES; + } else if (checkSupers) { + ResolvedType toMatchAgainst = ((ResolvedType) annotated).getSuperclass(); + while (toMatchAgainst != null) { + if (toMatchAgainst.hasAnnotation(annotationType)) { + return FuzzyBoolean.YES; + } + toMatchAgainst = toMatchAgainst.getSuperclass(); + } + } + } else { + // check parameter annotations + if (parameterAnnotations==null) return FuzzyBoolean.NO; + for (int i = 0; i < parameterAnnotations.length; i++) { + if (annotationType.equals(parameterAnnotations[i])) { + return FuzzyBoolean.YES; + } } - } + } + + return FuzzyBoolean.NO; } @@ -144,6 +163,7 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern { binding.copyLocationFrom(this); bindings.register(binding, scope); binding.resolveBinding(scope.getWorld()); + if (isForParameterAnnotationMatch()) binding.setForParameterAnnotationMatch(); return binding; } @@ -183,6 +203,7 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern { ret.formalName = formalName; ret.bindingPattern = bindingPattern; ret.copyLocationFrom(this); + if (isForParameterAnnotationMatch()) ret.setForParameterAnnotationMatch(); return ret; } @@ -219,6 +240,7 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern { annotationType.write(s); } writeLocation(s); + s.writeBoolean(isForParameterAnnotationMatch()); } public static AnnotationTypePattern read(VersionedDataInputStream s,ISourceContext context) throws IOException { @@ -234,6 +256,9 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern { ret = new ExactAnnotationTypePattern(UnresolvedType.read(s)); } ret.readLocation(context,s); + if (s.getMajorVersion()>=WeaverVersionInfo.WEAVER_VERSION_MINOR_AJ160) { + if (s.readBoolean()) ret.setForParameterAnnotationMatch(); + } return ret; } @@ -243,14 +268,14 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern { public boolean equals(Object obj) { if (!(obj instanceof ExactAnnotationTypePattern)) return false; ExactAnnotationTypePattern other = (ExactAnnotationTypePattern) obj; - return (other.annotationType.equals(annotationType)); + return (other.annotationType.equals(annotationType)) && isForParameterAnnotationMatch()==other.isForParameterAnnotationMatch(); } /* (non-Javadoc) * @see java.lang.Object#hashCode() */ public int hashCode() { - return annotationType.hashCode(); + return annotationType.hashCode()*37+(isForParameterAnnotationMatch()?0:1); } public String toString() { diff --git a/weaver/src/org/aspectj/weaver/patterns/PatternParser.java b/weaver/src/org/aspectj/weaver/patterns/PatternParser.java index 29326a572..626900b9c 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PatternParser.java +++ b/weaver/src/org/aspectj/weaver/patterns/PatternParser.java @@ -42,6 +42,8 @@ public class PatternParser { /** extension handlers used in weaver tools API only */ private Set pointcutDesignatorHandlers = Collections.EMPTY_SET; private ReflectionWorld world; + + private AnnotationTypePattern[] parameterAnnotationTypePatterns; /** * Constructor for PatternParser. @@ -213,7 +215,7 @@ public class PatternParser { */ eat(":"); allowHasTypePatterns = true; - TypePattern p = parseTypePattern(false); + TypePattern p = parseTypePattern(false,false); allowHasTypePatterns = false; IToken t = tokenSource.next(); if (!(t.getString().equals("extends") || t.getString().equals("implements"))) { @@ -336,7 +338,7 @@ public class PatternParser { AnnotationTypePattern.ANY)); } else if (kind.equals("handler")) { eat("("); - TypePattern typePat = parseTypePattern(false); + TypePattern typePat = parseTypePattern(false,false); eat(")"); p = new HandlerPointcut(typePat); } else if (kind.equals("lock") || kind.equals("unlock")) { @@ -348,7 +350,7 @@ public class PatternParser { p = new KindedPointcut(Shadow.Initialization, sig); } else if (kind.equals("staticinitialization")) { eat("("); - TypePattern typePat = parseTypePattern(false); + TypePattern typePat = parseTypePattern(false,false); eat(")"); p = new KindedPointcut(Shadow.StaticInitialization, new SignaturePattern(Member.STATIC_INITIALIZATION, ModifiersPattern.ANY, @@ -522,7 +524,7 @@ public class PatternParser { */ private Pointcut parseArgsPointcut() { //parseIdentifier(); - TypePatternList arguments = parseArgumentsPattern(); + TypePatternList arguments = parseArgumentsPattern(false); return new ArgsPointcut(arguments); } @@ -553,7 +555,7 @@ public class PatternParser { throw new ParserException("(",tokenSource.peek(-1)); } - TypePatternList arguments = parseArgumentsPattern(); + TypePatternList arguments = parseArgumentsPattern(false); return new ReferencePointcut(onType, simpleName, arguments); } @@ -652,41 +654,44 @@ public class PatternParser { } public TypePattern parseTypePattern() { - return parseTypePattern(false); + return parseTypePattern(false,false); } - public TypePattern parseTypePattern(boolean insideTypeParameters) { - TypePattern p = parseAtomicTypePattern(insideTypeParameters); + public TypePattern parseTypePattern(boolean insideTypeParameters,boolean parameterAnnotationsPossible) { + TypePattern p = parseAtomicTypePattern(insideTypeParameters,parameterAnnotationsPossible); if (maybeEat("&&")) { - p = new AndTypePattern(p, parseNotOrTypePattern(insideTypeParameters)); + p = new AndTypePattern(p, parseNotOrTypePattern(insideTypeParameters,parameterAnnotationsPossible)); } if (maybeEat("||")) { - p = new OrTypePattern(p, parseTypePattern(insideTypeParameters)); + p = new OrTypePattern(p, parseTypePattern(insideTypeParameters,parameterAnnotationsPossible)); } return p; } - private TypePattern parseNotOrTypePattern(boolean insideTypeParameters) { - TypePattern p = parseAtomicTypePattern(insideTypeParameters); + private TypePattern parseNotOrTypePattern(boolean insideTypeParameters,boolean parameterAnnotationsPossible) { + TypePattern p = parseAtomicTypePattern(insideTypeParameters,parameterAnnotationsPossible); if (maybeEat("&&")) { - p = new AndTypePattern(p, parseTypePattern(insideTypeParameters)); + p = new AndTypePattern(p, parseTypePattern(insideTypeParameters,parameterAnnotationsPossible)); } return p; } - private TypePattern parseAtomicTypePattern(boolean insideTypeParameters) { - AnnotationTypePattern ap = maybeParseAnnotationPattern(); + + // Need to differentiate in here between two kinds of annotation pattern - depending on where the ( is + + private TypePattern parseAtomicTypePattern(boolean insideTypeParameters,boolean parameterAnnotationsPossible) { + AnnotationTypePattern ap = maybeParseAnnotationPattern(); // might be parameter annotation pattern or type annotation pattern if (maybeEat("!")) { //int startPos = tokenSource.peek(-1).getStart(); //??? we lose source location for true start of !type - TypePattern p = new NotTypePattern(parseAtomicTypePattern(insideTypeParameters)); - p = setAnnotationPatternForTypePattern(p,ap); + TypePattern p = new NotTypePattern(parseAtomicTypePattern(insideTypeParameters,parameterAnnotationsPossible)); + p = setAnnotationPatternForTypePattern(p,ap,false); return p; } if (maybeEat("(")) { - TypePattern p = parseTypePattern(insideTypeParameters); - p = setAnnotationPatternForTypePattern(p,ap); + TypePattern p = parseTypePattern(insideTypeParameters,false); + p = setAnnotationPatternForTypePattern(p,ap,parameterAnnotationsPossible); eat(")"); boolean isVarArgs = maybeEat("..."); if (isVarArgs) p.setIsVarArgs(isVarArgs); @@ -697,13 +702,15 @@ public class PatternParser { int startPos = tokenSource.peek().getStart(); TypePattern p = parseSingleTypePattern(insideTypeParameters); int endPos = tokenSource.peek(-1).getEnd(); - p = setAnnotationPatternForTypePattern(p,ap); + p = setAnnotationPatternForTypePattern(p,ap,false); p.setLocation(sourceContext, startPos, endPos); return p; } - private TypePattern setAnnotationPatternForTypePattern(TypePattern t, AnnotationTypePattern ap) { + + private TypePattern setAnnotationPatternForTypePattern(TypePattern t, AnnotationTypePattern ap,boolean parameterAnnotationsPattern) { TypePattern ret = t; + if (parameterAnnotationsPattern) ap.setForParameterAnnotationMatch(); if (ap != AnnotationTypePattern.ANY) { if (t == TypePattern.ANY) { ret = new WildTypePattern(new NamePattern[] {NamePattern.ANY},false,0,false,null); @@ -836,11 +843,11 @@ public class PatternParser { TypePattern[] additionalInterfaceBounds = new TypePattern[0]; TypePattern lowerBound = null; if (maybeEatIdentifier("extends")) { - upperBound = parseTypePattern(false); + upperBound = parseTypePattern(false,false); additionalInterfaceBounds = maybeParseAdditionalInterfaceBounds(); } if (maybeEatIdentifier("super")) { - lowerBound = parseTypePattern(false); + lowerBound = parseTypePattern(false,false); } int endPos = tokenSource.peek(-1).getEnd(); return new WildTypePattern(names,false,0,endPos,false,null,upperBound,additionalInterfaceBounds,lowerBound); @@ -1098,19 +1105,21 @@ public class PatternParser { } } - public TypePatternList parseArgumentsPattern() { + public TypePatternList parseArgumentsPattern(boolean parameterAnnotationsPossible) { List patterns = new ArrayList(); eat("("); + + // () if (maybeEat(")")) { return new TypePatternList(); } do { - if (maybeEat(".")) { + if (maybeEat(".")) { // .. eat("."); patterns.add(TypePattern.ELLIPSIS); - } else { - patterns.add(parseTypePattern()); + } else { + patterns.add(parseTypePattern(false,parameterAnnotationsPossible)); } } while (maybeEat(",")); eat(")"); @@ -1162,7 +1171,7 @@ public class PatternParser { int startPos = tokenSource.peek().getStart(); AnnotationTypePattern annotationPattern = maybeParseAnnotationPattern(); ModifiersPattern modifiers = parseModifiersPattern(); - TypePattern returnType = parseTypePattern(false); + TypePattern returnType = parseTypePattern(false,false); TypePattern declaringType; NamePattern name = null; @@ -1180,7 +1189,7 @@ public class PatternParser { } else { kind = Member.METHOD; IToken nameToken = tokenSource.peek(); - declaringType = parseTypePattern(false); + declaringType = parseTypePattern(false,false); if (maybeEat(".")) { nameToken = tokenSource.peek(); name = parseNamePattern(); @@ -1201,8 +1210,8 @@ public class PatternParser { } } - TypePatternList parameterTypes = parseArgumentsPattern(); - + TypePatternList parameterTypes = parseArgumentsPattern(true); + ThrowsPattern throwsPattern = parseOptionalThrowsPattern(); SignaturePattern ret = new SignaturePattern(kind, modifiers, returnType, declaringType, name, parameterTypes, throwsPattern, annotationPattern); int endPos = tokenSource.peek(-1).getEnd(); @@ -1304,7 +1313,7 @@ public class PatternParser { if (!maybeEat("<")) return null; List typePats = new ArrayList(); do { - TypePattern tp = parseTypePattern(true); + TypePattern tp = parseTypePattern(true,false); typePats.add(tp); } while(maybeEat(",")); eat(">"); diff --git a/weaver/src/org/aspectj/weaver/patterns/TypePattern.java b/weaver/src/org/aspectj/weaver/patterns/TypePattern.java index 49eb0c314..dcd453fa6 100644 --- a/weaver/src/org/aspectj/weaver/patterns/TypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/TypePattern.java @@ -467,9 +467,16 @@ class AnyWithAnnotationTypePattern extends TypePattern { protected boolean matchesExactly(ResolvedType type) { annotationPattern.resolve(type.getWorld()); - return annotationPattern.matches(type).alwaysTrue(); + boolean b = false; + if (type.temporaryAnnotationTypes!=null) { + b = annotationPattern.matches(type,type.temporaryAnnotationTypes).alwaysTrue(); + } else { + b = annotationPattern.matches(type).alwaysTrue(); + } + return b; } + protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) { annotationPattern.resolve(type.getWorld()); return annotationPattern.matches(annotatedType).alwaysTrue(); diff --git a/weaver/src/org/aspectj/weaver/patterns/TypePatternList.java b/weaver/src/org/aspectj/weaver/patterns/TypePatternList.java index aec01ed74..d2b51d7d9 100644 --- a/weaver/src/org/aspectj/weaver/patterns/TypePatternList.java +++ b/weaver/src/org/aspectj/weaver/patterns/TypePatternList.java @@ -87,6 +87,9 @@ public class TypePatternList extends PatternNode { return (size() -ellipsisCount) <= numParams; } } + public FuzzyBoolean matches(ResolvedType[] types, TypePattern.MatchKind kind) { + return matches(types,kind,null); + } //XXX shares much code with WildTypePattern and with NamePattern /** @@ -99,7 +102,7 @@ public class TypePatternList extends PatternNode { * * This method will never return FuzzyBoolean.NEVER */ - public FuzzyBoolean matches(ResolvedType[] types, TypePattern.MatchKind kind) { + public FuzzyBoolean matches(ResolvedType[] types, TypePattern.MatchKind kind, ResolvedType[][] parameterAnnotations) { int nameLength = types.length; int patternLength = typePatterns.length; @@ -110,7 +113,16 @@ public class TypePatternList extends PatternNode { if (nameLength != patternLength) return FuzzyBoolean.NO; FuzzyBoolean finalReturn = FuzzyBoolean.YES; while (patternIndex < patternLength) { - FuzzyBoolean ret = typePatterns[patternIndex++].matches(types[nameIndex++], kind); + ResolvedType t = types[nameIndex]; + FuzzyBoolean ret = null; + try { + if (parameterAnnotations!=null) t.temporaryAnnotationTypes = parameterAnnotations[nameIndex]; + ret = typePatterns[patternIndex].matches(t,kind); + } finally { + t.temporaryAnnotationTypes=null; + } + patternIndex++; + nameIndex++; if (ret == FuzzyBoolean.NO) return ret; if (ret == FuzzyBoolean.MAYBE) finalReturn = ret; } @@ -123,7 +135,15 @@ public class TypePatternList extends PatternNode { if (p == TypePattern.ELLIPSIS) { nameIndex = nameLength - (patternLength-patternIndex); } else { - FuzzyBoolean ret = p.matches(types[nameIndex++], kind); + ResolvedType t = types[nameIndex]; + FuzzyBoolean ret = null; + try { + if (parameterAnnotations!=null) t.temporaryAnnotationTypes = parameterAnnotations[nameIndex]; + ret = p.matches(t, kind); + } finally { + t.temporaryAnnotationTypes=null; + } + nameIndex++; if (ret == FuzzyBoolean.NO) return ret; if (ret == FuzzyBoolean.MAYBE) finalReturn = ret; } diff --git a/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java index 69a67ba4b..bb11d1156 100644 --- a/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java @@ -236,8 +236,8 @@ public class WildTypePattern extends TypePattern { return matchesExactlyByName(targetTypeName,type.isAnonymous(),type.isNested()) && matchesParameters(type,STATIC) && - matchesBounds(type,STATIC) && - annotationPattern.matches(annotatedType).alwaysTrue(); + matchesBounds(type,STATIC) && + annotationPattern.matches(annotatedType,type.temporaryAnnotationTypes).alwaysTrue(); } @@ -644,7 +644,7 @@ public class WildTypePattern extends TypePattern { if (dim == 0 && !isVarArgs && upperBound == null && lowerBound == null && (additionalInterfaceBounds == null || additionalInterfaceBounds.length==0)) { // pr72531 return TypePattern.ANY; //??? loses source location } - } else { + } else if (!isVarArgs){ annotationPattern = annotationPattern.resolveBindings(scope,bindings,allowBinding); AnyWithAnnotationTypePattern ret = new AnyWithAnnotationTypePattern(annotationPattern); ret.setLocation(sourceContext,start,end); diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/ParserTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/ParserTestCase.java index 08584fd00..4aa17f059 100644 --- a/weaver/testsrc/org/aspectj/weaver/patterns/ParserTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/patterns/ParserTestCase.java @@ -301,20 +301,20 @@ public class ParserTestCase extends TestCase { public void testParseAnythingTypeVariable() { PatternParser parser = new PatternParser("?"); - WildTypePattern tp = (WildTypePattern) parser.parseTypePattern(true); + WildTypePattern tp = (WildTypePattern) parser.parseTypePattern(true,false); assertEquals("Expected type variable ?","?",tp.maybeGetSimpleName()); } public void testParseAnythingExtendsTypeVariable() { PatternParser parser = new PatternParser("? extends Number"); - WildTypePattern tp = (WildTypePattern) parser.parseTypePattern(true); + WildTypePattern tp = (WildTypePattern) parser.parseTypePattern(true,false); assertEquals("Expected type variable ?","?",tp.maybeGetSimpleName()); assertEquals("upper Bound of Number",new PatternParser("Number").parseTypePattern(),tp.getUpperBound()); } public void testParseAnythingSuperTypeVariable() { PatternParser parser = new PatternParser("? super Number+"); - WildTypePattern tp = (WildTypePattern) parser.parseTypePattern(true); + WildTypePattern tp = (WildTypePattern) parser.parseTypePattern(true,false); assertEquals("Expected type variable ?","?",tp.maybeGetSimpleName()); assertEquals("lower Bound of Number+",new PatternParser("Number+").parseTypePattern(),tp.getLowerBound()); } @@ -335,7 +335,7 @@ public class ParserTestCase extends TestCase { public void testParameterizedTypePatternsAny() { try { PatternParser parser = new PatternParser("*"); - WildTypePattern wtp = (WildTypePattern) parser.parseTypePattern(false); + WildTypePattern wtp = (WildTypePattern) parser.parseTypePattern(false,false); // TypePatternList tvs = wtp.getTypeParameters(); // assertEquals("2 type parameters",2,tvs.getTypePatterns().length); // assertEquals("T",new PatternParser("T").parseTypePattern(),tvs.getTypePatterns()[0]); @@ -609,7 +609,7 @@ public class ParserTestCase extends TestCase { public void testTypeParamList() { PatternParser parser = new PatternParser("Bar"); try { - TypePattern tp = parser.parseTypePattern(false); + TypePattern tp = parser.parseTypePattern(false,false); // TypePattern[] tps = tp.getTypeParameters().getTypePatterns(); // assertEquals("3 type patterns",3,tps.length); // assertEquals("T",tps[0].toString()); diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/TypePatternListTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/TypePatternListTestCase.java index 4b1f2c737..accc8c5f5 100644 --- a/weaver/testsrc/org/aspectj/weaver/patterns/TypePatternListTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/patterns/TypePatternListTestCase.java @@ -99,7 +99,7 @@ public class TypePatternListTestCase extends TestCase { } private TypePatternList makeArgumentsPattern(String pattern) { - return new PatternParser(pattern).parseArgumentsPattern(); + return new PatternParser(pattern).parseArgumentsPattern(false); } private void checkStaticMatch(String pattern, String[] names,