diff options
author | aclement <aclement> | 2009-01-30 22:19:43 +0000 |
---|---|---|
committer | aclement <aclement> | 2009-01-30 22:19:43 +0000 |
commit | edafd55ed6eb5a20b160c798c7f5523f44498e62 (patch) | |
tree | d45b8006fbffdf3f8a1b3abf81fb8c4658ffb8f6 | |
parent | b62098640ed0a6b027e166b0978543500a9c5cea (diff) | |
download | aspectj-edafd55ed6eb5a20b160c798c7f5523f44498e62.tar.gz aspectj-edafd55ed6eb5a20b160c798c7f5523f44498e62.zip |
262905: recursive non matching cflow pointcut: set source context for matches nothing pointcut
-rw-r--r-- | org.aspectj.matcher/src/org/aspectj/weaver/patterns/ReferencePointcut.java | 265 |
1 files changed, 131 insertions, 134 deletions
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/ReferencePointcut.java b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/ReferencePointcut.java index 6ac7d0f97..f225f80b4 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/ReferencePointcut.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/ReferencePointcut.java @@ -10,7 +10,6 @@ * PARC initial implementation * ******************************************************************/ - package org.aspectj.weaver.patterns; import java.io.DataOutputStream; @@ -39,69 +38,67 @@ import org.aspectj.weaver.ast.Test; /** */ -//XXX needs check that arguments contains no WildTypePatterns +// XXX needs check that arguments contains no WildTypePatterns public class ReferencePointcut extends Pointcut { - public UnresolvedType onType; - public TypePattern onTypeSymbolic; + public UnresolvedType onType; + public TypePattern onTypeSymbolic; public String name; public TypePatternList arguments; - + /** * if this is non-null then when the pointcut is concretized the result will be parameterized too. */ private Map typeVariableMap; - - //public ResolvedPointcut binding; - + + // public ResolvedPointcut binding; + public ReferencePointcut(TypePattern onTypeSymbolic, String name, TypePatternList arguments) { this.onTypeSymbolic = onTypeSymbolic; this.name = name; this.arguments = arguments; this.pointcutKind = REFERENCE; } - + public ReferencePointcut(UnresolvedType onType, String name, TypePatternList arguments) { this.onType = onType; this.name = name; this.arguments = arguments; this.pointcutKind = REFERENCE; } - + public int couldMatchKinds() { return Shadow.ALL_SHADOW_KINDS_BITS; } - - //??? do either of these match methods make any sense??? + // ??? do either of these match methods make any sense??? public FuzzyBoolean fastMatch(FastMatchInfo type) { return FuzzyBoolean.MAYBE; } - + /** * Do I really match this shadow? */ protected FuzzyBoolean matchInternal(Shadow shadow) { return FuzzyBoolean.NO; } - + public String toString() { StringBuffer buf = new StringBuffer(); if (onType != null) { buf.append(onType); buf.append("."); -// for (int i=0, len=fromType.length; i < len; i++) { -// buf.append(fromType[i]); -// buf.append("."); -// } + // for (int i=0, len=fromType.length; i < len; i++) { + // buf.append(fromType[i]); + // buf.append("."); + // } } buf.append(name); buf.append(arguments.toString()); return buf.toString(); } - public void write(DataOutputStream s) throws IOException { - //XXX ignores onType + // XXX ignores onType s.writeByte(Pointcut.REFERENCE); if (onType != null) { s.writeBoolean(true); @@ -109,30 +106,31 @@ public class ReferencePointcut extends Pointcut { } else { s.writeBoolean(false); } - + s.writeUTF(name); arguments.write(s); writeLocation(s); } - + public static Pointcut read(VersionedDataInputStream s, ISourceContext context) throws IOException { UnresolvedType onType = null; if (s.readBoolean()) { onType = UnresolvedType.read(s); } - ReferencePointcut ret = new ReferencePointcut(onType, s.readUTF(), - TypePatternList.read(s, context)); + ReferencePointcut ret = new ReferencePointcut(onType, s.readUTF(), TypePatternList.read(s, context)); ret.readLocation(context, s); return ret; } - + public void resolveBindings(IScope scope, Bindings bindings) { if (onTypeSymbolic != null) { onType = onTypeSymbolic.resolveExactType(scope, bindings); // in this case we've already signalled an error - if (ResolvedType.isMissing(onType)) return; + if (ResolvedType.isMissing(onType)) { + return; + } } - + ResolvedType searchType; if (onType != null) { searchType = scope.getWorld().resolve(onType); @@ -140,21 +138,21 @@ public class ReferencePointcut extends Pointcut { searchType = scope.getEnclosingType(); } if (searchType.isTypeVariableReference()) { - searchType = ((TypeVariableReference)searchType).getTypeVariable().getUpperBound().resolve(scope.getWorld()); + searchType = ((TypeVariableReference) searchType).getTypeVariable().getUpperBound().resolve(scope.getWorld()); } - - + arguments.resolveBindings(scope, bindings, true, true); - //XXX ensure that arguments has no ..'s in it - + // XXX ensure that arguments has no ..'s in it + // check that I refer to a real pointcut declaration and that I match - + ResolvedPointcutDefinition pointcutDef = searchType.findPointcut(name); // if we're not a static reference, then do a lookup of outers if (pointcutDef == null && onType == null) { while (true) { UnresolvedType declaringType = searchType.getDeclaringType(); - if (declaringType == null) break; + if (declaringType == null) + break; searchType = declaringType.resolve(scope.getWorld()); pointcutDef = searchType.findPointcut(name); if (pointcutDef != null) { @@ -164,41 +162,37 @@ public class ReferencePointcut extends Pointcut { } } } - + if (pointcutDef == null) { scope.message(IMessage.ERROR, this, "can't find referenced pointcut " + name); return; - } - + } + // check visibility if (!pointcutDef.isVisible(scope.getEnclosingType())) { scope.message(IMessage.ERROR, this, "pointcut declaration " + pointcutDef + " is not accessible"); return; } - + if (Modifier.isAbstract(pointcutDef.getModifiers())) { - if (onType != null && !onType.isTypeVariableReference()) { - scope.message(IMessage.ERROR, this, - "can't make static reference to abstract pointcut"); + if (onType != null && !onType.isTypeVariableReference()) { + scope.message(IMessage.ERROR, this, "can't make static reference to abstract pointcut"); return; } else if (!searchType.isAbstract()) { - scope.message(IMessage.ERROR, this, - "can't use abstract pointcut in concrete context"); + scope.message(IMessage.ERROR, this, "can't use abstract pointcut in concrete context"); return; } } - - - ResolvedType[] parameterTypes = - scope.getWorld().resolve(pointcutDef.getParameterTypes()); - + + ResolvedType[] parameterTypes = scope.getWorld().resolve(pointcutDef.getParameterTypes()); + if (parameterTypes.length != arguments.size()) { - scope.message(IMessage.ERROR, this, "incompatible number of arguments to pointcut, expected " + - parameterTypes.length + " found " + arguments.size()); + scope.message(IMessage.ERROR, this, "incompatible number of arguments to pointcut, expected " + parameterTypes.length + + " found " + arguments.size()); return; } - - //if (onType == null) onType = pointcutDef.getDeclaringType(); + + // if (onType == null) onType = pointcutDef.getDeclaringType(); if (onType != null) { if (onType.isParameterizedType()) { // build a type map mapping type variable names in the generic type to @@ -206,46 +200,44 @@ public class ReferencePointcut extends Pointcut { typeVariableMap = new HashMap(); ResolvedType underlyingGenericType = ((ResolvedType) onType).getGenericType(); TypeVariable[] tVars = underlyingGenericType.getTypeVariables(); - ResolvedType[] typeParams = ((ResolvedType)onType).getResolvedTypeParameters(); + ResolvedType[] typeParams = ((ResolvedType) onType).getResolvedTypeParameters(); for (int i = 0; i < tVars.length; i++) { - typeVariableMap.put(tVars[i].getName(),typeParams[i]); + typeVariableMap.put(tVars[i].getName(), typeParams[i]); } } else if (onType.isGenericType()) { scope.message(MessageUtil.error(WeaverMessages.format(WeaverMessages.CANT_REFERENCE_POINTCUT_IN_RAW_TYPE), getSourceLocation())); - } + } } - - for (int i=0,len=arguments.size(); i < len; i++) { + + for (int i = 0, len = arguments.size(); i < len; i++) { TypePattern p = arguments.get(i); - //we are allowed to bind to pointcuts which use subtypes as this is type safe + // we are allowed to bind to pointcuts which use subtypes as this is type safe if (typeVariableMap != null) { - p = p.parameterizeWith(typeVariableMap,scope.getWorld()); + p = p.parameterizeWith(typeVariableMap, scope.getWorld()); } if (p == TypePattern.NO) { - scope.message(IMessage.ERROR, this, - "bad parameter to pointcut reference"); + scope.message(IMessage.ERROR, this, "bad parameter to pointcut reference"); return; } - + boolean reportProblem = false; if (parameterTypes[i].isTypeVariableReference() && p.getExactType().isTypeVariableReference()) { - UnresolvedType One = ((TypeVariableReference)parameterTypes[i]).getTypeVariable().getFirstBound(); - UnresolvedType Two = ((TypeVariableReference)p.getExactType()).getTypeVariable().getFirstBound(); + UnresolvedType One = ((TypeVariableReference) parameterTypes[i]).getTypeVariable().getFirstBound(); + UnresolvedType Two = ((TypeVariableReference) p.getExactType()).getTypeVariable().getFirstBound(); reportProblem = !One.resolve(scope.getWorld()).isAssignableFrom(Two.resolve(scope.getWorld())); } else { - reportProblem = !p.matchesSubtypes(parameterTypes[i]) && - !p.getExactType().equals(UnresolvedType.OBJECT); + reportProblem = !p.matchesSubtypes(parameterTypes[i]) && !p.getExactType().equals(UnresolvedType.OBJECT); } if (reportProblem) { - scope.message(IMessage.ERROR, this, "incompatible type, expected " + - parameterTypes[i].getName() + " found " + p +". Check the type specified in your pointcut"); + scope.message(IMessage.ERROR, this, "incompatible type, expected " + parameterTypes[i].getName() + " found " + p + + ". Check the type specified in your pointcut"); return; } } } - + public void postRead(ResolvedType enclosingType) { arguments.postRead(enclosingType); } @@ -254,37 +246,38 @@ public class ReferencePointcut extends Pointcut { throw new RuntimeException("shouldn't happen"); } - - //??? This is not thread safe, but this class is not designed for multi-threading + // ??? This is not thread safe, but this class is not designed for multi-threading private boolean concretizing = false; + // declaring type is the type that declared the member referencing this pointcut. // If it declares a matching private pointcut, then that pointcut should be used // and not one in a subtype that happens to have the same name. public Pointcut concretize1(ResolvedType searchStart, ResolvedType declaringType, IntMap bindings) { if (concretizing) { - //Thread.currentThread().dumpStack(); + // Thread.currentThread().dumpStack(); searchStart.getWorld().getMessageHandler().handleMessage( - MessageUtil.error(WeaverMessages.format(WeaverMessages.CIRCULAR_POINTCUT,this), - getSourceLocation())); - return Pointcut.makeMatchesNothing(Pointcut.CONCRETE); + MessageUtil.error(WeaverMessages.format(WeaverMessages.CIRCULAR_POINTCUT, this), getSourceLocation())); + Pointcut p = Pointcut.makeMatchesNothing(Pointcut.CONCRETE); + p.sourceContext = sourceContext; + return p; } - + try { concretizing = true; - + ResolvedPointcutDefinition pointcutDec; if (onType != null) { searchStart = onType.resolve(searchStart.getWorld()); if (searchStart.isMissing()) { return Pointcut.makeMatchesNothing(Pointcut.CONCRETE); } - + if (onType.isTypeVariableReference()) { // need to replace on type with the binding for the type variable // in the declaring type if (declaringType.isParameterizedType()) { TypeVariable[] tvs = declaringType.getGenericType().getTypeVariables(); - String typeVariableName = ((TypeVariableReference)onType).getTypeVariable().getName(); + String typeVariableName = ((TypeVariableReference) onType).getTypeVariable().getName(); for (int i = 0; i < tvs.length; i++) { if (tvs[i].getName().equals(typeVariableName)) { ResolvedType realOnType = declaringType.getTypeParameters()[i].resolve(declaringType.getWorld()); @@ -298,45 +291,46 @@ public class ReferencePointcut extends Pointcut { } - if (declaringType == null) declaringType = searchStart; + if (declaringType == null) + declaringType = searchStart; pointcutDec = declaringType.findPointcut(name); boolean foundMatchingPointcut = (pointcutDec != null && pointcutDec.isPrivate()); - if (!foundMatchingPointcut) { + if (!foundMatchingPointcut) { pointcutDec = searchStart.findPointcut(name); if (pointcutDec == null) { searchStart.getWorld().getMessageHandler().handleMessage( - MessageUtil.error(WeaverMessages.format(WeaverMessages.CANT_FIND_POINTCUT,name,searchStart.getName()), - getSourceLocation()) - ); + MessageUtil.error( + WeaverMessages.format(WeaverMessages.CANT_FIND_POINTCUT, name, searchStart.getName()), + getSourceLocation())); return Pointcut.makeMatchesNothing(Pointcut.CONCRETE); } } - + if (pointcutDec.isAbstract()) { - //Thread.currentThread().dumpStack(); + // Thread.currentThread().dumpStack(); ShadowMunger enclosingAdvice = bindings.getEnclosingAdvice(); searchStart.getWorld().showMessage(IMessage.ERROR, - WeaverMessages.format(WeaverMessages.ABSTRACT_POINTCUT,pointcutDec), - getSourceLocation(), + WeaverMessages.format(WeaverMessages.ABSTRACT_POINTCUT, pointcutDec), getSourceLocation(), (null == enclosingAdvice) ? null : enclosingAdvice.getSourceLocation()); return Pointcut.makeMatchesNothing(Pointcut.CONCRETE); } - - //System.err.println("start: " + searchStart); -// ResolvedType[] parameterTypes = searchStart.getWorld().resolve(pointcutDec.getParameterTypes()); - + + // System.err.println("start: " + searchStart); + // ResolvedType[] parameterTypes = searchStart.getWorld().resolve(pointcutDec.getParameterTypes()); + TypePatternList arguments = this.arguments.resolveReferences(bindings); - + IntMap newBindings = new IntMap(); - for (int i=0,len=arguments.size(); i < len; i++) { + for (int i = 0, len = arguments.size(); i < len; i++) { TypePattern p = arguments.get(i); - if (p == TypePattern.NO) continue; + if (p == TypePattern.NO) + continue; // we are allowed to bind to pointcuts which use subtypes as this is type safe - // this will be checked in ReferencePointcut.resolveBindings(). Can't check it here + // this will be checked in ReferencePointcut.resolveBindings(). Can't check it here // as we don't know about any new parents added via decp. - if (p instanceof BindingTypePattern) { - newBindings.put(i, ((BindingTypePattern)p).getFormalIndex()); - } + if (p instanceof BindingTypePattern) { + newBindings.put(i, ((BindingTypePattern) p).getFormalIndex()); + } } if (searchStart.isParameterizedType()) { @@ -347,61 +341,64 @@ public class ReferencePointcut extends Pointcut { TypeVariable[] tVars = underlyingGenericType.getTypeVariables(); ResolvedType[] typeParams = searchStart.getResolvedTypeParameters(); for (int i = 0; i < tVars.length; i++) { - typeVariableMap.put(tVars[i].getName(),typeParams[i]); + typeVariableMap.put(tVars[i].getName(), typeParams[i]); } } - + newBindings.copyContext(bindings); newBindings.pushEnclosingDefinition(pointcutDec); try { Pointcut ret = pointcutDec.getPointcut(); - if (typeVariableMap != null && !hasBeenParameterized) { - ret = ret.parameterizeWith(typeVariableMap,searchStart.getWorld()); - ret.hasBeenParameterized=true; + if (typeVariableMap != null && !hasBeenParameterized) { + ret = ret.parameterizeWith(typeVariableMap, searchStart.getWorld()); + ret.hasBeenParameterized = true; } return ret.concretize(searchStart, declaringType, newBindings); } finally { newBindings.popEnclosingDefinitition(); } - + } finally { concretizing = false; } } /** - * make a version of this pointcut with any refs to typeVariables replaced by their entry in the map. - * Tricky thing is, we can't do this at the point in time this method will be called, so we make a - * version that will parameterize the pointcut it ultimately resolves to. + * make a version of this pointcut with any refs to typeVariables replaced by their entry in the map. Tricky thing is, we can't + * do this at the point in time this method will be called, so we make a version that will parameterize the pointcut it + * ultimately resolves to. */ - public Pointcut parameterizeWith(Map typeVariableMap,World w) { - ReferencePointcut ret = new ReferencePointcut(onType,name,arguments); + public Pointcut parameterizeWith(Map typeVariableMap, World w) { + ReferencePointcut ret = new ReferencePointcut(onType, name, arguments); ret.onTypeSymbolic = onTypeSymbolic; ret.typeVariableMap = typeVariableMap; return ret; } - - // We want to keep the original source location, not the reference location - protected boolean shouldCopyLocationForConcretize() { - return false; - } - - public boolean equals(Object other) { - if (!(other instanceof ReferencePointcut)) return false; - if (this == other) return true; - ReferencePointcut o = (ReferencePointcut)other; - return o.name.equals(name) && o.arguments.equals(arguments) - && ((o.onType == null) ? (onType == null) : o.onType.equals(onType)); - } - public int hashCode() { - int result = 17; - result = 37*result + ((onType == null) ? 0 : onType.hashCode()); - result = 37*result + arguments.hashCode(); - result = 37*result + name.hashCode(); - return result; - } - - public Object accept(PatternNodeVisitor visitor, Object data) { - return visitor.visit(this, data); - } + + // We want to keep the original source location, not the reference location + protected boolean shouldCopyLocationForConcretize() { + return false; + } + + public boolean equals(Object other) { + if (!(other instanceof ReferencePointcut)) + return false; + if (this == other) + return true; + ReferencePointcut o = (ReferencePointcut) other; + return o.name.equals(name) && o.arguments.equals(arguments) + && ((o.onType == null) ? (onType == null) : o.onType.equals(onType)); + } + + public int hashCode() { + int result = 17; + result = 37 * result + ((onType == null) ? 0 : onType.hashCode()); + result = 37 * result + arguments.hashCode(); + result = 37 * result + name.hashCode(); + return result; + } + + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this, data); + } } |