import org.aspectj.weaver.patterns.DeclareParents;
import org.aspectj.weaver.patterns.FastMatchInfo;
import org.aspectj.weaver.patterns.IfPointcut;
+import org.aspectj.weaver.patterns.KindedPointcut;
import org.aspectj.weaver.patterns.NameBindingPointcut;
import org.aspectj.weaver.patterns.NotPointcut;
import org.aspectj.weaver.patterns.OrPointcut;
import org.aspectj.weaver.patterns.Pointcut;
import org.aspectj.weaver.patterns.PointcutRewriter;
+import org.aspectj.weaver.patterns.WithinPointcut;
public class BcelWeaver implements IWeaver {
}
Set kindsInCommon = left.couldMatchKinds();
kindsInCommon.retainAll(right.couldMatchKinds());
- if (!kindsInCommon.isEmpty()) {
+ if (!kindsInCommon.isEmpty() && couldEverMatchSameJoinPoints(left,right)) {
// we know that every branch binds every formal, so there is no ambiguity
// if each branch binds it in exactly the same way...
List ambiguousNames = new ArrayList();
}
}
+
+ // By returning false from this method, we are allowing binding of the same
+ // variable on either side of an or.
+ // Be conservative :- have to consider overriding, varargs, autoboxing,
+ // the effects of itds (on within for example), interfaces, the fact that
+ // join points can have multiple signatures and so on.
+ private boolean couldEverMatchSameJoinPoints(Pointcut left, Pointcut right) {
+ if ((left instanceof OrPointcut) || (right instanceof OrPointcut)) return true;
+ // look for withins
+ WithinPointcut leftWithin = (WithinPointcut) findFirstPointcutIn(left,WithinPointcut.class);
+ WithinPointcut rightWithin = (WithinPointcut) findFirstPointcutIn(right,WithinPointcut.class);
+ if ((leftWithin != null) && (rightWithin != null)) {
+ if (!leftWithin.couldEverMatchSameJoinPointsAs(rightWithin)) return false;
+ }
+ // look for kinded
+ KindedPointcut leftKind = (KindedPointcut) findFirstPointcutIn(left,KindedPointcut.class);
+ KindedPointcut rightKind = (KindedPointcut) findFirstPointcutIn(right,KindedPointcut.class);
+ if ((leftKind != null) && (rightKind != null)) {
+ if (!leftKind.couldEverMatchSameJoinPointsAs(rightKind)) return false;
+ }
+ return true;
+ }
+
+ private Pointcut findFirstPointcutIn(Pointcut toSearch, Class toLookFor) {
+ if (toSearch instanceof NotPointcut) return null;
+ if (toLookFor.isInstance(toSearch)) return toSearch;
+ if (toSearch instanceof AndPointcut) {
+ AndPointcut apc = (AndPointcut) toSearch;
+ Pointcut left = findFirstPointcutIn(apc.getLeft(),toLookFor);
+ if (left != null) return left;
+ return findFirstPointcutIn(apc.getRight(),toLookFor);
+ }
+ return null;
+ }
+
/**
* @param userPointcut
*/
setLocation(left.getSourceContext(), left.getStart(), right.getEnd());
}
+ protected boolean couldEverMatchSameTypesAs(TypePattern other) {
+ return true; // don't dive into ands yet....
+ }
public FuzzyBoolean matchesInstanceof(ResolvedTypeX type) {
return left.matchesInstanceof(type).and(right.matchesInstanceof(type));
}
this.type = type;
}
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.TypePattern#couldEverMatchSameTypesAs(org.aspectj.weaver.patterns.TypePattern)
+ */
+ protected boolean couldEverMatchSameTypesAs(TypePattern other) {
+ if (super.couldEverMatchSameTypesAs(other)) return true;
+ // false is necessary but not sufficient
+ TypeX otherType = other.getExactType();
+ if (otherType != ResolvedTypeX.MISSING) {
+ return type.equals(otherType);
+ }
+ if (other instanceof WildTypePattern) {
+ WildTypePattern owtp = (WildTypePattern) other;
+ String yourSimpleNamePrefix = owtp.namePatterns[0].maybeGetSimpleName();
+ if (yourSimpleNamePrefix != null) {
+ return (type.getName().startsWith(yourSimpleNamePrefix));
+ }
+ }
+ return true;
+ }
+
protected boolean matchesExactly(ResolvedTypeX matchType) {
return this.type.equals(matchType);
}
return matchKinds;
}
+ public boolean couldEverMatchSameJoinPointsAs(KindedPointcut other) {
+ if (this.kind != other.kind) return false;
+ String myName = signature.getName().maybeGetSimpleName();
+ String yourName = other.signature.getName().maybeGetSimpleName();
+ if (myName != null && yourName != null) {
+ if ( !myName.equals(yourName)) {
+ return false;
+ }
+ }
+ if (signature.getParameterTypes().ellipsisCount == 0) {
+ if (other.signature.getParameterTypes().ellipsisCount == 0) {
+ if (signature.getParameterTypes().getTypePatterns().length !=
+ other.signature.getParameterTypes().getTypePatterns().length) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
public FuzzyBoolean fastMatch(FastMatchInfo info) {
if (info.getKind() != null) {
if (info.getKind() != kind) return FuzzyBoolean.NO;
setLocation(pattern.getSourceContext(), pattern.getStart(), pattern.getEnd());
}
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.TypePattern#couldEverMatchSameTypesAs(org.aspectj.weaver.patterns.TypePattern)
+ */
+ protected boolean couldEverMatchSameTypesAs(TypePattern other) {
+ return true;
+ }
+
public FuzzyBoolean matchesInstanceof(ResolvedTypeX type) {
return pattern.matchesInstanceof(type).not();
}
import org.aspectj.weaver.IntMap;
import org.aspectj.weaver.ResolvedTypeX;
import org.aspectj.weaver.Shadow;
+import org.aspectj.weaver.ast.Literal;
import org.aspectj.weaver.ast.Test;
public class OrPointcut extends Pointcut {
setLocation(left.getSourceContext(), left.getStart(), right.getEnd());
}
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.TypePattern#couldEverMatchSameTypesAs(org.aspectj.weaver.patterns.TypePattern)
+ */
+ protected boolean couldEverMatchSameTypesAs(TypePattern other) {
+ return true; // don't dive at the moment...
+ }
+
public FuzzyBoolean matchesInstanceof(ResolvedTypeX type) {
return left.matchesInstanceof(type).or(right.matchesInstanceof(type));
}
this.annotationPattern = annPatt;
}
+ // answer conservatively...
+ protected boolean couldEverMatchSameTypesAs(TypePattern other) {
+ if (this.includeSubtypes || other.includeSubtypes) return true;
+ if (this.annotationPattern != AnnotationTypePattern.ANY) return true;
+ if (other.annotationPattern != AnnotationTypePattern.ANY) return true;
+ return false;
+ }
+
//XXX non-final for Not, && and ||
public boolean matchesStatically(ResolvedTypeX type) {
if (includeSubtypes) {
super(false,false);
}
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.TypePattern#couldEverMatchSameTypesAs(org.aspectj.weaver.patterns.TypePattern)
+ */
+ protected boolean couldEverMatchSameTypesAs(TypePattern other) {
+ return true;
+ }
/**
* @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType)
*/
super(false,false);
}
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.TypePattern#couldEverMatchSameTypesAs(org.aspectj.weaver.patterns.TypePattern)
+ */
+ protected boolean couldEverMatchSameTypesAs(TypePattern other) {
+ return true;
+ }
/**
* @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType)
*/
super(false,false);
}
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.TypePattern#couldEverMatchSameTypesAs(org.aspectj.weaver.patterns.TypePattern)
+ */
+ protected boolean couldEverMatchSameTypesAs(TypePattern other) {
+ return false;
+ }
/**
* @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType)
*/
this.isVarArgs = isVarArg;
}
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.TypePattern#couldEverMatchSameTypesAs(org.aspectj.weaver.patterns.TypePattern)
+ */
+ protected boolean couldEverMatchSameTypesAs(TypePattern other) {
+ if (super.couldEverMatchSameTypesAs(other)) return true;
+ // false is necessary but not sufficient
+ TypeX otherType = other.getExactType();
+ if (otherType != ResolvedTypeX.MISSING) {
+ if (namePatterns.length > 0) {
+ if (!namePatterns[0].matches(otherType.getName())) return false;
+ }
+ }
+ if (other instanceof WildTypePattern) {
+ WildTypePattern owtp = (WildTypePattern) other;
+ String mySimpleName = namePatterns[0].maybeGetSimpleName();
+ String yourSimpleName = owtp.namePatterns[0].maybeGetSimpleName();
+ if (mySimpleName != null && yourSimpleName != null) {
+ return (mySimpleName.startsWith(yourSimpleName) ||
+ yourSimpleName.startsWith(mySimpleName));
+ }
+ }
+ return true;
+ }
+
//XXX inefficient implementation
public static char[][] splitNames(String s) {
List ret = new ArrayList();
typePattern.postRead(enclosingType);
}
+ public boolean couldEverMatchSameJoinPointsAs(WithinPointcut other) {
+ return typePattern.couldEverMatchSameTypesAs(other.typePattern);
+ }
+
public boolean equals(Object other) {
if (!(other instanceof WithinPointcut)) return false;
WithinPointcut o = (WithinPointcut)other;