summaryrefslogtreecommitdiffstats
path: root/weaver/src
diff options
context:
space:
mode:
authoracolyer <acolyer>2004-06-08 15:04:34 +0000
committeracolyer <acolyer>2004-06-08 15:04:34 +0000
commitcc06e1423e24c178b809cdc62ec3a73dd41bdfb2 (patch)
tree1943c00cbc162822c81fa519411242dbd55ed15c /weaver/src
parent33ae558f9a81b8a059a4f909b8c630bd6d8390ab (diff)
downloadaspectj-cc06e1423e24c178b809cdc62ec3a73dd41bdfb2.tar.gz
aspectj-cc06e1423e24c178b809cdc62ec3a73dd41bdfb2.zip
added a method to all Pointcuts that matches against a
JoinPoint (as opposed to a Shadow).
Diffstat (limited to 'weaver/src')
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/AndPointcut.java16
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/AndTypePattern.java22
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java14
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java6
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/ConcreteCflowPointcut.java3
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java24
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/HandlerPointcut.java18
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/IfPointcut.java2
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java15
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/NotPointcut.java13
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/NotTypePattern.java20
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/OrPointcut.java14
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/OrTypePattern.java20
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/PerCflow.java2
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/PerClause.java6
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/Pointcut.java37
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java4
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java123
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java11
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/ThrowsPattern.java32
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/TypePattern.java88
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/TypePatternList.java214
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java66
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/WithinPointcut.java20
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java9
25 files changed, 790 insertions, 9 deletions
diff --git a/weaver/src/org/aspectj/weaver/patterns/AndPointcut.java b/weaver/src/org/aspectj/weaver/patterns/AndPointcut.java
index aea40a3e3..05952f593 100644
--- a/weaver/src/org/aspectj/weaver/patterns/AndPointcut.java
+++ b/weaver/src/org/aspectj/weaver/patterns/AndPointcut.java
@@ -17,6 +17,7 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import org.aspectj.lang.JoinPoint;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.IntMap;
@@ -42,6 +43,14 @@ public class AndPointcut extends Pointcut {
return left.match(shadow).and(right.match(shadow));
}
+ public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJP) {
+ return left.match(jp,encJP).and(right.match(jp,encJP));
+ }
+
+ public FuzzyBoolean match(JoinPoint.StaticPart jpsp) {
+ return left.match(jpsp).and(right.match(jpsp));
+ }
+
public String toString() {
return "(" + left.toString() + " && " + right.toString() + ")";
}
@@ -63,8 +72,11 @@ public class AndPointcut extends Pointcut {
left.resolveBindings(scope, bindings);
right.resolveBindings(scope, bindings);
}
-
-
+
+ public void resolveBindingsFromRTTI() {
+ left.resolveBindingsFromRTTI();
+ right.resolveBindingsFromRTTI();
+ }
public void write(DataOutputStream s) throws IOException {
s.writeByte(Pointcut.AND);
diff --git a/weaver/src/org/aspectj/weaver/patterns/AndTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/AndTypePattern.java
index 468e95ab2..c055692fe 100644
--- a/weaver/src/org/aspectj/weaver/patterns/AndTypePattern.java
+++ b/weaver/src/org/aspectj/weaver/patterns/AndTypePattern.java
@@ -48,10 +48,23 @@ public class AndTypePattern extends TypePattern {
return left.matchesExactly(type) && right.matchesExactly(type);
}
- public boolean matchesStatically(ResolvedTypeX type) {
+ public boolean matchesStatically(Class type) {
return left.matchesStatically(type) && right.matchesStatically(type);
}
+ public FuzzyBoolean matchesInstanceof(Class type) {
+ return left.matchesInstanceof(type).and(right.matchesInstanceof(type));
+ }
+
+ protected boolean matchesExactly(Class type) {
+ //??? if these had side-effects, this sort-circuit could be a mistake
+ return left.matchesExactly(type) && right.matchesExactly(type);
+ }
+
+ public boolean matchesStatically(ResolvedTypeX type) {
+ return left.matchesStatically(type) && right.matchesStatically(type);
+ }
+
public void write(DataOutputStream s) throws IOException {
s.writeByte(TypePattern.AND);
left.write(s);
@@ -76,6 +89,13 @@ public class AndTypePattern extends TypePattern {
return this;
}
+ public TypePattern resolveBindingsFromRTTI(boolean allowBinding, boolean requireExactType) {
+ if (requireExactType) return TypePattern.NO;
+ left = left.resolveBindingsFromRTTI(allowBinding,requireExactType);
+ right = right.resolveBindingsFromRTTI(allowBinding,requireExactType);
+ return this;
+ }
+
public String toString() {
return "(" + left.toString() + " && " + right.toString() + ")";
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java b/weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java
index a8c6b0bb3..efc1219c0 100644
--- a/weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java
+++ b/weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java
@@ -20,6 +20,7 @@ import java.io.IOException;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.Message;
+import org.aspectj.lang.JoinPoint;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.BetaException;
import org.aspectj.weaver.ISourceContext;
@@ -36,7 +37,7 @@ import org.aspectj.weaver.ast.Test;
* @author Erik Hilsdale
* @author Jim Hugunin
*/
-public class ArgsPointcut extends NameBindingPointcut {
+public class ArgsPointcut extends NameBindingPointcut {
TypePatternList arguments;
public ArgsPointcut(TypePatternList arguments) {
@@ -52,6 +53,10 @@ public class ArgsPointcut extends NameBindingPointcut {
arguments.matches(shadow.getIWorld().resolve(shadow.getArgTypes()), TypePattern.DYNAMIC);
return ret;
}
+
+ public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart jpsp) {
+ return arguments.matches(jp.getArgs(),TypePattern.DYNAMIC);
+ }
public void write(DataOutputStream s) throws IOException {
s.writeByte(Pointcut.ARGS);
@@ -84,6 +89,13 @@ public class ArgsPointcut extends NameBindingPointcut {
}
}
+ public void resolveBindingsFromRTTI() {
+ arguments.resolveBindingsFromRTTI(true, true);
+ if (arguments.ellipsisCount > 1) {
+ throw new UnsupportedOperationException("uses more than one .. in args (compiler limitation)");
+ }
+ }
+
public void postRead(ResolvedTypeX enclosingType) {
arguments.postRead(enclosingType);
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java b/weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java
index ef6dc5d80..3a00891b1 100644
--- a/weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java
+++ b/weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java
@@ -101,6 +101,12 @@ public class CflowPointcut extends Pointcut {
}
}
+ public void resolveBindingsFromRTTI() {
+ if (entry.state != RESOLVED) {
+ entry.resolveBindingsFromRTTI();
+ }
+ }
+
public boolean equals(Object other) {
if (!(other instanceof CflowPointcut)) return false;
CflowPointcut o = (CflowPointcut)other;
diff --git a/weaver/src/org/aspectj/weaver/patterns/ConcreteCflowPointcut.java b/weaver/src/org/aspectj/weaver/patterns/ConcreteCflowPointcut.java
index cbb65f37e..df2c76bba 100644
--- a/weaver/src/org/aspectj/weaver/patterns/ConcreteCflowPointcut.java
+++ b/weaver/src/org/aspectj/weaver/patterns/ConcreteCflowPointcut.java
@@ -58,6 +58,9 @@ public class ConcreteCflowPointcut extends Pointcut {
throw new RuntimeException("unimplemented");
}
+ public void resolveBindingsFromRTTI() {
+ throw new RuntimeException("unimplemented");
+ }
public boolean equals(Object other) {
if (!(other instanceof ConcreteCflowPointcut)) return false;
diff --git a/weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java
index 1da25d363..99ecf9012 100644
--- a/weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java
+++ b/weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java
@@ -48,6 +48,26 @@ public class ExactTypePattern extends TypePattern {
return matchType.isCoerceableFrom(type) ? FuzzyBoolean.MAYBE : FuzzyBoolean.NO;
}
+ public boolean matchesExactly(Class matchType) {
+ try {
+ Class toMatchAgainst = Class.forName(type.getName());
+ return matchType == toMatchAgainst;
+ } catch (ClassNotFoundException cnfEx) {
+ return false;
+ }
+ }
+
+ public FuzzyBoolean matchesInstanceof(Class matchType) {
+ if (matchType.equals(Object.class)) return FuzzyBoolean.YES;
+
+ try {
+ Class toMatchAgainst = Class.forName(type.getName());
+ return toMatchAgainst.isAssignableFrom(matchType) ? FuzzyBoolean.YES : FuzzyBoolean.NO;
+ } catch (ClassNotFoundException cnfEx) {
+ return FuzzyBoolean.NO;
+ }
+ }
+
public boolean equals(Object other) {
if (!(other instanceof ExactTypePattern)) return false;
ExactTypePattern o = (ExactTypePattern)other;
@@ -81,5 +101,9 @@ public class ExactTypePattern extends TypePattern {
throw new BCException("trying to re-resolve");
}
+
+ public TypePattern resolveBindingsFromRTTI(boolean allowBinding, boolean requireExactType) {
+ throw new IllegalStateException("trying to re-resolve");
+ }
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/HandlerPointcut.java b/weaver/src/org/aspectj/weaver/patterns/HandlerPointcut.java
index aa50bd7b6..c1fcfdbd3 100644
--- a/weaver/src/org/aspectj/weaver/patterns/HandlerPointcut.java
+++ b/weaver/src/org/aspectj/weaver/patterns/HandlerPointcut.java
@@ -17,6 +17,7 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import org.aspectj.lang.JoinPoint;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.IntMap;
@@ -52,6 +53,18 @@ public class HandlerPointcut extends Pointcut {
TypePattern.STATIC);
}
+ public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart jpsp) {
+ if (!jp.getKind().equals(JoinPoint.EXCEPTION_HANDLER)) return FuzzyBoolean.NO;
+ if (jp.getArgs().length > 0) {
+ Object caughtException = jp.getArgs()[0];
+ return exceptionType.matches(caughtException,TypePattern.STATIC);
+ } else {
+ return FuzzyBoolean.NO;
+ }
+ }
+
+
+
public boolean equals(Object other) {
if (!(other instanceof HandlerPointcut)) return false;
HandlerPointcut o = (HandlerPointcut)other;
@@ -92,6 +105,11 @@ public class HandlerPointcut extends Pointcut {
exceptionType = exceptionType.resolveBindings(scope, bindings, false, false);
//XXX add error if exact binding and not an exception
}
+
+ public void resolveBindingsFromRTTI() {
+ exceptionType = exceptionType.resolveBindingsFromRTTI(false,false);
+ }
+
public Test findResidue(Shadow shadow, ExposedState state) {
return match(shadow).alwaysTrue() ? Literal.TRUE : Literal.FALSE;
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/IfPointcut.java b/weaver/src/org/aspectj/weaver/patterns/IfPointcut.java
index a534f68d4..e770509b3 100644
--- a/weaver/src/org/aspectj/weaver/patterns/IfPointcut.java
+++ b/weaver/src/org/aspectj/weaver/patterns/IfPointcut.java
@@ -75,6 +75,8 @@ public class IfPointcut extends Pointcut {
//??? all we need is good error messages in here in cflow contexts
}
+ public void resolveBindingsFromRTTI() {}
+
public boolean equals(Object other) {
if (!(other instanceof IfPointcut)) return false;
IfPointcut o = (IfPointcut)other;
diff --git a/weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java b/weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java
index 202c4ead7..6154f07d8 100644
--- a/weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java
+++ b/weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java
@@ -18,6 +18,7 @@ import java.io.DataOutputStream;
import java.io.IOException;
import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.lang.JoinPoint;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.Checker;
import org.aspectj.weaver.ISourceContext;
@@ -73,6 +74,15 @@ public class KindedPointcut extends Pointcut {
return FuzzyBoolean.YES;
}
+ public FuzzyBoolean match(JoinPoint.StaticPart jpsp) {
+ if (jpsp.getKind().equals(kind.getName())) {
+ if (signature.matches(jpsp)) {
+ return FuzzyBoolean.YES;
+ }
+ }
+ return FuzzyBoolean.NO;
+ }
+
private void warnOnConfusingSig(Shadow shadow) {
// no warnings for declare error/warning
if (munger instanceof Checker) return;
@@ -196,6 +206,11 @@ public class KindedPointcut extends Pointcut {
}
}
}
+
+ public void resolveBindingsFromRTTI() {
+ signature = signature.resolveBindingsFromRTTI();
+ }
+
public Test findResidue(Shadow shadow, ExposedState state) {
return match(shadow).alwaysTrue() ? Literal.TRUE : Literal.FALSE;
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/NotPointcut.java b/weaver/src/org/aspectj/weaver/patterns/NotPointcut.java
index 59fe2522a..f57d2475d 100644
--- a/weaver/src/org/aspectj/weaver/patterns/NotPointcut.java
+++ b/weaver/src/org/aspectj/weaver/patterns/NotPointcut.java
@@ -17,6 +17,7 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import org.aspectj.lang.JoinPoint;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.IntMap;
@@ -44,6 +45,14 @@ public class NotPointcut extends Pointcut {
public FuzzyBoolean match(Shadow shadow) {
return body.match(shadow).not();
}
+
+ public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJP) {
+ return body.match(jp,encJP).not();
+ }
+
+ public FuzzyBoolean match(JoinPoint.StaticPart jpsp) {
+ return body.match(jpsp).not();
+ }
public String toString() {
return "!" + body.toString();
@@ -73,6 +82,10 @@ public class NotPointcut extends Pointcut {
}
+ public void resolveBindingsFromRTTI() {
+ body.resolveBindingsFromRTTI();
+ }
+
public void write(DataOutputStream s) throws IOException {
s.writeByte(Pointcut.NOT);
diff --git a/weaver/src/org/aspectj/weaver/patterns/NotTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/NotTypePattern.java
index 5a3ceacf9..68a719c73 100644
--- a/weaver/src/org/aspectj/weaver/patterns/NotTypePattern.java
+++ b/weaver/src/org/aspectj/weaver/patterns/NotTypePattern.java
@@ -47,10 +47,22 @@ public class NotTypePattern extends TypePattern {
return !pattern.matchesExactly(type);
}
- public boolean matchesStatically(ResolvedTypeX type) {
+ public boolean matchesStatically(Class type) {
return !pattern.matchesStatically(type);
}
+ public FuzzyBoolean matchesInstanceof(Class type) {
+ return pattern.matchesInstanceof(type).not();
+ }
+
+ protected boolean matchesExactly(Class type) {
+ return !pattern.matchesExactly(type);
+ }
+
+ public boolean matchesStatically(ResolvedTypeX type) {
+ return !pattern.matchesStatically(type);
+ }
+
public void write(DataOutputStream s) throws IOException {
s.writeByte(TypePattern.NOT);
pattern.write(s);
@@ -72,6 +84,12 @@ public class NotTypePattern extends TypePattern {
pattern = pattern.resolveBindings(scope, bindings, false, false);
return this;
}
+
+ public TypePattern resolveBindingsFromRTTI(boolean allowBinding, boolean requireExactType) {
+ if (requireExactType) return TypePattern.NO;
+ pattern = pattern.resolveBindingsFromRTTI(allowBinding,requireExactType);
+ return this;
+ }
public String toString() {
return "!" + pattern;
diff --git a/weaver/src/org/aspectj/weaver/patterns/OrPointcut.java b/weaver/src/org/aspectj/weaver/patterns/OrPointcut.java
index 1d1ce6298..225b100d7 100644
--- a/weaver/src/org/aspectj/weaver/patterns/OrPointcut.java
+++ b/weaver/src/org/aspectj/weaver/patterns/OrPointcut.java
@@ -17,6 +17,7 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import org.aspectj.lang.JoinPoint;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.IntMap;
@@ -43,6 +44,14 @@ public class OrPointcut extends Pointcut {
return left.match(shadow).or(right.match(shadow));
}
+ public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJP) {
+ return left.match(jp,encJP).or(right.match(jp,encJP));
+ }
+
+ public FuzzyBoolean match(JoinPoint.StaticPart jpsp) {
+ return left.match(jpsp).or(right.match(jpsp));
+ }
+
public String toString() {
return "(" + left.toString() + " || " + right.toString() + ")";
}
@@ -69,6 +78,11 @@ public class OrPointcut extends Pointcut {
if (bindings != null) bindings.checkEquals(old, scope);
}
+
+ public void resolveBindingsFromRTTI() {
+ left.resolveBindingsFromRTTI();
+ right.resolveBindingsFromRTTI();
+ }
public void write(DataOutputStream s) throws IOException {
s.writeByte(Pointcut.OR);
diff --git a/weaver/src/org/aspectj/weaver/patterns/OrTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/OrTypePattern.java
index 2900d4a2b..da53ad6e5 100644
--- a/weaver/src/org/aspectj/weaver/patterns/OrTypePattern.java
+++ b/weaver/src/org/aspectj/weaver/patterns/OrTypePattern.java
@@ -52,6 +52,19 @@ public class OrTypePattern extends TypePattern {
return left.matchesStatically(type) || right.matchesStatically(type);
}
+ public FuzzyBoolean matchesInstanceof(Class type) {
+ return left.matchesInstanceof(type).or(right.matchesInstanceof(type));
+ }
+
+ protected boolean matchesExactly(Class type) {
+ //??? if these had side-effects, this sort-circuit could be a mistake
+ return left.matchesExactly(type) || right.matchesExactly(type);
+ }
+
+ public boolean matchesStatically(Class type) {
+ return left.matchesStatically(type) || right.matchesStatically(type);
+ }
+
public void write(DataOutputStream s) throws IOException {
s.writeByte(TypePattern.OR);
left.write(s);
@@ -76,6 +89,13 @@ public class OrTypePattern extends TypePattern {
return this;
}
+ public TypePattern resolveBindingsFromRTTI(boolean allowBinding, boolean requireExactType) {
+ if (requireExactType) return TypePattern.NO;
+ left = left.resolveBindingsFromRTTI(allowBinding,requireExactType);
+ right = right.resolveBindingsFromRTTI(allowBinding,requireExactType);
+ return this;
+ }
+
public String toString() {
return "(" + left.toString() + " || " + right.toString() + ")";
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/PerCflow.java b/weaver/src/org/aspectj/weaver/patterns/PerCflow.java
index 1c511bb08..f0626758f 100644
--- a/weaver/src/org/aspectj/weaver/patterns/PerCflow.java
+++ b/weaver/src/org/aspectj/weaver/patterns/PerCflow.java
@@ -59,7 +59,7 @@ public class PerCflow extends PerClause {
// assert bindings == null;
entry.resolve(scope);
}
-
+
public Test findResidue(Shadow shadow, ExposedState state) {
Expr myInstance =
Expr.makeCallExpr(AjcMemberMaker.perCflowAspectOfMethod(inAspect),
diff --git a/weaver/src/org/aspectj/weaver/patterns/PerClause.java b/weaver/src/org/aspectj/weaver/patterns/PerClause.java
index b28e8fc24..632778c9e 100644
--- a/weaver/src/org/aspectj/weaver/patterns/PerClause.java
+++ b/weaver/src/org/aspectj/weaver/patterns/PerClause.java
@@ -54,7 +54,11 @@ public abstract class PerClause extends Pointcut {
throw new BCException("weird kind " + key);
}
}
-
+
+ public void resolveBindingsFromRTTI() {
+ throw new UnsupportedOperationException("Can't resolve per-clauses at runtime");
+ }
+
public static final Kind SINGLETON = new Kind("issingleton", 1);
public static final Kind PERCFLOW = new Kind("percflow", 2);
public static final Kind PEROBJECT = new Kind("perobject", 3);
diff --git a/weaver/src/org/aspectj/weaver/patterns/Pointcut.java b/weaver/src/org/aspectj/weaver/patterns/Pointcut.java
index c7c98b425..466363135 100644
--- a/weaver/src/org/aspectj/weaver/patterns/Pointcut.java
+++ b/weaver/src/org/aspectj/weaver/patterns/Pointcut.java
@@ -17,6 +17,7 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import org.aspectj.lang.JoinPoint;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.util.TypeSafeEnum;
import org.aspectj.weaver.Advice;
@@ -72,7 +73,23 @@ public abstract class Pointcut extends PatternNode {
* XXX implementors need to handle state
*/
public abstract FuzzyBoolean match(Shadow shadow);
+
+ /*
+ * for runtime / dynamic pointcuts.
+ * Default implementation delegates to StaticPart matcher
+ */
+ public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart enclosingJoinPoint) {
+ return match(jp.getStaticPart());
+ }
+ /*
+ * for runtime / dynamic pointcuts.
+ * Not all pointcuts can be matched at runtime, those that can should overide either
+ * match(JoinPoint), or this method, or both.
+ */
+ public FuzzyBoolean match(JoinPoint.StaticPart jpsp) {
+ throw new UnsupportedOperationException("Pointcut expression " + this.toString() + "cannot be matched at runtime");
+ }
public static final byte KINDED = 1;
public static final byte WITHIN = 2;
@@ -93,6 +110,9 @@ public abstract class Pointcut extends PatternNode {
// internal, only called from resolve
protected abstract void resolveBindings(IScope scope, Bindings bindings);
+ // internal, only called from resolve
+ protected abstract void resolveBindingsFromRTTI();
+
/**
* Returns this pointcut mutated
*/
@@ -104,6 +124,16 @@ public abstract class Pointcut extends PatternNode {
this.state = RESOLVED;
return this;
}
+
+ /**
+ * Returns this pointcut with type patterns etc resolved based on available RTTI
+ */
+ public Pointcut resolve() {
+ assertState(SYMBOLIC);
+ this.resolveBindingsFromRTTI();
+ this.state = RESOLVED;
+ return this;
+ }
/**
* Returns a new pointcut
@@ -218,9 +248,16 @@ public abstract class Pointcut extends PatternNode {
public FuzzyBoolean match(Shadow shadow) {
return FuzzyBoolean.NO;
}
+
+ public FuzzyBoolean match(JoinPoint.StaticPart jpsp) {
+ return FuzzyBoolean.NO;
+ }
public void resolveBindings(IScope scope, Bindings bindings) {
}
+
+ public void resolveBindingsFromRTTI() {
+ }
public void postRead(ResolvedTypeX enclosingType) {
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java b/weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java
index b253b4d18..af09bf906 100644
--- a/weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java
+++ b/weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java
@@ -199,6 +199,10 @@ public class ReferencePointcut extends Pointcut {
}
}
+ public void resolveBindingsFromRTTI() {
+ throw new UnsupportedOperationException("Referenced pointcuts are not supported in runtime evaluation");
+ }
+
public void postRead(ResolvedTypeX enclosingType) {
arguments.postRead(enclosingType);
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java b/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java
index 64a3f66b7..5e4e12185 100644
--- a/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java
+++ b/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java
@@ -16,9 +16,19 @@ package org.aspectj.weaver.patterns;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
+import java.util.List;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.Signature;
+import org.aspectj.lang.reflect.AdviceSignature;
+import org.aspectj.lang.reflect.ConstructorSignature;
+import org.aspectj.lang.reflect.FieldSignature;
+import org.aspectj.lang.reflect.MethodSignature;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.Member;
import org.aspectj.weaver.NameMangler;
@@ -68,6 +78,23 @@ public class SignaturePattern extends PatternNode {
return this;
}
+ public SignaturePattern resolveBindingsFromRTTI() {
+ if (returnType != null) {
+ returnType = returnType.resolveBindingsFromRTTI(false, false);
+ }
+ if (declaringType != null) {
+ declaringType = declaringType.resolveBindingsFromRTTI(false, false);
+ }
+ if (parameterTypes != null) {
+ parameterTypes = parameterTypes.resolveBindingsFromRTTI(false, false);
+ }
+ if (throwsPattern != null) {
+ throwsPattern = throwsPattern.resolveBindingsFromRTTI();
+ }
+
+ return this;
+ }
+
public void postRead(ResolvedTypeX enclosingType) {
if (returnType != null) {
@@ -134,6 +161,57 @@ public class SignaturePattern extends PatternNode {
return false;
}
+ // for dynamic join point matching
+ public boolean matches(JoinPoint.StaticPart jpsp) {
+ Signature sig = jpsp.getSignature();
+ if (kind == Member.ADVICE && !(sig instanceof AdviceSignature)) return false;
+ if (kind == Member.CONSTRUCTOR && !(sig instanceof ConstructorSignature)) return false;
+ if (kind == Member.FIELD && !(sig instanceof FieldSignature)) return false;
+ if (kind == Member.METHOD && !(sig instanceof MethodSignature)) return false;
+ if (kind == Member.STATIC_INITIALIZATION && !(jpsp.getKind().equals(JoinPoint.STATICINITIALIZATION))) return false;
+ if (kind == Member.POINTCUT) return false;
+
+ if (kind == Member.ADVICE) return true;
+
+ if (!modifiers.matches(sig.getModifiers())) return false;
+
+ if (kind == Member.STATIC_INITIALIZATION) {
+ //System.err.println("match static init: " + sig.getDeclaringType() + " with " + this);
+ return declaringType.matchesStatically(sig.getDeclaringType());
+ } else if (kind == Member.FIELD) {
+ Class returnTypeClass = ((FieldSignature)sig).getFieldType();
+ if (!returnType.matchesStatically(returnTypeClass)) return false;
+ if (!name.matches(sig.getName())) return false;
+ boolean ret = declaringTypeMatch(sig);
+ //System.out.println(" ret: " + ret);
+ return ret;
+ } else if (kind == Member.METHOD) {
+ MethodSignature msig = ((MethodSignature)sig);
+ Class returnTypeClass = msig.getReturnType();
+ Class[] params = msig.getParameterTypes();
+ Class[] exceptionTypes = msig.getExceptionTypes();
+ if (!returnType.matchesStatically(returnTypeClass)) return false;
+ if (!name.matches(sig.getName())) return false;
+ if (!parameterTypes.matches(params, TypePattern.STATIC).alwaysTrue()) {
+ return false;
+ }
+ if (!throwsPattern.matches(exceptionTypes)) return false;
+ return declaringTypeMatch(sig);
+ } else if (kind == Member.CONSTRUCTOR) {
+ ConstructorSignature csig = (ConstructorSignature)sig;
+ Class[] params = csig.getParameterTypes();
+ Class[] exceptionTypes = csig.getExceptionTypes();
+ if (!parameterTypes.matches(params, TypePattern.STATIC).alwaysTrue()) {
+ return false;
+ }
+ if (!throwsPattern.matches(exceptionTypes)) return false;
+ return declaringType.matchesStatically(sig.getDeclaringType());
+ //return declaringTypeMatch(member.getDeclaringType(), member, world);
+ }
+
+ return false;
+ }
+
private boolean declaringTypeMatch(TypeX onTypeUnresolved, Member member, World world) {
ResolvedTypeX onType = onTypeUnresolved.resolve(world);
@@ -149,7 +227,50 @@ public class SignaturePattern extends PatternNode {
return false;
}
-
+ private boolean declaringTypeMatch(Signature sig) {
+ Class onType = sig.getDeclaringType();
+ if (declaringType.matchesStatically(onType)) return true;
+
+ Collection declaringTypes = getDeclaringTypes(sig);
+
+ for (Iterator it = declaringTypes.iterator(); it.hasNext(); ) {
+ Class pClass = (Class) it.next();
+ if (declaringType.matchesStatically(pClass)) return true;
+ }
+
+ return false;
+ }
+
+ private Collection getDeclaringTypes(Signature sig) {
+ List l = new ArrayList();
+ Class onType = sig.getDeclaringType();
+ String memberName = sig.getName();
+ if (sig instanceof FieldSignature) {
+ Class fieldType = ((FieldSignature)sig).getFieldType();
+ Class superType = onType;
+ while(superType != null) {
+ try {
+ Field f = (superType.getDeclaredField(memberName));
+ if (f.getType() == fieldType) {
+ l.add(superType);
+ }
+ } catch (NoSuchFieldException nsf) {}
+ superType = superType.getSuperclass();
+ }
+ } else if (sig instanceof MethodSignature) {
+ Class[] paramTypes = ((MethodSignature)sig).getParameterTypes();
+ Class superType = onType;
+ while(superType != null) {
+ try {
+ Method m = (superType.getDeclaredMethod(memberName,paramTypes));
+ l.add(superType);
+ } catch (NoSuchMethodException nsm) {}
+ superType = superType.getSuperclass();
+ }
+ }
+ return l;
+ }
+
public NamePattern getName() { return name; }
public TypePattern getDeclaringType() { return declaringType; }
diff --git a/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java b/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java
index daca6f922..4e8c9fc72 100644
--- a/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java
+++ b/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java
@@ -18,6 +18,7 @@ import java.io.DataOutputStream;
import java.io.IOException;
import org.aspectj.bridge.IMessage;
+import org.aspectj.lang.JoinPoint;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.IntMap;
@@ -67,6 +68,12 @@ public class ThisOrTargetPointcut extends NameBindingPointcut {
return type.matches(typeToMatch.resolve(shadow.getIWorld()), TypePattern.DYNAMIC);
}
+ public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJP) {
+ Object toMatch = isThis ? jp.getThis() : jp.getTarget();
+ if (toMatch == null) return FuzzyBoolean.NO;
+ return type.matches(toMatch.getClass(), TypePattern.DYNAMIC);
+ }
+
public void write(DataOutputStream s) throws IOException {
s.writeByte(Pointcut.THIS_OR_TARGET);
s.writeBoolean(isThis);
@@ -87,6 +94,10 @@ public class ThisOrTargetPointcut extends NameBindingPointcut {
// ??? handle non-formal
}
+ public void resolveBindingsFromRTTI() {
+ type = type.resolveBindingsFromRTTI(true,true);
+ }
+
public void postRead(ResolvedTypeX enclosingType) {
type.postRead(enclosingType);
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/ThrowsPattern.java b/weaver/src/org/aspectj/weaver/patterns/ThrowsPattern.java
index 113b90000..dd95137ec 100644
--- a/weaver/src/org/aspectj/weaver/patterns/ThrowsPattern.java
+++ b/weaver/src/org/aspectj/weaver/patterns/ThrowsPattern.java
@@ -66,6 +66,12 @@ public class ThrowsPattern extends PatternNode {
return this;
}
+ public ThrowsPattern resolveBindingsFromRTTI() {
+ required = required.resolveBindingsFromRTTI(false,false);
+ forbidden = forbidden.resolveBindingsFromRTTI(false,false);
+ return this;
+ }
+
public boolean matches(TypeX[] tys, World world) {
if (this == ANY) return true;
@@ -85,6 +91,25 @@ public class ThrowsPattern extends PatternNode {
}
return true;
}
+
+ public boolean matches(Class[] onTypes) {
+ if (this == ANY) return true;
+
+ //System.out.println("matching: " + this + " with " + Arrays.asList(tys));
+
+ for (int j=0, lenj = required.size(); j < lenj; j++) {
+ if (! matchesAny(required.get(j), onTypes)) {
+ return false;
+ }
+ }
+ for (int j=0, lenj = forbidden.size(); j < lenj; j++) {
+ if (matchesAny(forbidden.get(j), onTypes)) {
+ return false;
+ }
+ }
+ return true;
+
+ }
private boolean matchesAny(
TypePattern typePattern,
@@ -95,6 +120,13 @@ public class ThrowsPattern extends PatternNode {
}
return false;
}
+
+ private boolean matchesAny(TypePattern typePattern, Class[] types) {
+ for (int i = types.length - 1; i >= 0; i--) {
+ if (typePattern.matchesStatically(types[i])) return true;
+ }
+ return false;
+ }
public static ThrowsPattern read(DataInputStream s, ISourceContext context) throws IOException {
TypePatternList required = TypePatternList.read(s, context);
diff --git a/weaver/src/org/aspectj/weaver/patterns/TypePattern.java b/weaver/src/org/aspectj/weaver/patterns/TypePattern.java
index 6c58c5c6b..ad6b88fb4 100644
--- a/weaver/src/org/aspectj/weaver/patterns/TypePattern.java
+++ b/weaver/src/org/aspectj/weaver/patterns/TypePattern.java
@@ -83,6 +83,51 @@ public abstract class TypePattern extends PatternNode {
}
+ // methods for dynamic pc matching...
+ public final FuzzyBoolean matches(Class toMatch, MatchKind kind) {
+ if (kind == STATIC) {
+ return FuzzyBoolean.fromBoolean(matchesStatically(toMatch));
+ } else if (kind == DYNAMIC) {
+ //System.err.println("matching: " + this + " with " + type);
+ FuzzyBoolean ret = matchesInstanceof(toMatch);
+ //System.err.println(" got: " + ret);
+ return ret;
+ } else {
+ throw new IllegalArgumentException("kind must be DYNAMIC or STATIC");
+ }
+ }
+
+ public final FuzzyBoolean matches(Object o, MatchKind kind) {
+ if (kind == STATIC) {
+ return FuzzyBoolean.fromBoolean(matchesStatically(o.getClass()));
+ } else if (kind == DYNAMIC) {
+ return FuzzyBoolean.fromBoolean(matchesSubtypes(o.getClass()));
+ } else {
+ throw new IllegalArgumentException("kind must be DYNAMIC or STATIC");
+ }
+ }
+
+ public boolean matchesStatically(Class toMatch) {
+ if (includeSubtypes) {
+ return matchesSubtypes(toMatch);
+ } else {
+ return matchesExactly(toMatch);
+ }
+ }
+ public abstract FuzzyBoolean matchesInstanceof(Class toMatch);
+
+ protected abstract boolean matchesExactly(Class toMatch);
+ protected boolean matchesSubtypes(Class toMatch) {
+ if (matchesExactly(toMatch)) {
+ return true;
+ }
+ Class superClass = toMatch.getSuperclass();
+ if (superClass != null) {
+ return matchesSubtypes(superClass);
+ }
+ return false;
+ }
+
protected abstract boolean matchesExactly(ResolvedTypeX type);
protected boolean matchesSubtypes(ResolvedTypeX type) {
//System.out.println("matching: " + this + " to " + type);
@@ -133,6 +178,10 @@ public abstract class TypePattern extends PatternNode {
return this;
}
+ public TypePattern resolveBindingsFromRTTI(boolean allowBindng, boolean requireExactType) {
+ return this;
+ }
+
public void postRead(ResolvedTypeX enclosingType) {
}
@@ -222,6 +271,19 @@ class EllipsisTypePattern extends TypePattern {
}
/**
+ * @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType)
+ */
+ protected boolean matchesExactly(Class type) {
+ return false;
+ }
+
+ /**
+ * @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(IType)
+ */
+ public FuzzyBoolean matchesInstanceof(Class type) {
+ return FuzzyBoolean.NO;
+ }
+ /**
* @see org.aspectj.weaver.patterns.PatternNode#write(DataOutputStream)
*/
public void write(DataOutputStream s) throws IOException {
@@ -256,6 +318,19 @@ class AnyTypePattern extends TypePattern {
}
/**
+ * @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType)
+ */
+ protected boolean matchesExactly(Class type) {
+ return true;
+ }
+
+ /**
+ * @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(IType)
+ */
+ public FuzzyBoolean matchesInstanceof(Class type) {
+ return FuzzyBoolean.YES;
+ }
+ /**
* @see org.aspectj.weaver.patterns.PatternNode#write(DataOutputStream)
*/
public void write(DataOutputStream s) throws IOException {
@@ -305,6 +380,19 @@ class NoTypePattern extends TypePattern {
}
/**
+ * @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType)
+ */
+ protected boolean matchesExactly(Class type) {
+ return false;
+ }
+
+ /**
+ * @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(IType)
+ */
+ public FuzzyBoolean matchesInstanceof(Class type) {
+ return FuzzyBoolean.NO;
+ }
+ /**
* @see org.aspectj.weaver.patterns.PatternNode#write(DataOutputStream)
*/
public void write(DataOutputStream s) throws IOException {
diff --git a/weaver/src/org/aspectj/weaver/patterns/TypePatternList.java b/weaver/src/org/aspectj/weaver/patterns/TypePatternList.java
index dc4979e30..25111cf15 100644
--- a/weaver/src/org/aspectj/weaver/patterns/TypePatternList.java
+++ b/weaver/src/org/aspectj/weaver/patterns/TypePatternList.java
@@ -122,6 +122,86 @@ public class TypePatternList extends PatternNode {
return b;
}
}
+
+
+ // TODO Add TypePatternList.matches(Object[] objs)
+ public FuzzyBoolean matches(Object[] objs, TypePattern.MatchKind kind) {
+ int nameLength = objs.length;
+ int patternLength = typePatterns.length;
+
+ int nameIndex = 0;
+ int patternIndex = 0;
+
+ if (ellipsisCount == 0) {
+ if (nameLength != patternLength) return FuzzyBoolean.NO;
+ FuzzyBoolean finalReturn = FuzzyBoolean.YES;
+ while (patternIndex < patternLength) {
+ FuzzyBoolean ret = typePatterns[patternIndex++].matches(objs[nameIndex++],kind);
+ if (ret == FuzzyBoolean.NO) return ret;
+ if (ret == FuzzyBoolean.MAYBE) finalReturn = ret;
+ }
+ return finalReturn;
+ } else if (ellipsisCount == 1) {
+ if (nameLength < patternLength-1) return FuzzyBoolean.NO;
+ FuzzyBoolean finalReturn = FuzzyBoolean.YES;
+ while (patternIndex < patternLength) {
+ TypePattern p = typePatterns[patternIndex++];
+ if (p == TypePattern.ELLIPSIS) {
+ nameIndex = nameLength - (patternLength-patternIndex);
+ } else {
+ FuzzyBoolean ret = p.matches(objs[nameIndex++],kind);
+ if (ret == FuzzyBoolean.NO) return ret;
+ if (ret == FuzzyBoolean.MAYBE) finalReturn = ret;
+ }
+ }
+ return finalReturn;
+ } else {
+// System.err.print("match(" + arguments + ", " + types + ") -> ");
+ FuzzyBoolean b = outOfStar(typePatterns, objs, 0, 0, patternLength - ellipsisCount, nameLength, ellipsisCount, kind);
+// System.err.println(b);
+ return b;
+ }
+ }
+
+ // XXX run-time signature matching, too much duplicated code
+ public FuzzyBoolean matches(Class[] types, TypePattern.MatchKind kind) {
+ int nameLength = types.length;
+ int patternLength = typePatterns.length;
+
+ int nameIndex = 0;
+ int patternIndex = 0;
+
+ if (ellipsisCount == 0) {
+ if (nameLength != patternLength) return FuzzyBoolean.NO;
+ FuzzyBoolean finalReturn = FuzzyBoolean.YES;
+ while (patternIndex < patternLength) {
+ FuzzyBoolean ret = typePatterns[patternIndex++].matches(types[nameIndex++], kind);
+ if (ret == FuzzyBoolean.NO) return ret;
+ if (ret == FuzzyBoolean.MAYBE) finalReturn = ret;
+ }
+ return finalReturn;
+ } else if (ellipsisCount == 1) {
+ if (nameLength < patternLength-1) return FuzzyBoolean.NO;
+ FuzzyBoolean finalReturn = FuzzyBoolean.YES;
+ while (patternIndex < patternLength) {
+ TypePattern p = typePatterns[patternIndex++];
+ if (p == TypePattern.ELLIPSIS) {
+ nameIndex = nameLength - (patternLength-patternIndex);
+ } else {
+ FuzzyBoolean ret = p.matches(types[nameIndex++], kind);
+ if (ret == FuzzyBoolean.NO) return ret;
+ if (ret == FuzzyBoolean.MAYBE) finalReturn = ret;
+ }
+ }
+ return finalReturn;
+ } else {
+// System.err.print("match(" + arguments + ", " + types + ") -> ");
+ FuzzyBoolean b = outOfStar(typePatterns, types, 0, 0, patternLength - ellipsisCount, nameLength, ellipsisCount, kind);
+// System.err.println(b);
+ return b;
+ }
+ }
+
private static FuzzyBoolean outOfStar(final TypePattern[] pattern, final ResolvedTypeX[] target,
int pi, int ti,
int pLeft, int tLeft,
@@ -168,6 +248,130 @@ public class TypePatternList extends PatternNode {
ti++; tLeft--;
}
}
+
+
+
+ private static FuzzyBoolean outOfStar(final TypePattern[] pattern,
+ final Class[] target, int pi, int ti, int pLeft, int tLeft,
+ final int starsLeft, TypePattern.MatchKind kind) {
+ if (pLeft > tLeft)
+ return FuzzyBoolean.NO;
+ FuzzyBoolean finalReturn = FuzzyBoolean.YES;
+ while (true) {
+ // invariant: if (tLeft > 0) then (ti < target.length && pi <
+ // pattern.length)
+ if (tLeft == 0)
+ return finalReturn;
+ if (pLeft == 0) {
+ if (starsLeft > 0) {
+ return finalReturn;
+ } else {
+ return FuzzyBoolean.NO;
+ }
+ }
+ if (pattern[pi] == TypePattern.ELLIPSIS) {
+ return inStar(pattern, target, pi + 1, ti, pLeft, tLeft,
+ starsLeft - 1, kind);
+ }
+ FuzzyBoolean ret = pattern[pi].matches(target[ti], kind);
+ if (ret == FuzzyBoolean.NO)
+ return ret;
+ if (ret == FuzzyBoolean.MAYBE)
+ finalReturn = ret;
+ pi++;
+ ti++;
+ pLeft--;
+ tLeft--;
+ }
+ }
+
+ private static FuzzyBoolean inStar(final TypePattern[] pattern,
+ final Class[] target, int pi, int ti, final int pLeft,
+ int tLeft, int starsLeft, TypePattern.MatchKind kind) {
+ // invariant: pLeft > 0, so we know we'll run out of stars and find a
+ // real char in pattern
+ TypePattern patternChar = pattern[pi];
+ while (patternChar == TypePattern.ELLIPSIS) {
+ starsLeft--;
+ patternChar = pattern[++pi];
+ }
+ while (true) {
+ // invariant: if (tLeft > 0) then (ti < target.length)
+ if (pLeft > tLeft)
+ return FuzzyBoolean.NO;
+ FuzzyBoolean ff = patternChar.matches(target[ti], kind);
+ if (ff.maybeTrue()) {
+ FuzzyBoolean xx = outOfStar(pattern, target, pi + 1, ti + 1,
+ pLeft - 1, tLeft - 1, starsLeft, kind);
+ if (xx.maybeTrue())
+ return ff.and(xx);
+ }
+ ti++;
+ tLeft--;
+ }
+ }
+
+ private static FuzzyBoolean outOfStar(final TypePattern[] pattern,
+ final Object[] target, int pi, int ti, int pLeft, int tLeft,
+ final int starsLeft, TypePattern.MatchKind kind) {
+ if (pLeft > tLeft)
+ return FuzzyBoolean.NO;
+ FuzzyBoolean finalReturn = FuzzyBoolean.YES;
+ while (true) {
+ // invariant: if (tLeft > 0) then (ti < target.length && pi <
+ // pattern.length)
+ if (tLeft == 0)
+ return finalReturn;
+ if (pLeft == 0) {
+ if (starsLeft > 0) {
+ return finalReturn;
+ } else {
+ return FuzzyBoolean.NO;
+ }
+ }
+ if (pattern[pi] == TypePattern.ELLIPSIS) {
+ return inStar(pattern, target, pi + 1, ti, pLeft, tLeft,
+ starsLeft - 1,kind);
+ }
+ FuzzyBoolean ret = pattern[pi].matches(target[ti],kind);
+ if (ret == FuzzyBoolean.NO)
+ return ret;
+ if (ret == FuzzyBoolean.MAYBE)
+ finalReturn = ret;
+ pi++;
+ ti++;
+ pLeft--;
+ tLeft--;
+ }
+ }
+
+ private static FuzzyBoolean inStar(final TypePattern[] pattern,
+ final Object[] target, int pi, int ti, final int pLeft,
+ int tLeft, int starsLeft, TypePattern.MatchKind kind) {
+ // invariant: pLeft > 0, so we know we'll run out of stars and find a
+ // real char in pattern
+ TypePattern patternChar = pattern[pi];
+ while (patternChar == TypePattern.ELLIPSIS) {
+ starsLeft--;
+ patternChar = pattern[++pi];
+ }
+ while (true) {
+ // invariant: if (tLeft > 0) then (ti < target.length)
+ if (pLeft > tLeft)
+ return FuzzyBoolean.NO;
+ FuzzyBoolean ff = patternChar.matches(target[ti],kind);
+ if (ff.maybeTrue()) {
+ FuzzyBoolean xx = outOfStar(pattern, target, pi + 1, ti + 1,
+ pLeft - 1, tLeft - 1, starsLeft,kind);
+ if (xx.maybeTrue())
+ return ff.and(xx);
+ }
+ ti++;
+ tLeft--;
+ }
+ }
+
+
public TypePatternList resolveBindings(IScope scope, Bindings bindings, boolean allowBinding, boolean requireExactType) {
for (int i=0; i<typePatterns.length; i++) {
@@ -179,6 +383,16 @@ public class TypePatternList extends PatternNode {
return this;
}
+ public TypePatternList resolveBindingsFromRTTI(boolean allowBinding, boolean requireExactType) {
+ for (int i=0; i<typePatterns.length; i++) {
+ TypePattern p = typePatterns[i];
+ if (p != null) {
+ typePatterns[i] = typePatterns[i].resolveBindingsFromRTTI(allowBinding, requireExactType);
+ }
+ }
+ return this;
+ }
+
public TypePatternList resolveReferences(IntMap bindings) {
int len = typePatterns.length;
TypePattern[] ret = new TypePattern[len];
diff --git a/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java
index e6003191d..61c778358 100644
--- a/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java
+++ b/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java
@@ -82,6 +82,14 @@ public class WildTypePattern extends TypePattern {
//System.err.println("match: " + targetTypeName + ", " + knownMatches); //Arrays.asList(importedPrefixes));
+ return matchesExactlyByName(targetTypeName);
+ }
+
+ /**
+ * @param targetTypeName
+ * @return
+ */
+ private boolean matchesExactlyByName(String targetTypeName) {
//XXX hack
if (knownMatches == null && importedPrefixes == null) {
return innerMatchesExactly(targetTypeName);
@@ -122,7 +130,7 @@ public class WildTypePattern extends TypePattern {
return innerMatchesExactly(targetTypeName);
}
- private int lastIndexOfDotOrDollar(String string) {
+ private int lastIndexOfDotOrDollar(String string) {
int dot = string.lastIndexOf('.');
int dollar = string.lastIndexOf('$');
return Math.max(dot, dollar);
@@ -370,6 +378,53 @@ public class WildTypePattern extends TypePattern {
return this;
}
+ public TypePattern resolveBindingsFromRTTI(boolean allowBinding, boolean requireExactType) {
+ if (isStar()) {
+ return TypePattern.ANY; //??? loses source location
+ }
+
+ String cleanName = maybeGetCleanName();
+ if (cleanName != null) {
+ Class clazz = null;
+
+ while (clazz == null) {
+ try {
+ clazz = Class.forName(cleanName);
+ } catch (ClassNotFoundException cnf) {
+ int lastDotIndex = cleanName.lastIndexOf('.');
+ if (lastDotIndex == -1) break;
+ cleanName = cleanName.substring(0, lastDotIndex) + '$' + cleanName.substring(lastDotIndex+1);
+ }
+ }
+
+ if (clazz == null) {
+ try {
+ clazz = Class.forName("java.lang." + cleanName);
+ } catch (ClassNotFoundException cnf) {
+ }
+ }
+
+ if (clazz == null) {
+ if (requireExactType) {
+ return NO;
+ }
+ } else {
+ TypeX type = TypeX.forName(clazz.getName());
+ if (dim != 0) type = TypeX.makeArray(type,dim);
+ TypePattern ret = new ExactTypePattern(type, includeSubtypes);
+ ret.copyLocationFrom(this);
+ return ret;
+ }
+ } else if (requireExactType) {
+ return NO;
+ }
+
+ importedPrefixes = SimpleScope.javaLangPrefixArray;
+ knownMatches = new String[0];
+
+ return this;
+ }
+
public boolean isStar() {
return namePatterns.length == 1 && namePatterns[0].isAny();
}
@@ -429,6 +484,15 @@ public class WildTypePattern extends TypePattern {
}
return result;
}
+
+
+ public FuzzyBoolean matchesInstanceof(Class type) {
+ return FuzzyBoolean.NO;
+ }
+
+ public boolean matchesExactly(Class type) {
+ return matchesExactlyByName(type.getName());
+ }
/**
* @see org.aspectj.weaver.patterns.PatternNode#write(DataOutputStream)
diff --git a/weaver/src/org/aspectj/weaver/patterns/WithinPointcut.java b/weaver/src/org/aspectj/weaver/patterns/WithinPointcut.java
index 14267da07..d0acd286b 100644
--- a/weaver/src/org/aspectj/weaver/patterns/WithinPointcut.java
+++ b/weaver/src/org/aspectj/weaver/patterns/WithinPointcut.java
@@ -17,6 +17,7 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import org.aspectj.lang.JoinPoint;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.IntMap;
@@ -51,6 +52,21 @@ public class WithinPointcut extends Pointcut {
return isWithinType(enclosingType);
}
+ public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJp) {
+ return isWithinType(encJp.getSignature().getDeclaringType());
+ }
+
+ private FuzzyBoolean isWithinType(Class type) {
+ while (type != null) {
+ if (typePattern.matchesStatically(type)) {
+ return FuzzyBoolean.YES;
+ }
+ type = type.getDeclaringClass();
+ }
+ return FuzzyBoolean.NO;
+ }
+
+
public void write(DataOutputStream s) throws IOException {
s.writeByte(Pointcut.WITHIN);
typePattern.write(s);
@@ -67,6 +83,10 @@ public class WithinPointcut extends Pointcut {
typePattern = typePattern.resolveBindings(scope, bindings, false, false);
}
+ public void resolveBindingsFromRTTI() {
+ typePattern = typePattern.resolveBindingsFromRTTI(false,false);
+ }
+
public void postRead(ResolvedTypeX enclosingType) {
typePattern.postRead(enclosingType);
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java b/weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java
index f30329bb2..c666d53ac 100644
--- a/weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java
+++ b/weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java
@@ -17,6 +17,7 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import org.aspectj.lang.JoinPoint;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.IntMap;
@@ -43,6 +44,10 @@ public class WithincodePointcut extends Pointcut {
signature.matches(shadow.getEnclosingCodeSignature(), shadow.getIWorld()));
}
+ public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJP) {
+ return FuzzyBoolean.fromBoolean(signature.matches(encJP));
+ }
+
public void write(DataOutputStream s) throws IOException {
s.writeByte(Pointcut.WITHINCODE);
signature.write(s);
@@ -58,6 +63,10 @@ public class WithincodePointcut extends Pointcut {
public void resolveBindings(IScope scope, Bindings bindings) {
signature = signature.resolveBindings(scope, bindings);
}
+
+ public void resolveBindingsFromRTTI() {
+ signature = signature.resolveBindingsFromRTTI();
+ }
public void postRead(ResolvedTypeX enclosingType) {
signature.postRead(enclosingType);