instead of type patterntags/V_1_1_b2
@@ -140,7 +140,8 @@ public class AjLookupEnvironment extends LookupEnvironment { | |||
private void addParent(DeclareParents declareParents, ClassScope scope, TypePattern typePattern) { | |||
SourceTypeBinding sourceType = scope.referenceContext.binding; | |||
if (!typePattern.assertExactType(world.getMessageHandler())) return; | |||
//if (!typePattern.assertExactType(world.getMessageHandler())) return; | |||
if (typePattern == TypePattern.NO) return; // already had an error here | |||
TypeX iType = typePattern.getExactType(); | |||
// if (iType == null) { | |||
// throw new RuntimeException("yikes: " + typePattern); |
@@ -103,6 +103,7 @@ public abstract class Shadow { | |||
public TypeX getReturnType() { | |||
if (kind == ConstructorCall) return getSignature().getDeclaringType(); | |||
else if (kind == FieldSet) return ResolvedTypeX.VOID; | |||
return getSignature().getReturnType(); | |||
} | |||
@@ -1706,12 +1706,10 @@ public class BcelShadow extends Shadow { | |||
} | |||
TypeX returnType; | |||
if (getKind() == ConstructorCall) { | |||
returnType = getSignature().getDeclaringType(); | |||
} else if (getKind() == PreInitialization) { | |||
if (getKind() == PreInitialization) { | |||
returnType = TypeX.OBJECTARRAY; | |||
} else { | |||
returnType = getSignature().getReturnType(); | |||
returnType = getReturnType(); | |||
} | |||
return | |||
new LazyMethodGen( |
@@ -66,9 +66,11 @@ public class AndTypePattern extends TypePattern { | |||
public TypePattern resolveBindings( | |||
IScope scope, | |||
Bindings bindings, | |||
boolean allowBinding) { | |||
left = left.resolveBindings(scope, bindings, false); | |||
right = right.resolveBindings(scope, bindings, false); | |||
boolean allowBinding, boolean requireExactType) | |||
{ | |||
if (requireExactType) return notExactType(scope); | |||
left = left.resolveBindings(scope, bindings, false, false); | |||
right = right.resolveBindings(scope, bindings, false, false); | |||
return this; | |||
} | |||
@@ -68,7 +68,7 @@ public class ArgsPointcut extends NameBindingPointcut { | |||
} | |||
public void resolveBindings(IScope scope, Bindings bindings) { | |||
arguments.resolveBindings(scope, bindings, true); | |||
arguments.resolveBindings(scope, bindings, true, true); | |||
if (arguments.ellipsisCount > 1) { | |||
scope.message(IMessage.ERROR, this, | |||
"uses more than one .. in args (compiler limitation)"); |
@@ -63,7 +63,7 @@ public class DeclareDominates extends Declare { | |||
} | |||
public void resolve(IScope scope) { | |||
patterns = patterns.resolveBindings(scope, Bindings.NONE, false); | |||
patterns = patterns.resolveBindings(scope, Bindings.NONE, false, false); | |||
} | |||
public TypePatternList getPatterns() { |
@@ -78,11 +78,11 @@ public class DeclareParents extends Declare { | |||
} | |||
public void resolve(IScope scope) { | |||
child = child.resolveBindings(scope, Bindings.NONE, false); | |||
parents = parents.resolveBindings(scope, Bindings.NONE, false); | |||
for (int i=0; i < parents.size(); i++) { | |||
parents.get(i).assertExactType(scope.getMessageHandler()); | |||
} | |||
child = child.resolveBindings(scope, Bindings.NONE, false, false); | |||
parents = parents.resolveBindings(scope, Bindings.NONE, false, true); | |||
// for (int i=0; i < parents.size(); i++) { | |||
// parents.get(i).assertExactType(scope.getMessageHandler()); | |||
// } | |||
} | |||
public TypePatternList getParents() { |
@@ -77,7 +77,7 @@ public class DeclareSoft extends Declare { | |||
} | |||
public void resolve(IScope scope) { | |||
exception = exception.resolveBindings(scope, null, false); | |||
exception = exception.resolveBindings(scope, null, false, true); | |||
pointcut = pointcut.resolve(scope); | |||
} | |||
@@ -70,11 +70,9 @@ public class ExactTypePattern extends TypePattern { | |||
//Thread.currentThread().dumpStack(); | |||
return "ExactTypePattern(" + type.toString() + (includeSubtypes ? "+" : "") + ")"; | |||
} | |||
public TypePattern resolveBindings( | |||
IScope scope, | |||
Bindings bindings, | |||
boolean allowBinding) | |||
{ | |||
public TypePattern resolveBindings(IScope scope, Bindings bindings, | |||
boolean allowBinding, boolean requireExactType) | |||
{ | |||
throw new BCException("trying to re-resolve"); | |||
} |
@@ -81,7 +81,7 @@ public class HandlerPointcut extends Pointcut { | |||
// We want to do something here to make sure we don't sidestep the parameter | |||
// list in capturing type identifiers. | |||
public void resolveBindings(IScope scope, Bindings bindings) { | |||
exceptionType = exceptionType.resolveBindings(scope, bindings, false); | |||
exceptionType = exceptionType.resolveBindings(scope, bindings, false, false); | |||
//XXX add error if exact binding and not an exception | |||
} | |||
public Test findResidue(Shadow shadow, ExposedState state) { |
@@ -64,8 +64,10 @@ public class NotTypePattern extends TypePattern { | |||
public TypePattern resolveBindings( | |||
IScope scope, | |||
Bindings bindings, | |||
boolean allowBinding) { | |||
pattern = pattern.resolveBindings(scope, bindings, false); | |||
boolean allowBinding, boolean requireExactType) | |||
{ | |||
if (requireExactType) return notExactType(scope); | |||
pattern = pattern.resolveBindings(scope, bindings, false, false); | |||
return this; | |||
} | |||
@@ -66,9 +66,11 @@ public class OrTypePattern extends TypePattern { | |||
public TypePattern resolveBindings( | |||
IScope scope, | |||
Bindings bindings, | |||
boolean allowBinding) { | |||
left = left.resolveBindings(scope, bindings, false); | |||
right = right.resolveBindings(scope, bindings, false); | |||
boolean allowBinding, boolean requireExactType) | |||
{ | |||
if (requireExactType) return notExactType(scope); | |||
left = left.resolveBindings(scope, bindings, false, false); | |||
right = right.resolveBindings(scope, bindings, false, false); | |||
return this; | |||
} | |||
@@ -116,7 +116,7 @@ public class ReferencePointcut extends Pointcut { | |||
} | |||
arguments.resolveBindings(scope, bindings, true); | |||
arguments.resolveBindings(scope, bindings, true, true); | |||
//XXX ensure that arguments has no ..'s in it | |||
// check that I refer to a real pointcut declaration and that I match |
@@ -45,13 +45,13 @@ public class SignaturePattern extends PatternNode { | |||
public SignaturePattern resolveBindings(IScope scope, Bindings bindings) { | |||
if (returnType != null) { | |||
returnType = returnType.resolveBindings(scope, bindings, false); | |||
returnType = returnType.resolveBindings(scope, bindings, false, false); | |||
} | |||
if (declaringType != null) { | |||
declaringType = declaringType.resolveBindings(scope, bindings, false); | |||
declaringType = declaringType.resolveBindings(scope, bindings, false, false); | |||
} | |||
if (parameterTypes != null) { | |||
parameterTypes = parameterTypes.resolveBindings(scope, bindings, false); | |||
parameterTypes = parameterTypes.resolveBindings(scope, bindings, false, false); | |||
} | |||
if (throwsPattern != null) { | |||
throwsPattern = throwsPattern.resolveBindings(scope, bindings); |
@@ -69,7 +69,8 @@ public class ThisOrTargetPointcut extends NameBindingPointcut { | |||
} | |||
public void resolveBindings(IScope scope, Bindings bindings) { | |||
type = type.resolveBindings(scope, bindings, true); | |||
type = type.resolveBindings(scope, bindings, true, true); | |||
// ??? handle non-formal | |||
} | |||
@@ -58,8 +58,8 @@ public class ThrowsPattern extends PatternNode { | |||
public ThrowsPattern resolveBindings(IScope scope, Bindings bindings) { | |||
if (this == ANY) return this; | |||
required = required.resolveBindings(scope, bindings, false); | |||
forbidden = forbidden.resolveBindings(scope, bindings, false); | |||
required = required.resolveBindings(scope, bindings, false, false); | |||
forbidden = forbidden.resolveBindings(scope, bindings, false, false); | |||
return this; | |||
} | |||
@@ -41,6 +41,7 @@ public abstract class TypePattern extends PatternNode { | |||
public static final TypePattern ELLIPSIS = new EllipsisTypePattern(); | |||
public static final TypePattern ANY = new AnyTypePattern(); | |||
public static final TypePattern NO = new NoTypePattern(); | |||
protected boolean includeSubtypes; | |||
@@ -91,8 +92,8 @@ public abstract class TypePattern extends PatternNode { | |||
} | |||
public TypeX resolveExactType(IScope scope, Bindings bindings) { | |||
TypePattern p = resolveBindings(scope, bindings, false); | |||
if (!p.assertExactType(scope.getMessageHandler())) return ResolvedTypeX.MISSING; | |||
TypePattern p = resolveBindings(scope, bindings, false, true); | |||
if (p == NO) return ResolvedTypeX.MISSING; | |||
return ((ExactTypePattern)p).getType(); | |||
} | |||
@@ -102,18 +103,25 @@ public abstract class TypePattern extends PatternNode { | |||
else return ResolvedTypeX.MISSING; | |||
} | |||
public boolean assertExactType(IMessageHandler m) { | |||
if (this instanceof ExactTypePattern) return true; | |||
//XXX should try harder to avoid multiple errors for one problem | |||
m.handleMessage(MessageUtil.error("exact type pattern required", getSourceLocation())); | |||
return false; | |||
protected TypePattern notExactType(IScope s) { | |||
s.getMessageHandler().handleMessage(MessageUtil.error("exact type pattern required", getSourceLocation())); | |||
return NO; | |||
} | |||
// public boolean assertExactType(IMessageHandler m) { | |||
// if (this instanceof ExactTypePattern) return true; | |||
// | |||
// //XXX should try harder to avoid multiple errors for one problem | |||
// m.handleMessage(MessageUtil.error("exact type pattern required", getSourceLocation())); | |||
// return false; | |||
// } | |||
/** | |||
* This can modify in place, or return a new TypePattern if the type changes. | |||
*/ | |||
public TypePattern resolveBindings(IScope scope, Bindings bindings, boolean allowBinding) { | |||
public TypePattern resolveBindings(IScope scope, Bindings bindings, | |||
boolean allowBinding, boolean requireExactType) | |||
{ | |||
return this; | |||
} | |||
@@ -157,6 +165,7 @@ public abstract class TypePattern extends PatternNode { | |||
public static final byte NOT = 6; | |||
public static final byte OR = 7; | |||
public static final byte AND = 8; | |||
public static final byte NO_KEY = 9; | |||
public static TypePattern read(DataInputStream s, ISourceContext context) throws IOException { | |||
byte key = s.readByte(); | |||
@@ -166,6 +175,7 @@ public abstract class TypePattern extends PatternNode { | |||
case BINDING: return BindingTypePattern.read(s, context); | |||
case ELLIPSIS_KEY: return ELLIPSIS; | |||
case ANY_KEY: return ANY; | |||
case NO_KEY: return NO; | |||
case NOT: return NotTypePattern.read(s, context); | |||
case OR: return OrTypePattern.read(s, context); | |||
case AND: return AndTypePattern.read(s, context); | |||
@@ -259,5 +269,54 @@ class AnyTypePattern extends TypePattern { | |||
} | |||
public String toString() { return "*"; } | |||
} | |||
class NoTypePattern extends TypePattern { | |||
public NoTypePattern() { | |||
super(false); | |||
} | |||
/** | |||
* @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType) | |||
*/ | |||
protected boolean matchesExactly(ResolvedTypeX type) { | |||
return false; | |||
} | |||
/** | |||
* @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(IType) | |||
*/ | |||
public FuzzyBoolean matchesInstanceof(ResolvedTypeX type) { | |||
return FuzzyBoolean.NO; | |||
} | |||
/** | |||
* @see org.aspectj.weaver.patterns.PatternNode#write(DataOutputStream) | |||
*/ | |||
public void write(DataOutputStream s) throws IOException { | |||
s.writeByte(NO_KEY); | |||
} | |||
/** | |||
* @see org.aspectj.weaver.patterns.TypePattern#matches(IType, MatchKind) | |||
*/ | |||
// public FuzzyBoolean matches(IType type, MatchKind kind) { | |||
// return FuzzyBoolean.YES; | |||
// } | |||
/** | |||
* @see org.aspectj.weaver.patterns.TypePattern#matchesSubtypes(IType) | |||
*/ | |||
protected boolean matchesSubtypes(ResolvedTypeX type) { | |||
return false; | |||
} | |||
public boolean isStar() { | |||
return false; | |||
} | |||
public String toString() { return "<nothing>"; } | |||
} | |||
@@ -162,11 +162,11 @@ public class TypePatternList extends PatternNode { | |||
} | |||
} | |||
public TypePatternList resolveBindings(IScope scope, Bindings bindings, boolean allowBinding) { | |||
public TypePatternList resolveBindings(IScope scope, Bindings bindings, boolean allowBinding, boolean requireExactType) { | |||
for (int i=0; i<typePatterns.length; i++) { | |||
TypePattern p = typePatterns[i]; | |||
if (p != null) { | |||
typePatterns[i] = typePatterns[i].resolveBindings(scope, bindings, allowBinding); | |||
typePatterns[i] = typePatterns[i].resolveBindings(scope, bindings, allowBinding, requireExactType); | |||
} | |||
} | |||
return this; |
@@ -287,8 +287,10 @@ public class WildTypePattern extends TypePattern { | |||
* | |||
* We will be replaced by what we return | |||
*/ | |||
public TypePattern resolveBindings(IScope scope, Bindings bindings, boolean allowBinding) { | |||
if (isStar()) { | |||
public TypePattern resolveBindings(IScope scope, Bindings bindings, | |||
boolean allowBinding, boolean requireExactType) | |||
{ | |||
if (isStar()) { | |||
return TypePattern.ANY; //??? loses source location | |||
} | |||
@@ -320,7 +322,16 @@ public class WildTypePattern extends TypePattern { | |||
cleanName = cleanName.substring(0, lastDot) + '$' + cleanName.substring(lastDot+1); | |||
} | |||
if (type == ResolvedTypeX.MISSING) { | |||
if (scope.getWorld().getLint().invalidAbsoluteTypeName.isEnabled()) { | |||
if (requireExactType) { | |||
if (!allowBinding) { | |||
scope.getWorld().getMessageHandler().handleMessage( | |||
MessageUtil.error("can't bind type name '" + cleanName + "'", | |||
getSourceLocation())); | |||
} else if (scope.getWorld().getLint().invalidAbsoluteTypeName.isEnabled()) { | |||
scope.getWorld().getLint().invalidAbsoluteTypeName.signal(cleanName, getSourceLocation()); | |||
} | |||
return NO; | |||
} else if (scope.getWorld().getLint().invalidAbsoluteTypeName.isEnabled()) { | |||
scope.getWorld().getLint().invalidAbsoluteTypeName.signal(cleanName, getSourceLocation()); | |||
} | |||
} else { | |||
@@ -330,6 +341,12 @@ public class WildTypePattern extends TypePattern { | |||
return ret; | |||
} | |||
} else { | |||
if (requireExactType) { | |||
scope.getWorld().getMessageHandler().handleMessage( | |||
MessageUtil.error("wildcard type pattern not allowed, must use type name", | |||
getSourceLocation())); | |||
return NO; | |||
} | |||
//XXX need to implement behavior for Lint.invalidWildcardTypeName | |||
} | |||
@@ -50,7 +50,7 @@ public class WithinPointcut extends Pointcut { | |||
} | |||
public void resolveBindings(IScope scope, Bindings bindings) { | |||
type = type.resolveBindings(scope, bindings, false); | |||
type = type.resolveBindings(scope, bindings, false, false); | |||
} | |||
public void postRead(ResolvedTypeX enclosingType) { |
@@ -43,7 +43,7 @@ public class BindingTestCase extends TestCase { | |||
BindingTypePattern[] b = new BindingTypePattern[] {null, bt}; | |||
checkBindings("this(b)",b); | |||
checkBindings("this(Foo)", none); | |||
checkBindings("this(java.lang.String)", none); | |||
checkBindings("this(*)", none); | |||
checkBindings("this(a)", a); | |||
@@ -65,12 +65,12 @@ public class BindingTestCase extends TestCase { | |||
//checkBindingFailure("this(a) && this(b)"); | |||
checkBindingFailure("this(a) || this(b)", "inconsistent"); | |||
checkBindingFailure("this(A) || this(b)", "inconsistent"); | |||
checkBindingFailure("this(a) || this(B)", "inconsistent"); | |||
checkBindingFailure("this(java.lang.String) || this(b)", "inconsistent"); | |||
checkBindingFailure("this(a) || this(java.lang.String)", "inconsistent"); | |||
checkBindings("this(a) || this(a)", a); | |||
checkBindings("!this(Foo)", none); | |||
checkBindings("!this(Foo) && this(a)", a); | |||
checkBindings("!this(java.lang.String)", none); | |||
checkBindings("!this(java.lang.String) && this(a)", a); | |||
checkBindingFailure("!this(a)", "negation"); | |||
//checkBindingFailure("this(a)"); | |||
@@ -113,7 +113,7 @@ public class TypePatternListTestCase extends TestCase { | |||
types[i] = world.resolve(names[i]); | |||
} | |||
p.resolveBindings(makeTestScope(), Bindings.NONE, false); | |||
p.resolveBindings(makeTestScope(), Bindings.NONE, false, false); | |||
//System.out.println("type: " + type); | |||
FuzzyBoolean result = p.matches(types, TypePattern.STATIC); | |||
String msg = "matches statically " + pattern + " to " + Arrays.asList(types); | |||
@@ -127,7 +127,7 @@ public class TypePatternListTestCase extends TestCase { | |||
public void stupidCheck(String pattern, boolean[] matches) { | |||
TypePatternList p = makeArgumentsPattern(pattern); | |||
p.resolveBindings(makeTestScope(), Bindings.NONE, false); | |||
p.resolveBindings(makeTestScope(), Bindings.NONE, false, false); | |||
int len = matches.length; | |||
@@ -173,7 +173,7 @@ public class TypePatternTestCase extends TestCase { | |||
TestScope scope = makeTestScope(); | |||
scope.setImportedPrefixes(importedPrefixes); | |||
scope.setImportedNames(importedNames); | |||
return (WildTypePattern) unresolved.resolveBindings(scope, Bindings.NONE, false); | |||
return (WildTypePattern) unresolved.resolveBindings(scope, Bindings.NONE, false, false); | |||
} | |||
@@ -218,7 +218,7 @@ public class TypePatternTestCase extends TestCase { | |||
TypePattern p = makeTypePattern(pattern); | |||
ResolvedTypeX type = world.resolve(name); | |||
p = p.resolveBindings(makeTestScope(), null, false); | |||
p = p.resolveBindings(makeTestScope(), null, false, false); | |||
//System.out.println("type: " + p); | |||
@@ -238,7 +238,7 @@ public class TypePatternTestCase extends TestCase { | |||
private void checkMatch(String pattern, String name, boolean shouldMatch) { | |||
TypePattern p = makeTypePattern(pattern); | |||
p = p.resolveBindings(makeTestScope(), null, false); | |||
p = p.resolveBindings(makeTestScope(), null, false, false); | |||
checkPatternMatch(p, name, shouldMatch); | |||
} | |||