diff options
Diffstat (limited to 'org.aspectj.matcher/src')
-rw-r--r-- | org.aspectj.matcher/src/org/aspectj/weaver/patterns/WildTypePattern.java | 1296 |
1 files changed, 661 insertions, 635 deletions
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/WildTypePattern.java b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/WildTypePattern.java index 73e36177d..ab72026a1 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/WildTypePattern.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/WildTypePattern.java @@ -10,7 +10,6 @@ * PARC initial implementation * ******************************************************************/ - package org.aspectj.weaver.patterns; import java.io.DataOutputStream; @@ -43,37 +42,26 @@ import org.aspectj.weaver.WeaverMessages; import org.aspectj.weaver.World; /** - * The PatternParser always creates WildTypePatterns for type patterns in pointcut - * expressions (apart from *, which is sometimes directly turned into TypePattern.ANY). - * resolveBindings() tries to work out what we've really got and turn it into a type - * pattern that we can use for matching. This will normally be either an ExactTypePattern - * or a WildTypePattern. + * The PatternParser always creates WildTypePatterns for type patterns in pointcut expressions (apart from *, which is sometimes + * directly turned into TypePattern.ANY). resolveBindings() tries to work out what we've really got and turn it into a type pattern + * that we can use for matching. This will normally be either an ExactTypePattern or a WildTypePattern. + * + * Here's how the process pans out for various generic and parameterized patterns: (see GenericsWildTypePatternResolvingTestCase) * - * Here's how the process pans out for various generic and parameterized patterns: - * (see GenericsWildTypePatternResolvingTestCase) + * Foo where Foo exists and is generic Parser creates WildTypePattern namePatterns={Foo} resolveBindings resolves Foo to RT(Foo - + * raw) return ExactTypePattern(LFoo;) * - * Foo where Foo exists and is generic - * Parser creates WildTypePattern namePatterns={Foo} - * resolveBindings resolves Foo to RT(Foo - raw) - * return ExactTypePattern(LFoo;) + * Foo<String> where Foo exists and String meets the bounds Parser creates WildTypePattern namePatterns = {Foo}, + * typeParameters=WTP{String} resolveBindings resolves typeParameters to ExactTypePattern(String) resolves Foo to RT(Foo) returns + * ExactTypePattern(PFoo<String>; - parameterized) * - * Foo<String> where Foo exists and String meets the bounds - * Parser creates WildTypePattern namePatterns = {Foo}, typeParameters=WTP{String} - * resolveBindings resolves typeParameters to ExactTypePattern(String) - * resolves Foo to RT(Foo) - * returns ExactTypePattern(PFoo<String>; - parameterized) - * - * Foo<Str*> where Foo exists and takes one bound - * Parser creates WildTypePattern namePatterns = {Foo}, typeParameters=WTP{Str*} - * resolveBindings resolves typeParameters to WTP{Str*} - * resolves Foo to RT(Foo) - * returns WildTypePattern(name = Foo, typeParameters = WTP{Str*} isGeneric=false) + * Foo<Str*> where Foo exists and takes one bound Parser creates WildTypePattern namePatterns = {Foo}, typeParameters=WTP{Str*} + * resolveBindings resolves typeParameters to WTP{Str*} resolves Foo to RT(Foo) returns WildTypePattern(name = Foo, typeParameters = + * WTP{Str*} isGeneric=false) + * + * Fo*<String> Parser creates WildTypePattern namePatterns = {Fo*}, typeParameters=WTP{String} resolveBindings resolves + * typeParameters to ETP{String} returns WildTypePattern(name = Fo*, typeParameters = ETP{String} isGeneric=false) * - * Fo*<String> - * Parser creates WildTypePattern namePatterns = {Fo*}, typeParameters=WTP{String} - * resolveBindings resolves typeParameters to ETP{String} - * returns WildTypePattern(name = Fo*, typeParameters = ETP{String} isGeneric=false) - * * * Foo<?> * @@ -92,37 +80,38 @@ public class WildTypePattern extends TypePattern { String[] importedPrefixes; String[] knownMatches; int dim; - + // SECRETAPI - just for testing, turns off boundschecking temporarily... public static boolean boundscheckingoff = false; - + // these next three are set if the type pattern is constrained by extends or super clauses, in which case the // namePatterns must have length 1 // TODO AMC: read/write/resolve of these fields - TypePattern upperBound; // extends Foo - TypePattern[] additionalInterfaceBounds; // extends Foo & A,B,C - TypePattern lowerBound; // super Foo + TypePattern upperBound; // extends Foo + TypePattern[] additionalInterfaceBounds; // extends Foo & A,B,C + TypePattern lowerBound; // super Foo // if we have type parameters, these fields indicate whether we should be a generic type pattern or a parameterized // type pattern. We can only tell during resolve bindings. private boolean isGeneric = true; - + WildTypePattern(NamePattern[] namePatterns, boolean includeSubtypes, int dim, boolean isVarArgs, TypePatternList typeParams) { - super(includeSubtypes,isVarArgs,typeParams); + super(includeSubtypes, isVarArgs, typeParams); this.namePatterns = namePatterns; this.dim = dim; ellipsisCount = 0; - for (int i=0; i<namePatterns.length; i++) { - if (namePatterns[i] == NamePattern.ELLIPSIS) ellipsisCount++; + for (int i = 0; i < namePatterns.length; i++) { + if (namePatterns[i] == NamePattern.ELLIPSIS) + ellipsisCount++; } - setLocation(namePatterns[0].getSourceContext(), namePatterns[0].getStart(), namePatterns[namePatterns.length-1].getEnd()); + setLocation(namePatterns[0].getSourceContext(), namePatterns[0].getStart(), namePatterns[namePatterns.length - 1].getEnd()); } public WildTypePattern(List names, boolean includeSubtypes, int dim) { - this((NamePattern[])names.toArray(new NamePattern[names.size()]), includeSubtypes, dim,false,TypePatternList.EMPTY); + this((NamePattern[]) names.toArray(new NamePattern[names.size()]), includeSubtypes, dim, false, TypePatternList.EMPTY); } - + public WildTypePattern(List names, boolean includeSubtypes, int dim, int endPos) { this(names, includeSubtypes, dim); this.end = endPos; @@ -133,75 +122,72 @@ public class WildTypePattern extends TypePattern { this.end = endPos; this.isVarArgs = isVarArg; } - - public WildTypePattern( - List names, - boolean includeSubtypes, - int dim, - int endPos, - boolean isVarArg, - TypePatternList typeParams, - TypePattern upperBound, - TypePattern[] additionalInterfaceBounds, - TypePattern lowerBound) { - this((NamePattern[])names.toArray(new NamePattern[names.size()]),includeSubtypes,dim,isVarArg,typeParams); + + public WildTypePattern(List names, boolean includeSubtypes, int dim, int endPos, boolean isVarArg, TypePatternList typeParams, + TypePattern upperBound, TypePattern[] additionalInterfaceBounds, TypePattern lowerBound) { + this((NamePattern[]) names.toArray(new NamePattern[names.size()]), includeSubtypes, dim, isVarArg, typeParams); this.end = endPos; this.upperBound = upperBound; this.lowerBound = lowerBound; this.additionalInterfaceBounds = additionalInterfaceBounds; } - - public WildTypePattern( - List names, - boolean includeSubtypes, - int dim, - int endPos, - boolean isVarArg, - TypePatternList typeParams) - { - this((NamePattern[])names.toArray(new NamePattern[names.size()]),includeSubtypes,dim,isVarArg,typeParams); - this.end = endPos; + + public WildTypePattern(List names, boolean includeSubtypes, int dim, int endPos, boolean isVarArg, TypePatternList typeParams) { + this((NamePattern[]) names.toArray(new NamePattern[names.size()]), includeSubtypes, dim, isVarArg, typeParams); + this.end = endPos; + } + + public NamePattern[] getNamePatterns() { + return namePatterns; + } + + public TypePattern getUpperBound() { + return upperBound; + } + + public TypePattern getLowerBound() { + return lowerBound; + } + + public TypePattern[] getAdditionalIntefaceBounds() { + return additionalInterfaceBounds; } - - public NamePattern[] getNamePatterns() { - return namePatterns; - } - - public TypePattern getUpperBound() { return upperBound; } - public TypePattern getLowerBound() { return lowerBound; } - public TypePattern[] getAdditionalIntefaceBounds() { return additionalInterfaceBounds; } // called by parser after parsing a type pattern, must bump dim as well as setting flag public void setIsVarArgs(boolean isVarArgs) { this.isVarArgs = isVarArgs; - if (isVarArgs) this.dim += 1; + if (isVarArgs) + this.dim += 1; } - - /* (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)) { if (namePatterns.length > 0) { - if (!namePatterns[0].matches(otherType.getName())) return false; + if (!namePatterns[0].matches(otherType.getName())) + return false; } - } + } if (other instanceof WildTypePattern) { WildTypePattern owtp = (WildTypePattern) other; String mySimpleName = namePatterns[0].maybeGetSimpleName(); String yourSimpleName = owtp.namePatterns[0].maybeGetSimpleName(); if (mySimpleName != null && yourSimpleName != null) { - return (mySimpleName.startsWith(yourSimpleName) || - yourSimpleName.startsWith(mySimpleName)); + return (mySimpleName.startsWith(yourSimpleName) || yourSimpleName.startsWith(mySimpleName)); } } return true; } - - //XXX inefficient implementation + + // XXX inefficient implementation // we don't know whether $ characters are from nested types, or were // part of the declared type name (generated code often uses $s in type // names). More work required on our part to get this right... @@ -209,114 +195,118 @@ public class WildTypePattern extends TypePattern { List ret = new ArrayList(); int startIndex = 0; while (true) { - int breakIndex = s.indexOf('.', startIndex); // what about / - if (convertDollar && (breakIndex == -1)) breakIndex = s.indexOf('$', startIndex); // we treat $ like . here - if (breakIndex == -1) break; - char[] name = s.substring(startIndex, breakIndex).toCharArray(); - ret.add(name); - startIndex = breakIndex+1; + int breakIndex = s.indexOf('.', startIndex); // what about / + if (convertDollar && (breakIndex == -1)) + breakIndex = s.indexOf('$', startIndex); // we treat $ like . here + if (breakIndex == -1) + break; + char[] name = s.substring(startIndex, breakIndex).toCharArray(); + ret.add(name); + startIndex = breakIndex + 1; } ret.add(s.substring(startIndex).toCharArray()); - return (char[][])ret.toArray(new char[ret.size()][]); - } - + return (char[][]) ret.toArray(new char[ret.size()][]); + } /** * @see org.aspectj.weaver.TypePattern#matchesExactly(IType) */ protected boolean matchesExactly(ResolvedType type) { - return matchesExactly(type,type); + return matchesExactly(type, type); } protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) { String targetTypeName = type.getName(); - - //System.err.println("match: " + targetTypeName + ", " + knownMatches); //Arrays.asList(importedPrefixes)); + + // System.err.println("match: " + targetTypeName + ", " + knownMatches); //Arrays.asList(importedPrefixes)); // Ensure the annotation pattern is resolved annotationPattern.resolve(type.getWorld()); - - return matchesExactlyByName(targetTypeName,type.isAnonymous(),type.isNested()) && - matchesParameters(type,STATIC) && - matchesBounds(type,STATIC) && - annotationPattern.matches(annotatedType,type.temporaryAnnotationTypes).alwaysTrue(); + + return matchesExactlyByName(targetTypeName, type.isAnonymous(), type.isNested()) && matchesParameters(type, STATIC) + && matchesBounds(type, STATIC) + && annotationPattern.matches(annotatedType, type.temporaryAnnotationTypes).alwaysTrue(); } - - + // we've matched against the base (or raw) type, but if this type pattern specifies parameters or // type variables we need to make sure we match against them too private boolean matchesParameters(ResolvedType aType, MatchKind staticOrDynamic) { if (!isGeneric && typeParameters.size() > 0) { - if(!aType.isParameterizedType()) return false; + if (!aType.isParameterizedType()) + return false; // we have to match type parameters return typeParameters.matches(aType.getResolvedTypeParameters(), staticOrDynamic).alwaysTrue(); } return true; } - + // we've matched against the base (or raw) type, but if this type pattern specifies bounds because // it is a ? extends or ? super deal then we have to match them too. private boolean matchesBounds(ResolvedType aType, MatchKind staticOrDynamic) { - if (!(aType instanceof BoundedReferenceType)) return true; - BoundedReferenceType boundedRT = (BoundedReferenceType) aType; + if (!(aType instanceof BoundedReferenceType)) + return true; + BoundedReferenceType boundedRT = (BoundedReferenceType) aType; if (upperBound == null && boundedRT.getUpperBound() != null) { // for upper bound, null can also match against Object - but anything else and we're out. if (!boundedRT.getUpperBound().getName().equals(UnresolvedType.OBJECT.getName())) { return false; } } - if (lowerBound == null && boundedRT.getLowerBound() != null) return false; + if (lowerBound == null && boundedRT.getLowerBound() != null) + return false; if (upperBound != null) { // match ? extends - if (aType.isGenericWildcard() && boundedRT.isSuper()) return false; - if (boundedRT.getUpperBound() == null) return false; - return upperBound.matches((ResolvedType) boundedRT.getUpperBound(), staticOrDynamic).alwaysTrue(); + if (aType.isGenericWildcard() && boundedRT.isSuper()) + return false; + if (boundedRT.getUpperBound() == null) + return false; + return upperBound.matches((ResolvedType) boundedRT.getUpperBound(), staticOrDynamic).alwaysTrue(); } if (lowerBound != null) { // match ? super - if (!(boundedRT.isGenericWildcard() && boundedRT.isSuper())) return false; - return lowerBound.matches((ResolvedType) boundedRT.getLowerBound(), staticOrDynamic).alwaysTrue(); + if (!(boundedRT.isGenericWildcard() && boundedRT.isSuper())) + return false; + return lowerBound.matches((ResolvedType) boundedRT.getLowerBound(), staticOrDynamic).alwaysTrue(); } return true; } - + /** - * Used in conjunction with checks on 'isStar()' to tell you if this pattern represents '*' or '*[]' which are - * different ! + * Used in conjunction with checks on 'isStar()' to tell you if this pattern represents '*' or '*[]' which are different ! */ public int getDimensions() { return dim; } - + public boolean isArray() { return dim > 1; } - - /** + + /** * @param targetTypeName * @return */ private boolean matchesExactlyByName(String targetTypeName, boolean isAnonymous, boolean isNested) { // we deal with parameter matching separately... if (targetTypeName.indexOf('<') != -1) { - targetTypeName = targetTypeName.substring(0,targetTypeName.indexOf('<')); + targetTypeName = targetTypeName.substring(0, targetTypeName.indexOf('<')); } // we deal with bounds matching separately too... if (targetTypeName.startsWith(GENERIC_WILDCARD_CHARACTER)) { targetTypeName = GENERIC_WILDCARD_CHARACTER; } - //XXX hack + // XXX hack if (knownMatches == null && importedPrefixes == null) { return innerMatchesExactly(targetTypeName, isAnonymous, isNested); } - + if (isNamePatternStar()) { // we match if the dimensions match int numDimensionsInTargetType = 0; if (dim > 0) { int index; - while((index = targetTypeName.indexOf('[')) != -1) { + while ((index = targetTypeName.indexOf('[')) != -1) { numDimensionsInTargetType++; - targetTypeName = targetTypeName.substring(index+1); + targetTypeName = targetTypeName.substring(index + 1); } if (numDimensionsInTargetType == dim) { return true; @@ -325,7 +315,7 @@ public class WildTypePattern extends TypePattern { } } } - + // if our pattern is length 1, then known matches are exact matches // if it's longer than that, then known matches are prefixes of a sort if (namePatterns.length == 1) { @@ -333,149 +323,159 @@ public class WildTypePattern extends TypePattern { // we've already ruled out "*", and no other name pattern should match an anonymous type return false; } - for (int i=0, len=knownMatches.length; i < len; i++) { - if (knownMatches[i].equals(targetTypeName)) return true; + for (int i = 0, len = knownMatches.length; i < len; i++) { + if (knownMatches[i].equals(targetTypeName)) + return true; } } else { - for (int i=0, len=knownMatches.length; i < len; i++) { + for (int i = 0, len = knownMatches.length; i < len; i++) { String knownPrefix = knownMatches[i] + "$"; if (targetTypeName.startsWith(knownPrefix)) { int pos = lastIndexOfDotOrDollar(knownMatches[i]); - if (innerMatchesExactly(targetTypeName.substring(pos+1),isAnonymous,isNested)) { + if (innerMatchesExactly(targetTypeName.substring(pos + 1), isAnonymous, isNested)) { return true; } } } } - // if any prefixes match, strip the prefix and check that the rest matches // assumes that prefixes have a dot at the end - for (int i=0, len=importedPrefixes.length; i < len; i++) { + for (int i = 0, len = importedPrefixes.length; i < len; i++) { String prefix = importedPrefixes[i]; - //System.err.println("prefix match? " + prefix + " to " + targetTypeName); + // System.err.println("prefix match? " + prefix + " to " + targetTypeName); if (targetTypeName.startsWith(prefix)) { - - if (innerMatchesExactly(targetTypeName.substring(prefix.length()),isAnonymous,isNested)) { + + if (innerMatchesExactly(targetTypeName.substring(prefix.length()), isAnonymous, isNested)) { return true; } } } - - return innerMatchesExactly(targetTypeName,isAnonymous,isNested); + + return innerMatchesExactly(targetTypeName, isAnonymous, isNested); } private int lastIndexOfDotOrDollar(String string) { - int dot = string.lastIndexOf('.'); - int dollar = string.lastIndexOf('$'); - return Math.max(dot, dollar); - } - - - - private boolean innerMatchesExactly(String s, boolean isAnonymous, boolean convertDollar /*isNested*/) { - - List ret = new ArrayList(); - int startIndex = 0; - while (true) { - int breakIndex = s.indexOf('.', startIndex); // what about / - if (convertDollar && (breakIndex == -1)) breakIndex = s.indexOf('$', startIndex); // we treat $ like . here - if (breakIndex == -1) break; - char[] name = s.substring(startIndex, breakIndex).toCharArray(); - ret.add(name); - startIndex = breakIndex+1; - } - ret.add(s.substring(startIndex).toCharArray()); - - int namesLength = ret.size(); - int patternsLength = namePatterns.length; - - int namesIndex = 0; - int patternsIndex = 0; - - if ((!namePatterns[patternsLength-1].isAny()) && isAnonymous) return false; - - if (ellipsisCount == 0) { - if (namesLength != patternsLength) return false; - while (patternsIndex < patternsLength) { - if (!namePatterns[patternsIndex++].matches((char[])ret.get(namesIndex++))) { - return false; - } - } - return true; - } else if (ellipsisCount == 1) { - if (namesLength < patternsLength-1) return false; - while (patternsIndex < patternsLength) { - NamePattern p = namePatterns[patternsIndex++]; - if (p == NamePattern.ELLIPSIS) { - namesIndex = namesLength - (patternsLength-patternsIndex); - } else { - if (!p.matches((char[])ret.get(namesIndex++))) { - return false; - } - } - } - return true; - } else { - // System.err.print("match(\"" + Arrays.asList(namePatterns) + "\", \"" + Arrays.asList(names) + "\") -> "); - boolean b = outOfStar(namePatterns, (char[][])ret.toArray(new char[ret.size()][]), 0, 0, patternsLength - ellipsisCount, namesLength, ellipsisCount); - // System.err.println(b); - return b; - } - } - private static boolean outOfStar(final NamePattern[] pattern, final char[][] target, - int pi, int ti, - int pLeft, int tLeft, - final int starsLeft) { - if (pLeft > tLeft) return false; - while (true) { - // invariant: if (tLeft > 0) then (ti < target.length && pi < pattern.length) - if (tLeft == 0) return true; - if (pLeft == 0) { - return (starsLeft > 0); - } - if (pattern[pi] == NamePattern.ELLIPSIS) { - return inStar(pattern, target, pi+1, ti, pLeft, tLeft, starsLeft-1); - } - if (! pattern[pi].matches(target[ti])) { - return false; - } - pi++; ti++; pLeft--; tLeft--; - } - } - private static boolean inStar(final NamePattern[] pattern, final char[][] target, - int pi, int ti, - final int pLeft, int tLeft, - int starsLeft) { - // invariant: pLeft > 0, so we know we'll run out of stars and find a real char in pattern - // of course, we probably can't parse multiple ..'s in a row, but this keeps the algorithm - // exactly parallel with that in NamePattern - NamePattern patternChar = pattern[pi]; - while (patternChar == NamePattern.ELLIPSIS) { - starsLeft--; - patternChar = pattern[++pi]; - } - while (true) { - // invariant: if (tLeft > 0) then (ti < target.length) - if (pLeft > tLeft) return false; - if (patternChar.matches(target[ti])) { - if (outOfStar(pattern, target, pi+1, ti+1, pLeft-1, tLeft-1, starsLeft)) return true; - } - ti++; tLeft--; - } - } - + int dot = string.lastIndexOf('.'); + int dollar = string.lastIndexOf('$'); + return Math.max(dot, dollar); + } + + private boolean innerMatchesExactly(String s, boolean isAnonymous, boolean convertDollar /* isNested */) { + + List ret = new ArrayList(); + int startIndex = 0; + while (true) { + int breakIndex = s.indexOf('.', startIndex); // what about / + if (convertDollar && (breakIndex == -1)) + breakIndex = s.indexOf('$', startIndex); // we treat $ like . here + if (breakIndex == -1) + break; + char[] name = s.substring(startIndex, breakIndex).toCharArray(); + ret.add(name); + startIndex = breakIndex + 1; + } + ret.add(s.substring(startIndex).toCharArray()); + + int namesLength = ret.size(); + int patternsLength = namePatterns.length; + + int namesIndex = 0; + int patternsIndex = 0; + + if ((!namePatterns[patternsLength - 1].isAny()) && isAnonymous) + return false; + + if (ellipsisCount == 0) { + if (namesLength != patternsLength) + return false; + while (patternsIndex < patternsLength) { + if (!namePatterns[patternsIndex++].matches((char[]) ret.get(namesIndex++))) { + return false; + } + } + return true; + } else if (ellipsisCount == 1) { + if (namesLength < patternsLength - 1) + return false; + while (patternsIndex < patternsLength) { + NamePattern p = namePatterns[patternsIndex++]; + if (p == NamePattern.ELLIPSIS) { + namesIndex = namesLength - (patternsLength - patternsIndex); + } else { + if (!p.matches((char[]) ret.get(namesIndex++))) { + return false; + } + } + } + return true; + } else { + // System.err.print("match(\"" + Arrays.asList(namePatterns) + "\", \"" + Arrays.asList(names) + "\") -> "); + boolean b = outOfStar(namePatterns, (char[][]) ret.toArray(new char[ret.size()][]), 0, 0, patternsLength + - ellipsisCount, namesLength, ellipsisCount); + // System.err.println(b); + return b; + } + } + + private static boolean outOfStar(final NamePattern[] pattern, final char[][] target, int pi, int ti, int pLeft, int tLeft, + final int starsLeft) { + if (pLeft > tLeft) + return false; + while (true) { + // invariant: if (tLeft > 0) then (ti < target.length && pi < pattern.length) + if (tLeft == 0) + return true; + if (pLeft == 0) { + return (starsLeft > 0); + } + if (pattern[pi] == NamePattern.ELLIPSIS) { + return inStar(pattern, target, pi + 1, ti, pLeft, tLeft, starsLeft - 1); + } + if (!pattern[pi].matches(target[ti])) { + return false; + } + pi++; + ti++; + pLeft--; + tLeft--; + } + } + + private static boolean inStar(final NamePattern[] pattern, final char[][] target, int pi, int ti, final int pLeft, int tLeft, + int starsLeft) { + // invariant: pLeft > 0, so we know we'll run out of stars and find a real char in pattern + // of course, we probably can't parse multiple ..'s in a row, but this keeps the algorithm + // exactly parallel with that in NamePattern + NamePattern patternChar = pattern[pi]; + while (patternChar == NamePattern.ELLIPSIS) { + starsLeft--; + patternChar = pattern[++pi]; + } + while (true) { + // invariant: if (tLeft > 0) then (ti < target.length) + if (pLeft > tLeft) + return false; + if (patternChar.matches(target[ti])) { + if (outOfStar(pattern, target, pi + 1, ti + 1, pLeft - 1, tLeft - 1, starsLeft)) + return true; + } + ti++; + tLeft--; + } + } + /** * @see org.aspectj.weaver.TypePattern#matchesInstanceof(IType) */ public FuzzyBoolean matchesInstanceof(ResolvedType type) { - //XXX hack to let unmatched types just silently remain so - if (maybeGetSimpleName() != null) return - FuzzyBoolean.NO; - + // XXX hack to let unmatched types just silently remain so + if (maybeGetSimpleName() != null) { + return FuzzyBoolean.NO; + } + type.getWorld().getMessageHandler().handleMessage( - new Message("can't do instanceof matching on patterns with wildcards", - IMessage.ERROR, null, getSourceLocation())); + new Message("can't do instanceof matching on patterns with wildcards", IMessage.ERROR, null, getSourceLocation())); return FuzzyBoolean.NO; } @@ -485,25 +485,27 @@ public class WildTypePattern extends TypePattern { // it is not ok to treat Foo as a method name! return null; } - //System.err.println("extract from : " + Arrays.asList(namePatterns)); + // System.err.println("extract from : " + Arrays.asList(namePatterns)); int len = namePatterns.length; - if (len ==1 && !annotationPattern.isAny()) return null; // can't extract - NamePattern ret = namePatterns[len-1]; - NamePattern[] newNames = new NamePattern[len-1]; - System.arraycopy(namePatterns, 0, newNames, 0, len-1); + if (len == 1 && !annotationPattern.isAny()) + return null; // can't extract + NamePattern ret = namePatterns[len - 1]; + NamePattern[] newNames = new NamePattern[len - 1]; + System.arraycopy(namePatterns, 0, newNames, 0, len - 1); namePatterns = newNames; - //System.err.println(" left : " + Arrays.asList(namePatterns)); + // System.err.println(" left : " + Arrays.asList(namePatterns)); return ret; } - + /** * Method maybeExtractName. + * * @param string * @return boolean */ public boolean maybeExtractName(String string) { int len = namePatterns.length; - NamePattern ret = namePatterns[len-1]; + NamePattern ret = namePatterns[len - 1]; String simple = ret.maybeGetSimpleName(); if (simple != null && simple.equals(string)) { extractName(); @@ -511,10 +513,9 @@ public class WildTypePattern extends TypePattern { } return false; } - + /** - * If this type pattern has no '.' or '*' in it, then - * return a simple string + * If this type pattern has no '.' or '*' in it, then return a simple string * * otherwise, this will return null; */ @@ -524,7 +525,7 @@ public class WildTypePattern extends TypePattern { } return null; } - + /** * If this type pattern has no '*' or '..' in it */ @@ -532,54 +533,53 @@ public class WildTypePattern extends TypePattern { if (namePatterns.length == 0) { throw new RuntimeException("bad name: " + namePatterns); } - //System.out.println("get clean: " + this); + // System.out.println("get clean: " + this); StringBuffer buf = new StringBuffer(); - for (int i=0, len=namePatterns.length; i < len; i++) { + for (int i = 0, len = namePatterns.length; i < len; i++) { NamePattern p = namePatterns[i]; String simpleName = p.maybeGetSimpleName(); - if (simpleName == null) return null; - if (i > 0) buf.append("."); + if (simpleName == null) + return null; + if (i > 0) + buf.append("."); buf.append(simpleName); } - //System.out.println(buf); + // System.out.println(buf); return buf.toString(); - } + } - public TypePattern parameterizeWith(Map typeVariableMap,World w) { + public TypePattern parameterizeWith(Map typeVariableMap, World w) { NamePattern[] newNamePatterns = new NamePattern[namePatterns.length]; - for(int i=0; i<namePatterns.length;i++) { newNamePatterns[i] = namePatterns[i]; } + for (int i = 0; i < namePatterns.length; i++) { + newNamePatterns[i] = namePatterns[i]; + } if (newNamePatterns.length == 1) { String simpleName = newNamePatterns[0].maybeGetSimpleName(); if (simpleName != null) { if (typeVariableMap.containsKey(simpleName)) { - String newName = ((ReferenceType)typeVariableMap.get(simpleName)).getName().replace('$','.'); - StringTokenizer strTok = new StringTokenizer(newName,"."); + String newName = ((ReferenceType) typeVariableMap.get(simpleName)).getName().replace('$', '.'); + StringTokenizer strTok = new StringTokenizer(newName, "."); newNamePatterns = new NamePattern[strTok.countTokens()]; int index = 0; - while(strTok.hasMoreTokens()) { + while (strTok.hasMoreTokens()) { newNamePatterns[index++] = new NamePattern(strTok.nextToken()); - } + } } } } - WildTypePattern ret = new WildTypePattern( - newNamePatterns, - includeSubtypes, - dim, - isVarArgs, - typeParameters.parameterizeWith(typeVariableMap,w) - ); - ret.annotationPattern = this.annotationPattern.parameterizeWith(typeVariableMap,w); + WildTypePattern ret = new WildTypePattern(newNamePatterns, includeSubtypes, dim, isVarArgs, typeParameters + .parameterizeWith(typeVariableMap, w)); + ret.annotationPattern = this.annotationPattern.parameterizeWith(typeVariableMap, w); if (additionalInterfaceBounds == null) { ret.additionalInterfaceBounds = null; } else { ret.additionalInterfaceBounds = new TypePattern[additionalInterfaceBounds.length]; for (int i = 0; i < additionalInterfaceBounds.length; i++) { - ret.additionalInterfaceBounds[i] = additionalInterfaceBounds[i].parameterizeWith(typeVariableMap,w); + ret.additionalInterfaceBounds[i] = additionalInterfaceBounds[i].parameterizeWith(typeVariableMap, w); } } - ret.upperBound = upperBound != null ? upperBound.parameterizeWith(typeVariableMap,w) : null; - ret.lowerBound = lowerBound != null ? lowerBound.parameterizeWith(typeVariableMap,w) : null; + ret.upperBound = upperBound != null ? upperBound.parameterizeWith(typeVariableMap, w) : null; + ret.lowerBound = lowerBound != null ? lowerBound.parameterizeWith(typeVariableMap, w) : null; ret.isGeneric = isGeneric; ret.knownMatches = knownMatches; ret.importedPrefixes = importedPrefixes; @@ -594,76 +594,75 @@ public class WildTypePattern extends TypePattern { * * We will be replaced by what we return */ - public TypePattern resolveBindings(IScope scope, Bindings bindings, - boolean allowBinding, boolean requireExactType) - { - if (isNamePatternStar()) { - TypePattern anyPattern = maybeResolveToAnyPattern(scope, bindings, allowBinding, requireExactType); - if (anyPattern != null) { - if (requireExactType) { - scope.getWorld().getMessageHandler().handleMessage( - MessageUtil.error(WeaverMessages.format(WeaverMessages.WILDCARD_NOT_ALLOWED), - getSourceLocation())); + public TypePattern resolveBindings(IScope scope, Bindings bindings, boolean allowBinding, boolean requireExactType) { + if (isNamePatternStar()) { + TypePattern anyPattern = maybeResolveToAnyPattern(scope, bindings, allowBinding, requireExactType); + if (anyPattern != null) { + if (requireExactType) { + scope.getWorld().getMessageHandler().handleMessage( + MessageUtil.error(WeaverMessages.format(WeaverMessages.WILDCARD_NOT_ALLOWED), getSourceLocation())); return NO; - } else { - return anyPattern; - } - } + } else { + return anyPattern; + } + } } - TypePattern bindingTypePattern = maybeResolveToBindingTypePattern(scope, bindings, allowBinding, requireExactType); - if (bindingTypePattern != null) return bindingTypePattern; - - annotationPattern = annotationPattern.resolveBindings(scope,bindings,allowBinding); - + TypePattern bindingTypePattern = maybeResolveToBindingTypePattern(scope, bindings, allowBinding, requireExactType); + if (bindingTypePattern != null) + return bindingTypePattern; + + annotationPattern = annotationPattern.resolveBindings(scope, bindings, allowBinding); + // resolve any type parameters - if (typeParameters!=null && typeParameters.size()>0) { - typeParameters.resolveBindings(scope,bindings,allowBinding,requireExactType); + if (typeParameters != null && typeParameters.size() > 0) { + typeParameters.resolveBindings(scope, bindings, allowBinding, requireExactType); isGeneric = false; } - + // resolve any bounds - if (upperBound != null) upperBound = upperBound.resolveBindings(scope, bindings, allowBinding, requireExactType); - if (lowerBound != null) lowerBound = lowerBound.resolveBindings(scope, bindings, allowBinding, requireExactType); + if (upperBound != null) + upperBound = upperBound.resolveBindings(scope, bindings, allowBinding, requireExactType); + if (lowerBound != null) + lowerBound = lowerBound.resolveBindings(scope, bindings, allowBinding, requireExactType); // amc - additional interface bounds only needed if we support type vars again. - + String fullyQualifiedName = maybeGetCleanName(); if (fullyQualifiedName != null) { return resolveBindingsFromFullyQualifiedTypeName(fullyQualifiedName, scope, bindings, allowBinding, requireExactType); } else { if (requireExactType) { scope.getWorld().getMessageHandler().handleMessage( - MessageUtil.error(WeaverMessages.format(WeaverMessages.WILDCARD_NOT_ALLOWED), - getSourceLocation())); + MessageUtil.error(WeaverMessages.format(WeaverMessages.WILDCARD_NOT_ALLOWED), getSourceLocation())); return NO; } importedPrefixes = scope.getImportedPrefixes(); - knownMatches = preMatch(scope.getImportedNames()); - return this; // pattern contains wildcards so can't be resolved to an ExactTypePattern... - //XXX need to implement behavior for Lint.invalidWildcardTypeName - } + knownMatches = preMatch(scope.getImportedNames()); + return this; // pattern contains wildcards so can't be resolved to an ExactTypePattern... + // XXX need to implement behavior for Lint.invalidWildcardTypeName + } } - - private TypePattern maybeResolveToAnyPattern(IScope scope, Bindings bindings, - boolean allowBinding, boolean requireExactType) { - // If there is an annotation specified we have to - // use a special variant of Any TypePattern called - // AnyWithAnnotation + + private TypePattern maybeResolveToAnyPattern(IScope scope, Bindings bindings, boolean allowBinding, boolean requireExactType) { + // If there is an annotation specified we have to + // use a special variant of Any TypePattern called + // AnyWithAnnotation if (annotationPattern == AnnotationTypePattern.ANY) { - if (dim == 0 && !isVarArgs && upperBound == null && lowerBound == null && (additionalInterfaceBounds == null || additionalInterfaceBounds.length==0)) { // pr72531 - return TypePattern.ANY; //??? loses source location - } - } else if (!isVarArgs){ - annotationPattern = annotationPattern.resolveBindings(scope,bindings,allowBinding); - AnyWithAnnotationTypePattern ret = new AnyWithAnnotationTypePattern(annotationPattern); - ret.setLocation(sourceContext,start,end); + if (dim == 0 && !isVarArgs && upperBound == null && lowerBound == null + && (additionalInterfaceBounds == null || additionalInterfaceBounds.length == 0)) { // pr72531 + return TypePattern.ANY; // ??? loses source location + } + } else if (!isVarArgs) { + annotationPattern = annotationPattern.resolveBindings(scope, bindings, allowBinding); + AnyWithAnnotationTypePattern ret = new AnyWithAnnotationTypePattern(annotationPattern); + ret.setLocation(sourceContext, start, end); return ret; } return null; // can't resolve to a simple "any" pattern } - - private TypePattern maybeResolveToBindingTypePattern(IScope scope, Bindings bindings, - boolean allowBinding, boolean requireExactType) { + + private TypePattern maybeResolveToBindingTypePattern(IScope scope, Bindings bindings, boolean allowBinding, + boolean requireExactType) { String simpleName = maybeGetSimpleName(); if (simpleName != null) { FormalBinding formalBinding = scope.lookupFormal(simpleName); @@ -673,101 +672,104 @@ public class WildTypePattern extends TypePattern { return this; } if (!allowBinding) { - scope.message(IMessage.ERROR, this, - "name binding only allowed in target, this, and args pcds"); + scope.message(IMessage.ERROR, this, "name binding only allowed in target, this, and args pcds"); return this; } - - BindingTypePattern binding = new BindingTypePattern(formalBinding,isVarArgs); + + BindingTypePattern binding = new BindingTypePattern(formalBinding, isVarArgs); binding.copyLocationFrom(this); bindings.register(binding, scope); - + return binding; } } return null; // not possible to resolve to a binding type pattern } - - private TypePattern resolveBindingsFromFullyQualifiedTypeName(String fullyQualifiedName, IScope scope, Bindings bindings, + + private TypePattern resolveBindingsFromFullyQualifiedTypeName(String fullyQualifiedName, IScope scope, Bindings bindings, boolean allowBinding, boolean requireExactType) { String originalName = fullyQualifiedName; ResolvedType resolvedTypeInTheWorld = null; UnresolvedType type; - - //System.out.println("resolve: " + cleanName); - //??? this loop has too many inefficiencies to count - resolvedTypeInTheWorld = lookupTypeInWorldIncludingPrefixes(scope.getWorld(), fullyQualifiedName, scope.getImportedPrefixes()); + + // System.out.println("resolve: " + cleanName); + // ??? this loop has too many inefficiencies to count + resolvedTypeInTheWorld = lookupTypeInWorldIncludingPrefixes(scope.getWorld(), fullyQualifiedName, scope + .getImportedPrefixes()); if (resolvedTypeInTheWorld.isGenericWildcard()) { type = resolvedTypeInTheWorld; } else { type = lookupTypeInScope(scope, fullyQualifiedName, this); } - if ((type instanceof ResolvedType) && ((ResolvedType)type).isMissing()) { - return resolveBindingsForMissingType(resolvedTypeInTheWorld, originalName, scope, bindings, allowBinding, requireExactType); + if ((type instanceof ResolvedType) && ((ResolvedType) type).isMissing()) { + return resolveBindingsForMissingType(resolvedTypeInTheWorld, originalName, scope, bindings, allowBinding, + requireExactType); } else { - return resolveBindingsForExactType(scope,type,fullyQualifiedName,requireExactType); + return resolveBindingsForExactType(scope, type, fullyQualifiedName, requireExactType); } } - - - + private UnresolvedType lookupTypeInScope(IScope scope, String typeName, IHasPosition location) { UnresolvedType type = null; while (ResolvedType.isMissing(type = scope.lookupType(typeName, location))) { int lastDot = typeName.lastIndexOf('.'); - if (lastDot == -1) break; - typeName = typeName.substring(0, lastDot) + '$' + typeName.substring(lastDot+1); + if (lastDot == -1) + break; + typeName = typeName.substring(0, lastDot) + '$' + typeName.substring(lastDot + 1); } return type; } - + /** - * Searches the world for the ResolvedType with the given typeName. If one - * isn't found then for each of the supplied prefixes, it prepends the typeName - * with the prefix and searches the world for the ResolvedType with this new name. - * If one still isn't found then a MissingResolvedTypeWithKnownSignature is - * returned with the originally requested typeName (this ensures the typeName - * makes sense). + * Searches the world for the ResolvedType with the given typeName. If one isn't found then for each of the supplied prefixes, + * it prepends the typeName with the prefix and searches the world for the ResolvedType with this new name. If one still isn't + * found then a MissingResolvedTypeWithKnownSignature is returned with the originally requested typeName (this ensures the + * typeName makes sense). */ private ResolvedType lookupTypeInWorldIncludingPrefixes(World world, String typeName, String[] prefixes) { ResolvedType ret = lookupTypeInWorld(world, typeName); - if (!ret.isMissing()) return ret; + if (!ret.isMissing()) + return ret; ResolvedType retWithPrefix = ret; int counter = 0; while (retWithPrefix.isMissing() && (counter < prefixes.length)) { - retWithPrefix = lookupTypeInWorld(world,prefixes[counter] + typeName); + retWithPrefix = lookupTypeInWorld(world, prefixes[counter] + typeName); counter++; } - if (!retWithPrefix.isMissing()) return retWithPrefix; + if (!retWithPrefix.isMissing()) + return retWithPrefix; return ret; } - + private ResolvedType lookupTypeInWorld(World world, String typeName) { UnresolvedType ut = UnresolvedType.forName(typeName); - ResolvedType ret = world.resolve(ut,true); + ResolvedType ret = world.resolve(ut, true); while (ret.isMissing()) { int lastDot = typeName.lastIndexOf('.'); - if (lastDot == -1) break; - typeName = typeName.substring(0, lastDot) + '$' + typeName.substring(lastDot+1); - ret = world.resolve(UnresolvedType.forName(typeName),true); + if (lastDot == -1) + break; + typeName = typeName.substring(0, lastDot) + '$' + typeName.substring(lastDot + 1); + ret = world.resolve(UnresolvedType.forName(typeName), true); } return ret; } - - private TypePattern resolveBindingsForExactType(IScope scope, UnresolvedType aType, String fullyQualifiedName,boolean requireExactType) { + + private TypePattern resolveBindingsForExactType(IScope scope, UnresolvedType aType, String fullyQualifiedName, + boolean requireExactType) { TypePattern ret = null; if (aType.isTypeVariableReference()) { // we have to set the bounds on it based on the bounds of this pattern ret = resolveBindingsForTypeVariable(scope, (UnresolvedTypeVariableReferenceType) aType); - } else if (typeParameters.size()>0) { + } else if (typeParameters.size() > 0) { ret = resolveParameterizedType(scope, aType, requireExactType); } else if (upperBound != null || lowerBound != null) { // this must be a generic wildcard with bounds - ret = resolveGenericWildcard(scope, aType); + ret = resolveGenericWildcard(scope, aType); } else { - if (dim != 0) aType = UnresolvedType.makeArray(aType, dim); - ret = new ExactTypePattern(aType,includeSubtypes,isVarArgs); + if (dim != 0) + aType = UnresolvedType.makeArray(aType, dim); + ret = new ExactTypePattern(aType, includeSubtypes, isVarArgs); } ret.setAnnotationTypePattern(annotationPattern); ret.copyLocationFrom(this); @@ -775,61 +777,67 @@ public class WildTypePattern extends TypePattern { } private TypePattern resolveGenericWildcard(IScope scope, UnresolvedType aType) { - if (!aType.getSignature().equals(GENERIC_WILDCARD_SIGNATURE_CHARACTER)) throw new IllegalStateException("Can only have bounds for a generic wildcard"); + if (!aType.getSignature().equals(GENERIC_WILDCARD_SIGNATURE_CHARACTER)) + throw new IllegalStateException("Can only have bounds for a generic wildcard"); boolean canBeExact = true; - if ((upperBound != null) && ResolvedType.isMissing(upperBound.getExactType())) canBeExact = false; - if ((lowerBound != null) && ResolvedType.isMissing(lowerBound.getExactType())) canBeExact = false; + if ((upperBound != null) && ResolvedType.isMissing(upperBound.getExactType())) + canBeExact = false; + if ((lowerBound != null) && ResolvedType.isMissing(lowerBound.getExactType())) + canBeExact = false; if (canBeExact) { ResolvedType type = null; if (upperBound != null) { - if (upperBound.isIncludeSubtypes()) { + if (upperBound.isIncludeSubtypes()) { canBeExact = false; } else { ReferenceType upper = (ReferenceType) upperBound.getExactType().resolve(scope.getWorld()); - type = new BoundedReferenceType(upper,true,scope.getWorld()); + type = new BoundedReferenceType(upper, true, scope.getWorld()); } } else { if (lowerBound.isIncludeSubtypes()) { canBeExact = false; } else { ReferenceType lower = (ReferenceType) lowerBound.getExactType().resolve(scope.getWorld()); - type = new BoundedReferenceType(lower,false,scope.getWorld()); + type = new BoundedReferenceType(lower, false, scope.getWorld()); } } if (canBeExact) { // might have changed if we find out include subtypes is set on one of the bounds... - return new ExactTypePattern(type,includeSubtypes,isVarArgs); + return new ExactTypePattern(type, includeSubtypes, isVarArgs); } - } - + } + // we weren't able to resolve to an exact type pattern... // leave as wild type pattern importedPrefixes = scope.getImportedPrefixes(); knownMatches = preMatch(scope.getImportedNames()); - return this; + return this; } private TypePattern resolveParameterizedType(IScope scope, UnresolvedType aType, boolean requireExactType) { ResolvedType rt = aType.resolve(scope.getWorld()); - if (!verifyTypeParameters(rt,scope,requireExactType)) return TypePattern.NO; // messages already isued - // Only if the type is exact *and* the type parameters are exact should we create an - // ExactTypePattern for this WildTypePattern + if (!verifyTypeParameters(rt, scope, requireExactType)) + return TypePattern.NO; // messages already isued + // Only if the type is exact *and* the type parameters are exact should we create an + // ExactTypePattern for this WildTypePattern if (typeParameters.areAllExactWithNoSubtypesAllowed()) { TypePattern[] typePats = typeParameters.getTypePatterns(); UnresolvedType[] typeParameterTypes = new UnresolvedType[typePats.length]; for (int i = 0; i < typeParameterTypes.length; i++) { - typeParameterTypes[i] = ((ExactTypePattern)typePats[i]).getExactType(); + typeParameterTypes[i] = ((ExactTypePattern) typePats[i]).getExactType(); } // rt could be a parameterized type 156058 if (rt.isParameterizedType()) { rt = rt.getGenericType(); } ResolvedType type = TypeFactory.createParameterizedType(rt, typeParameterTypes, scope.getWorld()); - if (isGeneric) type = type.getGenericType(); -// UnresolvedType tx = UnresolvedType.forParameterizedTypes(aType,typeParameterTypes); -// UnresolvedType type = scope.getWorld().resolve(tx,true); - if (dim != 0) type = ResolvedType.makeArray(type, dim); - return new ExactTypePattern(type,includeSubtypes,isVarArgs); + if (isGeneric) + type = type.getGenericType(); + // UnresolvedType tx = UnresolvedType.forParameterizedTypes(aType,typeParameterTypes); + // UnresolvedType type = scope.getWorld().resolve(tx,true); + if (dim != 0) + type = ResolvedType.makeArray(type, dim); + return new ExactTypePattern(type, includeSubtypes, isVarArgs); } else { // AMC... just leave it as a wild type pattern then? importedPrefixes = scope.getImportedPrefixes(); @@ -837,14 +845,14 @@ public class WildTypePattern extends TypePattern { return this; } } - - private TypePattern resolveBindingsForMissingType(ResolvedType typeFoundInWholeWorldSearch, String nameWeLookedFor, IScope scope, Bindings bindings, - boolean allowBinding, boolean requireExactType) { + + private TypePattern resolveBindingsForMissingType(ResolvedType typeFoundInWholeWorldSearch, String nameWeLookedFor, + IScope scope, Bindings bindings, boolean allowBinding, boolean requireExactType) { if (requireExactType) { if (!allowBinding) { scope.getWorld().getMessageHandler().handleMessage( - MessageUtil.error(WeaverMessages.format(WeaverMessages.CANT_BIND_TYPE,nameWeLookedFor), - getSourceLocation())); + MessageUtil.error(WeaverMessages.format(WeaverMessages.CANT_BIND_TYPE, nameWeLookedFor), + getSourceLocation())); } else if (scope.getWorld().getLint().invalidAbsoluteTypeName.isEnabled()) { scope.getWorld().getLint().invalidAbsoluteTypeName.signal(nameWeLookedFor, getSourceLocation()); } @@ -852,19 +860,19 @@ public class WildTypePattern extends TypePattern { } else if (scope.getWorld().getLint().invalidAbsoluteTypeName.isEnabled()) { // Only put the lint warning out if we can't find it in the world if (typeFoundInWholeWorldSearch.isMissing()) { - scope.getWorld().getLint().invalidAbsoluteTypeName.signal(nameWeLookedFor, getSourceLocation()); + scope.getWorld().getLint().invalidAbsoluteTypeName.signal(nameWeLookedFor, getSourceLocation()); } } importedPrefixes = scope.getImportedPrefixes(); knownMatches = preMatch(scope.getImportedNames()); - return this; + return this; } - + /** - * We resolved the type to a type variable declared in the pointcut designator. - * Now we have to create either an exact type pattern or a wild type pattern for it, - * with upper and lower bounds set accordingly. - * XXX none of this stuff gets serialized yet + * We resolved the type to a type variable declared in the pointcut designator. Now we have to create either an exact type + * pattern or a wild type pattern for it, with upper and lower bounds set accordingly. XXX none of this stuff gets serialized + * yet + * * @param scope * @param tvrType * @return @@ -880,29 +888,35 @@ public class WildTypePattern extends TypePattern { if (additionalInterfaceBounds != null) { TypePattern[] resolvedIfBounds = new TypePattern[additionalInterfaceBounds.length]; for (int i = 0; i < resolvedIfBounds.length; i++) { - resolvedIfBounds[i] = additionalInterfaceBounds[i].resolveBindings(scope, emptyBindings, false, false); + resolvedIfBounds[i] = additionalInterfaceBounds[i].resolveBindings(scope, emptyBindings, false, false); } additionalInterfaceBounds = resolvedIfBounds; } - if ( upperBound == null && lowerBound == null && additionalInterfaceBounds == null) { + if (upperBound == null && lowerBound == null && additionalInterfaceBounds == null) { // no bounds to worry about... ResolvedType rType = tvrType.resolve(scope.getWorld()); - if (dim != 0) rType = ResolvedType.makeArray(rType, dim); - return new ExactTypePattern(rType,includeSubtypes,isVarArgs); + if (dim != 0) + rType = ResolvedType.makeArray(rType, dim); + return new ExactTypePattern(rType, includeSubtypes, isVarArgs); } else { // we have to set bounds on the TypeVariable held by tvrType before resolving it boolean canCreateExactTypePattern = true; - if (upperBound != null && ResolvedType.isMissing(upperBound.getExactType())) canCreateExactTypePattern = false; - if (lowerBound != null && ResolvedType.isMissing(lowerBound.getExactType())) canCreateExactTypePattern = false; + if (upperBound != null && ResolvedType.isMissing(upperBound.getExactType())) + canCreateExactTypePattern = false; + if (lowerBound != null && ResolvedType.isMissing(lowerBound.getExactType())) + canCreateExactTypePattern = false; if (additionalInterfaceBounds != null) { for (int i = 0; i < additionalInterfaceBounds.length; i++) { - if (ResolvedType.isMissing(additionalInterfaceBounds[i].getExactType())) canCreateExactTypePattern = false; + if (ResolvedType.isMissing(additionalInterfaceBounds[i].getExactType())) + canCreateExactTypePattern = false; } } if (canCreateExactTypePattern) { TypeVariable tv = tvrType.getTypeVariable(); - if (upperBound != null) tv.setUpperBound(upperBound.getExactType()); - if (lowerBound != null) tv.setLowerBound(lowerBound.getExactType()); + if (upperBound != null) + tv.setUpperBound(upperBound.getExactType()); + if (lowerBound != null) + tv.setLowerBound(lowerBound.getExactType()); if (additionalInterfaceBounds != null) { UnresolvedType[] ifBounds = new UnresolvedType[additionalInterfaceBounds.length]; for (int i = 0; i < ifBounds.length; i++) { @@ -911,29 +925,27 @@ public class WildTypePattern extends TypePattern { tv.setAdditionalInterfaceBounds(ifBounds); } ResolvedType rType = tvrType.resolve(scope.getWorld()); - if (dim != 0) rType = ResolvedType.makeArray(rType, dim); - return new ExactTypePattern(rType,includeSubtypes,isVarArgs); + if (dim != 0) + rType = ResolvedType.makeArray(rType, dim); + return new ExactTypePattern(rType, includeSubtypes, isVarArgs); } - return this; // leave as wild type pattern then + return this; // leave as wild type pattern then } } - + /** - * When this method is called, we have resolved the base type to an exact type. - * We also have a set of type patterns for the parameters. - * Time to perform some basic checks: - * - can the base type be parameterized? (is it generic) - * - can the type parameter pattern list match the number of parameters on the base type - * - do all parameter patterns meet the bounds of the respective type variables - * If any of these checks fail, a warning message is issued and we return false. + * When this method is called, we have resolved the base type to an exact type. We also have a set of type patterns for the + * parameters. Time to perform some basic checks: - can the base type be parameterized? (is it generic) - can the type parameter + * pattern list match the number of parameters on the base type - do all parameter patterns meet the bounds of the respective + * type variables If any of these checks fail, a warning message is issued and we return false. + * * @return */ - private boolean verifyTypeParameters(ResolvedType baseType,IScope scope, boolean requireExactType) { + private boolean verifyTypeParameters(ResolvedType baseType, IScope scope, boolean requireExactType) { ResolvedType genericType = baseType.getGenericType(); if (genericType == null) { // issue message "does not match because baseType.getName() is not generic" - scope.message(MessageUtil.warn( - WeaverMessages.format(WeaverMessages.NOT_A_GENERIC_TYPE,baseType.getName()), + scope.message(MessageUtil.warn(WeaverMessages.format(WeaverMessages.NOT_A_GENERIC_TYPE, baseType.getName()), getSourceLocation())); return false; } @@ -950,48 +962,46 @@ public class WildTypePattern extends TypePattern { } } TypeVariable[] tvs = genericType.getTypeVariables(); - if ((tvs.length < minRequiredTypeParameters) || - (!foundEllipsis && minRequiredTypeParameters != tvs.length)) - { + if ((tvs.length < minRequiredTypeParameters) || (!foundEllipsis && minRequiredTypeParameters != tvs.length)) { // issue message "does not match because wrong no of type params" - String msg = WeaverMessages.format(WeaverMessages.INCORRECT_NUMBER_OF_TYPE_ARGUMENTS, - genericType.getName(),new Integer(tvs.length)); - if (requireExactType) scope.message(MessageUtil.error(msg,getSourceLocation())); - else scope.message(MessageUtil.warn(msg,getSourceLocation())); + String msg = WeaverMessages.format(WeaverMessages.INCORRECT_NUMBER_OF_TYPE_ARGUMENTS, genericType.getName(), + new Integer(tvs.length)); + if (requireExactType) + scope.message(MessageUtil.error(msg, getSourceLocation())); + else + scope.message(MessageUtil.warn(msg, getSourceLocation())); return false; - } - + } + // now check that each typeParameter pattern, if exact, matches the bounds // of the type variable. - + // pr133307 - delay verification until type binding completion, these next few lines replace // the call to checkBoundsOK if (!boundscheckingoff) { - VerifyBoundsForTypePattern verification = - new VerifyBoundsForTypePattern(scope,genericType,requireExactType,typeParameters,getSourceLocation()); + VerifyBoundsForTypePattern verification = new VerifyBoundsForTypePattern(scope, genericType, requireExactType, + typeParameters, getSourceLocation()); scope.getWorld().getCrosscuttingMembersSet().recordNecessaryCheck(verification); } -// return checkBoundsOK(scope,genericType,requireExactType); - - return true; + // return checkBoundsOK(scope,genericType,requireExactType); + + return true; } - + /** - * By capturing the verification in this class, rather than performing it in verifyTypeParameters(), - * we can cope with situations where the interactions between generics and declare parents would - * otherwise cause us problems. For example, if verifying as we go along we may report a problem - * which would have been fixed by a declare parents that we haven't looked at yet. If we - * create and store a verification object, we can verify this later when the type system is - * considered 'complete' + * By capturing the verification in this class, rather than performing it in verifyTypeParameters(), we can cope with situations + * where the interactions between generics and declare parents would otherwise cause us problems. For example, if verifying as + * we go along we may report a problem which would have been fixed by a declare parents that we haven't looked at yet. If we + * create and store a verification object, we can verify this later when the type system is considered 'complete' */ static class VerifyBoundsForTypePattern implements IVerificationRequired { - - private IScope scope; - private ResolvedType genericType; - private boolean requireExactType; + + private final IScope scope; + private final ResolvedType genericType; + private final boolean requireExactType; private TypePatternList typeParameters = TypePatternList.EMPTY; - private ISourceLocation sLoc; - + private final ISourceLocation sLoc; + public VerifyBoundsForTypePattern(IScope scope, ResolvedType genericType, boolean requireExactType, TypePatternList typeParameters, ISourceLocation sLoc) { this.scope = scope; @@ -1000,7 +1010,7 @@ public class WildTypePattern extends TypePattern { this.typeParameters = typeParameters; this.sLoc = sLoc; } - + public void verify() { TypeVariable[] tvs = genericType.getTypeVariables(); TypePattern[] typeParamPatterns = typeParameters.getTypePatterns(); @@ -1008,28 +1018,25 @@ public class WildTypePattern extends TypePattern { for (int i = 0; i < tvs.length; i++) { UnresolvedType ut = typeParamPatterns[i].getExactType(); boolean continueCheck = true; - // FIXME asc dont like this but ok temporary measure. If the type parameter + // FIXME asc dont like this but ok temporary measure. If the type parameter // is itself a type variable (from the generic aspect) then assume it'll be - // ok... (see pr112105) Want to break this? Run GenericAspectK test. + // ok... (see pr112105) Want to break this? Run GenericAspectK test. if (ut.isTypeVariableReference()) { continueCheck = false; } - - //System.err.println("Verifying "+ut.getName()+" meets bounds for "+tvs[i]); - if (continueCheck && - !tvs[i].canBeBoundTo(ut.resolve(scope.getWorld()))) { + + // System.err.println("Verifying "+ut.getName()+" meets bounds for "+tvs[i]); + if (continueCheck && !tvs[i].canBeBoundTo(ut.resolve(scope.getWorld()))) { // issue message that type parameter does not meet specification String parameterName = ut.getName(); - if (ut.isTypeVariableReference()) parameterName = ((TypeVariableReference)ut).getTypeVariable().getDisplayName(); - String msg = - WeaverMessages.format( - WeaverMessages.VIOLATES_TYPE_VARIABLE_BOUNDS, - parameterName, - new Integer(i+1), - tvs[i].getDisplayName(), - genericType.getName()); - if (requireExactType) scope.message(MessageUtil.error(msg,sLoc)); - else scope.message(MessageUtil.warn(msg,sLoc)); + if (ut.isTypeVariableReference()) + parameterName = ((TypeVariableReference) ut).getTypeVariable().getDisplayName(); + String msg = WeaverMessages.format(WeaverMessages.VIOLATES_TYPE_VARIABLE_BOUNDS, parameterName, + new Integer(i + 1), tvs[i].getDisplayName(), genericType.getName()); + if (requireExactType) + scope.message(MessageUtil.error(msg, sLoc)); + else + scope.message(MessageUtil.warn(msg, sLoc)); } } } @@ -1037,47 +1044,47 @@ public class WildTypePattern extends TypePattern { } // pr133307 - moved to verification object -// public boolean checkBoundsOK(IScope scope,ResolvedType genericType,boolean requireExactType) { -// if (boundscheckingoff) return true; -// TypeVariable[] tvs = genericType.getTypeVariables(); -// TypePattern[] typeParamPatterns = typeParameters.getTypePatterns(); -// if (typeParameters.areAllExactWithNoSubtypesAllowed()) { -// for (int i = 0; i < tvs.length; i++) { -// UnresolvedType ut = typeParamPatterns[i].getExactType(); -// boolean continueCheck = true; -// // FIXME asc dont like this but ok temporary measure. If the type parameter -// // is itself a type variable (from the generic aspect) then assume it'll be -// // ok... (see pr112105) Want to break this? Run GenericAspectK test. -// if (ut.isTypeVariableReference()) { -// continueCheck = false; -// } -// -// if (continueCheck && -// !tvs[i].canBeBoundTo(ut.resolve(scope.getWorld()))) { -// // issue message that type parameter does not meet specification -// String parameterName = ut.getName(); -// if (ut.isTypeVariableReference()) parameterName = ((TypeVariableReference)ut).getTypeVariable().getDisplayName(); -// String msg = -// WeaverMessages.format( -// WeaverMessages.VIOLATES_TYPE_VARIABLE_BOUNDS, -// parameterName, -// new Integer(i+1), -// tvs[i].getDisplayName(), -// genericType.getName()); -// if (requireExactType) scope.message(MessageUtil.error(msg,getSourceLocation())); -// else scope.message(MessageUtil.warn(msg,getSourceLocation())); -// return false; -// } -// } -// } -// return true; -// } - + // public boolean checkBoundsOK(IScope scope,ResolvedType genericType,boolean requireExactType) { + // if (boundscheckingoff) return true; + // TypeVariable[] tvs = genericType.getTypeVariables(); + // TypePattern[] typeParamPatterns = typeParameters.getTypePatterns(); + // if (typeParameters.areAllExactWithNoSubtypesAllowed()) { + // for (int i = 0; i < tvs.length; i++) { + // UnresolvedType ut = typeParamPatterns[i].getExactType(); + // boolean continueCheck = true; + // // FIXME asc dont like this but ok temporary measure. If the type parameter + // // is itself a type variable (from the generic aspect) then assume it'll be + // // ok... (see pr112105) Want to break this? Run GenericAspectK test. + // if (ut.isTypeVariableReference()) { + // continueCheck = false; + // } + // + // if (continueCheck && + // !tvs[i].canBeBoundTo(ut.resolve(scope.getWorld()))) { + // // issue message that type parameter does not meet specification + // String parameterName = ut.getName(); + // if (ut.isTypeVariableReference()) parameterName = ((TypeVariableReference)ut).getTypeVariable().getDisplayName(); + // String msg = + // WeaverMessages.format( + // WeaverMessages.VIOLATES_TYPE_VARIABLE_BOUNDS, + // parameterName, + // new Integer(i+1), + // tvs[i].getDisplayName(), + // genericType.getName()); + // if (requireExactType) scope.message(MessageUtil.error(msg,getSourceLocation())); + // else scope.message(MessageUtil.warn(msg,getSourceLocation())); + // return false; + // } + // } + // } + // return true; + // } + public boolean isStar() { boolean annPatternStar = annotationPattern == AnnotationTypePattern.ANY; return (isNamePatternStar() && annPatternStar); } - + private boolean isNamePatternStar() { return namePatterns.length == 1 && namePatterns[0].isAny(); } @@ -1086,108 +1093,125 @@ public class WildTypePattern extends TypePattern { * returns those possible matches which I match exactly the last element of */ private String[] preMatch(String[] possibleMatches) { - //if (namePatterns.length != 1) return CollectionUtil.NO_STRINGS; - + // if (namePatterns.length != 1) return CollectionUtil.NO_STRINGS; + List ret = new ArrayList(); - for (int i=0, len=possibleMatches.length; i < len; i++) { - char[][] names = splitNames(possibleMatches[i],true); //??? not most efficient - if (namePatterns[0].matches(names[names.length-1])) { + for (int i = 0, len = possibleMatches.length; i < len; i++) { + char[][] names = splitNames(possibleMatches[i], true); // ??? not most efficient + if (namePatterns[0].matches(names[names.length - 1])) { ret.add(possibleMatches[i]); continue; } if (possibleMatches[i].indexOf("$") != -1) { - names = splitNames(possibleMatches[i],false); //??? not most efficient - if (namePatterns[0].matches(names[names.length-1])) { + names = splitNames(possibleMatches[i], false); // ??? not most efficient + if (namePatterns[0].matches(names[names.length - 1])) { ret.add(possibleMatches[i]); } } } - return (String[])ret.toArray(new String[ret.size()]); + return (String[]) ret.toArray(new String[ret.size()]); } - - -// public void postRead(ResolvedType enclosingType) { -// this.importedPrefixes = enclosingType.getImportedPrefixes(); -// this.knownNames = prematch(enclosingType.getImportedNames()); -// } - - - public String toString() { - StringBuffer buf = new StringBuffer(); - if (annotationPattern != AnnotationTypePattern.ANY) { - buf.append('('); - buf.append(annotationPattern.toString()); - buf.append(' '); - } - for (int i=0, len=namePatterns.length; i < len; i++) { - NamePattern name = namePatterns[i]; - if (name == null) { - buf.append("."); - } else { - if (i > 0) buf.append("."); - buf.append(name.toString()); - } - } - if (upperBound != null) { - buf.append(" extends "); - buf.append(upperBound.toString()); - } - if (lowerBound != null) { - buf.append(" super "); - buf.append(lowerBound.toString()); - } - if (typeParameters!=null && typeParameters.size()!=0) { + + // public void postRead(ResolvedType enclosingType) { + // this.importedPrefixes = enclosingType.getImportedPrefixes(); + // this.knownNames = prematch(enclosingType.getImportedNames()); + // } + + public String toString() { + StringBuffer buf = new StringBuffer(); + if (annotationPattern != AnnotationTypePattern.ANY) { + buf.append('('); + buf.append(annotationPattern.toString()); + buf.append(' '); + } + for (int i = 0, len = namePatterns.length; i < len; i++) { + NamePattern name = namePatterns[i]; + if (name == null) { + buf.append("."); + } else { + if (i > 0) + buf.append("."); + buf.append(name.toString()); + } + } + if (upperBound != null) { + buf.append(" extends "); + buf.append(upperBound.toString()); + } + if (lowerBound != null) { + buf.append(" super "); + buf.append(lowerBound.toString()); + } + if (typeParameters != null && typeParameters.size() != 0) { buf.append("<"); buf.append(typeParameters.toString()); buf.append(">"); } - if (includeSubtypes) buf.append('+'); - if (isVarArgs) buf.append("..."); - if (annotationPattern != AnnotationTypePattern.ANY) { - buf.append(')'); - } - return buf.toString(); - } - - public boolean equals(Object other) { - if (!(other instanceof WildTypePattern)) return false; - WildTypePattern o = (WildTypePattern)other; - int len = o.namePatterns.length; - if (len != this.namePatterns.length) return false; - if (this.includeSubtypes != o.includeSubtypes) return false; - if (this.dim != o.dim) return false; - if (this.isVarArgs != o.isVarArgs) return false; - if (this.upperBound != null) { - if (o.upperBound == null) return false; - if (!this.upperBound.equals(o.upperBound)) return false; - } else { - if (o.upperBound != null) return false; - } - if (this.lowerBound != null) { - if (o.lowerBound == null) return false; - if (!this.lowerBound.equals(o.lowerBound)) return false; - } else { - if (o.lowerBound != null) return false; - } - if (!typeParameters.equals(o.typeParameters)) return false; - for (int i=0; i < len; i++) { - if (!o.namePatterns[i].equals(this.namePatterns[i])) return false; - } - return (o.annotationPattern.equals(this.annotationPattern)); + if (includeSubtypes) + buf.append('+'); + if (isVarArgs) + buf.append("..."); + if (annotationPattern != AnnotationTypePattern.ANY) { + buf.append(')'); + } + return buf.toString(); + } + + public boolean equals(Object other) { + if (!(other instanceof WildTypePattern)) + return false; + WildTypePattern o = (WildTypePattern) other; + int len = o.namePatterns.length; + if (len != this.namePatterns.length) + return false; + if (this.includeSubtypes != o.includeSubtypes) + return false; + if (this.dim != o.dim) + return false; + if (this.isVarArgs != o.isVarArgs) + return false; + if (this.upperBound != null) { + if (o.upperBound == null) + return false; + if (!this.upperBound.equals(o.upperBound)) + return false; + } else { + if (o.upperBound != null) + return false; + } + if (this.lowerBound != null) { + if (o.lowerBound == null) + return false; + if (!this.lowerBound.equals(o.lowerBound)) + return false; + } else { + if (o.lowerBound != null) + return false; + } + if (!typeParameters.equals(o.typeParameters)) + return false; + for (int i = 0; i < len; i++) { + if (!o.namePatterns[i].equals(this.namePatterns[i])) + return false; + } + return (o.annotationPattern.equals(this.annotationPattern)); } - public int hashCode() { - int result = 17; - for (int i = 0, len = namePatterns.length; i < len; i++) { - result = 37*result + namePatterns[i].hashCode(); - } - result = 37*result + annotationPattern.hashCode(); - if (upperBound != null) result = 37*result + upperBound.hashCode(); - if (lowerBound != null) result = 37*result + lowerBound.hashCode(); - return result; - } - - private static final byte VERSION = 1; // rev on change + public int hashCode() { + int result = 17; + for (int i = 0, len = namePatterns.length; i < len; i++) { + result = 37 * result + namePatterns[i].hashCode(); + } + result = 37 * result + annotationPattern.hashCode(); + if (upperBound != null) + result = 37 * result + upperBound.hashCode(); + if (lowerBound != null) + result = 37 * result + lowerBound.hashCode(); + return result; + } + + private static final byte VERSION = 1; // rev on change + /** * @see org.aspectj.weaver.patterns.PatternNode#write(DataOutputStream) */ @@ -1201,9 +1225,9 @@ public class WildTypePattern extends TypePattern { s.writeBoolean(includeSubtypes); s.writeInt(dim); s.writeBoolean(isVarArgs); - typeParameters.write(s); // ! change from M2 - //??? storing this information with every type pattern is wasteful of .class - // file size. Storing it on enclosing types would be more efficient + typeParameters.write(s); // ! change from M2 + // ??? storing this information with every type pattern is wasteful of .class + // file size. Storing it on enclosing types would be more efficient FileUtil.writeStringArray(knownMatches, s); FileUtil.writeStringArray(importedPrefixes, s); writeLocation(s); @@ -1211,9 +1235,11 @@ public class WildTypePattern extends TypePattern { // generics info, new in M3 s.writeBoolean(isGeneric); s.writeBoolean(upperBound != null); - if (upperBound != null) upperBound.write(s); + if (upperBound != null) + upperBound.write(s); s.writeBoolean(lowerBound != null); - if (lowerBound != null) lowerBound.write(s); + if (lowerBound != null) + lowerBound.write(s); s.writeInt(additionalInterfaceBounds == null ? 0 : additionalInterfaceBounds.length); if (additionalInterfaceBounds != null) { for (int i = 0; i < additionalInterfaceBounds.length; i++) { @@ -1221,69 +1247,69 @@ public class WildTypePattern extends TypePattern { } } } - + 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); - } - } - - public static TypePattern readTypePattern150(VersionedDataInputStream s, ISourceContext context) throws IOException { - byte version = s.readByte(); - if (version > VERSION) { - throw new BCException("WildTypePattern was written by a more recent version of AspectJ, cannot read"); - } - int len = s.readShort(); - NamePattern[] namePatterns = new NamePattern[len]; - for (int i=0; i < len; i++) { - namePatterns[i] = NamePattern.read(s); - } - boolean includeSubtypes = s.readBoolean(); - int dim = s.readInt(); - boolean varArg = s.readBoolean(); - TypePatternList typeParams = TypePatternList.read(s, context); - WildTypePattern ret = new WildTypePattern(namePatterns, includeSubtypes, dim, varArg,typeParams); - ret.knownMatches = FileUtil.readStringArray(s); - ret.importedPrefixes = FileUtil.readStringArray(s); - ret.readLocation(context, s); - ret.setAnnotationTypePattern(AnnotationTypePattern.read(s,context)); - // generics info, new in M3 - ret.isGeneric = s.readBoolean(); - if (s.readBoolean()) { - ret.upperBound = TypePattern.read(s,context); - } - if (s.readBoolean()) { - ret.lowerBound = TypePattern.read(s,context); - } - int numIfBounds = s.readInt(); - if (numIfBounds > 0) { - ret.additionalInterfaceBounds = new TypePattern[numIfBounds]; - for (int i = 0; i < numIfBounds; i++) { - ret.additionalInterfaceBounds[i] = TypePattern.read(s,context); - } - } - return ret; + return readTypePatternOldStyle(s, context); + } } - + + public static TypePattern readTypePattern150(VersionedDataInputStream s, ISourceContext context) throws IOException { + byte version = s.readByte(); + if (version > VERSION) { + throw new BCException("WildTypePattern was written by a more recent version of AspectJ, cannot read"); + } + int len = s.readShort(); + NamePattern[] namePatterns = new NamePattern[len]; + for (int i = 0; i < len; i++) { + namePatterns[i] = NamePattern.read(s); + } + boolean includeSubtypes = s.readBoolean(); + int dim = s.readInt(); + boolean varArg = s.readBoolean(); + TypePatternList typeParams = TypePatternList.read(s, context); + WildTypePattern ret = new WildTypePattern(namePatterns, includeSubtypes, dim, varArg, typeParams); + ret.knownMatches = FileUtil.readStringArray(s); + ret.importedPrefixes = FileUtil.readStringArray(s); + ret.readLocation(context, s); + ret.setAnnotationTypePattern(AnnotationTypePattern.read(s, context)); + // generics info, new in M3 + ret.isGeneric = s.readBoolean(); + if (s.readBoolean()) { + ret.upperBound = TypePattern.read(s, context); + } + if (s.readBoolean()) { + ret.lowerBound = TypePattern.read(s, context); + } + int numIfBounds = s.readInt(); + if (numIfBounds > 0) { + ret.additionalInterfaceBounds = new TypePattern[numIfBounds]; + for (int i = 0; i < numIfBounds; i++) { + ret.additionalInterfaceBounds[i] = TypePattern.read(s, context); + } + } + return ret; + } + public static TypePattern readTypePatternOldStyle(VersionedDataInputStream s, ISourceContext context) throws IOException { int len = s.readShort(); NamePattern[] namePatterns = new NamePattern[len]; - for (int i=0; i < len; i++) { + for (int i = 0; i < len; i++) { namePatterns[i] = NamePattern.read(s); } boolean includeSubtypes = s.readBoolean(); int dim = s.readInt(); - WildTypePattern ret = new WildTypePattern(namePatterns, includeSubtypes, dim, false,null); + WildTypePattern ret = new WildTypePattern(namePatterns, includeSubtypes, dim, false, null); ret.knownMatches = FileUtil.readStringArray(s); ret.importedPrefixes = FileUtil.readStringArray(s); ret.readLocation(context, s); 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); + } } |