blob: d23404f7fb23779daa2e59e3211387ab6e5c353e [file] [log] [blame]
/* *******************************************************************
* Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* PARC initial implementation
* ******************************************************************/
package org.aspectj.weaver.patterns;
import java.io.IOException;
import java.util.Map;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.CompressingDataOutputStream;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.World;
/**
* left && right
*
* <p>
* any binding to formals is explicitly forbidden for any composite by the language
*
* @author Erik Hilsdale
* @author Jim Hugunin
*/
public class AndTypePattern extends TypePattern {
private TypePattern left, right;
public AndTypePattern(TypePattern left, TypePattern right) {
super(false, false); // ?? we override all methods that care about includeSubtypes
this.left = left;
this.right = right;
setLocation(left.getSourceContext(), left.getStart(), right.getEnd());
}
protected boolean couldEverMatchSameTypesAs(TypePattern other) {
return true; // don't dive into ands yet....
}
public FuzzyBoolean matchesInstanceof(ResolvedType type) {
return left.matchesInstanceof(type).and(right.matchesInstanceof(type));
}
protected boolean matchesExactly(ResolvedType type) {
// ??? if these had side-effects, this sort-circuit could be a mistake
return left.matchesExactly(type) && right.matchesExactly(type);
}
protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) {
return left.matchesExactly(type, annotatedType) && right.matchesExactly(type, annotatedType);
}
public boolean matchesStatically(ResolvedType type) {
return left.matchesStatically(type) && right.matchesStatically(type);
}
public void setIsVarArgs(boolean isVarArgs) {
this.isVarArgs = isVarArgs;
left.setIsVarArgs(isVarArgs);
right.setIsVarArgs(isVarArgs);
}
public void setAnnotationTypePattern(AnnotationTypePattern annPatt) {
if (annPatt == AnnotationTypePattern.ANY) {
return;
}
if (left.annotationPattern == AnnotationTypePattern.ANY) {
left.setAnnotationTypePattern(annPatt);
} else {
left.setAnnotationTypePattern(new AndAnnotationTypePattern(left.annotationPattern, annPatt));
}
if (right.annotationPattern == AnnotationTypePattern.ANY) {
right.setAnnotationTypePattern(annPatt);
} else {
right.setAnnotationTypePattern(new AndAnnotationTypePattern(right.annotationPattern, annPatt));
}
}
public void write(CompressingDataOutputStream s) throws IOException {
s.writeByte(TypePattern.AND);
left.write(s);
right.write(s);
writeLocation(s);
}
public static TypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
AndTypePattern ret = new AndTypePattern(TypePattern.read(s, context), TypePattern.read(s, context));
ret.readLocation(context, s);
if (ret.left.isVarArgs && ret.right.isVarArgs) {
ret.isVarArgs = true;
}
return ret;
}
public TypePattern resolveBindings(IScope scope, Bindings bindings, 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 TypePattern parameterizeWith(Map typeVariableMap, World w) {
TypePattern newLeft = left.parameterizeWith(typeVariableMap, w);
TypePattern newRight = right.parameterizeWith(typeVariableMap, w);
AndTypePattern ret = new AndTypePattern(newLeft, newRight);
ret.copyLocationFrom(this);
return ret;
}
public String toString() {
StringBuffer buff = new StringBuffer();
if (annotationPattern != AnnotationTypePattern.ANY) {
buff.append('(');
buff.append(annotationPattern.toString());
buff.append(' ');
}
buff.append('(');
buff.append(left.toString());
buff.append(" && ");
buff.append(right.toString());
buff.append(')');
if (annotationPattern != AnnotationTypePattern.ANY) {
buff.append(')');
}
return buff.toString();
}
public TypePattern getLeft() {
return left;
}
public TypePattern getRight() {
return right;
}
public boolean equals(Object obj) {
if (!(obj instanceof AndTypePattern)) {
return false;
}
AndTypePattern atp = (AndTypePattern) obj;
return left.equals(atp.left) && right.equals(atp.right);
}
public boolean isStarAnnotation() {
return left.isStarAnnotation() && right.isStarAnnotation();
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
int ret = 17;
ret = ret + 37 * left.hashCode();
ret = ret + 37 * right.hashCode();
return ret;
}
public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
public Object traverse(PatternNodeVisitor visitor, Object data) {
Object ret = accept(visitor, data);
left.traverse(visitor, ret);
right.traverse(visitor, ret);
return ret;
}
}