]> source.dussan.org Git - aspectj.git/commitdiff
148508, 265418: tests and fixes: array and varargs subtype patterns
authoraclement <aclement>
Thu, 19 Feb 2009 21:04:10 +0000 (21:04 +0000)
committeraclement <aclement>
Thu, 19 Feb 2009 21:04:10 +0000 (21:04 +0000)
org.aspectj.matcher/src/org/aspectj/weaver/patterns/ExactTypePattern.java
org.aspectj.matcher/src/org/aspectj/weaver/patterns/PatternParser.java
org.aspectj.matcher/src/org/aspectj/weaver/patterns/TypePattern.java
org.aspectj.matcher/testsrc/org/aspectj/weaver/patterns/TypePatternTestCase.java

index 859e8316fe2005b58ac1bc460b2dee2299f16bd0..6f34590c5172305a4890e4509a347bb74a05a28b 100644 (file)
@@ -10,7 +10,6 @@
  *     PARC     initial implementation 
  * ******************************************************************/
 
-
 package org.aspectj.weaver.patterns;
 
 import java.io.DataInputStream;
@@ -36,57 +35,74 @@ public class ExactTypePattern extends TypePattern {
        public static final Map primitiveTypesMap;
        public static final Map boxedPrimitivesMap;
        private static final Map boxedTypesMap;
-       
+
        static {
                primitiveTypesMap = new HashMap();
-               primitiveTypesMap.put("int",int.class);
-               primitiveTypesMap.put("short",short.class);
-               primitiveTypesMap.put("long",long.class);
-               primitiveTypesMap.put("byte",byte.class);
-               primitiveTypesMap.put("char",char.class);
-               primitiveTypesMap.put("float",float.class);
-               primitiveTypesMap.put("double",double.class);
+               primitiveTypesMap.put("int", int.class);
+               primitiveTypesMap.put("short", short.class);
+               primitiveTypesMap.put("long", long.class);
+               primitiveTypesMap.put("byte", byte.class);
+               primitiveTypesMap.put("char", char.class);
+               primitiveTypesMap.put("float", float.class);
+               primitiveTypesMap.put("double", double.class);
 
                boxedPrimitivesMap = new HashMap();
-               boxedPrimitivesMap.put("java.lang.Integer",Integer.class);
-               boxedPrimitivesMap.put("java.lang.Short",Short.class);
-               boxedPrimitivesMap.put("java.lang.Long",Long.class);
-               boxedPrimitivesMap.put("java.lang.Byte",Byte.class);
-               boxedPrimitivesMap.put("java.lang.Character",Character.class);
-               boxedPrimitivesMap.put("java.lang.Float",Float.class);
-               boxedPrimitivesMap.put("java.lang.Double",Double.class);
-
-               
+               boxedPrimitivesMap.put("java.lang.Integer", Integer.class);
+               boxedPrimitivesMap.put("java.lang.Short", Short.class);
+               boxedPrimitivesMap.put("java.lang.Long", Long.class);
+               boxedPrimitivesMap.put("java.lang.Byte", Byte.class);
+               boxedPrimitivesMap.put("java.lang.Character", Character.class);
+               boxedPrimitivesMap.put("java.lang.Float", Float.class);
+               boxedPrimitivesMap.put("java.lang.Double", Double.class);
+
                boxedTypesMap = new HashMap();
-               boxedTypesMap.put("int",Integer.class);
-               boxedTypesMap.put("short",Short.class);
-               boxedTypesMap.put("long",Long.class);
-               boxedTypesMap.put("byte",Byte.class);
-               boxedTypesMap.put("char",Character.class);
-               boxedTypesMap.put("float",Float.class);
-               boxedTypesMap.put("double",Double.class);
+               boxedTypesMap.put("int", Integer.class);
+               boxedTypesMap.put("short", Short.class);
+               boxedTypesMap.put("long", Long.class);
+               boxedTypesMap.put("byte", Byte.class);
+               boxedTypesMap.put("char", Character.class);
+               boxedTypesMap.put("float", Float.class);
+               boxedTypesMap.put("double", Double.class);
 
        }
-       
-       public ExactTypePattern(UnresolvedType type, boolean includeSubtypes,boolean isVarArgs) {
-               super(includeSubtypes,isVarArgs);
+
+       protected boolean matchesSubtypes(ResolvedType type) {
+               boolean match = super.matchesSubtypes(type);
+               if (match) {
+                       return match;
+               }
+               // are we dealing with array funkyness - pattern might be jlObject[]+ and type jlString[]
+               if (type.isArray() && this.type.isArray()) {
+                       ResolvedType componentType = type.getComponentType().resolve(type.getWorld());
+                       UnresolvedType newPatternType = this.type.getComponentType();
+                       ExactTypePattern etp = new ExactTypePattern(newPatternType, includeSubtypes, false);
+                       return etp.matchesSubtypes(componentType, type);
+               }
+               return match;
+       }
+
+       public ExactTypePattern(UnresolvedType type, boolean includeSubtypes, boolean isVarArgs) {
+               super(includeSubtypes, isVarArgs);
                this.type = type;
        }
-       
-       public boolean isArray() { 
+
+       public boolean isArray() {
                return type.isArray();
        }
-       
-       /* (non-Javadoc)
+
+       /*
+        * (non-Javadoc)
+        * 
         * @see org.aspectj.weaver.patterns.TypePattern#couldEverMatchSameTypesAs(org.aspectj.weaver.patterns.TypePattern)
         */
        protected boolean couldEverMatchSameTypesAs(TypePattern other) {
-               if (super.couldEverMatchSameTypesAs(other)) return true;
+               if (super.couldEverMatchSameTypesAs(other))
+                       return true;
                // false is necessary but not sufficient
                UnresolvedType otherType = other.getExactType();
                if (!ResolvedType.isMissing(otherType)) {
                        return type.equals(otherType);
-               } 
+               }
                if (other instanceof WildTypePattern) {
                        WildTypePattern owtp = (WildTypePattern) other;
                        String yourSimpleNamePrefix = owtp.getNamePatterns()[0].maybeGetSimpleName();
@@ -96,91 +112,99 @@ public class ExactTypePattern extends TypePattern {
                }
                return true;
        }
-       
+
        protected boolean matchesExactly(ResolvedType matchType) {
                boolean typeMatch = this.type.equals(matchType);
                if (!typeMatch && (matchType.isParameterizedType() || matchType.isGenericType())) {
                        typeMatch = this.type.equals(matchType.getRawType());
                }
                if (!typeMatch && matchType.isTypeVariableReference()) {
-                       typeMatch = matchesTypeVariable((TypeVariableReferenceType)matchType);
+                       typeMatch = matchesTypeVariable((TypeVariableReferenceType) matchType);
                }
                annotationPattern.resolve(matchType.getWorld());
                boolean annMatch = false;
-        if (matchType.temporaryAnnotationTypes!=null) {
-            annMatch = annotationPattern.matches(matchType,matchType.temporaryAnnotationTypes).alwaysTrue();
-        } else {
-            annMatch = annotationPattern.matches(matchType).alwaysTrue();
-        }
+               if (matchType.temporaryAnnotationTypes != null) {
+                       annMatch = annotationPattern.matches(matchType, matchType.temporaryAnnotationTypes).alwaysTrue();
+               } else {
+                       annMatch = annotationPattern.matches(matchType).alwaysTrue();
+               }
                return (typeMatch && annMatch);
        }
-       
+
        private boolean matchesTypeVariable(TypeVariableReferenceType matchType) {
-           // was this method previously coded to return false *on purpose* ??  pr124808
-               return this.type.equals(((TypeVariableReference)matchType).getTypeVariable().getFirstBound());
-               //return false;
+               // was this method previously coded to return false *on purpose* ?? pr124808
+               return this.type.equals(((TypeVariableReference) matchType).getTypeVariable().getFirstBound());
+               // return false;
        }
-       
+
        protected boolean matchesExactly(ResolvedType matchType, ResolvedType annotatedType) {
                boolean typeMatch = this.type.equals(matchType);
                if (!typeMatch && (matchType.isParameterizedType() || matchType.isGenericType())) {
                        typeMatch = this.type.equals(matchType.getRawType());
                }
                if (!typeMatch && matchType.isTypeVariableReference()) {
-                       typeMatch = matchesTypeVariable((TypeVariableReferenceType)matchType);
+                       typeMatch = matchesTypeVariable((TypeVariableReferenceType) matchType);
                }
                annotationPattern.resolve(matchType.getWorld());
-        boolean annMatch = false;
-        if (annotatedType.temporaryAnnotationTypes!=null) {
-            annMatch = annotationPattern.matches(annotatedType,annotatedType.temporaryAnnotationTypes).alwaysTrue();
-        } else {
-            annMatch = annotationPattern.matches(annotatedType).alwaysTrue();
-        }
-               return (typeMatch && annMatch);         
+               boolean annMatch = false;
+               if (annotatedType.temporaryAnnotationTypes != null) {
+                       annMatch = annotationPattern.matches(annotatedType, annotatedType.temporaryAnnotationTypes).alwaysTrue();
+               } else {
+                       annMatch = annotationPattern.matches(annotatedType).alwaysTrue();
+               }
+               return (typeMatch && annMatch);
+       }
+
+       public UnresolvedType getType() {
+               return type;
        }
-       
-       public UnresolvedType getType() { return type; }
 
        // true if (matchType instanceof this.type)
        public FuzzyBoolean matchesInstanceof(ResolvedType matchType) {
                // in our world, Object is assignable from anything
                annotationPattern.resolve(matchType.getWorld());
-               if (type.equals(ResolvedType.OBJECT)) 
-                   return FuzzyBoolean.YES.and(annotationPattern.matches(matchType));
-               
+               if (type.equals(ResolvedType.OBJECT))
+                       return FuzzyBoolean.YES.and(annotationPattern.matches(matchType));
+
                if (type.resolve(matchType.getWorld()).isAssignableFrom(matchType)) {
                        return FuzzyBoolean.YES.and(annotationPattern.matches(matchType));
                }
-               
+
                // fix for PR 64262 - shouldn't try to coerce primitives
                if (type.isPrimitiveType()) {
                        return FuzzyBoolean.NO;
                } else {
-                   return matchType.isCoerceableFrom(type.resolve(matchType.getWorld())) ? FuzzyBoolean.MAYBE : FuzzyBoolean.NO;
+                       return matchType.isCoerceableFrom(type.resolve(matchType.getWorld())) ? FuzzyBoolean.MAYBE : FuzzyBoolean.NO;
                }
        }
-               
-    public boolean equals(Object other) {
-       if (!(other instanceof ExactTypePattern)) return false;
-       if (other instanceof BindingTypePattern) return false;
-       ExactTypePattern o = (ExactTypePattern)other;
-       if (includeSubtypes != o.includeSubtypes) return false;
-       if (isVarArgs != o.isVarArgs) return false;     
-       if (!typeParameters.equals(o.typeParameters)) return false;
-       return (o.type.equals(this.type) && o.annotationPattern.equals(this.annotationPattern));
-    }
-    
-    public int hashCode() {
-        int result = 17;
-        result = 37*result + type.hashCode();
-        result = 37*result + new Boolean(includeSubtypes).hashCode();
-        result = 37*result + new Boolean(isVarArgs).hashCode();
-        result = 37*result + typeParameters.hashCode();
-        result = 37*result + annotationPattern.hashCode();
-        return result;
-    }
-
-    private static final byte EXACT_VERSION = 1; // rev if changed
+
+       public boolean equals(Object other) {
+               if (!(other instanceof ExactTypePattern))
+                       return false;
+               if (other instanceof BindingTypePattern)
+                       return false;
+               ExactTypePattern o = (ExactTypePattern) other;
+               if (includeSubtypes != o.includeSubtypes)
+                       return false;
+               if (isVarArgs != o.isVarArgs)
+                       return false;
+               if (!typeParameters.equals(o.typeParameters))
+                       return false;
+               return (o.type.equals(this.type) && o.annotationPattern.equals(this.annotationPattern));
+       }
+
+       public int hashCode() {
+               int result = 17;
+               result = 37 * result + type.hashCode();
+               result = 37 * result + new Boolean(includeSubtypes).hashCode();
+               result = 37 * result + new Boolean(isVarArgs).hashCode();
+               result = 37 * result + typeParameters.hashCode();
+               result = 37 * result + annotationPattern.hashCode();
+               return result;
+       }
+
+       private static final byte EXACT_VERSION = 1; // rev if changed
+
        public void write(DataOutputStream out) throws IOException {
                out.writeByte(TypePattern.EXACT);
                out.writeByte(EXACT_VERSION);
@@ -191,27 +215,28 @@ public class ExactTypePattern extends TypePattern {
                typeParameters.write(out);
                writeLocation(out);
        }
-       
+
        public static TypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
-               if (s.getMajorVersion()>=AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) {
-                       return readTypePattern150(s,context);
+               if (s.getMajorVersion() >= AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) {
+                       return readTypePattern150(s, context);
                } else {
-                       return readTypePatternOldStyle(s,context);
-           }
-    }
-       
+                       return readTypePatternOldStyle(s, context);
+               }
+       }
+
        public static TypePattern readTypePattern150(VersionedDataInputStream s, ISourceContext context) throws IOException {
                byte version = s.readByte();
-               if (version > EXACT_VERSION) throw new BCException("ExactTypePattern was written by a more recent version of AspectJ");
+               if (version > EXACT_VERSION)
+                       throw new BCException("ExactTypePattern was written by a more recent version of AspectJ");
                TypePattern ret = new ExactTypePattern(UnresolvedType.read(s), s.readBoolean(), s.readBoolean());
-               ret.setAnnotationTypePattern(AnnotationTypePattern.read(s,context));
-               ret.setTypeParameters(TypePatternList.read(s,context));
+               ret.setAnnotationTypePattern(AnnotationTypePattern.read(s, context));
+               ret.setTypeParameters(TypePatternList.read(s, context));
                ret.readLocation(context, s);
                return ret;
        }
 
        public static TypePattern readTypePatternOldStyle(DataInputStream s, ISourceContext context) throws IOException {
-               TypePattern ret = new ExactTypePattern(UnresolvedType.read(s), s.readBoolean(),false);
+               TypePattern ret = new ExactTypePattern(UnresolvedType.read(s), s.readBoolean(), false);
                ret.readLocation(context, s);
                return ret;
        }
@@ -224,27 +249,28 @@ public class ExactTypePattern extends TypePattern {
                        buff.append(' ');
                }
                String typeString = type.toString();
-               if (isVarArgs) typeString = typeString.substring(0,typeString.lastIndexOf('['));
+               if (isVarArgs)
+                       typeString = typeString.substring(0, typeString.lastIndexOf('['));
                buff.append(typeString);
-       if (includeSubtypes) buff.append('+');
-       if (isVarArgs) buff.append("...");
+               if (includeSubtypes)
+                       buff.append('+');
+               if (isVarArgs)
+                       buff.append("...");
                if (annotationPattern != AnnotationTypePattern.ANY) {
                        buff.append(')');
                }
                return buff.toString();
-    }
-       public TypePattern resolveBindings(IScope scope, Bindings bindings, 
-                                                               boolean allowBinding, boolean requireExactType)
-    { 
+       }
+
+       public TypePattern resolveBindings(IScope scope, Bindings bindings, boolean allowBinding, boolean requireExactType) {
                throw new BCException("trying to re-resolve");
-               
+
        }
-       
+
        /**
-        * return a version of this type pattern with all type variables references replaced
-        * by the corresponding entry in the map.
+        * return a version of this type pattern with all type variables references replaced by the corresponding entry in the map.
         */
-       public TypePattern parameterizeWith(Map typeVariableMap,World w) {
+       public TypePattern parameterizeWith(Map typeVariableMap, World w) {
                UnresolvedType newType = type;
                if (type.isTypeVariableReference()) {
                        TypeVariableReference t = (TypeVariableReference) type;
@@ -255,14 +281,14 @@ public class ExactTypePattern extends TypePattern {
                } else if (type.isParameterizedType()) {
                        newType = w.resolve(type).parameterize(typeVariableMap);
                }
-               ExactTypePattern ret = new ExactTypePattern(newType,includeSubtypes,isVarArgs);
-               ret.annotationPattern = annotationPattern.parameterizeWith(typeVariableMap,w);
+               ExactTypePattern ret = new ExactTypePattern(newType, includeSubtypes, isVarArgs);
+               ret.annotationPattern = annotationPattern.parameterizeWith(typeVariableMap, w);
                ret.copyLocationFrom(this);
                return ret;
        }
-       
-    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 4c714b90cd55f23d0c6450670614ac049b2ff94a..5abdc74918c0a2c0abb563bb7c236e9bc40dd96d 100644 (file)
@@ -864,10 +864,16 @@ public class PatternParser {
                TypePatternList typeParameters = maybeParseTypeParameterList();
                int endPos = tokenSource.peek(-1).getEnd();
 
-               boolean isVarArgs = maybeEat("...");
-
                boolean includeSubtypes = maybeEat("+");
 
+               // TODO do we need to associate the + with either the type or the array?
+               while (maybeEat("[")) {
+                       eat("]");
+                       dim++;
+               }
+
+               boolean isVarArgs = maybeEat("...");
+
                // ??? what about the source location of any's????
                if (names.size() == 1 && ((NamePattern) names.get(0)).isAny() && dim == 0 && !isVarArgs && typeParameters == null)
                        return TypePattern.ANY;
@@ -1599,7 +1605,7 @@ public class PatternParser {
        public void checkEof() {
                IToken last = tokenSource.next();
                if (last != IToken.EOF) {
-                       throw new ParserException("unexpected pointcut element", last);
+                       throw new ParserException("unexpected pointcut element: " + last.toString(), last);
                }
        }
 
index ed4f1ddf039b6066c876482570738f031ca9a9c3..a5f7f075974f95084aeb5b87f86b01ecf03385b6 100644 (file)
@@ -10,7 +10,6 @@
  *     PARC     initial implementation 
  * ******************************************************************/
 
-
 package org.aspectj.weaver.patterns;
 
 import java.io.DataOutputStream;
@@ -30,90 +29,99 @@ import org.aspectj.weaver.UnresolvedType;
 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.
+ * 
+ * <p>
+ * Then we call resolveBindings() during compilation During concretization of enclosing pointcuts, we call remapAdviceFormals
  * 
- * <p>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 ||
+
+       // XXX non-final for Not, && and ||
        public boolean matchesStatically(ResolvedType type) {
                if (includeSubtypes) {
                        return matchesSubtypes(type);
@@ -121,64 +129,66 @@ public abstract class TypePattern extends PatternNode {
                        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");
                        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();
-                       // TODO asc generics, temporary whilst matching isnt aware..
-                       //if (superType.isParameterizedType()) superType = superType.getRawType().resolve(superType.getWorld());
-                       if (matchesSubtypes(superType,type)) return true;
+
+               for (Iterator i = typesIterator; i.hasNext();) {
+                       ResolvedType superType = (ResolvedType) i.next();
+                       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("matching2: " + this + " to " + superType);
+               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 +196,94 @@ public abstract class TypePattern extends PatternNode {
                        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.
-     * <pre>
-     * pointcut foo(String name): args(name);
-     * --&gt; This makes a BindingTypePattern(0) pointing to the 0th formal
-     * 
-     * before(Foo f, String n): this(f) && foo(n) { ... }
-     * --&gt; when resolveReferences is called on the args from the above, it
-     *     will return a BindingTypePattern(1)
-     * 
-     * before(Foo f): this(f) && foo(*) { ... }
-     * --&gt; when resolveReferences is called on the args from the above, it
-     *     will return an ExactTypePattern(String)
-     * </pre>
-     */
+       /**
+        * 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.
+        * 
+        * <pre>
+        * pointcut foo(String name): args(name);
+        * --&gt; This makes a BindingTypePattern(0) pointing to the 0th formal
+        * 
+        * before(Foo f, String n): this(f) &amp;&amp; foo(n) { ... }
+        * --&gt; when resolveReferences is called on the args from the above, it
+        *     will return a BindingTypePattern(1)
+        * 
+        * before(Foo f): this(f) &amp;&amp; foo(*) { ... }
+        * --&gt; when resolveReferences is called on the args from the above, it
+        *     will return an ExactTypePattern(String)
+        * </pre>
+        */
        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 +293,29 @@ public abstract class TypePattern extends PatternNode {
 
        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 +327,32 @@ public abstract class TypePattern extends PatternNode {
 }
 
 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 +370,59 @@ class EllipsisTypePattern extends TypePattern {
        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 +433,7 @@ class AnyTypePattern extends TypePattern {
        protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) {
                return true;
        }
-       
+
        /**
         * @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(IType)
         */
@@ -418,56 +451,55 @@ class AnyTypePattern extends TypePattern {
        /**
         * @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 +507,17 @@ class AnyWithAnnotationTypePattern extends TypePattern {
        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;
        }
-       
-       
+
        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 +527,76 @@ class AnyWithAnnotationTypePattern extends TypePattern {
                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);
        }
-       
-       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);
+               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 +618,47 @@ class NoTypePattern extends TypePattern {
        /**
         * @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 "<nothing>"; }//FIXME AV - bad! toString() cannot be parsed back (not idempotent)
-       
-       /* (non-Javadoc)
+
+       public String toString() {
+               return "<nothing>";
+       }// 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 15ccbbd0362bf754e303c5146c2513dd0fbdedbb..e4f5a4dbf2b4ef82dfb6b1c04a02d5f3e8027bc8 100644 (file)
@@ -21,11 +21,6 @@ import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.ResolvedType;
 import org.aspectj.weaver.VersionedDataInputStream;
 import org.aspectj.weaver.World;
-import org.aspectj.weaver.patterns.Bindings;
-import org.aspectj.weaver.patterns.PatternParser;
-import org.aspectj.weaver.patterns.TestScope;
-import org.aspectj.weaver.patterns.TypePattern;
-import org.aspectj.weaver.patterns.WildTypePattern;
 import org.aspectj.weaver.reflect.ReflectionWorld;
 
 public class TypePatternTestCase extends PatternsTestCase {
@@ -170,13 +165,17 @@ public class TypePatternTestCase extends PatternsTestCase {
                checkMatch("*[][]", "java.lang.Object", false);
                checkMatch("*[]", "java.lang.Object[]", true);
                checkMatch("*[][]", "java.lang.Object[][]", true);
+               checkMatch("java.lang.Object+", "java.lang.Object[]", true);
                checkMatch("java.lang.Object[]", "java.lang.Object", false);
                checkMatch("java.lang.Object[]", "java.lang.Object[]", true);
                checkMatch("java.lang.Object[][]", "java.lang.Object[][]", true);
                checkMatch("java.lang.String[]", "java.lang.Object", false);
                checkMatch("java.lang.String[]", "java.lang.Object[]", false);
                checkMatch("java.lang.String[][]", "java.lang.Object[][]", false);
+               checkMatch("java.lang.Object+[]", "java.lang.String[][]", true);
                checkMatch("java.lang.Object+[]", "java.lang.String[]", true);
+               checkMatch("java.lang.Object+[]", "int[][]", true);
+               checkMatch("java.lang.Object+[]", "int[]", false);
        }
 
        private void checkIllegalInstanceofMatch(String pattern, String name) {
@@ -208,7 +207,10 @@ public class TypePatternTestCase extends PatternsTestCase {
        }
 
        private TypePattern makeTypePattern(String pattern) {
-               return new PatternParser(pattern).parseSingleTypePattern();
+               PatternParser pp = new PatternParser(pattern);
+               TypePattern tp = pp.parseSingleTypePattern();
+               pp.checkEof();
+               return tp;
        }
 
        private void checkMatch(String pattern, String name, boolean shouldMatch) {