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);
public TypeX getReturnType() {
if (kind == ConstructorCall) return getSignature().getDeclaringType();
+ else if (kind == FieldSet) return ResolvedTypeX.VOID;
return getSignature().getReturnType();
}
}
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(
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;
}
}
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)");
}
public void resolve(IScope scope) {
- patterns = patterns.resolveBindings(scope, Bindings.NONE, false);
+ patterns = patterns.resolveBindings(scope, Bindings.NONE, false, false);
}
public TypePatternList getPatterns() {
}
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() {
}
public void resolve(IScope scope) {
- exception = exception.resolveBindings(scope, null, false);
+ exception = exception.resolveBindings(scope, null, false, true);
pointcut = pointcut.resolve(scope);
}
//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");
}
// 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) {
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;
}
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;
}
}
- 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
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);
}
public void resolveBindings(IScope scope, Bindings bindings) {
- type = type.resolveBindings(scope, bindings, true);
+ type = type.resolveBindings(scope, bindings, true, true);
+
// ??? handle non-formal
}
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;
}
public static final TypePattern ELLIPSIS = new EllipsisTypePattern();
public static final TypePattern ANY = new AnyTypePattern();
+ public static final TypePattern NO = new NoTypePattern();
protected boolean includeSubtypes;
}
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();
}
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;
}
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();
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);
}
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>"; }
}
+
}
}
- 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;
*
* 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
}
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 {
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
}
}
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) {
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);
//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)");
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);
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;
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);
}
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);
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);
}