package org.aspectj.weaver.patterns;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ResolvedPointcutDefinition;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.Shadow;
public class PerThisOrTargetPointcutVisitor extends AbstractPatternNodeVisitor {
private final static TypePattern MAYBE = new TypePatternMayBe();
private final boolean m_isTarget;
private final ResolvedType m_fromAspectType;
public PerThisOrTargetPointcutVisitor(boolean isTarget, ResolvedType fromAspectType) {
m_isTarget = isTarget;
m_fromAspectType = fromAspectType;
}
public TypePattern getPerTypePointcut(Pointcut perClausePointcut) {
Object o = perClausePointcut.accept(this, perClausePointcut);
if (o instanceof TypePattern) {
return (TypePattern) o;
} else {
throw new BCException("perClausePointcut visitor did not return a typepattern, it returned " + o
+ (o == null ? "" : " of type " + o.getClass()));
}
}
public Object visit(WithinPointcut node, Object data) {
if (m_isTarget) {
return MAYBE;
} else {
return node.getTypePattern();
}
}
public Object visit(WithincodePointcut node, Object data) {
if (m_isTarget) {
return MAYBE;
} else {
return node.getSignature().getDeclaringType();
}
}
public Object visit(WithinAnnotationPointcut node, Object data) {
if (m_isTarget) {
return MAYBE;
} else {
return new AnyWithAnnotationTypePattern(node.getAnnotationTypePattern());
}
}
public Object visit(WithinCodeAnnotationPointcut node, Object data) {
if (m_isTarget) {
return MAYBE;
} else {
return MAYBE;
}
}
public Object visit(KindedPointcut node, Object data) {
if (node.getKind().equals(Shadow.AdviceExecution)) {
return MAYBE;
} else if (node.getKind().equals(Shadow.ConstructorExecution) || node.getKind().equals(Shadow.Initialization)
|| node.getKind().equals(Shadow.MethodExecution) || node.getKind().equals(Shadow.PreInitialization)
|| node.getKind().equals(Shadow.StaticInitialization)) {
SignaturePattern signaturePattern = node.getSignature();
boolean isStarAnnotation = signaturePattern.isStarAnnotation();
if (!m_isTarget && node.getKind().equals(Shadow.MethodExecution)) {
if (!isStarAnnotation) {
return new HasMemberTypePatternForPerThisMatching(signaturePattern);
}
}
return signaturePattern.getDeclaringType();
} else if (node.getKind().equals(Shadow.ConstructorCall) || node.getKind().equals(Shadow.FieldGet)
|| node.getKind().equals(Shadow.FieldSet) || node.getKind().equals(Shadow.MethodCall)) {
if (m_isTarget) {
return node.getSignature().getDeclaringType();
} else {
return MAYBE;
}
} else if (node.getKind().equals(Shadow.ExceptionHandler)) {
return MAYBE;
} else {
throw new ParserException("Undetermined - should not happen: " + node.getKind().getSimpleName(), null);
}
}
public Object visit(AndPointcut node, Object data) {
return new AndTypePattern(getPerTypePointcut(node.left), getPerTypePointcut(node.right));
}
public Object visit(OrPointcut node, Object data) {
return new OrTypePattern(getPerTypePointcut(node.left), getPerTypePointcut(node.right));
}
public Object visit(NotPointcut node, Object data) {
return MAYBE;
}
public Object visit(ThisOrTargetAnnotationPointcut node, Object data) {
if (m_isTarget && !node.isThis()) {
return new AnyWithAnnotationTypePattern(node.getAnnotationTypePattern());
} else if (!m_isTarget && node.isThis()) {
return new AnyWithAnnotationTypePattern(node.getAnnotationTypePattern());
} else {
return MAYBE;
}
}
public Object visit(ThisOrTargetPointcut node, Object data) {
if ((m_isTarget && !node.isThis()) || (!m_isTarget && node.isThis())) {
String pointcutString = node.getType().toString();
if (pointcutString.equals("<nothing>")) {
return new NoTypePattern();
}
TypePattern copy = new PatternParser(pointcutString.replace('$', '.')).parseTypePattern();
copy.includeSubtypes = true;
return copy;
} else {
return MAYBE;
}
}
public Object visit(ReferencePointcut node, Object data) {
ResolvedPointcutDefinition pointcutDec;
ResolvedType searchStart = m_fromAspectType;
if (node.onType != null) {
searchStart = node.onType.resolve(m_fromAspectType.getWorld());
if (searchStart.isMissing()) {
return MAYBE;
}
}
pointcutDec = searchStart.findPointcut(node.name);
return getPerTypePointcut(pointcutDec.getPointcut());
}
public Object visit(IfPointcut node, Object data) {
return TypePattern.ANY;
}
public Object visit(HandlerPointcut node, Object data) {
return MAYBE;
}
public Object visit(CflowPointcut node, Object data) {
return MAYBE;
}
public Object visit(ConcreteCflowPointcut node, Object data) {
return MAYBE;
}
public Object visit(ArgsPointcut node, Object data) {
return MAYBE;
}
public Object visit(ArgsAnnotationPointcut node, Object data) {
return MAYBE;
}
public Object visit(AnnotationPointcut node, Object data) {
return MAYBE;
}
public Object visit(Pointcut.MatchesNothingPointcut node, Object data) {
return new NoTypePattern() {
public String toString() {
return "false";
}
};
}
private static class TypePatternMayBe extends AnyTypePattern {
}
}