summaryrefslogtreecommitdiffstats
path: root/org.aspectj.matcher/src
diff options
context:
space:
mode:
Diffstat (limited to 'org.aspectj.matcher/src')
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/patterns/WildTypePattern.java1296
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);
+ }
}