aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoracolyer <acolyer>2004-12-02 15:00:18 +0000
committeracolyer <acolyer>2004-12-02 15:00:18 +0000
commitc6f7ba2782307c17dcf4cf9aabc3770cae09a3a2 (patch)
treed510cad97bd56a384c3bd7427cd0ab7d4f721d89
parent09ba8cb317e7273a0f8dbb3323ba85b2414f702c (diff)
downloadaspectj-c6f7ba2782307c17dcf4cf9aabc3770cae09a3a2.tar.gz
aspectj-c6f7ba2782307c17dcf4cf9aabc3770cae09a3a2.zip
support for 3rd party integration with pointcut parsing /matching
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/NotPointcut.java1
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/Pointcut.java4
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java2
-rw-r--r--weaver/src/org/aspectj/weaver/tools/PointcutParser.java172
4 files changed, 179 insertions, 0 deletions
diff --git a/weaver/src/org/aspectj/weaver/patterns/NotPointcut.java b/weaver/src/org/aspectj/weaver/patterns/NotPointcut.java
index 292bf92ee..6bf9c9d73 100644
--- a/weaver/src/org/aspectj/weaver/patterns/NotPointcut.java
+++ b/weaver/src/org/aspectj/weaver/patterns/NotPointcut.java
@@ -38,6 +38,7 @@ public class NotPointcut extends Pointcut {
setLocation(pointcut.getSourceContext(), startPos, pointcut.getEnd());
}
+ public Pointcut getNegatedPointcut() { return body; }
public FuzzyBoolean fastMatch(FastMatchInfo type) {
return body.fastMatch(type).not();
diff --git a/weaver/src/org/aspectj/weaver/patterns/Pointcut.java b/weaver/src/org/aspectj/weaver/patterns/Pointcut.java
index b7ebca222..2c42179bc 100644
--- a/weaver/src/org/aspectj/weaver/patterns/Pointcut.java
+++ b/weaver/src/org/aspectj/weaver/patterns/Pointcut.java
@@ -52,6 +52,7 @@ public abstract class Pointcut extends PatternNode implements PointcutExpression
public static final State RESOLVED = new State("resolved", 1);
public static final State CONCRETE = new State("concrete", 2);
+ private byte pointcutKind;
public State state;
@@ -126,6 +127,7 @@ public abstract class Pointcut extends PatternNode implements PointcutExpression
public static final byte NONE = 20;
+ public byte getPointcutKind() { return pointcutKind; }
// internal, only called from resolve
protected abstract void resolveBindings(IScope scope, Bindings bindings);
@@ -245,7 +247,9 @@ public abstract class Pointcut extends PatternNode implements PointcutExpression
throw new BCException("unknown kind: " + kind);
}
ret.state = RESOLVED;
+ ret.pointcutKind = kind;
return ret;
+
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java b/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java
index f1592f161..c7784e2b3 100644
--- a/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java
+++ b/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java
@@ -56,6 +56,8 @@ public class ThisOrTargetPointcut extends NameBindingPointcut {
this.type = type;
}
+ public boolean isThis() { return isThis; }
+
public FuzzyBoolean fastMatch(FastMatchInfo type) {
return FuzzyBoolean.MAYBE;
}
diff --git a/weaver/src/org/aspectj/weaver/tools/PointcutParser.java b/weaver/src/org/aspectj/weaver/tools/PointcutParser.java
new file mode 100644
index 000000000..87a50e80c
--- /dev/null
+++ b/weaver/src/org/aspectj/weaver/tools/PointcutParser.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.aspectj.weaver.tools;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.aspectj.weaver.internal.tools.PointcutExpressionImpl;
+import org.aspectj.weaver.patterns.AndPointcut;
+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.Pointcut;
+import org.aspectj.weaver.patterns.ThisOrTargetPointcut;
+
+/**
+ * A PointcutParser can be used to build PointcutExpressions for a
+ * user-defined subset of AspectJ's pointcut language
+ */
+public class PointcutParser {
+
+ private Set supportedPrimitives;
+
+ /**
+ * @return a Set containing every PointcutPrimitive except
+ * if, cflow, and cflowbelow (useful for passing to
+ * PointcutParser constructor).
+ */
+ public static Set getAllSupportedPointcutPrimitives() {
+ Set primitives = new HashSet();
+ primitives.add(PointcutPrimitives.ADVICE_EXECUTION);
+ primitives.add(PointcutPrimitives.ARGS);
+ primitives.add(PointcutPrimitives.CALL);
+ primitives.add(PointcutPrimitives.EXECUTION);
+ primitives.add(PointcutPrimitives.GET);
+ primitives.add(PointcutPrimitives.HANDLER);
+ primitives.add(PointcutPrimitives.INITIALIZATION);
+ primitives.add(PointcutPrimitives.PRE_INITIALIZATION);
+ primitives.add(PointcutPrimitives.SET);
+ primitives.add(PointcutPrimitives.STATIC_INITIALIZATION);
+ primitives.add(PointcutPrimitives.TARGET);
+ primitives.add(PointcutPrimitives.THIS);
+ primitives.add(PointcutPrimitives.WITHIN);
+ primitives.add(PointcutPrimitives.WITHIN_CODE);
+ return primitives;
+ }
+
+ /**
+ * Create a pointcut parser that can parse the full AspectJ pointcut
+ * language with the following exceptions:
+ * <ul>
+ * <li>The <code>if, cflow, and cflowbelow</code> pointcut designators are not supported
+ * <li>Pointcut expressions must be self-contained :- they cannot contain references
+ * to other named pointcuts
+ * <li>The pointcut expression must be anonymous with no formals allowed.
+ * </ul>
+ */
+ public PointcutParser() {
+ supportedPrimitives = getAllSupportedPointcutPrimitives();
+ }
+
+ /**
+ * Create a pointcut parser that can parse pointcut expressions built
+ * from a user-defined subset of AspectJ's supported pointcut primitives.
+ * The following restrictions apply:
+ * <ul>
+ * <li>The <code>if, cflow, and cflowbelow</code> pointcut designators are not supported
+ * <li>Pointcut expressions must be self-contained :- they cannot contain references
+ * to other named pointcuts
+ * <li>The pointcut expression must be anonymous with no formals allowed.
+ * </ul>
+ * @param supportedPointcutKinds a set of PointcutPrimitives this parser
+ * should support
+ * @throws UnsupportedOperationException if the set contains if, cflow, or
+ * cflow below
+ */
+ public PointcutParser(Set/*<PointcutPrimitives>*/ supportedPointcutKinds) {
+ supportedPrimitives = supportedPointcutKinds;
+ for (Iterator iter = supportedPointcutKinds.iterator(); iter.hasNext();) {
+ PointcutPrimitives element = (PointcutPrimitives) iter.next();
+ if ((element == PointcutPrimitives.IF) ||
+ (element == PointcutPrimitives.CFLOW) ||
+ (element == PointcutPrimitives.CFLOW_BELOW)) {
+ throw new UnsupportedOperationException("Cannot handle if, cflow, and cflowbelow primitives");
+ }
+ }
+ }
+
+
+ /**
+ * Parse the given pointcut expression.
+ * @throws UnsupportedOperationException if the parser encounters a
+ * primitive pointcut expression of a kind not supported by this PointcutParser.
+ * @throws IllegalArgumentException if the expression is not a well-formed
+ * pointcut expression
+ */
+ public PointcutExpression parsePointcutExpression(String expression)
+ throws UnsupportedOperationException, IllegalArgumentException {
+ PointcutExpressionImpl pcExpr = null;
+ try {
+ Pointcut pc = new PatternParser(expression).parsePointcut();
+ validateAgainstSupportedPrimitives(pc);
+ pcExpr = new PointcutExpressionImpl(pc);
+ } catch (ParserException pEx) {
+ throw new IllegalArgumentException(pEx.getMessage());
+ }
+ return pcExpr;
+ }
+
+ private void validateAgainstSupportedPrimitives(Pointcut pc) {
+ switch(pc.getPointcutKind()) {
+ case Pointcut.AND:
+ validateAgainstSupportedPrimitives(((AndPointcut)pc).getLeft());
+ validateAgainstSupportedPrimitives(((AndPointcut)pc).getRight());
+ break;
+ case Pointcut.ARGS:
+ if (!supportedPrimitives.contains(PointcutPrimitives.ARGS))
+ throw new UnsupportedOperationException("args is not supported by this parser");
+ break;
+ case Pointcut.CFLOW:
+ throw new UnsupportedOperationException("cflow and cflowbelow are not supported by this parser");
+ case Pointcut.HANDLER:
+ if (!supportedPrimitives.contains(PointcutPrimitives.HANDLER))
+ throw new UnsupportedOperationException("handler is not supported by this parser");
+ break;
+ case Pointcut.IF:
+ case Pointcut.IF_FALSE:
+ case Pointcut.IF_TRUE:
+ throw new UnsupportedOperationException("if is not supported by this parser");
+ case Pointcut.KINDED:
+ break;
+ case Pointcut.NOT:
+ validateAgainstSupportedPrimitives(((NotPointcut)pc).getNegatedPointcut());
+ break;
+ case Pointcut.OR:
+ validateAgainstSupportedPrimitives(((OrPointcut)pc).getLeft());
+ validateAgainstSupportedPrimitives(((OrPointcut)pc).getRight());
+ break;
+ case Pointcut.REFERENCE:
+ throw new UnsupportedOperationException("reference pointcuts are not supported by this parser");
+ case Pointcut.THIS_OR_TARGET:
+ boolean isThis = ((ThisOrTargetPointcut)pc).isThis();
+ if (isThis && !supportedPrimitives.contains(PointcutPrimitives.THIS)) {
+ throw new UnsupportedOperationException("this is not supported by this parser");
+ } else if (!supportedPrimitives.contains(PointcutPrimitives.TARGET)) {
+ throw new UnsupportedOperationException("target is not supported by this parser");
+ }
+ break;
+ case Pointcut.WITHIN:
+ if (!supportedPrimitives.contains(PointcutPrimitives.WITHIN))
+ throw new UnsupportedOperationException("within is not supported by this parser");
+ break;
+ case Pointcut.WITHINCODE:
+ if (!supportedPrimitives.contains(PointcutPrimitives.WITHIN_CODE))
+ throw new UnsupportedOperationException("withincode is not supported by this parser");
+ break;
+ case Pointcut.NONE: // deliberate fall-through
+ default:
+ throw new UnsupportedOperationException("Unknown pointcut kind: " + pc.getPointcutKind());
+ }
+ }
+}