]> source.dussan.org Git - aspectj.git/commitdiff
262905: recursive non matching cflow pointcut: set source context for matches nothing...
authoraclement <aclement>
Fri, 30 Jan 2009 22:19:43 +0000 (22:19 +0000)
committeraclement <aclement>
Fri, 30 Jan 2009 22:19:43 +0000 (22:19 +0000)
org.aspectj.matcher/src/org/aspectj/weaver/patterns/ReferencePointcut.java

index 6ac7d0f970681176851aa5ce48058e1919c52cb8..f225f80b45459b09f4d660e45faca2137ebbd396 100644 (file)
@@ -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);
+       }
 }