*******************************************************************************/
package org.aspectj.weaver.bcel;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
import org.aspectj.apache.bcel.classfile.Attribute;
import org.aspectj.apache.bcel.classfile.Field;
import org.aspectj.apache.bcel.classfile.JavaClass;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.IMessageHandler;
-import org.aspectj.bridge.Message;
import org.aspectj.bridge.ISourceLocation;
-import org.aspectj.bridge.SourceLocation;
+import org.aspectj.bridge.Message;
import org.aspectj.weaver.Advice;
import org.aspectj.weaver.AdviceKind;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.AjcMemberMaker;
+import org.aspectj.weaver.IHasPosition;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.NameMangler;
import org.aspectj.weaver.ResolvedPointcutDefinition;
import org.aspectj.weaver.ResolvedTypeX;
import org.aspectj.weaver.TypeX;
-import org.aspectj.weaver.IHasPosition;
+import org.aspectj.weaver.patterns.AndPointcut;
import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
import org.aspectj.weaver.patterns.DeclarePrecedence;
import org.aspectj.weaver.patterns.FormalBinding;
import org.aspectj.weaver.patterns.IScope;
+import org.aspectj.weaver.patterns.IdentityPointcutVisitor;
+import org.aspectj.weaver.patterns.IfPointcut;
+import org.aspectj.weaver.patterns.NotPointcut;
+import org.aspectj.weaver.patterns.OrPointcut;
import org.aspectj.weaver.patterns.ParserException;
import org.aspectj.weaver.patterns.PatternParser;
import org.aspectj.weaver.patterns.PerCflow;
import org.aspectj.weaver.patterns.PerClause;
+import org.aspectj.weaver.patterns.PerFromSuper;
import org.aspectj.weaver.patterns.PerObject;
import org.aspectj.weaver.patterns.PerSingleton;
import org.aspectj.weaver.patterns.PerTypeWithin;
import org.aspectj.weaver.patterns.Pointcut;
import org.aspectj.weaver.patterns.SimpleScope;
import org.aspectj.weaver.patterns.TypePattern;
-import org.aspectj.weaver.patterns.PerFromSuper;
-import org.aspectj.weaver.patterns.PointcutVisitor;
-import org.aspectj.weaver.patterns.IdentityPointcutVisitor;
-import org.aspectj.weaver.patterns.IfPointcut;
-import org.aspectj.weaver.patterns.AndPointcut;
-import org.aspectj.weaver.patterns.NotPointcut;
-import org.aspectj.weaver.patterns.OrPointcut;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
/**
* Annotation defined aspect reader.
import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
+import org.aspectj.weaver.patterns.AbstractPatternNodeVisitor;
+import org.aspectj.weaver.patterns.ArgsAnnotationPointcut;
+import org.aspectj.weaver.patterns.ArgsPointcut;
+import org.aspectj.weaver.patterns.CflowPointcut;
+import org.aspectj.weaver.patterns.FastMatchInfo;
+import org.aspectj.weaver.patterns.IfPointcut;
+import org.aspectj.weaver.patterns.NotAnnotationTypePattern;
+import org.aspectj.weaver.patterns.NotPointcut;
import org.aspectj.weaver.patterns.Pointcut;
+import org.aspectj.weaver.patterns.ThisOrTargetAnnotationPointcut;
+import org.aspectj.weaver.patterns.ThisOrTargetPointcut;
import org.aspectj.weaver.tools.FuzzyBoolean;
import org.aspectj.weaver.tools.PointcutExpression;
this.pointcut = pointcut;
this.expression = expression;
}
+
+ public boolean couldMatchJoinPointsInType(Class aClass) {
+ return pointcut.fastMatch(aClass).maybeTrue();
+ }
+
+ public boolean mayNeedDynamicTest() {
+ HasPossibleDynamicContentVisitor visitor = new HasPossibleDynamicContentVisitor();
+ pointcut.traverse(visitor, null);
+ return visitor.hasDynamicContent();
+ }
/* (non-Javadoc)
* @see org.aspectj.weaver.tools.PointcutExpression#matchesMethodCall(java.lang.reflect.Method, java.lang.Class, java.lang.Class, java.lang.reflect.Member)
throw new IllegalArgumentException("Cant match FuzzyBoolean " + fb);
}
+ private static class HasPossibleDynamicContentVisitor extends AbstractPatternNodeVisitor {
+ private boolean hasDynamicContent = false;
+
+ public boolean hasDynamicContent() { return hasDynamicContent; }
+
+ public Object visit(ArgsAnnotationPointcut node, Object data) {
+ hasDynamicContent = true;
+ return null;
+ }
+
+ public Object visit(ArgsPointcut node, Object data) {
+ hasDynamicContent = true;
+ return null;
+ }
+
+ public Object visit(CflowPointcut node, Object data) {
+ hasDynamicContent = true;
+ return null;
+ }
+
+ public Object visit(IfPointcut node, Object data) {
+ hasDynamicContent = true;
+ return null;
+ }
+
+ public Object visit(NotAnnotationTypePattern node, Object data) {
+ return node.getNegatedPattern().accept(this, data);
+ }
+
+ public Object visit(NotPointcut node, Object data) {
+ return node.getNegatedPointcut().accept(this, data);
+ }
+
+ public Object visit(ThisOrTargetAnnotationPointcut node, Object data) {
+ hasDynamicContent = true;
+ return null;
+ }
+
+ public Object visit(ThisOrTargetPointcut node, Object data) {
+ hasDynamicContent = true;
+ return null;
+ }
+ }
+
public static class Handler implements Member {
private Class decClass;
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors.
+ * 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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Adrian Colyer Initial implementation
+ * ******************************************************************/
+package org.aspectj.weaver.patterns;
+
+import org.aspectj.weaver.patterns.Pointcut.MatchesNothingPointcut;
+
+/**
+ * @author colyer
+ *
+ */
+public abstract class AbstractPatternNodeVisitor implements PatternNodeVisitor {
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AnyTypePattern, java.lang.Object)
+ */
+ public Object visit(AnyTypePattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.NoTypePattern, java.lang.Object)
+ */
+ public Object visit(NoTypePattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.EllipsisTypePattern, java.lang.Object)
+ */
+ public Object visit(EllipsisTypePattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AnyWithAnnotationTypePattern, java.lang.Object)
+ */
+ public Object visit(AnyWithAnnotationTypePattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AnyAnnotationTypePattern, java.lang.Object)
+ */
+ public Object visit(AnyAnnotationTypePattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.EllipsisAnnotationTypePattern, java.lang.Object)
+ */
+ public Object visit(EllipsisAnnotationTypePattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AndAnnotationTypePattern, java.lang.Object)
+ */
+ public Object visit(AndAnnotationTypePattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AndPointcut, java.lang.Object)
+ */
+ public Object visit(AndPointcut node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AndTypePattern, java.lang.Object)
+ */
+ public Object visit(AndTypePattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AnnotationPatternList, java.lang.Object)
+ */
+ public Object visit(AnnotationPatternList node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AnnotationPointcut, java.lang.Object)
+ */
+ public Object visit(AnnotationPointcut node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ArgsAnnotationPointcut, java.lang.Object)
+ */
+ public Object visit(ArgsAnnotationPointcut node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ArgsPointcut, java.lang.Object)
+ */
+ public Object visit(ArgsPointcut node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.BindingAnnotationTypePattern, java.lang.Object)
+ */
+ public Object visit(BindingAnnotationTypePattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.BindingTypePattern, java.lang.Object)
+ */
+ public Object visit(BindingTypePattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.CflowPointcut, java.lang.Object)
+ */
+ public Object visit(CflowPointcut node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ConcreteCflowPointcut, java.lang.Object)
+ */
+ public Object visit(ConcreteCflowPointcut node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.DeclareAnnotation, java.lang.Object)
+ */
+ public Object visit(DeclareAnnotation node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.DeclareErrorOrWarning, java.lang.Object)
+ */
+ public Object visit(DeclareErrorOrWarning node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.DeclareParents, java.lang.Object)
+ */
+ public Object visit(DeclareParents node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.DeclarePrecedence, java.lang.Object)
+ */
+ public Object visit(DeclarePrecedence node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.DeclareSoft, java.lang.Object)
+ */
+ public Object visit(DeclareSoft node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ExactAnnotationTypePattern, java.lang.Object)
+ */
+ public Object visit(ExactAnnotationTypePattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ExactTypePattern, java.lang.Object)
+ */
+ public Object visit(ExactTypePattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.HandlerPointcut, java.lang.Object)
+ */
+ public Object visit(HandlerPointcut node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.IfPointcut, java.lang.Object)
+ */
+ public Object visit(IfPointcut node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.KindedPointcut, java.lang.Object)
+ */
+ public Object visit(KindedPointcut node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ModifiersPattern, java.lang.Object)
+ */
+ public Object visit(ModifiersPattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.NamePattern, java.lang.Object)
+ */
+ public Object visit(NamePattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.NotAnnotationTypePattern, java.lang.Object)
+ */
+ public Object visit(NotAnnotationTypePattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.NotPointcut, java.lang.Object)
+ */
+ public Object visit(NotPointcut node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.NotTypePattern, java.lang.Object)
+ */
+ public Object visit(NotTypePattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.OrAnnotationTypePattern, java.lang.Object)
+ */
+ public Object visit(OrAnnotationTypePattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.OrPointcut, java.lang.Object)
+ */
+ public Object visit(OrPointcut node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.OrTypePattern, java.lang.Object)
+ */
+ public Object visit(OrTypePattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.PerCflow, java.lang.Object)
+ */
+ public Object visit(PerCflow node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.PerFromSuper, java.lang.Object)
+ */
+ public Object visit(PerFromSuper node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.PerObject, java.lang.Object)
+ */
+ public Object visit(PerObject node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.PerSingleton, java.lang.Object)
+ */
+ public Object visit(PerSingleton node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.PerTypeWithin, java.lang.Object)
+ */
+ public Object visit(PerTypeWithin node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.PatternNode, java.lang.Object)
+ */
+ public Object visit(PatternNode node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ReferencePointcut, java.lang.Object)
+ */
+ public Object visit(ReferencePointcut node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.SignaturePattern, java.lang.Object)
+ */
+ public Object visit(SignaturePattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ThisOrTargetAnnotationPointcut, java.lang.Object)
+ */
+ public Object visit(ThisOrTargetAnnotationPointcut node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ThisOrTargetPointcut, java.lang.Object)
+ */
+ public Object visit(ThisOrTargetPointcut node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ThrowsPattern, java.lang.Object)
+ */
+ public Object visit(ThrowsPattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.TypePatternList, java.lang.Object)
+ */
+ public Object visit(TypePatternList node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WildAnnotationTypePattern, java.lang.Object)
+ */
+ public Object visit(WildAnnotationTypePattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WildTypePattern, java.lang.Object)
+ */
+ public Object visit(WildTypePattern node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WithinAnnotationPointcut, java.lang.Object)
+ */
+ public Object visit(WithinAnnotationPointcut node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WithinCodeAnnotationPointcut, java.lang.Object)
+ */
+ public Object visit(WithinCodeAnnotationPointcut node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WithinPointcut, java.lang.Object)
+ */
+ public Object visit(WithinPointcut node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WithincodePointcut, java.lang.Object)
+ */
+ public Object visit(WithincodePointcut node, Object data) {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.Pointcut.MatchesNothingPointcut, java.lang.Object)
+ */
+ public Object visit(MatchesNothingPointcut node, Object data) {
+ return node;
+ }
+
+ public Object visit(TypeVariable node, Object data) {
+ return node;
+ }
+
+ public Object visit(TypeVariablePatternList node, Object data) {
+ return node;
+ }
+}
public AnnotationTypePattern getLeft() { return left; }
public AnnotationTypePattern getRight() { return right; }
- public Object accept(PointcutVisitor visitor, Object data) {
+ 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;
+ }
}
public FuzzyBoolean fastMatch(FastMatchInfo type) {
return left.fastMatch(type).and(right.fastMatch(type));
}
+
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return left.fastMatch(targetType).and(right.fastMatch(targetType));
+ }
protected FuzzyBoolean matchInternal(Shadow shadow) {
FuzzyBoolean leftMatch = left.match(shadow);
return right;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ 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;
+ }
}
return ret;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ 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;
+ }
}
writeLocation(s);
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ 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;
+ }
}
return FuzzyBoolean.MAYBE;
}
}
+
+ public FuzzyBoolean fastMatch(Class targetType) {
+ // TODO AMC
+ return FuzzyBoolean.MAYBE;
+ }
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow)
return buf.toString();
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
public String toString() { return "@ANY"; }
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
public String toString() { return ".."; }
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
public FuzzyBoolean fastMatch(FastMatchInfo info) {
return FuzzyBoolean.MAYBE;
}
+
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return FuzzyBoolean.MAYBE;
+ }
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow)
return buf.toString();
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
public FuzzyBoolean fastMatch(FastMatchInfo type) {
return FuzzyBoolean.MAYBE;
}
+
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return FuzzyBoolean.MAYBE;
+ }
protected FuzzyBoolean matchInternal(Shadow shadow) {
FuzzyBoolean ret =
return "args" + arguments.toString() + "";
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
case '!':
case ':':
case '@':
+ case '<':
+ case '>':
+ case '?':
tokens.add(BasicToken.makeOperator(makeString(ch), i-1, i-1));
continue;
case '.':
}
continue;
case '&':
+ if ((i+1) <= chars.length && chars[i] != '&') {
+ tokens.add(BasicToken.makeOperator(makeString(ch),i-1,i-1));
+ continue;
+ }
+ // fall-through
case '|':
if (i == chars.length) {
throw new BCException("bad " + ch);
public class CflowPointcut extends Pointcut {
private Pointcut entry; // The pointcut inside the cflow() that represents the 'entry' point
- private boolean isBelow;// Is this cflowbelow?
+ boolean isBelow;// Is this cflowbelow?
private int[] freeVars;
private static Hashtable cflowFields = new Hashtable();
this.pointcutKind = CFLOW;
}
- public boolean isBelow() {
- return isBelow;
- }
+ /**
+ * @return Returns true is this is a cflowbelow pointcut
+ */
+ public boolean isCflowBelow() {
+ return isBelow;
+ }
public Set couldMatchKinds() {
return Shadow.ALL_SHADOW_KINDS;
public FuzzyBoolean fastMatch(FastMatchInfo type) {
return FuzzyBoolean.MAYBE;
}
+
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return FuzzyBoolean.MAYBE;
+ }
protected FuzzyBoolean matchInternal(Shadow shadow) {
//??? this is not maximally efficient
}
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
- }
-
+ }
}
public FuzzyBoolean fastMatch(FastMatchInfo type) {
return FuzzyBoolean.MAYBE;
}
+
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return FuzzyBoolean.MAYBE;
+ }
protected FuzzyBoolean matchInternal(Shadow shadow) {
//??? this is not maximally efficient
throw new RuntimeException("unimplemented");
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
return ret.toString();
}
+ public Object accept(PatternNodeVisitor visitor, Object data) {
+ return visitor.visit(this,data);
+ }
+
public void resolve(IScope scope) {
if (typePattern != null) {
typePattern = typePattern.resolveBindings(scope,Bindings.NONE,false,false);
return result;
}
-
+ public Object accept(PatternNodeVisitor visitor, Object data) {
+ return visitor.visit(this,data);
+ }
+
public void write(DataOutputStream s) throws IOException {
s.writeByte(Declare.ERROR_OR_WARNING);
s.writeBoolean(isError);
import java.util.List;
import org.aspectj.bridge.IMessage;
+import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.ResolvedTypeX;
import org.aspectj.weaver.TypeX;
private TypePattern child;
private TypePatternList parents;
private boolean isWildChild = false;
+ private TypeVariablePatternList typeVariablesInScope = TypeVariablePatternList.EMPTY; // AspectJ 5 extension for generic types
public DeclareParents(TypePattern child, List parents) {
if (child instanceof WildTypePattern) isWildChild = true;
}
+ public TypeVariablePatternList getTypeParameters() {
+ return this.typeVariablesInScope;
+ }
+
+ public void setTypeParameters(TypeVariablePatternList typeParameters) {
+ this.typeVariablesInScope = typeParameters;
+ }
+
public boolean match(ResolvedTypeX typeX) {
if (!child.matchesStatically(typeX)) return false;
if (typeX.getWorld().getLint().typeNotExposedToWeaver.isEnabled() &&
return true;
}
+ public Object accept(PatternNodeVisitor visitor, Object data) {
+ return visitor.visit(this,data);
+ }
+
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("declare parents: ");
s.writeByte(Declare.PARENTS);
child.write(s);
parents.write(s);
+ typeVariablesInScope.write(s); // change to binary form in AJ 5
writeLocation(s);
}
public static Declare read(VersionedDataInputStream s, ISourceContext context) throws IOException {
- Declare ret = new DeclareParents(TypePattern.read(s, context), TypePatternList.read(s, context));
+ DeclareParents ret = new DeclareParents(TypePattern.read(s, context), TypePatternList.read(s, context));
+ if (s.getMajorVersion()>=AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) {
+ ret.setTypeParameters(TypeVariablePatternList.read(s,context));
+ }
ret.readLocation(context, s);
return ret;
}
}
public void resolve(IScope scope) {
- child = child.resolveBindings(scope, Bindings.NONE, false, false);
- parents = parents.resolveBindings(scope, Bindings.NONE, false, true);
+ ScopeWithTypeVariables resolutionScope = new ScopeWithTypeVariables(typeVariablesInScope,scope);
+ child = child.resolveBindings(resolutionScope, Bindings.NONE, false, false);
+ parents = parents.resolveBindings(resolutionScope, Bindings.NONE, false, true);
// Could assert this ...
// for (int i=0; i < parents.size(); i++) {
this.patterns = patterns;
}
+ public Object accept(PatternNodeVisitor visitor, Object data) {
+ return visitor.visit(this,data);
+ }
+
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("declare precedence: ");
this.pointcut = pointcut;
}
+ public Object accept(PatternNodeVisitor visitor, Object data) {
+ return visitor.visit(this,data);
+ }
+
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("declare soft: ");
return ret;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
out.writeBoolean(includeSubtypes);
out.writeBoolean(isVarArgs);
annotationPattern.write(out);
+ typeParameters.write(out);
writeLocation(out);
}
if (version > EXACT_VERSION) throw new BCException("ExactTypePattern was written by a more recent version of AspectJ");
TypePattern ret = new ExactTypePattern(TypeX.read(s), s.readBoolean(), s.readBoolean());
ret.setAnnotationTypePattern(AnnotationTypePattern.read(s,context));
+ ret.setTypeParameters(TypePatternList.read(s,context));
ret.readLocation(context, s);
return ret;
}
throw new IllegalStateException("trying to re-resolve");
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
return FuzzyBoolean.MAYBE;
}
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return FuzzyBoolean.MAYBE;
+ }
+
protected FuzzyBoolean matchInternal(Shadow shadow) {
if (shadow.getKind() != Shadow.ExceptionHandler) return FuzzyBoolean.NO;
return ret;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
/**
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
*/
-public class IdentityPointcutVisitor implements PointcutVisitor {
+public class IdentityPointcutVisitor implements PatternNodeVisitor {
public Object visit(AnyTypePattern node, Object data) {
return node;
public Object visit(Pointcut.MatchesNothingPointcut node, Object data) {
return node;
}
+
+ public Object visit(TypeVariable node, Object data) {
+ return node;
+ }
+
+ public Object visit(TypeVariablePatternList node, Object data) {
+ return node;
+ }
}
public FuzzyBoolean fastMatch(FastMatchInfo type) {
return FuzzyBoolean.MAYBE;
}
+
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return FuzzyBoolean.MAYBE;
+ }
protected FuzzyBoolean matchInternal(Shadow shadow) {
//??? this is not maximally efficient
return ret;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
return FuzzyBoolean.MAYBE;
}
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return FuzzyBoolean.fromBoolean(signature.couldMatch(targetType));
+ }
+
+
protected FuzzyBoolean matchInternal(Shadow shadow) {
if (shadow.getKind() != kind) return FuzzyBoolean.NO;
return kind;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
return flag.intValue();
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
return starCount == 1 && pattern.length == 1;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
return negatedPattern;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
+
+ public Object traverse(PatternNodeVisitor visitor, Object data) {
+ Object ret = accept(visitor,data);
+ negatedPattern.traverse(visitor,ret);
+ return ret;
+ }
}
public FuzzyBoolean fastMatch(FastMatchInfo type) {
return body.fastMatch(type).not();
}
+
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return body.fastMatch(targetType).not();
+ }
protected FuzzyBoolean matchInternal(Shadow shadow) {
return body.match(shadow).not();
return ret;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
+
+ public Object traverse(PatternNodeVisitor visitor, Object data) {
+ Object ret = accept(visitor,data);
+ this.body.traverse(visitor,ret);
+ return ret;
+ }
}
return 17 + 37 * negatedPattern.hashCode();
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
+
+ public Object traverse(PatternNodeVisitor visitor, Object data) {
+ Object ret = accept(visitor,data);
+ negatedPattern.traverse(visitor, ret);
+ return ret;
+ }
+
}
return this;
}
+ 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;
+ }
+
public static AnnotationTypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
AnnotationTypePattern p = new OrAnnotationTypePattern(
AnnotationTypePattern.read(s,context),
return left.fastMatch(type).or(right.fastMatch(type));
}
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return left.fastMatch(targetType).or(right.fastMatch(targetType));
+ }
+
protected FuzzyBoolean matchInternal(Shadow shadow) {
FuzzyBoolean leftMatch = left.match(shadow);
if (leftMatch.alwaysTrue()) return leftMatch;
return right;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ 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;
+ }
}
return ret;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ 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;
+ }
+
}
this.sourceContext = context;
}
- public Object accept(PointcutVisitor visitor, Object data) {
- return visitor.visit(this, data);
- }
+ public abstract Object accept(PatternNodeVisitor visitor, Object data);
+
+ public Object traverse(PatternNodeVisitor visitor, Object data) {
+ return accept(visitor,data);
+ }
}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2005 Contributors.
+ * 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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Vasseur initial implementation
+ * Adrian Colyer refactoring for traversal and grouping by kind
+ *******************************************************************************/
+package org.aspectj.weaver.patterns;
+
+import org.aspectj.weaver.Member;
+
+/**
+ * A Pointcut or TypePattern visitor
+ *
+ * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+ */
+public interface PatternNodeVisitor {
+
+ // Annotation type patterns
+ Object visit(AndAnnotationTypePattern node, Object data);
+ Object visit(AnyAnnotationTypePattern node, Object data);
+ Object visit(EllipsisAnnotationTypePattern node, Object data);
+ Object visit(ExactAnnotationTypePattern node, Object data);
+ Object visit(BindingAnnotationTypePattern node, Object data);
+ Object visit(NotAnnotationTypePattern node, Object data);
+ Object visit(OrAnnotationTypePattern node, Object data);
+ Object visit(WildAnnotationTypePattern node, Object data);
+ Object visit(AnnotationPatternList node, Object data);
+
+ // Regular type patterns
+ Object visit(AndTypePattern node, Object data);
+ Object visit(AnyTypePattern node, Object data);
+ Object visit(AnyWithAnnotationTypePattern node, Object data);
+ Object visit(EllipsisTypePattern node, Object data);
+ Object visit(ExactTypePattern node, Object data);
+ Object visit(BindingTypePattern node, Object data);
+ Object visit(NotTypePattern node, Object data);
+ Object visit(NoTypePattern node, Object data);
+ Object visit(OrTypePattern node, Object data);
+ Object visit(WildTypePattern node, Object data);
+ Object visit(TypePatternList node, Object data);
+
+ // Pointcuts
+ Object visit(AndPointcut node, Object data);
+ Object visit(CflowPointcut node, Object data);
+ Object visit(ConcreteCflowPointcut node, Object data);
+ Object visit(HandlerPointcut node, Object data);
+ Object visit(IfPointcut node, Object data);
+ Object visit(KindedPointcut node, Object data);
+ Object visit(Pointcut.MatchesNothingPointcut node, Object data);
+ Object visit(AnnotationPointcut node, Object data);
+ Object visit(ArgsAnnotationPointcut node, Object data);
+ Object visit(ArgsPointcut node, Object data);
+ Object visit(ThisOrTargetAnnotationPointcut node, Object data);
+ Object visit(ThisOrTargetPointcut node, Object data);
+ Object visit(WithinAnnotationPointcut node, Object data);
+ Object visit(WithinCodeAnnotationPointcut node, Object data);
+ Object visit(NotPointcut node, Object data);
+ Object visit(OrPointcut node, Object data);
+ Object visit(ReferencePointcut node, Object data);
+ Object visit(WithinPointcut node, Object data);
+ Object visit(WithincodePointcut node, Object data);
+
+ // Per-clauses
+ Object visit(PerCflow node, Object data);
+ Object visit(PerFromSuper node, Object data);
+ Object visit(PerObject node, Object data);
+ Object visit(PerSingleton node, Object data);
+ Object visit(PerTypeWithin node, Object data);
+
+
+ // Declares
+ Object visit(DeclareAnnotation node, Object data);
+ Object visit(DeclareErrorOrWarning node, Object data);
+ Object visit(DeclareParents node, Object data);
+ Object visit(DeclarePrecedence node, Object data);
+ Object visit(DeclareSoft node, Object data);
+
+ // Miscellaneous patterns
+ Object visit(ModifiersPattern node, Object data);
+ Object visit(NamePattern node, Object data);
+ Object visit(SignaturePattern node, Object data);
+ Object visit(ThrowsPattern node, Object data);
+ Object visit(TypeVariable node, Object data);
+ Object visit(TypeVariablePatternList node,Object data);
+
+ // Catch-all
+ Object visit(PatternNode node, Object data);
+
+ /**
+ * A sample toString like visitor that helps understanding the AST tree structure organization
+ *
+ * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+ */
+ static class DumpPointcutVisitor implements PatternNodeVisitor {
+
+ private StringBuffer sb = new StringBuffer();
+ public String get() {
+ return sb.toString();
+ }
+
+ private void append(Object o) {
+ sb.append(o.toString());
+ }
+
+ private void append(char c) {
+ sb.append(c);
+ }
+
+ /**
+ * This method helps maintaining the API and raises warning when PatternNode subclasses do not
+ * implement the visitor pattern
+ *
+ * @param node
+ * @param data
+ * @return
+ */
+ public Object visit(PatternNode node, Object data) {
+ System.err.println("Should implement: " + node.getClass());
+ return null;
+ }
+
+ public Object visit(AnyTypePattern node, Object data) {
+ append('*');
+ return null;
+ }
+
+ public Object visit(NoTypePattern node, Object data) {
+ append(node.toString());//TODO no idea when this one is used
+ return null;
+ }
+
+ public Object visit(EllipsisTypePattern node, Object data) {
+ append(node.toString());
+ return null;
+ }
+
+ public Object visit(AnyWithAnnotationTypePattern node, Object data) {
+ node.annotationPattern.accept(this, data);
+ append(" *");
+ return null;
+ }
+
+ public Object visit(AnyAnnotationTypePattern node, Object data) {
+ //@ANY : ignore
+ append('*');
+ return null;
+ }
+
+ public Object visit(EllipsisAnnotationTypePattern node, Object data) {
+ append("..");
+ return null;
+ }
+
+ public Object visit(AndAnnotationTypePattern node, Object data) {
+ node.getLeft().accept(this, data);
+ append(' ');
+ node.getRight().accept(this, data);
+ return null;
+ }
+
+ public Object visit(AndPointcut node, Object data) {
+ append('(');
+ node.getLeft().accept(this, data);
+ append(" && ");
+ node.getRight().accept(this, data);
+ append(')');
+ return null;
+ }
+
+ public Object visit(AndTypePattern node, Object data) {
+ append('(');
+ node.getLeft().accept(this, data);
+ append(" && ");
+ node.getRight().accept(this, data);
+ append(')');
+ return null;
+ }
+
+ public Object visit(AnnotationPatternList node, Object data) {
+ AnnotationTypePattern[] annotations = node.getAnnotationPatterns();
+ for (int i = 0; i < annotations.length; i++) {
+ if (i>0) append(", ");//Note: list is ",", and is " " separated for annotations
+ annotations[i].accept(this, data);
+ }
+ return null;
+ }
+
+ public Object visit(AnnotationPointcut node, Object data) {
+ append("@annotation(");
+ node.getAnnotationTypePattern().accept(this, data);
+ append(')');
+ return null;
+ }
+
+ public Object visit(ArgsAnnotationPointcut node, Object data) {
+ append("@args(");
+ node.getArguments().accept(this, data);
+ append(')');
+ return null;
+ }
+
+ public Object visit(ArgsPointcut node, Object data) {
+ append("args(");
+ node.getArguments().accept(this, data);
+ append(')');
+ return null;
+ }
+
+ public Object visit(BindingAnnotationTypePattern node, Object data) {
+ append(node);
+ return null;
+ }
+
+ public Object visit(BindingTypePattern node, Object data) {
+ append(node);
+ return null;
+ }
+
+ public Object visit(CflowPointcut node, Object data) {
+ append(node.isCflowBelow()?"cflowbelow(":"cflow(");
+ node.getEntry().accept(this, data);
+ append(')');
+ return null;
+ }
+
+ public Object visit(ExactAnnotationTypePattern node, Object data) {
+ //append('@'); // since @annotation(@someAnno) cannot be parsed anymore
+ append(node.getAnnotationType().getName());
+ return null;
+ }
+
+ public Object visit(ExactTypePattern node, Object data) {
+ if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
+ append('(');
+ node.getAnnotationPattern().accept(this, data);
+ append(' ');
+ }
+
+ String typeString = node.getType().toString();
+ if (node.isVarArgs()) typeString = typeString.substring(0, typeString.lastIndexOf('['));//TODO AV - ugly
+ append(typeString);
+ if (node.isIncludeSubtypes()) append('+');
+ if (node.isVarArgs()) append("...");
+ if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
+ append(')');
+ }
+ return null;
+ }
+
+ public Object visit(KindedPointcut node, Object data) {
+ append(node.getKind().getSimpleName());
+ append('(');
+ node.getSignature().accept(this, data);
+ append(')');
+ return null;
+ }
+
+ public Object visit(ModifiersPattern node, Object data) {
+ append(node.toString());//note: node takes care of forbidden mods
+ return null;
+ }
+
+ public Object visit(NamePattern node, Object data) {
+ append(node.toString());
+ return null;
+ }
+
+ public Object visit(NotAnnotationTypePattern node, Object data) {
+ append("!");
+ node.getNegatedPattern().accept(this, data);
+ return null;
+ }
+
+ public Object visit(NotPointcut node, Object data) {
+ append("!(");
+ node.getNegatedPointcut().accept(this, data);
+ append(')');
+ return null;
+ }
+
+ public Object visit(NotTypePattern node, Object data) {
+ append("!(");
+ node.getNegatedPattern().accept(this, data);
+ append(')');
+ return null;
+ }
+
+ public Object visit(OrAnnotationTypePattern node, Object data) {
+ append('(');
+ node.getLeft().accept(this, data);
+ append(" || ");
+ node.getRight().accept(this, data);
+ append(')');
+ return null;
+ }
+
+ public Object visit(OrPointcut node, Object data) {
+ append('(');
+ node.getLeft().accept(this, data);
+ append(" || ");
+ node.getRight().accept(this, data);
+ append(')');
+ return null;
+ }
+
+ public Object visit(OrTypePattern node, Object data) {
+ append('(');
+ node.getLeft().accept(this, data);
+ append(" || ");
+ node.getRight().accept(this, data);
+ append(')');
+ return null;
+ }
+
+ public Object visit(ReferencePointcut node, Object data) {
+ append(node.toString());
+ return null;
+ }
+
+ public Object visit(SignaturePattern node, Object data) {
+ if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
+ node.getAnnotationPattern().accept(this, data);
+ append(' ');
+ }
+
+ if (node.getModifiers() != ModifiersPattern.ANY) {
+ node.getModifiers().accept(this, data);
+ append(' ');
+ }
+
+ if (node.getKind() == Member.STATIC_INITIALIZATION) {
+ node.getDeclaringType().accept(this, data);
+ } else if (node.getKind() == Member.HANDLER) {
+ append("handler(");
+ node.getParameterTypes().get(0).accept(this, data);//Note: we know we have 1 child
+ append(')');
+ } else {
+ if (!(node.getKind() == Member.CONSTRUCTOR)) {
+ node.getReturnType().accept(this, data);
+ append(' ');
+ }
+ if (node.getDeclaringType() != TypePattern.ANY) {
+ node.getDeclaringType().accept(this, data);
+ append('.');
+ }
+ if (node.getKind() == Member.CONSTRUCTOR) {
+ append("new");
+ } else {
+ node.getName().accept(this, data);
+ }
+ if (node.getKind() == Member.METHOD || node.getKind() == Member.CONSTRUCTOR) {
+ append('(');
+ node.getParameterTypes().accept(this, data);
+ append(')');
+ }
+ if (node.getThrowsPattern() != null) {
+ append(' ');
+ node.getThrowsPattern().accept(this, data);
+ }
+ }
+ return null;
+ }
+
+ public Object visit(ThisOrTargetAnnotationPointcut node, Object data) {
+ append(node.isThis() ? "@this(" : "@target(");
+ node.getAnnotationTypePattern().accept(this, data);
+ append(')');
+ return null;
+ }
+
+ public Object visit(ThisOrTargetPointcut node, Object data) {
+ append(node.isThis() ? "this(" : "target(");
+ node.getType().accept(this, data);
+ append(')');
+ return null;
+ }
+
+ // Note: a visitor instance is not thread safe so should not be shared
+ private boolean inThrowsForbidden = false;
+
+ public Object visit(ThrowsPattern node, Object data) {
+ if (node == ThrowsPattern.ANY) return null;
+
+ append("throws ");
+ node.getRequired().accept(this, data);
+ if (node.getForbidden().size() > 0) {
+ // a hack since throws !(A, B) cannot be parsed
+ try {
+ inThrowsForbidden = true;
+ node.getForbidden().accept(this, data);
+ } finally {
+ inThrowsForbidden = false;
+ }
+ }
+ return null;
+ }
+
+ public Object visit(TypePatternList node, Object data) {
+ if (node.getTypePatterns().length == 0) return null;
+
+ TypePattern[] typePatterns = node.getTypePatterns();
+ for (int i = 0; i < typePatterns.length; i++) {
+ TypePattern typePattern = typePatterns[i];
+ if (i > 0) append(", ");
+ if (inThrowsForbidden) append('!');
+ typePattern.accept(this, data);
+ }
+ return null;
+ }
+
+ public Object visit(WildAnnotationTypePattern node, Object data) {
+ append("@(");
+ node.getTypePattern().accept(this, data);
+ append(')');
+ return null;
+ }
+
+ public Object visit(WildTypePattern node, Object data) {
+ if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
+ append('(');
+ node.getAnnotationPattern().accept(this, data);
+ append(' ');
+ }
+ NamePattern[] namePatterns = node.getNamePatterns();
+ for (int i=0; i < namePatterns.length; i++) {
+ if (namePatterns[i] == null) {
+ append('.');//FIXME mh, error prone, can't we have a nullNamePattern ?
+ } else {
+ if (i > 0) append('.');
+ namePatterns[i].accept(this, data);
+ }
+ }
+ if (node.isIncludeSubtypes()) append('+');
+ if (node.isVarArgs()) append("...");
+ if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
+ append(')');
+ }
+ return null;
+ }
+
+ public Object visit(WithinAnnotationPointcut node, Object data) {
+ append("@within(");
+ node.getAnnotationTypePattern().accept(this, data);
+ append(')');
+ return null;
+ }
+
+ public Object visit(WithinCodeAnnotationPointcut node, Object data) {
+ append("@withincode(");
+ node.getAnnotationTypePattern().accept(this, data);
+ append(')');
+ return null;
+ }
+
+ public Object visit(WithinPointcut node, Object data) {
+ append("within(");
+ node.getTypePattern().accept(this, data);
+ append(')');
+ return null;
+ }
+
+ public Object visit(WithincodePointcut node, Object data) {
+ append("withincode(");
+ node.getSignature().accept(this, data);
+ append(')');
+ return null;
+ }
+
+ public Object visit(Pointcut.MatchesNothingPointcut node, Object data) {
+ append("");//TODO shouldn't that be a "false" ?
+ return null;
+ }
+
+
+ //-------------- perX
+
+ public Object visit(PerCflow node, Object data) {
+ append(node);
+ return null;
+ }
+
+ public Object visit(PerFromSuper node, Object data) {
+ append(node);
+ return null;
+ }
+
+ public Object visit(PerObject node, Object data) {
+ append(node);
+ return null;
+ }
+
+ public Object visit(PerSingleton node, Object data) {
+ append(node);
+ return null;
+ }
+
+ public Object visit(PerTypeWithin node, Object data) {
+ append(node);
+ return null;
+ }
+
+ // ------------- declare X
+
+ public Object visit(DeclareAnnotation node, Object data) {
+ append(node);
+ return null;
+ }
+
+ public Object visit(DeclareErrorOrWarning node, Object data) {
+ append(node);
+ return null;
+ }
+
+ public Object visit(DeclareParents node, Object data) {
+ append(node);
+ return null;
+ }
+
+ public Object visit(DeclarePrecedence node, Object data) {
+ append(node);
+ return null;
+ }
+
+ public Object visit(DeclareSoft node, Object data) {
+ append(node);
+ return null;
+ }
+
+ // ----------- misc
+
+ public Object visit(ConcreteCflowPointcut node, Object data) {
+ append(node);
+ return null;
+ }
+
+ public Object visit(HandlerPointcut node, Object data) {
+ append(node);
+ return null;
+ }
+
+ public Object visit(IfPointcut node, Object data) {
+ append(node);
+ return null;
+ }
+
+ public Object visit(TypeVariable node, Object data) {
+ append(node);
+ return null;
+ }
+
+ public Object visit(TypeVariablePatternList node, Object data) {
+ append(node);
+ return null;
+ }
+
+ public static void check(String s) {
+ check(Pointcut.fromString(s), false);
+ }
+
+ public static void check(PatternNode pc, boolean isTypePattern) {
+ DumpPointcutVisitor v1 = new DumpPointcutVisitor();
+ pc.accept(v1, null);
+
+ DumpPointcutVisitor v2 = new DumpPointcutVisitor();
+ final PatternNode pc2;
+ if (isTypePattern) {
+ pc2 = new PatternParser(v1.get()).parseTypePattern();
+ } else {
+ pc2 = Pointcut.fromString(v1.get());
+ }
+ pc2.accept(v2, null);
+
+ // at second parsing, the String form stay stable when parsed and parsed again
+ if (! v1.get().equals(v2.get())) {
+ throw new ParserException("Unstable back parsing for '"+pc+"', got '" + v1.get() + "' and '" + v2.get() + "'", null);
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ String[] s = new String[]{
+ //"@args(Foo, Goo, *, .., Moo)",
+ //"execution(* *())",
+ //"call(* *(int, Integer...))",
+ //"staticinitialization(@(Foo) @(Boo) @(Goo) Moo)",
+ "(if(true) && set(int BaseApp.i))"
+
+ };
+ for (int i = 0; i < s.length; i++) {
+ check(s[i]);
+ }
+ }
+
+ }
+
+}
}
private Declare parseParents() {
- TypePattern p = parseTypePattern();
+ TypeVariablePatternList typeParameters = maybeParseTypeVariableList();
+ TypePattern p = parseTypePattern(false,false);
IToken t = tokenSource.next();
if (!(t.getString().equals("extends") || t.getString().equals("implements"))) {
throw new ParserException("extends or implements", t);
//XXX somewhere in the chain we need to enforce that we have only ExactTypePatterns
- return new DeclareParents(p, l);
+ DeclareParents decp = new DeclareParents(p, l);
+ if (typeParameters != null) {
+ decp.setTypeParameters(typeParameters);
+ }
+ return decp;
}
private Declare parseSoft() {
}
String kind = parseIdentifier();
+ IToken possibleTypeVariableToken = tokenSource.peek();
+ TypeVariablePatternList typeVariables = maybeParseSimpleTypeVariableList();
tokenSource.setIndex(start);
if (kind.equals("execution") || kind.equals("call") ||
kind.equals("get") || kind.equals("set")) {
- return parseKindedPointcut();
+ p = parseKindedPointcut();
} else if (kind.equals("args")) {
- return parseArgsPointcut();
+ p = parseArgsPointcut();
} else if (kind.equals("this") || kind.equals("target")) {
- return parseThisOrTargetPointcut();
+ p = parseThisOrTargetPointcut();
} else if (kind.equals("within")) {
- return parseWithinPointcut();
+ p = parseWithinPointcut();
} else if (kind.equals("withincode")) {
- return parseWithinCodePointcut();
+ p = parseWithinCodePointcut();
} else if (kind.equals("cflow")) {
- return parseCflowPointcut(false);
+ p = parseCflowPointcut(false);
} else if (kind.equals("cflowbelow")) {
- return parseCflowPointcut(true);
+ p = parseCflowPointcut(true);
} else if (kind.equals("adviceexecution")) {
parseIdentifier(); eat("(");
eat(")");
- return new KindedPointcut(Shadow.AdviceExecution,
+ p = new KindedPointcut(Shadow.AdviceExecution,
new SignaturePattern(Member.ADVICE, ModifiersPattern.ANY,
TypePattern.ANY, TypePattern.ANY, NamePattern.ANY,
TypePatternList.ANY,
AnnotationTypePattern.ANY));
} else if (kind.equals("handler")) {
parseIdentifier(); eat("(");
- TypePattern typePat = parseTypePattern();
+ TypePattern typePat = parseTypePattern(false,true);
eat(")");
- return new HandlerPointcut(typePat);
+ p = new HandlerPointcut(typePat);
} else if (kind.equals("initialization")) {
parseIdentifier(); eat("(");
SignaturePattern sig = parseConstructorSignaturePattern();
eat(")");
- return new KindedPointcut(Shadow.Initialization, sig);
+ p = new KindedPointcut(Shadow.Initialization, sig);
} else if (kind.equals("staticinitialization")) {
parseIdentifier(); eat("(");
- TypePattern typePat = parseTypePattern();
+ TypePattern typePat = parseTypePattern(false,true);
eat(")");
- return new KindedPointcut(Shadow.StaticInitialization,
+ p = new KindedPointcut(Shadow.StaticInitialization,
new SignaturePattern(Member.STATIC_INITIALIZATION, ModifiersPattern.ANY,
TypePattern.ANY, typePat, NamePattern.ANY, TypePatternList.EMPTY,
ThrowsPattern.ANY,AnnotationTypePattern.ANY));
- } else if (kind.equals("preinitialization")) {
+ } else if (kind.equals("preinitialization")) {
parseIdentifier(); eat("(");
SignaturePattern sig = parseConstructorSignaturePattern();
eat(")");
- return new KindedPointcut(Shadow.PreInitialization, sig);
- } else if (kind.equals("if")) {
- //@style support
- parseIdentifier();
- eat("(");
- if (maybeEat("true")) {
- eat(")");
- return new IfPointcut.IfTruePointcut();
- } else if (maybeEat("false")) {
- eat(")");
- return new IfPointcut.IfFalsePointcut();
- } else {
- //TODO AV - true/false stuff needed ? What are the token here ?
- eat(")");
- // build a readable pointcut as an hint (toString() dumps raw token array into an horrible thing)
- StringBuffer sb = new StringBuffer();
- int currentIndex = tokenSource.getIndex();
- try {
- tokenSource.setIndex(0);
- for (int i = 0; !IToken.EOF.equals(tokenSource.peek(i)); i++) {
- if (i > 0) sb.append(' ');
- sb.append(tokenSource.peek(i).getString());
- }
- } finally {
- tokenSource.setIndex(currentIndex);
- }
- return new IfPointcut(sb.toString());
- }
- } else {
- return parseReferencePointcut();
+ p = new KindedPointcut(Shadow.PreInitialization, sig);
+ } else if (kind.equals("if")) {
+ // @style support allows if(), if(true), if(false)
+ parseIdentifier();
+ eat("(");
+ if (maybeEatIdentifier("true")) {
+ eat(")");
+ p = new IfPointcut.IfTruePointcut();
+ } else if (maybeEatIdentifier("false")) {
+ eat(")");
+ p = new IfPointcut.IfFalsePointcut();
+ } else {
+ eat(")");
+ // TODO - Alex has some token stuff going on here to get a readable name in place of ""...
+ p = new IfPointcut("");
+ }
}
+ else {
+ p = parseReferencePointcut();
+ if (typeVariables != null)
+ throw new ParserException("type variable specification not allowed for reference pointcuts",possibleTypeVariableToken);
+ }
+ if (typeVariables != null) p.setTypeVariables(typeVariables);
+ return p;
}
public Pointcut parseAnnotationPointcut() {
}
public TypePattern parseTypePattern() {
- TypePattern p = parseAtomicTypePattern();
+ return parseTypePattern(false,false);
+ }
+
+ public TypePattern parseTypePattern(boolean insideTypeParameters, boolean allowTypeVariableDeclarations) {
+ TypePattern p = parseAtomicTypePattern(insideTypeParameters,allowTypeVariableDeclarations);
if (maybeEat("&&")) {
- p = new AndTypePattern(p, parseNotOrTypePattern());
+ p = new AndTypePattern(p, parseNotOrTypePattern(insideTypeParameters,allowTypeVariableDeclarations));
}
if (maybeEat("||")) {
- p = new OrTypePattern(p, parseTypePattern());
+ p = new OrTypePattern(p, parseTypePattern(insideTypeParameters,allowTypeVariableDeclarations));
}
return p;
}
- private TypePattern parseNotOrTypePattern() {
- TypePattern p = parseAtomicTypePattern();
+ private TypePattern parseNotOrTypePattern(boolean insideTypeParameters,boolean allowTypeVariableDeclarations) {
+ TypePattern p = parseAtomicTypePattern(insideTypeParameters,allowTypeVariableDeclarations);
if (maybeEat("&&")) {
- p = new AndTypePattern(p, parseTypePattern());
+ p = new AndTypePattern(p, parseTypePattern(insideTypeParameters,allowTypeVariableDeclarations));
}
return p;
}
- private TypePattern parseAtomicTypePattern() {
+ private TypePattern parseAtomicTypePattern(boolean insideTypeParameters, boolean allowTypeVariableDeclarations) {
AnnotationTypePattern ap = maybeParseAnnotationPattern();
if (maybeEat("!")) {
//int startPos = tokenSource.peek(-1).getStart();
//??? we lose source location for true start of !type
- TypePattern p = new NotTypePattern(parseAtomicTypePattern());
+ TypePattern p = new NotTypePattern(parseAtomicTypePattern(insideTypeParameters,allowTypeVariableDeclarations));
p = setAnnotationPatternForTypePattern(p,ap);
return p;
}
if (maybeEat("(")) {
- TypePattern p = parseTypePattern();
+ TypePattern p = parseTypePattern(insideTypeParameters,allowTypeVariableDeclarations);
p = setAnnotationPatternForTypePattern(p,ap);
eat(")");
boolean isVarArgs = maybeEat("...");
return p;
}
int startPos = tokenSource.peek().getStart();
- TypePattern p = parseSingleTypePattern();
+ TypePattern p = parseSingleTypePattern(insideTypeParameters,allowTypeVariableDeclarations);
int endPos = tokenSource.peek(-1).getEnd();
p = setAnnotationPatternForTypePattern(p,ap);
p.setLocation(sourceContext, startPos, endPos);
TypePattern ret = t;
if (ap != AnnotationTypePattern.ANY) {
if (t == TypePattern.ANY) {
- ret = new WildTypePattern(new NamePattern[] {NamePattern.ANY},false,0,false);
+ ret = new WildTypePattern(new NamePattern[] {NamePattern.ANY},false,0,false,null);
}
if (t.annotationPattern == AnnotationTypePattern.ANY) {
ret.setAnnotationTypePattern(ap);
}
public TypePattern parseSingleTypePattern() {
+ return parseSingleTypePattern(false, false);
+ }
+
+ public TypePattern parseSingleTypePattern(boolean insideTypeParameters, boolean allowTypeVariableDeclarations) {
+ if (insideTypeParameters && maybeEat("?")) return parseGenericsWildcardTypePattern();
+
List names = parseDottedNamePattern();
-// new ArrayList();
-// NamePattern p1 = parseNamePattern();
-// names.add(p1);
-// while (maybeEat(".")) {
-// if (maybeEat(".")) {
-// names.add(NamePattern.ELLIPSIS);
-// }
-// NamePattern p2 = parseNamePattern();
-// names.add(p2);
-// }
+
+ TypePattern upperBound = null;
+ TypePattern[] additionalInterfaceBounds = new TypePattern[0];
+ TypePattern lowerBound = null;
+ if ((names.size() == 1) && allowTypeVariableDeclarations) {
+ if (maybeEatIdentifier("extends")) {
+ upperBound = parseTypePattern(false,false);
+ additionalInterfaceBounds = maybeParseAdditionalInterfaceBounds();
+ }
+ if (maybeEatIdentifier("super")) {
+ lowerBound = parseTypePattern(false,false);
+ }
+ }
+
int dim = 0;
while (maybeEat("[")) {
eat("]");
boolean isVarArgs = maybeEat("...");
boolean includeSubtypes = maybeEat("+");
+
+ TypePatternList typeParameters = maybeParseTypeParameterList(allowTypeVariableDeclarations);
int endPos = tokenSource.peek(-1).getEnd();
//??? what about the source location of any's????
- if (names.size() == 1 && ((NamePattern)names.get(0)).isAny() && dim == 0 && !isVarArgs) return TypePattern.ANY;
+ if (names.size() == 1 && ((NamePattern)names.get(0)).isAny() &&
+ dim == 0 && !isVarArgs && typeParameters == null && upperBound == null &&
+ lowerBound == null) return TypePattern.ANY;
// Notice we increase the dimensions if varargs is set. this is to allow type matching to
// succeed later: The actual signature at runtime of a method declared varargs is an array type of
// pattern 'Integer...' we create a WildTypePattern 'Integer[]' with varargs set. If this matches
// during shadow matching, we confirm that the varargs flags match up before calling it a successful
// match.
- return new WildTypePattern(names, includeSubtypes, dim+(isVarArgs?1:0), endPos,isVarArgs);
+ return new WildTypePattern(names, includeSubtypes, dim+(isVarArgs?1:0), endPos,isVarArgs,typeParameters,
+ upperBound,additionalInterfaceBounds,lowerBound);
}
-
+ public TypePattern parseGenericsWildcardTypePattern() {
+ List names = new ArrayList();
+ names.add(new NamePattern("?"));
+ TypePattern upperBound = null;
+ TypePattern[] additionalInterfaceBounds = new TypePattern[0];
+ TypePattern lowerBound = null;
+ if (maybeEatIdentifier("extends")) {
+ upperBound = parseTypePattern(false,false);
+ additionalInterfaceBounds = maybeParseAdditionalInterfaceBounds();
+ }
+ if (maybeEatIdentifier("super")) {
+ lowerBound = parseTypePattern(false,false);
+ }
+ int endPos = tokenSource.peek(-1).getEnd();
+ return new WildTypePattern(names,false,0,endPos,false,null,upperBound,additionalInterfaceBounds,lowerBound);
+ }
// private AnnotationTypePattern completeAnnotationPattern(AnnotationTypePattern p) {
// if (maybeEat("&&")) {
if (previous != null) {
if (!isAdjacent(previous, tok)) break;
}
- if ("*".equals(tok.getString()) || (tok.isIdentifier() && !"...".equals(tok.getString()))) {
+ if (tok.getString() == "*" || (tok.isIdentifier() && tok.getString()!="...")) {
buf.append(tok.getString());
- } else if ("...".equals(tok.getString())) {
+ } else if (tok.getString()=="...") {
break;
} else if (tok.getLiteralKind() != null) {
//System.err.println("literal kind: " + tok.getString());
if (previous != null) {
if (!isAdjacent(previous, tok)) break;
}
- if (tok.getString().equals("*") || tok.isIdentifier()) {
+ if (tok.getString() == "*" || tok.isIdentifier()) {
buf.append(tok.getString());
} else if (tok.getLiteralKind() != null) {
//System.err.println("literal kind: " + tok.getString());
public SignaturePattern parseFieldSignaturePattern() {
int startPos = tokenSource.peek().getStart();
+
+ // TypePatternList followMe = TypePatternList.ANY;
+
AnnotationTypePattern annotationPattern = maybeParseAnnotationPattern();
ModifiersPattern modifiers = parseModifiersPattern();
TypePattern returnType = parseTypePattern();
return null;
}
}
+
+ /**
+ * Parse type variable declarations for a generic method or at the start of a signature pointcut to identify
+ * type variable names in a generic type.
+ * @param includeParameterizedTypes
+ * @return
+ */
+ public TypeVariablePatternList maybeParseTypeVariableList() {
+ if (!maybeEat("<")) return null;
+ List typeVars = new ArrayList();
+ TypeVariable t = parseTypeVariable();
+ typeVars.add(t);
+ while (maybeEat(",")) {
+ TypeVariable nextT = parseTypeVariable();
+ typeVars.add(nextT);
+ }
+ eat(">");
+ TypeVariable[] tvs = new TypeVariable[typeVars.size()];
+ typeVars.toArray(tvs);
+ return new TypeVariablePatternList(tvs);
+ }
+
+ // of the form execution<T,S,V> - allows identifiers only
+ public TypeVariablePatternList maybeParseSimpleTypeVariableList() {
+ if (!maybeEat("<")) return null;
+ List typeVars = new ArrayList();
+ do {
+ String typeVarName = parseIdentifier();
+ TypeVariable tv = new TypeVariable(typeVarName);
+ typeVars.add(tv);
+ } while (maybeEat(","));
+ eat(">");
+ TypeVariable[] tvs = new TypeVariable[typeVars.size()];
+ typeVars.toArray(tvs);
+ return new TypeVariablePatternList(tvs);
+ }
+
+ public TypePatternList maybeParseTypeParameterList(boolean allowTypeVariables) {
+ if (!maybeEat("<")) return null;
+ List typePats = new ArrayList();
+ do {
+ TypePattern tp = parseTypePattern(true,allowTypeVariables);
+ typePats.add(tp);
+ } while(maybeEat(","));
+ eat(">");
+ TypePattern[] tps = new TypePattern[typePats.size()];
+ typePats.toArray(tps);
+ return new TypePatternList(tps);
+ }
+
+ public TypeVariable parseTypeVariable() {
+ TypePattern upperBound = null;
+ TypePattern[] additionalInterfaceBounds = null;
+ TypePattern lowerBound = null;
+ String typeVariableName = null;
+ if (typeVariableName == null) typeVariableName = parseIdentifier();
+ if (maybeEatIdentifier("extends")) {
+ upperBound = parseTypePattern();
+ additionalInterfaceBounds = maybeParseAdditionalInterfaceBounds();
+ } else if (maybeEatIdentifier("super")) {
+ lowerBound = parseTypePattern();
+ }
+ return new TypeVariable(typeVariableName,upperBound,additionalInterfaceBounds,lowerBound);
+ }
+
+ private TypePattern[] maybeParseAdditionalInterfaceBounds() {
+ List boundsList = new ArrayList();
+ while (maybeEat("&")) {
+ TypePattern tp = parseTypePattern();
+ boundsList.add(tp);
+ }
+ if (boundsList.size() == 0) return null;
+ TypePattern[] ret = new TypePattern[boundsList.size()];
+ boundsList.toArray(ret);
+ return ret;
+ }
public String parsePossibleStringSequence(boolean shouldEnd) {
StringBuffer result = new StringBuffer();
public String parseStringLiteral() {
IToken token = tokenSource.next();
String literalKind = token.getLiteralKind();
- if (literalKind.equals("string")) {
+ if (literalKind == "string") {
return token.getString();
}
public boolean maybeEat(String token) {
IToken next = tokenSource.peek();
- if (next.getString().equals(token)) {
+ if (next.getString() == token) {
tokenSource.next();
return true;
} else {
public boolean peek(String token) {
IToken next = tokenSource.peek();
- return next.getString().equals(token);
+ return next.getString() == token;
}
// -----
+ public Object accept(PatternNodeVisitor visitor, Object data) {
+ return visitor.visit(this,data);
+ }
+
public Set couldMatchKinds() {
return Shadow.ALL_SHADOW_KINDS;
}
return FuzzyBoolean.MAYBE;
}
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return FuzzyBoolean.MAYBE;
+ }
+
protected FuzzyBoolean matchInternal(Shadow shadow) {
return FuzzyBoolean.YES;
}
this.kind = kind;
}
+ public Object accept(PatternNodeVisitor visitor, Object data) {
+ return visitor.visit(this,data);
+ }
+
public Set couldMatchKinds() {
return Shadow.ALL_SHADOW_KINDS;
}
throw new RuntimeException("unimplemented");
}
+ public FuzzyBoolean fastMatch(Class targetType) {
+ throw new RuntimeException("unimplemented");
+ }
+
protected FuzzyBoolean matchInternal(Shadow shadow) {
throw new RuntimeException("unimplemented");
}
this.isThis = isThis;
}
+ public Object accept(PatternNodeVisitor visitor, Object data) {
+ return visitor.visit(this,data);
+ }
+
public Set couldMatchKinds() {
return isThis ? thisKindSet : targetKindSet;
}
return FuzzyBoolean.MAYBE;
}
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return FuzzyBoolean.MAYBE;
+ }
+
protected FuzzyBoolean matchInternal(Shadow shadow) {
//System.err.println("matches " + this + " ? " + shadow + ", " + shadow.hasTarget());
public PerSingleton() {
}
+ public Object accept(PatternNodeVisitor visitor, Object data) {
+ return visitor.visit(this,data);
+ }
+
public Set couldMatchKinds() {
return Shadow.ALL_SHADOW_KINDS;
}
return FuzzyBoolean.YES;
}
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return FuzzyBoolean.YES;
+ }
+
protected FuzzyBoolean matchInternal(Shadow shadow) {
return FuzzyBoolean.YES;
}
this.typePattern = p;
}
+ public Object accept(PatternNodeVisitor visitor, Object data) {
+ return visitor.visit(this,data);
+ }
+
public Set couldMatchKinds() {
return kindSet;
}
return FuzzyBoolean.MAYBE;
}
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return FuzzyBoolean.MAYBE;
+ }
+
protected FuzzyBoolean matchInternal(Shadow shadow) {
ResolvedTypeX enclosingType = shadow.getIWorld().resolve(shadow.getEnclosingType(),true);
protected int lastMatchedShadowId;
private FuzzyBoolean lastMatchedShadowResult;
private Test lastMatchedShadowResidue;
+ private TypeVariablePatternList typeVariables = TypeVariablePatternList.EMPTY;
/**
* Constructor for Pattern.
* Could I match any shadows in the code defined within this type?
*/
public abstract FuzzyBoolean fastMatch(FastMatchInfo info);
+
+ /**
+ * Could I match any shadows defined in this type?
+ */
+ public abstract FuzzyBoolean fastMatch(Class targetType);
/**
* The set of ShadowKinds that this Pointcut could possibly match
*/
public abstract /*Enum*/Set/*<Shadow.Kind>*/ couldMatchKinds();
+ public TypeVariablePatternList getTypeVariables() {
+ return typeVariables;
+ }
+
+ public void setTypeVariables(TypeVariablePatternList typeVars) {
+ this.typeVariables = typeVars;
+ }
+
/**
* Do I really match this shadow?
* XXX implementors need to handle state
return FuzzyBoolean.NO;
}
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return FuzzyBoolean.NO;
+ }
+
protected FuzzyBoolean matchInternal(Shadow shadow) {
return FuzzyBoolean.NO;
}
public String toString() { return ""; }
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2005 Contributors.
- * 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://eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Vasseur initial implementation
- *******************************************************************************/
-package org.aspectj.weaver.patterns;
-
-import org.aspectj.weaver.Member;
-
-/**
- * A Pointcut or TypePattern visitor
- *
- * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
- */
-public interface PointcutVisitor {
-
- Object visit(AnyTypePattern node, Object data);
-
- Object visit(NoTypePattern node, Object data);
-
- Object visit(EllipsisTypePattern node, Object data);
-
- Object visit(AnyWithAnnotationTypePattern node, Object data);
-
- Object visit(AnyAnnotationTypePattern node, Object data);
-
- Object visit(EllipsisAnnotationTypePattern node, Object data);
-
- Object visit(AndAnnotationTypePattern node, Object data);
-
- Object visit(AndPointcut node, Object data);
-
- Object visit(AndTypePattern node, Object data);
-
- Object visit(AnnotationPatternList node, Object data);
-
- Object visit(AnnotationPointcut node, Object data);
-
- Object visit(ArgsAnnotationPointcut node, Object data);
-
- Object visit(ArgsPointcut node, Object data);
-
- Object visit(BindingAnnotationTypePattern node, Object data);
-
- Object visit(BindingTypePattern node, Object data);
-
- Object visit(CflowPointcut node, Object data);
-
- Object visit(ConcreteCflowPointcut node, Object data);
-
- Object visit(DeclareAnnotation node, Object data);
-
- Object visit(DeclareErrorOrWarning node, Object data);
-
- Object visit(DeclareParents node, Object data);
-
- Object visit(DeclarePrecedence node, Object data);
-
- Object visit(DeclareSoft node, Object data);
-
- Object visit(ExactAnnotationTypePattern node, Object data);
-
- Object visit(ExactTypePattern node, Object data);
-
- Object visit(HandlerPointcut node, Object data);
-
- Object visit(IfPointcut node, Object data);
-
- Object visit(KindedPointcut node, Object data);
-
- Object visit(ModifiersPattern node, Object data);
-
- Object visit(NamePattern node, Object data);
-
- Object visit(NotAnnotationTypePattern node, Object data);
-
- Object visit(NotPointcut node, Object data);
-
- Object visit(NotTypePattern node, Object data);
-
- Object visit(OrAnnotationTypePattern node, Object data);
-
- Object visit(OrPointcut node, Object data);
-
- Object visit(OrTypePattern node, Object data);
-
- Object visit(PerCflow node, Object data);
-
- Object visit(PerFromSuper node, Object data);
-
- Object visit(PerObject node, Object data);
-
- Object visit(PerSingleton node, Object data);
-
- Object visit(PerTypeWithin node, Object data);
-
- Object visit(PatternNode node, Object data);
-
- Object visit(ReferencePointcut node, Object data);
-
- Object visit(SignaturePattern node, Object data);
-
- Object visit(ThisOrTargetAnnotationPointcut node, Object data);
-
- Object visit(ThisOrTargetPointcut node, Object data);
-
- Object visit(ThrowsPattern node, Object data);
-
- Object visit(TypePatternList node, Object data);
-
- Object visit(WildAnnotationTypePattern node, Object data);
-
- Object visit(WildTypePattern node, Object data);
-
- Object visit(WithinAnnotationPointcut node, Object data);
-
- Object visit(WithinCodeAnnotationPointcut node, Object data);
-
- Object visit(WithinPointcut node, Object data);
-
- Object visit(WithincodePointcut node, Object data);
-
- Object visit(Pointcut.MatchesNothingPointcut node, Object data);
-
- /**
- * A sample toString like visitor that helps understanding the AST tree structure organization
- *
- * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
- */
- static class DumpPointcutVisitor implements PointcutVisitor {
-
- private StringBuffer sb = new StringBuffer();
- public String get() {
- return sb.toString();
- }
-
- private void append(Object o) {
- sb.append(o.toString());
- }
-
- private void append(char c) {
- sb.append(c);
- }
-
- /**
- * This method helps maintaining the API and raises warning when PatternNode subclasses do not
- * implement the visitor pattern
- *
- * @param node
- * @param data
- * @return
- */
- public Object visit(PatternNode node, Object data) {
- System.err.println("Should implement: " + node.getClass());
- return null;
- }
-
- public Object visit(AnyTypePattern node, Object data) {
- append('*');
- return null;
- }
-
- public Object visit(NoTypePattern node, Object data) {
- append(node.toString());//TODO no idea when this one is used
- return null;
- }
-
- public Object visit(EllipsisTypePattern node, Object data) {
- append(node.toString());
- return null;
- }
-
- public Object visit(AnyWithAnnotationTypePattern node, Object data) {
- node.annotationPattern.accept(this, data);
- append(" *");
- return null;
- }
-
- public Object visit(AnyAnnotationTypePattern node, Object data) {
- //@ANY : ignore
- append('*');
- return null;
- }
-
- public Object visit(EllipsisAnnotationTypePattern node, Object data) {
- append("..");
- return null;
- }
-
- public Object visit(AndAnnotationTypePattern node, Object data) {
- node.getLeft().accept(this, data);
- append(' ');
- node.getRight().accept(this, data);
- return null;
- }
-
- public Object visit(AndPointcut node, Object data) {
- append('(');
- node.getLeft().accept(this, data);
- append(" && ");
- node.getRight().accept(this, data);
- append(')');
- return null;
- }
-
- public Object visit(AndTypePattern node, Object data) {
- append('(');
- node.getLeft().accept(this, data);
- append(" && ");
- node.getRight().accept(this, data);
- append(')');
- return null;
- }
-
- public Object visit(AnnotationPatternList node, Object data) {
- AnnotationTypePattern[] annotations = node.getAnnotationPatterns();
- for (int i = 0; i < annotations.length; i++) {
- if (i>0) append(", ");//Note: list is ",", and is " " separated for annotations
- annotations[i].accept(this, data);
- }
- return null;
- }
-
- public Object visit(AnnotationPointcut node, Object data) {
- append("@annotation(");
- node.getAnnotationTypePattern().accept(this, data);
- append(')');
- return null;
- }
-
- public Object visit(ArgsAnnotationPointcut node, Object data) {
- append("@args(");
- node.getArguments().accept(this, data);
- append(')');
- return null;
- }
-
- public Object visit(ArgsPointcut node, Object data) {
- append("args(");
- node.getArguments().accept(this, data);
- append(')');
- return null;
- }
-
- public Object visit(BindingAnnotationTypePattern node, Object data) {
- append(node);
- return null;
- }
-
- public Object visit(BindingTypePattern node, Object data) {
- append(node);
- return null;
- }
-
- public Object visit(CflowPointcut node, Object data) {
- append(node.isBelow()?"cflowbelow(":"cflow(");
- node.getEntry().accept(this, data);
- append(')');
- return null;
- }
-
- public Object visit(ExactAnnotationTypePattern node, Object data) {
- //append('@'); // since @annotation(@someAnno) cannot be parsed anymore
- append(node.getAnnotationType().getName());
- return null;
- }
-
- public Object visit(ExactTypePattern node, Object data) {
- if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
- append('(');
- node.getAnnotationPattern().accept(this, data);
- append(' ');
- }
-
- String typeString = node.getType().toString();
- if (node.isVarArgs()) typeString = typeString.substring(0, typeString.lastIndexOf('['));//TODO AV - ugly
- append(typeString);
- if (node.isIncludeSubtypes()) append('+');
- if (node.isVarArgs()) append("...");
- if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
- append(')');
- }
- return null;
- }
-
- public Object visit(KindedPointcut node, Object data) {
- append(node.getKind().getSimpleName());
- append('(');
- node.getSignature().accept(this, data);
- append(')');
- return null;
- }
-
- public Object visit(ModifiersPattern node, Object data) {
- append(node.toString());//note: node takes care of forbidden mods
- return null;
- }
-
- public Object visit(NamePattern node, Object data) {
- append(node.toString());
- return null;
- }
-
- public Object visit(NotAnnotationTypePattern node, Object data) {
- append("!");
- node.getNegatedPattern().accept(this, data);
- return null;
- }
-
- public Object visit(NotPointcut node, Object data) {
- append("!(");
- node.getNegatedPointcut().accept(this, data);
- append(')');
- return null;
- }
-
- public Object visit(NotTypePattern node, Object data) {
- append("!(");
- node.getNegatedPattern().accept(this, data);
- append(')');
- return null;
- }
-
- public Object visit(OrAnnotationTypePattern node, Object data) {
- append('(');
- node.getLeft().accept(this, data);
- append(" || ");
- node.getRight().accept(this, data);
- append(')');
- return null;
- }
-
- public Object visit(OrPointcut node, Object data) {
- append('(');
- node.getLeft().accept(this, data);
- append(" || ");
- node.getRight().accept(this, data);
- append(')');
- return null;
- }
-
- public Object visit(OrTypePattern node, Object data) {
- append('(');
- node.getLeft().accept(this, data);
- append(" || ");
- node.getRight().accept(this, data);
- append(')');
- return null;
- }
-
- public Object visit(ReferencePointcut node, Object data) {
- append(node.toString());
- return null;
- }
-
- public Object visit(SignaturePattern node, Object data) {
- if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
- node.getAnnotationPattern().accept(this, data);
- append(' ');
- }
-
- if (node.getModifiers() != ModifiersPattern.ANY) {
- node.getModifiers().accept(this, data);
- append(' ');
- }
-
- if (node.getKind() == Member.STATIC_INITIALIZATION) {
- node.getDeclaringType().accept(this, data);
- } else if (node.getKind() == Member.HANDLER) {
- append("handler(");
- node.getParameterTypes().get(0).accept(this, data);//Note: we know we have 1 child
- append(')');
- } else {
- if (!(node.getKind() == Member.CONSTRUCTOR)) {
- node.getReturnType().accept(this, data);
- append(' ');
- }
- if (node.getDeclaringType() != TypePattern.ANY) {
- node.getDeclaringType().accept(this, data);
- append('.');
- }
- if (node.getKind() == Member.CONSTRUCTOR) {
- append("new");
- } else {
- node.getName().accept(this, data);
- }
- if (node.getKind() == Member.METHOD || node.getKind() == Member.CONSTRUCTOR) {
- append('(');
- node.getParameterTypes().accept(this, data);
- append(')');
- }
- if (node.getThrowsPattern() != null) {
- append(' ');
- node.getThrowsPattern().accept(this, data);
- }
- }
- return null;
- }
-
- public Object visit(ThisOrTargetAnnotationPointcut node, Object data) {
- append(node.isThis() ? "@this(" : "@target(");
- node.getAnnotationTypePattern().accept(this, data);
- append(')');
- return null;
- }
-
- public Object visit(ThisOrTargetPointcut node, Object data) {
- append(node.isThis() ? "this(" : "target(");
- node.getType().accept(this, data);
- append(')');
- return null;
- }
-
- // Note: a visitor instance is not thread safe so should not be shared
- private boolean inThrowsForbidden = false;
-
- public Object visit(ThrowsPattern node, Object data) {
- if (node == ThrowsPattern.ANY) return null;
-
- append("throws ");
- node.getRequired().accept(this, data);
- if (node.getForbidden().size() > 0) {
- // a hack since throws !(A, B) cannot be parsed
- try {
- inThrowsForbidden = true;
- node.getForbidden().accept(this, data);
- } finally {
- inThrowsForbidden = false;
- }
- }
- return null;
- }
-
- public Object visit(TypePatternList node, Object data) {
- if (node.getTypePatterns().length == 0) return null;
-
- TypePattern[] typePatterns = node.getTypePatterns();
- for (int i = 0; i < typePatterns.length; i++) {
- TypePattern typePattern = typePatterns[i];
- if (i > 0) append(", ");
- if (inThrowsForbidden) append('!');
- typePattern.accept(this, data);
- }
- return null;
- }
-
- public Object visit(WildAnnotationTypePattern node, Object data) {
- append("@(");
- node.getTypePattern().accept(this, data);
- append(')');
- return null;
- }
-
- public Object visit(WildTypePattern node, Object data) {
- if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
- append('(');
- node.getAnnotationPattern().accept(this, data);
- append(' ');
- }
- NamePattern[] namePatterns = node.getNamePatterns();
- for (int i=0; i < namePatterns.length; i++) {
- if (namePatterns[i] == null) {
- append('.');//FIXME mh, error prone, can't we have a nullNamePattern ?
- } else {
- if (i > 0) append('.');
- namePatterns[i].accept(this, data);
- }
- }
- if (node.isIncludeSubtypes()) append('+');
- if (node.isVarArgs()) append("...");
- if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
- append(')');
- }
- return null;
- }
-
- public Object visit(WithinAnnotationPointcut node, Object data) {
- append("@within(");
- node.getAnnotationTypePattern().accept(this, data);
- append(')');
- return null;
- }
-
- public Object visit(WithinCodeAnnotationPointcut node, Object data) {
- append("@withincode(");
- node.getAnnotationTypePattern().accept(this, data);
- append(')');
- return null;
- }
-
- public Object visit(WithinPointcut node, Object data) {
- append("within(");
- node.getTypePattern().accept(this, data);
- append(')');
- return null;
- }
-
- public Object visit(WithincodePointcut node, Object data) {
- append("withincode(");
- node.getSignature().accept(this, data);
- append(')');
- return null;
- }
-
- public Object visit(Pointcut.MatchesNothingPointcut node, Object data) {
- append("");//TODO shouldn't that be a "false" ?
- return null;
- }
-
-
- //-------------- perX
-
- public Object visit(PerCflow node, Object data) {
- append(node);
- return null;
- }
-
- public Object visit(PerFromSuper node, Object data) {
- append(node);
- return null;
- }
-
- public Object visit(PerObject node, Object data) {
- append(node);
- return null;
- }
-
- public Object visit(PerSingleton node, Object data) {
- append(node);
- return null;
- }
-
- public Object visit(PerTypeWithin node, Object data) {
- append(node);
- return null;
- }
-
- // ------------- declare X
-
- public Object visit(DeclareAnnotation node, Object data) {
- append(node);
- return null;
- }
-
- public Object visit(DeclareErrorOrWarning node, Object data) {
- append(node);
- return null;
- }
-
- public Object visit(DeclareParents node, Object data) {
- append(node);
- return null;
- }
-
- public Object visit(DeclarePrecedence node, Object data) {
- append(node);
- return null;
- }
-
- public Object visit(DeclareSoft node, Object data) {
- append(node);
- return null;
- }
-
- // ----------- misc
-
- public Object visit(ConcreteCflowPointcut node, Object data) {
- append(node);
- return null;
- }
-
- public Object visit(HandlerPointcut node, Object data) {
- append(node);
- return null;
- }
-
- public Object visit(IfPointcut node, Object data) {
- append(node);
- return null;
- }
-
- public static void check(String s) {
- check(Pointcut.fromString(s), false);
- }
-
- public static void check(PatternNode pc, boolean isTypePattern) {
- DumpPointcutVisitor v1 = new DumpPointcutVisitor();
- pc.accept(v1, null);
-
- DumpPointcutVisitor v2 = new DumpPointcutVisitor();
- final PatternNode pc2;
- if (isTypePattern) {
- pc2 = new PatternParser(v1.get()).parseTypePattern();
- } else {
- pc2 = Pointcut.fromString(v1.get());
- }
- pc2.accept(v2, null);
-
- // at second parsing, the String form stay stable when parsed and parsed again
- if (! v1.get().equals(v2.get())) {
- throw new ParserException("Unstable back parsing for '"+pc+"', got '" + v1.get() + "' and '" + v2.get() + "'", null);
- }
- }
-
- public static void main(String args[]) throws Throwable {
- String[] s = new String[]{
-// "@args(Foo, Goo, *, .., Moo)",
-// "execution(* *())",
-// "call(* *(int, Integer...))",
-// "staticinitialization(@(Foo) @(Boo) @(Goo) Moo)",
-// "staticinitialization(!@(Immutable) *)"
-// "execution(* *()) && if()",
- "(if(true) && set(int BaseApp.i))"
-
- };
- for (int i = 0; i < s.length; i++) {
- check(s[i]);
- }
- }
-
- }
-
-}
return FuzzyBoolean.MAYBE;
}
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return FuzzyBoolean.MAYBE;
+ }
+
/**
* Do I really match this shadow?
*/
return result;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors.
+ * 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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Adrian Colyer Initial implementation
+ * ******************************************************************/
+package org.aspectj.weaver.patterns;
+
+import org.aspectj.bridge.IMessageHandler;
+import org.aspectj.bridge.IMessage.Kind;
+import org.aspectj.weaver.IHasPosition;
+import org.aspectj.weaver.ResolvedTypeX;
+import org.aspectj.weaver.TypeX;
+import org.aspectj.weaver.World;
+
+/**
+ * A scope that also considers type variables when looking up a type.
+ *
+ */
+public class ScopeWithTypeVariables implements IScope {
+
+ private IScope delegateScope;
+ private TypeVariablePatternList typeVariables;
+
+ public ScopeWithTypeVariables(TypeVariablePatternList typeVars, IScope delegate) {
+ this.delegateScope = delegate;
+ this.typeVariables = typeVars;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.IScope#lookupType(java.lang.String, org.aspectj.weaver.IHasPosition)
+ */
+ public TypeX lookupType(String name, IHasPosition location) {
+ TypeVariable typeVariableMatch = typeVariables.lookupTypeVariable(name);
+ if (typeVariableMatch != null) {
+ return typeVariableMatch.resolvedType();
+ } else {
+ return delegateScope.lookupType(name, location);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.IScope#getWorld()
+ */
+ public World getWorld() {
+ return delegateScope.getWorld();
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.IScope#getEnclosingType()
+ */
+ public ResolvedTypeX getEnclosingType() {
+ return delegateScope.getEnclosingType();
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.IScope#getMessageHandler()
+ */
+ public IMessageHandler getMessageHandler() {
+ return delegateScope.getMessageHandler();
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.IScope#lookupFormal(java.lang.String)
+ */
+ public FormalBinding lookupFormal(String name) {
+ return delegateScope.lookupFormal(name);
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.IScope#getFormal(int)
+ */
+ public FormalBinding getFormal(int i) {
+ return delegateScope.getFormal(i);
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.IScope#getFormalCount()
+ */
+ public int getFormalCount() {
+ return delegateScope.getFormalCount();
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.IScope#getImportedPrefixes()
+ */
+ public String[] getImportedPrefixes() {
+ return delegateScope.getImportedPrefixes();
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.IScope#getImportedNames()
+ */
+ public String[] getImportedNames() {
+ return delegateScope.getImportedNames();
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.IScope#message(org.aspectj.bridge.IMessage.Kind, org.aspectj.weaver.IHasPosition, java.lang.String)
+ */
+ public void message(Kind kind, IHasPosition location, String message) {
+ delegateScope.message(kind, location, message);
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.IScope#message(org.aspectj.bridge.IMessage.Kind, org.aspectj.weaver.IHasPosition, org.aspectj.weaver.IHasPosition, java.lang.String)
+ */
+ public void message(Kind kind, IHasPosition location1,
+ IHasPosition location2, String message) {
+ delegateScope.message(kind,location1,location2,message);
+ }
+
+}
return false;
}
+ public boolean couldMatch(Class declaringClass) {
+ return declaringTypeMatch(declaringClass);
+ }
+
public boolean matches(Class declaringClass, java.lang.reflect.Member member) {
if (kind == Member.ADVICE) return true;
if (kind == Member.POINTCUT) return false;
return annotationPattern == AnnotationTypePattern.ANY;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
public FuzzyBoolean fastMatch(FastMatchInfo info) {
return FuzzyBoolean.MAYBE;
}
+
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return FuzzyBoolean.MAYBE;
+ }
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow)
return buf.toString();
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
public FuzzyBoolean fastMatch(FastMatchInfo type) {
return FuzzyBoolean.MAYBE;
}
+
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return FuzzyBoolean.MAYBE;
+ }
private boolean couldMatch(Shadow shadow) {
return isThis ? shadow.hasThis() : shadow.hasTarget();
return ret;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
//XXXwriteLocation(s);
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
protected boolean includeSubtypes;
protected boolean isVarArgs = false;
protected AnnotationTypePattern annotationPattern = AnnotationTypePattern.ANY;
+ protected TypePatternList typeParameters = TypePatternList.EMPTY;
- protected TypePattern(boolean includeSubtypes,boolean isVarArgs) {
+ protected TypePattern(boolean includeSubtypes,boolean isVarArgs,TypePatternList typeParams) {
this.includeSubtypes = includeSubtypes;
this.isVarArgs = isVarArgs;
+ this.typeParameters = (typeParams == null ? TypePatternList.EMPTY : typeParams);
+ }
+
+ protected TypePattern(boolean includeSubtypes, boolean isVarArgs) {
+ this(includeSubtypes,isVarArgs,null);
}
public AnnotationTypePattern getAnnotationPattern() {
this.annotationPattern = annPatt;
}
+ public void setTypeParameters(TypePatternList typeParams) {
+ this.typeParameters = typeParams;
+ }
+
+ public TypePatternList getTypeParameters() {
+ return this.typeParameters;
+ }
+
public void setIsVarArgs(boolean isVarArgs) {
this.isVarArgs = isVarArgs;
}
* @param includeSubtypes
*/
public EllipsisTypePattern() {
- super(false,false);
+ super(false,false,new TypePatternList());
}
/* (non-Javadoc)
return 17 * 37;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
* @param includeSubtypes
*/
public AnyTypePattern() {
- super(false,false);
+ super(false,false,new TypePatternList());
}
/* (non-Javadoc)
return 37;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
annotationPattern = atp;
}
+ public Object accept(PatternNodeVisitor visitor, Object data) {
+ return visitor.visit(this,data);
+ }
+
protected boolean couldEverMatchSameTypesAs(TypePattern other) {
return true;
}
class NoTypePattern extends TypePattern {
public NoTypePattern() {
- super(false,false);
+ super(false,false,new TypePatternList());
}
return 17 * 37 * 37;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
new TypePatternList(new TypePattern[] {});
public static final TypePatternList ANY =
- new TypePatternList(new TypePattern[] {TypePattern.ELLIPSIS});
+ new TypePatternList(new TypePattern[] {new EllipsisTypePattern()}); //can't use TypePattern.ELLIPSIS because of circular static dependency that introduces
public TypePatternList() {
typePatterns = new TypePattern[0];
return ret;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ 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;
+ }
}
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors.
+ * 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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Adrian Colyer Initial implementation
+ * ******************************************************************/
+package org.aspectj.weaver.patterns;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.weaver.ISourceContext;
+import org.aspectj.weaver.ResolvedTypeX;
+import org.aspectj.weaver.TypeX;
+import org.aspectj.weaver.VersionedDataInputStream;
+
+/**
+ * @author colyer
+ * Represents a type variable as declared as part of a type declaration, parameter declaration,
+ * or type parameter specification.
+ * <p>For example:</p>
+ * <ul>
+ * <li><T> T genericMethod(T t) {...}</li>
+ * <li>static <T extends Foo> T staticGenericMethod(T t) {...}</li>
+ * <li>Foo<T extends Bar & IGoo>
+ * </ul>
+ */
+public class TypeVariable extends PatternNode {
+
+ private static final String anything = "?";
+
+ private String name; // eg. "T"
+ private TypePattern upperBound; // default is object unless of the form T extends Bar
+ private TypePattern[] interfaceBounds; // additional upper bounds (must be interfaces) arising from
+ // declarations of the form T extends Bar & IGoo, IDoo
+ private TypePattern lowerBound; // only set if type variable is of the form T super Bar
+ private ResolvedTypeX resolvedType; // only set if resolved
+
+ /**
+ * Create a named type variable with upper bound Object and no lower bounds.
+ * Use this constructor for the simple "T" case
+ */
+ public TypeVariable(String variableName) {
+ this.name = variableName;
+ this.upperBound = new ExactTypePattern(TypeX.OBJECT,false,false);
+ this.lowerBound = null;
+ this.interfaceBounds = null;
+ }
+
+ /**
+ * Create a named type variable with the given upper bound and no lower bounds
+ * Use this constructor for the T extends Foo case
+ * @param variableName
+ * @param upperBound
+ */
+ public TypeVariable(String variableName, TypePattern upperBound) {
+ this.name = variableName;
+ this.upperBound = upperBound;
+ this.lowerBound = null;
+ this.interfaceBounds = null;
+ }
+
+ public TypeVariable(String variableName, TypePattern upperLimit, TypePattern[] interfaceBounds, TypePattern lowerBound) {
+ this.name = variableName;
+ this.upperBound = upperLimit;
+ if (upperBound == null) upperBound = new ExactTypePattern(TypeX.OBJECT,false,false);
+ this.interfaceBounds = interfaceBounds;
+ this.lowerBound = lowerBound;
+ }
+
+ public Object accept(PatternNodeVisitor visitor, Object data) {
+ return visitor.visit(this,data);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean isAnythingPattern() {
+ return name.equals(anything);
+ }
+
+ public TypePattern getRawTypePattern() {
+ return upperBound;
+ }
+
+ public TypePattern getUpperBound() {
+ return upperBound;
+ }
+
+ public boolean hasLowerBound() { return (lowerBound != null); }
+
+ public TypePattern getLowerBound() {
+ return lowerBound;
+ }
+
+ public boolean hasAdditionalInterfaceBounds() {
+ return (interfaceBounds != null);
+ }
+
+ public TypePattern[] getAdditionalInterfaceBounds() {
+ if (interfaceBounds != null) {
+ return interfaceBounds;
+ } else {
+ return new TypePattern[0];
+ }
+ }
+
+ public ResolvedTypeX resolvedType() {
+ throw new UnsupportedOperationException("Haven't implement ResolvedTypeX for TypeVariables yet...");
+ //return this.resolvedType;
+ }
+
+ public boolean equals(Object obj) {
+ if (!(obj instanceof TypeVariable)) return false;
+ TypeVariable other = (TypeVariable) obj;
+ if (!name.equals(other.name)) return false;
+ if (!upperBound.equals(other.upperBound)) return false;
+ if (lowerBound != null) {
+ if (other.lowerBound == null) return false;
+ if (!lowerBound.equals(other.lowerBound)) return false;
+ } else {
+ if (other.lowerBound != null) return false;
+ }
+ if (interfaceBounds != null) {
+ if (other.interfaceBounds == null) return false;
+ if (interfaceBounds.length != other.interfaceBounds.length) return false;
+ for (int i = 0; i < interfaceBounds.length; i++) {
+ if (!interfaceBounds[i].equals(other.interfaceBounds[i])) return false;
+ }
+ } else {
+ if (other.interfaceBounds != null) return false;
+ }
+ return true;
+ }
+
+ public int hashCode() {
+ int hashCode = 17 + (37 * name.hashCode());
+ hashCode = hashCode * 37 + upperBound.hashCode();
+ if (lowerBound != null) hashCode = hashCode * 37 + lowerBound.hashCode();
+ if (interfaceBounds != null) {
+ for (int i = 0; i < interfaceBounds.length; i++) {
+ hashCode = 37*hashCode + interfaceBounds[i].hashCode();
+ }
+ }
+ return hashCode;
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(name);
+ sb.append(getExtendsClause());
+ if (interfaceBounds != null) {
+ sb.append(" & ");
+ for (int i = 0; i < interfaceBounds.length; i++) {
+ sb.append(interfaceBounds[i].toString());
+ if (i < interfaceBounds.length) sb.append(",");
+ }
+ }
+ if (lowerBound != null) {
+ sb.append(" super ");
+ sb.append(lowerBound.toString());
+ }
+ return sb.toString();
+ }
+
+ private String getExtendsClause() {
+ if (upperBound instanceof ExactTypePattern) {
+ ExactTypePattern bound = (ExactTypePattern) upperBound;
+ if (bound.type == TypeX.OBJECT) return "";
+ }
+ return " extends " + upperBound.toString();
+ }
+
+ public void write(DataOutputStream s) throws IOException {
+ s.writeUTF(name);
+ upperBound.write(s);
+ if (interfaceBounds == null) {
+ s.writeInt(0);
+ } else {
+ s.writeInt(interfaceBounds.length);
+ for (int i = 0; i < interfaceBounds.length; i++) {
+ interfaceBounds[i].write(s);
+ }
+ }
+ s.writeBoolean(hasLowerBound());
+ if (hasLowerBound()) lowerBound.write(s);
+ writeLocation(s);
+ }
+
+ public static TypeVariable read(VersionedDataInputStream s, ISourceContext context) throws IOException {
+ TypeVariable tv = null;
+ String name = s.readUTF();
+ TypePattern upperBound = TypePattern.read(s, context);
+ TypePattern[] additionalInterfaceBounds = null;
+ int numInterfaceBounds = s.readInt();
+ if (numInterfaceBounds > 0) {
+ additionalInterfaceBounds = new TypePattern[numInterfaceBounds];
+ for (int i = 0; i < additionalInterfaceBounds.length; i++) {
+ additionalInterfaceBounds[i] = TypePattern.read(s, context);
+ }
+ }
+ boolean hasLowerBound = s.readBoolean();
+ TypePattern lowerBound = null;
+ if (hasLowerBound) lowerBound = TypePattern.read(s,context);
+ tv = new TypeVariable(name,upperBound,additionalInterfaceBounds,lowerBound);
+ tv.readLocation(context, s);
+ return tv;
+ }
+
+}
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors.
+ * 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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Adrian Colyer Initial implementation
+ * ******************************************************************/
+package org.aspectj.weaver.patterns;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.weaver.ISourceContext;
+import org.aspectj.weaver.VersionedDataInputStream;
+
+/**
+ * @author colyer
+ * A list of type variable specifications, eg. <T,S>
+ */
+public class TypeVariablePatternList extends PatternNode {
+
+ public static final TypeVariablePatternList EMPTY = new TypeVariablePatternList(new TypeVariable[0]);
+
+ private TypeVariable[] patterns;
+
+ public TypeVariablePatternList(TypeVariable[] typeVars) {
+ this.patterns = typeVars;
+ }
+
+ public TypeVariable[] getTypeVariablePatterns() {
+ return this.patterns;
+ }
+
+ public TypeVariable lookupTypeVariable(String name) {
+ for (int i = 0; i < patterns.length; i++) {
+ if (patterns[i].getName().equals(name)) {
+ return patterns[i];
+ }
+ }
+ return null;
+ }
+
+ public void write(DataOutputStream s) throws IOException {
+ s.writeInt(patterns.length);
+ for (int i = 0; i < patterns.length; i++) {
+ patterns[i].write(s);
+ }
+ writeLocation(s);
+ }
+
+ public static TypeVariablePatternList read(VersionedDataInputStream s, ISourceContext context) throws IOException {
+ TypeVariablePatternList ret = EMPTY;
+ int length = s.readInt();
+ if (length > 0) {
+ TypeVariable[] patterns = new TypeVariable[length];
+ for (int i = 0; i < patterns.length; i++) {
+ patterns[i] = TypeVariable.read(s,context);
+ }
+ ret = new TypeVariablePatternList(patterns);
+ }
+ ret.readLocation(context, s); // redundant but safe to read location for EMPTY
+ 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);
+ for (int i = 0; i < patterns.length; i++) {
+ patterns[i].traverse(visitor,ret);
+ }
+ return ret;
+ }
+
+}
return "@(" + typePattern.toString() + ")";
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
String[] importedPrefixes;
String[] knownMatches;
int dim;
-
- WildTypePattern(NamePattern[] namePatterns, boolean includeSubtypes, int dim, boolean isVarArgs) {
- super(includeSubtypes,isVarArgs);
+
+ // these next three are set if the type pattern is constrained by extends or super clauses, in which case the
+ // namePatterns must have length 1
+ // TODO AMC: read/write/resolve of these fields
+ TypePattern upperBound; // extends Foo
+ TypePattern[] additionalInterfaceBounds; // extends Foo & A,B,C
+ TypePattern lowerBound; // super Foo
+
+ WildTypePattern(NamePattern[] namePatterns, boolean includeSubtypes, int dim, boolean isVarArgs, TypePatternList typeParams) {
+ super(includeSubtypes,isVarArgs,typeParams);
this.namePatterns = namePatterns;
this.dim = dim;
ellipsisCount = 0;
}
public WildTypePattern(List names, boolean includeSubtypes, int dim) {
- this((NamePattern[])names.toArray(new NamePattern[names.size()]), includeSubtypes, dim,false);
+ this((NamePattern[])names.toArray(new NamePattern[names.size()]), includeSubtypes, dim,false,TypePatternList.EMPTY);
}
this.end = endPos;
this.isVarArgs = isVarArg;
}
-
+
+ public WildTypePattern(
+ List names,
+ boolean includeSubtypes,
+ int dim,
+ int endPos,
+ boolean isVarArg,
+ TypePatternList typeParams,
+ TypePattern upperBound,
+ TypePattern[] additionalInterfaceBounds,
+ TypePattern lowerBound) {
+ this((NamePattern[])names.toArray(new NamePattern[names.size()]),includeSubtypes,dim,isVarArg,typeParams);
+ this.end = endPos;
+ this.upperBound = upperBound;
+ this.lowerBound = lowerBound;
+ this.additionalInterfaceBounds = additionalInterfaceBounds;
+ }
+
public NamePattern[] getNamePatterns() {
return namePatterns;
}
+
+ public TypePattern getUpperBound() { return upperBound; }
+ public TypePattern getLowerBound() { return lowerBound; }
+ public TypePattern[] getAdditionalIntefaceBounds() { return additionalInterfaceBounds; }
// called by parser after parsing a type pattern, must bump dim as well as setting flag
public void setIsVarArgs(boolean isVarArgs) {
s.writeBoolean(includeSubtypes);
s.writeInt(dim);
s.writeBoolean(isVarArgs);
+ typeParameters.write(s); // ! change from M2
//??? storing this information with every type pattern is wasteful of .class
// file size. Storing it on enclosing types would be more efficient
FileUtil.writeStringArray(knownMatches, s);
boolean includeSubtypes = s.readBoolean();
int dim = s.readInt();
boolean varArg = s.readBoolean();
- WildTypePattern ret = new WildTypePattern(namePatterns, includeSubtypes, dim, varArg);
+ TypePatternList typeParams = TypePatternList.read(s, context);
+ WildTypePattern ret = new WildTypePattern(namePatterns, includeSubtypes, dim, varArg,typeParams);
ret.knownMatches = FileUtil.readStringArray(s);
ret.importedPrefixes = FileUtil.readStringArray(s);
ret.readLocation(context, s);
}
boolean includeSubtypes = s.readBoolean();
int dim = s.readInt();
- WildTypePattern ret = new WildTypePattern(namePatterns, includeSubtypes, dim, false);
+ WildTypePattern ret = new WildTypePattern(namePatterns, includeSubtypes, dim, false,null);
ret.knownMatches = FileUtil.readStringArray(s);
ret.importedPrefixes = FileUtil.readStringArray(s);
ret.readLocation(context, s);
return ret;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
return annotationTypePattern.fastMatches(info.getType());
}
+ public FuzzyBoolean fastMatch(Class targetType) {
+ // TODO AMC
+ return FuzzyBoolean.MAYBE;
+ }
+
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow)
*/
return buf.toString();
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
return FuzzyBoolean.MAYBE;
}
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return FuzzyBoolean.MAYBE;
+ }
+
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow)
*/
return buf.toString();
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
}
return FuzzyBoolean.MAYBE;
}
+
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return FuzzyBoolean.MAYBE;
+ }
protected FuzzyBoolean matchInternal(Shadow shadow) {
ResolvedTypeX enclosingType = shadow.getIWorld().resolve(shadow.getEnclosingType(),true);
return ret;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
public FuzzyBoolean fastMatch(FastMatchInfo type) {
return FuzzyBoolean.MAYBE;
}
+
+ public FuzzyBoolean fastMatch(Class targetType) {
+ return FuzzyBoolean.MAYBE;
+ }
+
protected FuzzyBoolean matchInternal(Shadow shadow) {
//This will not match code in local or anonymous classes as if
return ret;
}
- public Object accept(PointcutVisitor visitor, Object data) {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}
*/
public interface PointcutExpression {
+ /**
+ * Determine whether or not this pointcut could ever match a join point in the given class.
+ * @param aClass the candidate class
+ * @return true iff this pointcut <i>may</i> match a join point within(aClass), and false otherwise
+ */
+ boolean couldMatchJoinPointsInType(Class aClass);
+
+ /**
+ * Returns true iff this pointcut contains any expression that might necessitate a dynamic test
+ * at some join point (e.g. args)
+ */
+ boolean mayNeedDynamicTest();
+
/**
* Determine whether or not this pointcut matches a method call to the given method.
* @param aMethod the method being called
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * ******************************************************************/
+
+package org.aspectj.weaver.tools;
+
+import org.aspectj.util.TypeSafeEnum;
+
+/**
+ * An enumeration of the different kinds of pointcut primitives
+ * supported by AspectJ.
+ */
+public class PointcutPrimitive extends TypeSafeEnum {
+
+ public static final PointcutPrimitive CALL = new PointcutPrimitive("call",1);
+ public static final PointcutPrimitive EXECUTION = new PointcutPrimitive("execution",2);
+ public static final PointcutPrimitive GET = new PointcutPrimitive("get",3);
+ public static final PointcutPrimitive SET = new PointcutPrimitive("set",4);
+ public static final PointcutPrimitive INITIALIZATION = new PointcutPrimitive("initialization",5);
+ public static final PointcutPrimitive PRE_INITIALIZATION = new PointcutPrimitive("preinitialization",6);
+ public static final PointcutPrimitive STATIC_INITIALIZATION = new PointcutPrimitive("staticinitialization",7);
+ public static final PointcutPrimitive HANDLER = new PointcutPrimitive("handler",8);
+ public static final PointcutPrimitive ADVICE_EXECUTION = new PointcutPrimitive("adviceexecution",9);
+ public static final PointcutPrimitive WITHIN = new PointcutPrimitive("within",10);
+ public static final PointcutPrimitive WITHIN_CODE = new PointcutPrimitive("withincode",11);
+ public static final PointcutPrimitive CFLOW = new PointcutPrimitive("cflow",12);
+ public static final PointcutPrimitive CFLOW_BELOW = new PointcutPrimitive("cflowbelow",13);
+ public static final PointcutPrimitive IF = new PointcutPrimitive("if",14);
+ public static final PointcutPrimitive THIS = new PointcutPrimitive("this",15);
+ public static final PointcutPrimitive TARGET = new PointcutPrimitive("target",16);
+ public static final PointcutPrimitive ARGS = new PointcutPrimitive("args",17);
+ public static final PointcutPrimitive REFERENCE = new PointcutPrimitive("reference pointcut",18);
+
+ private PointcutPrimitive(String name, int key) {
+ super(name, key);
+ }
+
+}
+++ /dev/null
-/* *******************************************************************
- * Copyright (c) 2004 IBM Corporation.
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Common Public License v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * ******************************************************************/
-
-package org.aspectj.weaver.tools;
-
-import org.aspectj.util.TypeSafeEnum;
-
-/**
- * An enumeration of the different kinds of pointcut primitives
- * supported by AspectJ.
- */
-public class PointcutPrimitives extends TypeSafeEnum {
-
- public static final PointcutPrimitives CALL = new PointcutPrimitives("call",1);
- public static final PointcutPrimitives EXECUTION = new PointcutPrimitives("execution",2);
- public static final PointcutPrimitives GET = new PointcutPrimitives("get",3);
- public static final PointcutPrimitives SET = new PointcutPrimitives("set",4);
- public static final PointcutPrimitives INITIALIZATION = new PointcutPrimitives("initialization",5);
- public static final PointcutPrimitives PRE_INITIALIZATION = new PointcutPrimitives("preinitialization",6);
- public static final PointcutPrimitives STATIC_INITIALIZATION = new PointcutPrimitives("staticinitialization",7);
- public static final PointcutPrimitives HANDLER = new PointcutPrimitives("handler",8);
- public static final PointcutPrimitives ADVICE_EXECUTION = new PointcutPrimitives("adviceexecution",9);
- public static final PointcutPrimitives WITHIN = new PointcutPrimitives("within",10);
- public static final PointcutPrimitives WITHIN_CODE = new PointcutPrimitives("withincode",11);
- public static final PointcutPrimitives CFLOW = new PointcutPrimitives("cflow",12);
- public static final PointcutPrimitives CFLOW_BELOW = new PointcutPrimitives("cflowbelow",13);
- public static final PointcutPrimitives IF = new PointcutPrimitives("if",14);
- public static final PointcutPrimitives THIS = new PointcutPrimitives("this",15);
- public static final PointcutPrimitives TARGET = new PointcutPrimitives("target",16);
- public static final PointcutPrimitives ARGS = new PointcutPrimitives("args",17);
-
- private PointcutPrimitives(String name, int key) {
- super(name, key);
- }
-
-}
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors.
+ * 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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Adrian Colyer Initial implementation
+ * ******************************************************************/
+package org.aspectj.weaver.tools;
+
+/**
+ * @author colyer
+ *
+ */
+public class UnsupportedPointcutPrimitiveException extends RuntimeException {
+
+ private static final long serialVersionUID = 3258689888517043251L;
+
+ private PointcutPrimitive unsupportedPrimitive;
+ private String pointcutExpression;
+
+ public UnsupportedPointcutPrimitiveException(String pcExpression, PointcutPrimitive primitive) {
+ super("Pointcut expression " + pcExpression + " contains unsupported pointcut primitive '" +
+ primitive.getName() + "'");
+ this.pointcutExpression = pcExpression;
+ this.unsupportedPrimitive = primitive;
+ }
+
+ /**
+ * @return Returns the unsupportedPrimitive.
+ */
+ public PointcutPrimitive getUnsupportedPrimitive() {
+ return unsupportedPrimitive;
+ }
+
+ public String getInvalidPointcutExpression() {
+ return pointcutExpression;
+ }
+
+}
import org.aspectj.weaver.BcweaverTests;
import org.aspectj.weaver.Shadow;
+import org.aspectj.weaver.TypeX;
import org.aspectj.weaver.World;
import org.aspectj.weaver.bcel.BcelShadow;
import org.aspectj.weaver.bcel.BcelWorld;
+import sun.reflect.generics.tree.TypeVariableSignature;
+
/**
* @author hugunin
*
assertEquals("@args(Foo, Goo, ANY, .., Moo)",p.toString());
}
+ public void testParseSimpleTypeVariable() {
+ PatternParser parser = new PatternParser("T");
+ TypeVariable tv = parser.parseTypeVariable();
+ TypeVariable expected = new TypeVariable("T");
+ assertEquals("Expected simple type variable T",expected,tv);
+ }
+
+ public void testParseExtendingTypeVariable() {
+ PatternParser parser = new PatternParser("T extends Number");
+ TypeVariable tv = parser.parseTypeVariable();
+ TypeVariable expected = new TypeVariable("T",new PatternParser("Number").parseTypePattern());
+ assertEquals("Expected type variable T extends Number",expected,tv);
+ }
+
+ public void testParseExtendingTypeVariableWithPattern() {
+ PatternParser parser = new PatternParser("T extends Number+");
+ TypeVariable tv = parser.parseTypeVariable();
+ TypeVariable expected = new TypeVariable("T",new PatternParser("Number+").parseTypePattern());
+ assertEquals("Expected type variable T extends Number+",expected,tv);
+ }
+
+ public void testParseExtendingTypeVariableWithInterface() {
+ PatternParser parser = new PatternParser("T extends Number & Comparable");
+ TypeVariable tv = parser.parseTypeVariable();
+ TypeVariable expected = new TypeVariable("T",new PatternParser("Number").parseTypePattern(),
+ new TypePattern[] {new PatternParser("Comparable").parseTypePattern()},null);
+ assertEquals("Expected type variable T extends Number",expected,tv);
+ }
+
+ public void testParseExtendingTypeVariableWithInterfaceList() {
+ PatternParser parser = new PatternParser("T extends Number & Comparable & Cloneable");
+ TypeVariable tv = parser.parseTypeVariable();
+ TypeVariable expected = new TypeVariable("T",new PatternParser("Number").parseTypePattern(),
+ new TypePattern[] {new PatternParser("Comparable").parseTypePattern(),
+ new PatternParser("Cloneable").parseTypePattern()},null);
+ assertEquals("Expected type variable T extends Number",expected,tv);
+ }
+
+ public void testParseTypeParameterList() {
+ PatternParser parser = new PatternParser("<T>");
+ TypeVariablePatternList list = parser.maybeParseTypeVariableList();
+ TypeVariable[] patterns = list.getTypeVariablePatterns();
+ TypeVariable expected = new TypeVariable("T");
+ assertEquals("Expected simple type variable T",expected,patterns[0]);
+ assertEquals("One pattern in list",1,patterns.length);
+ }
+
+ public void testParseTypeParameterListWithSeveralTypeParameters() {
+ PatternParser parser = new PatternParser("<T,S extends Number, R>");
+ TypeVariablePatternList list = parser.maybeParseTypeVariableList();
+ TypeVariable[] patterns = list.getTypeVariablePatterns();
+ TypeVariable expected0 = new TypeVariable("T");
+ assertEquals("Expected simple type variable T",expected0,patterns[0]);
+ TypeVariable expected1 = new TypeVariable("S",new PatternParser("Number").parseTypePattern());
+ assertEquals("Expected type variable S extends Number",expected1,patterns[1]);
+ TypeVariable expected2 = new TypeVariable("R");
+ assertEquals("Expected simple type variable R",expected2,patterns[2]);
+
+ assertEquals("3 patterns in list",3,patterns.length);
+ }
+
+
+ public void testParseAllowedSuperInTypeVariable() {
+ PatternParser parser = new PatternParser("T super Number+");
+ TypeVariable tv = parser.parseTypeVariable();
+ TypeVariable expected = new TypeVariable("T",new ExactTypePattern(TypeX.OBJECT,false,false),null,new PatternParser("Number+").parseTypePattern());
+ assertEquals("Expected type variable T super Number+",expected,tv);
+ }
+
+ public void testParseAnythingTypeVariable() {
+ PatternParser parser = new PatternParser("?");
+ WildTypePattern tp = (WildTypePattern) parser.parseTypePattern(true,false);
+ assertEquals("Expected type variable ?","?",tp.maybeGetSimpleName());
+ }
+
+ public void testParseAnythingExtendsTypeVariable() {
+ PatternParser parser = new PatternParser("? extends Number");
+ WildTypePattern tp = (WildTypePattern) parser.parseTypePattern(true,false);
+ assertEquals("Expected type variable ?","?",tp.maybeGetSimpleName());
+ assertEquals("upper Bound of Number",new PatternParser("Number").parseTypePattern(),tp.getUpperBound());
+ }
+
+ public void testParseAnythingSuperTypeVariable() {
+ PatternParser parser = new PatternParser("? super Number+");
+ WildTypePattern tp = (WildTypePattern) parser.parseTypePattern(true,false);
+ assertEquals("Expected type variable ?","?",tp.maybeGetSimpleName());
+ assertEquals("lower Bound of Number+",new PatternParser("Number+").parseTypePattern(),tp.getLowerBound());
+ }
+
+ public void testParseDeclareParentsWithTypeParameterList() {
+ PatternParser parser = new PatternParser("declare parents : <T> Foo<T> implements IveGoneMad");
+ DeclareParents decp = (DeclareParents) parser.parseDeclare();
+ TypeVariablePatternList tvp = decp.getTypeParameters();
+ assertEquals("one type parameter",1,tvp.getTypeVariablePatterns().length);
+ assertEquals("expecting T","T",tvp.getTypeVariablePatterns()[0].getName());
+ }
+
+ public void testParameterizedTypePatternsAny() {
+ PatternParser parser = new PatternParser("*<T,S extends Number>");
+ WildTypePattern wtp = (WildTypePattern) parser.parseTypePattern(false,true);
+ TypePatternList tvs = wtp.getTypeParameters();
+ assertEquals("2 type parameters",2,tvs.getTypePatterns().length);
+ assertEquals("T",new PatternParser("T").parseTypePattern(),tvs.getTypePatterns()[0]);
+ assertEquals("S extends Number",new PatternParser("S extends Number").parseTypePattern(false,true),tvs.getTypePatterns()[1]);
+ }
+
+ public void testParameterizedTypePatternsSimple() {
+ PatternParser parser = new PatternParser("List<String>");
+ WildTypePattern wtp = (WildTypePattern) parser.parseTypePattern();
+ TypePatternList tvs = wtp.getTypeParameters();
+ assertEquals("1 type parameter",1,tvs.getTypePatterns().length);
+ assertEquals("String",new PatternParser("String").parseTypePattern(),tvs.getTypePatterns()[0]);
+ assertEquals("List",wtp.getNamePatterns()[0].toString());
+ }
+
+ public void testNestedParameterizedTypePatterns() {
+ PatternParser parser = new PatternParser("List<List<List<String>>>");
+ WildTypePattern wtp = (WildTypePattern) parser.parseTypePattern();
+ TypePatternList typeParameters = wtp.getTypeParameters();
+ WildTypePattern expected = (WildTypePattern) typeParameters.getTypePatterns()[0];
+ assertEquals("expecting a List", "List",expected.maybeGetSimpleName());
+ typeParameters = expected.getTypeParameters();
+ expected = (WildTypePattern) typeParameters.getTypePatterns()[0];
+ assertEquals("expecting a List", "List",expected.maybeGetSimpleName());
+ typeParameters = expected.getTypeParameters();
+ expected = (WildTypePattern) typeParameters.getTypePatterns()[0];
+ assertEquals("expecting a String", "String",expected.maybeGetSimpleName());
+ }
+
+ public void testSimpleTypeVariableList() {
+ PatternParser parser = new PatternParser("<T,S,V>");
+ TypeVariablePatternList tl = parser.maybeParseSimpleTypeVariableList();
+ TypeVariable[] patterns = tl.getTypeVariablePatterns();
+ assertEquals("3 patterns",3,patterns.length);
+ assertEquals("T",new TypeVariable("T"),patterns[0]);
+ assertEquals("S",new TypeVariable("S"),patterns[1]);
+ assertEquals("V",new TypeVariable("V"),patterns[2]);
+ }
+
+ public void testSimpleTypeVariableListError() {
+ PatternParser parser = new PatternParser("<T extends Number>");
+ try {
+ TypeVariablePatternList tl = parser.maybeParseSimpleTypeVariableList();
+ } catch (ParserException ex) {
+ assertEquals("Expecting >",">",ex.getMessage());
+ }
+ }
+
public TestScope makeSimpleScope() {
TestScope s = new TestScope(new String[] {"int", "java.lang.String"}, new String[] {"a", "b"}, world);
s.setImportedPrefixes(new String[]{"p."});
public void testMatchJP() {
Pointcut p = new Pointcut() {
+ public Object accept(PatternNodeVisitor visitor, Object data) {
+ return visitor.visit(this,data);
+ }
+
public Set couldMatchKinds() {
return null;
}
public FuzzyBoolean fastMatch(FastMatchInfo info) {
return null;
}
+
+ public FuzzyBoolean fastMatch(Class targetClass) {
+ return null;
+ }
protected FuzzyBoolean matchInternal(Shadow shadow) {
return null;
for (Iterator iterator = pointcuts.iterator(); iterator.hasNext();) {
String pointcut = (String) iterator.next();
try {
- PointcutVisitor.DumpPointcutVisitor.check(pointcut);
+ PatternNodeVisitor.DumpPointcutVisitor.check(pointcut);
} catch (Throwable t) {
t.printStackTrace();
fail("Failed on '"+pointcut+"': " +t.toString());
String tp = (String) iterator.next();
try {
TypePattern p = new PatternParser(tp).parseTypePattern();
- PointcutVisitor.DumpPointcutVisitor.check(p, true);
+ PatternNodeVisitor.DumpPointcutVisitor.check(p, true);
} catch (Throwable t) {
fail("Failed on '"+tp+"': " +t.toString());
}
PointcutExpression ex = p.parsePointcutExpression("staticinitialization(*..A+)");
assertEquals("staticinitialization(*..A+)",ex.getPointcutExpression());
}
+
+ public void testCouldMatchJoinPointsInType() {
+ PointcutExpression ex = p.parsePointcutExpression("execution(* org.aspectj.weaver.tools.PointcutExpressionTest.B.*(..))");
+ assertFalse("Could never match String",ex.couldMatchJoinPointsInType(String.class));
+ assertTrue("Will always match B",ex.couldMatchJoinPointsInType(B.class));
+ assertFalse("Does not match A",ex.couldMatchJoinPointsInType(A.class));
+ }
+
+ public void testMayNeedDynamicTest() {
+ PointcutExpression ex = p.parsePointcutExpression("execution(* org.aspectj.weaver.tools.PointcutExpressionTest.B.*(..))");
+ assertFalse("No dynamic test needed",ex.mayNeedDynamicTest());
+ ex = p.parsePointcutExpression("execution(* org.aspectj.weaver.tools.PointcutExpressionTest.B.*(..)) && args(X)");
+ assertTrue("Dynamic test needed",ex.mayNeedDynamicTest());
+ }
protected void setUp() throws Exception {
super.setUp();