package org.aspectj.weaver.patterns;
import java.io.IOException;
import java.util.Map;
import org.aspectj.weaver.CompressingDataOutputStream;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.World;
public class ThrowsPattern extends PatternNode {
private TypePatternList required;
private TypePatternList forbidden;
public static final ThrowsPattern ANY = new ThrowsPattern(TypePatternList.EMPTY, TypePatternList.EMPTY);
public ThrowsPattern(TypePatternList required, TypePatternList forbidden) {
this.required = required;
this.forbidden = forbidden;
}
public TypePatternList getRequired() {
return required;
}
public TypePatternList getForbidden() {
return forbidden;
}
public String toString() {
if (this == ANY) {
return "";
}
String ret = "throws " + required.toString();
if (forbidden.size() > 0) {
ret = ret + " !(" + forbidden.toString() + ")";
}
return ret;
}
public boolean equals(Object other) {
if (!(other instanceof ThrowsPattern)) {
return false;
}
ThrowsPattern o = (ThrowsPattern) other;
boolean ret = o.required.equals(this.required) && o.forbidden.equals(this.forbidden);
return ret;
}
public int hashCode() {
int result = 17;
result = 37 * result + required.hashCode();
result = 37 * result + forbidden.hashCode();
return result;
}
public ThrowsPattern resolveBindings(IScope scope, Bindings bindings) {
if (this == ANY) {
return this;
}
required = required.resolveBindings(scope, bindings, false, false);
forbidden = forbidden.resolveBindings(scope, bindings, false, false);
return this;
}
public ThrowsPattern parameterizeWith(Map<String,UnresolvedType> typeVariableMap, World w) {
ThrowsPattern ret = new ThrowsPattern(required.parameterizeWith(typeVariableMap, w), forbidden.parameterizeWith(
typeVariableMap, w));
ret.copyLocationFrom(this);
return ret;
}
public boolean matches(UnresolvedType[] tys, World world) {
if (this == ANY) {
return true;
}
ResolvedType[] types = world.resolve(tys);
for (int j = 0, lenj = required.size(); j < lenj; j++) {
if (!matchesAny(required.get(j), types)) {
return false;
}
}
for (int j = 0, lenj = forbidden.size(); j < lenj; j++) {
if (matchesAny(forbidden.get(j), types)) {
return false;
}
}
return true;
}
private boolean matchesAny(TypePattern typePattern, ResolvedType[] types) {
for (int i = types.length - 1; i >= 0; i--) {
if (typePattern.matchesStatically(types[i])) {
return true;
}
}
return false;
}
public static ThrowsPattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
TypePatternList required = TypePatternList.read(s, context);
TypePatternList forbidden = TypePatternList.read(s, context);
if (required.size() == 0 && forbidden.size() == 0) {
return ANY;
}
ThrowsPattern ret = new ThrowsPattern(required, forbidden);
return ret;
}
public void write(CompressingDataOutputStream s) throws IOException {
required.write(s);
forbidden.write(s);
}
public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
public Object traverse(PatternNodeVisitor visitor, Object data) {
Object ret = accept(visitor, data);
forbidden.traverse(visitor, data);
required.traverse(visitor, data);
return ret;
}
}