package org.aspectj.weaver.patterns;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.CompressingDataOutputStream;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.IntMap;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.World;
public class AnnotationPatternList extends PatternNode {
private AnnotationTypePattern[] typePatterns;
int ellipsisCount = 0;
public static final AnnotationPatternList EMPTY = new AnnotationPatternList(new AnnotationTypePattern[] {});
public static final AnnotationPatternList ANY = new AnnotationPatternList(
new AnnotationTypePattern[] { AnnotationTypePattern.ELLIPSIS });
public AnnotationPatternList() {
typePatterns = new AnnotationTypePattern[0];
ellipsisCount = 0;
}
public AnnotationPatternList(AnnotationTypePattern[] arguments) {
this.typePatterns = arguments;
for (int i = 0; i < arguments.length; i++) {
if (arguments[i] == AnnotationTypePattern.ELLIPSIS) {
ellipsisCount++;
}
}
}
public AnnotationPatternList(List<AnnotationTypePattern> l) {
this((AnnotationTypePattern[]) l.toArray(new AnnotationTypePattern[l.size()]));
}
protected AnnotationTypePattern[] getAnnotationPatterns() {
return typePatterns;
}
public AnnotationPatternList parameterizeWith(Map<String,UnresolvedType> typeVariableMap, World w) {
AnnotationTypePattern[] parameterizedPatterns = new AnnotationTypePattern[this.typePatterns.length];
for (int i = 0; i < parameterizedPatterns.length; i++) {
parameterizedPatterns[i] = this.typePatterns[i].parameterizeWith(typeVariableMap, w);
}
AnnotationPatternList ret = new AnnotationPatternList(parameterizedPatterns);
ret.copyLocationFrom(this);
return ret;
}
public void resolve(World inWorld) {
for (int i = 0; i < typePatterns.length; i++) {
typePatterns[i].resolve(inWorld);
}
}
public FuzzyBoolean matches(ResolvedType[] someArgs) {
int numArgsMatchedByEllipsis = (someArgs.length + ellipsisCount) - typePatterns.length;
if (numArgsMatchedByEllipsis < 0) {
return FuzzyBoolean.NO;
}
if ((numArgsMatchedByEllipsis > 0) && (ellipsisCount == 0)) {
return FuzzyBoolean.NO;
}
FuzzyBoolean ret = FuzzyBoolean.YES;
int argsIndex = 0;
for (int i = 0; i < typePatterns.length; i++) {
if (typePatterns[i] == AnnotationTypePattern.ELLIPSIS) {
argsIndex += numArgsMatchedByEllipsis;
} else if (typePatterns[i] == AnnotationTypePattern.ANY) {
argsIndex++;
} else {
if (someArgs[argsIndex].isPrimitiveType()) {
return FuzzyBoolean.NO;
}
ExactAnnotationTypePattern ap = (ExactAnnotationTypePattern) typePatterns[i];
FuzzyBoolean matches = ap.matchesRuntimeType(someArgs[argsIndex]);
if (matches == FuzzyBoolean.NO) {
return FuzzyBoolean.MAYBE;
} else {
argsIndex++;
ret = ret.and(matches);
}
}
}
return ret;
}
public int size() {
return typePatterns.length;
}
public AnnotationTypePattern get(int index) {
return typePatterns[index];
}
public AnnotationPatternList resolveBindings(IScope scope, Bindings bindings, boolean allowBinding) {
for (int i = 0; i < typePatterns.length; i++) {
AnnotationTypePattern p = typePatterns[i];
if (p != null) {
typePatterns[i] = typePatterns[i].resolveBindings(scope, bindings, allowBinding);
}
}
return this;
}
public AnnotationPatternList resolveReferences(IntMap bindings) {
int len = typePatterns.length;
AnnotationTypePattern[] ret = new AnnotationTypePattern[len];
for (int i = 0; i < len; i++) {
ret[i] = typePatterns[i].remapAdviceFormals(bindings);
}
return new AnnotationPatternList(ret);
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("(");
for (int i = 0, len = typePatterns.length; i < len; i++) {
AnnotationTypePattern type = typePatterns[i];
if (i > 0) {
buf.append(", ");
}
if (type == AnnotationTypePattern.ELLIPSIS) {
buf.append("..");
} else {
String annPatt = type.toString();
buf.append(annPatt.startsWith("@") ? annPatt.substring(1) : annPatt);
}
}
buf.append(")");
return buf.toString();
}
public boolean equals(Object other) {
if (!(other instanceof AnnotationPatternList)) {
return false;
}
AnnotationPatternList o = (AnnotationPatternList) other;
int len = o.typePatterns.length;
if (len != this.typePatterns.length) {
return false;
}
for (int i = 0; i < len; i++) {
if (!this.typePatterns[i].equals(o.typePatterns[i])) {
return false;
}
}
return true;
}
public int hashCode() {
int result = 41;
for (int i = 0, len = typePatterns.length; i < len; i++) {
result = 37 * result + typePatterns[i].hashCode();
}
return result;
}
public static AnnotationPatternList read(VersionedDataInputStream s, ISourceContext context) throws IOException {
short len = s.readShort();
AnnotationTypePattern[] arguments = new AnnotationTypePattern[len];
for (int i = 0; i < len; i++) {
arguments[i] = AnnotationTypePattern.read(s, context);
}
AnnotationPatternList ret = new AnnotationPatternList(arguments);
ret.readLocation(context, s);
return ret;
}
public void write(CompressingDataOutputStream s) throws IOException {
s.writeShort(typePatterns.length);
for (int i = 0; i < typePatterns.length; i++) {
typePatterns[i].write(s);
}
writeLocation(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);
for (int i = 0; i < typePatterns.length; i++) {
typePatterns[i].traverse(visitor, ret);
}
return ret;
}
}