summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/src/org/aspectj/systemtest/ajc150/ataspectj/misuse.xml2
-rw-r--r--weaver/src/org/aspectj/weaver/IntMap.java6
-rw-r--r--weaver/src/org/aspectj/weaver/PerObjectInterfaceTypeMunger.java165
-rw-r--r--weaver/src/org/aspectj/weaver/PerTypeWithinTargetTypeMunger.java3
-rw-r--r--weaver/src/org/aspectj/weaver/ResolvedPointcutDefinition.java29
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java41
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/ExposedState.java2
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/IfPointcut.java221
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/PatternParser.java39
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/PerThisOrTargetPointcutVisitor.java2
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/PointcutVisitor.java12
-rw-r--r--weaver/src/org/aspectj/weaver/tools/PointcutParser.java7
-rw-r--r--weaver/testdata/visitor.pointcuts.txt57
-rw-r--r--weaver/testsrc/org/aspectj/weaver/tools/PointcutParserTest.java8
14 files changed, 379 insertions, 215 deletions
diff --git a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/misuse.xml b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/misuse.xml
index f78aa87b3..d0204141a 100644
--- a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/misuse.xml
+++ b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/misuse.xml
@@ -21,7 +21,7 @@
<ajc-test dir="java5/ataspectj"
pr="" title="@Pointcut not returning void">
<compile files="ataspectj/misuse/Test008.java" options="-1.5 -Xdev:NoAtAspectJProcessing">
- <message kind="warning" line="9" text="Found @Pointcut on a method not returning void"/>
+ <message kind="warning" line="9" text="Found @Pointcut on a method not returning 'void' or not 'public static boolean'"/>
</compile>
</ajc-test>
diff --git a/weaver/src/org/aspectj/weaver/IntMap.java b/weaver/src/org/aspectj/weaver/IntMap.java
index 4025a6211..f8646c8e3 100644
--- a/weaver/src/org/aspectj/weaver/IntMap.java
+++ b/weaver/src/org/aspectj/weaver/IntMap.java
@@ -38,7 +38,11 @@ public class IntMap {
public ResolvedPointcutDefinition peekEnclosingDefinitition() {
- return (ResolvedPointcutDefinition)enclosingDefinition.get(enclosingDefinition.size()-1);
+ try {
+ return (ResolvedPointcutDefinition)enclosingDefinition.get(enclosingDefinition.size()-1);
+ } catch (IndexOutOfBoundsException e) {
+ return null;
+ }
}
diff --git a/weaver/src/org/aspectj/weaver/PerObjectInterfaceTypeMunger.java b/weaver/src/org/aspectj/weaver/PerObjectInterfaceTypeMunger.java
index 99ce3bd50..c044edb29 100644
--- a/weaver/src/org/aspectj/weaver/PerObjectInterfaceTypeMunger.java
+++ b/weaver/src/org/aspectj/weaver/PerObjectInterfaceTypeMunger.java
@@ -1,138 +1,67 @@
/* *******************************************************************
* Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * 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:
- * PARC initial implementation
+ * 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:
+ * PARC initial implementation
+ * Alexandre Vasseur rearchitected for #75442 finer grained matching
* ******************************************************************/
-
-
package org.aspectj.weaver;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.Map;
-import java.util.WeakHashMap;
-import java.util.List;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.HashMap;
-
-import org.aspectj.weaver.patterns.Pointcut;
-import org.aspectj.weaver.patterns.FastMatchInfo;
-import org.aspectj.weaver.patterns.PerClause;
-import org.aspectj.weaver.patterns.PointcutVisitor;
-import org.aspectj.weaver.patterns.PatternNode;
-import org.aspectj.weaver.patterns.PerThisOrTargetPointcutVisitor;
+import org.aspectj.weaver.patterns.PerFromSuper;
import org.aspectj.weaver.patterns.PerObject;
+import org.aspectj.weaver.patterns.PerThisOrTargetPointcutVisitor;
+import org.aspectj.weaver.patterns.Pointcut;
import org.aspectj.weaver.patterns.TypePattern;
-import org.aspectj.weaver.patterns.PerFromSuper;
-import org.aspectj.util.FuzzyBoolean;
-
-public class PerObjectInterfaceTypeMunger extends ResolvedTypeMunger {
-
- // key is advisedType, value is Set of aspect type that advise the type and are perObject
- public static Map s_advisedTypeToAspects = new HashMap();
- public static void registerAsAdvisedBy(ResolvedTypeX matchType, ResolvedTypeX aspectType) {
- if (PerClause.PEROBJECT.equals(aspectType.getPerClause().getKind())) {
- Set aspects = (Set)s_advisedTypeToAspects.get(matchType);
- if (aspects == null) {
- aspects = new HashSet(1);
- s_advisedTypeToAspects.put(matchType, aspects);
- }
- aspects.add(aspectType);
- }
- }
- public static void unregisterFromAsAdvisedBy(ResolvedTypeX matchType) {
- s_advisedTypeToAspects.remove(matchType);
- }
-
- private ResolvedMember getMethod;
- private ResolvedMember setMethod;
- private TypeX aspectType;
- private TypeX interfaceType;
- private Pointcut testPointcut;
+import java.io.DataOutputStream;
+import java.io.IOException;
- public PerObjectInterfaceTypeMunger(TypeX aspectType, Pointcut testPointcut) {
- super(PerObjectInterface, null);
- this.aspectType = aspectType;
- this.testPointcut = testPointcut;
- this.interfaceType = AjcMemberMaker.perObjectInterfaceType(aspectType);
- this.getMethod = AjcMemberMaker.perObjectInterfaceGet(aspectType);
- this.setMethod = AjcMemberMaker.perObjectInterfaceSet(aspectType);
- }
-
-
- public void write(DataOutputStream s) throws IOException {
- throw new RuntimeException("shouldn't be serialized");
- }
- public TypeX getAspectType() {
- return aspectType;
- }
-
- public ResolvedMember getGetMethod() {
- return getMethod;
- }
-
- public TypeX getInterfaceType() {
- return interfaceType;
- }
+public class PerObjectInterfaceTypeMunger extends ResolvedTypeMunger {
- public ResolvedMember getSetMethod() {
- return setMethod;
- }
+ private final TypeX interfaceType;
+ private final Pointcut testPointcut;
+ private TypePattern lazyTestTypePattern;
- public Pointcut getTestPointcut() {
- return testPointcut;
- }
-
- public boolean matches(ResolvedTypeX matchType, ResolvedTypeX aspectType) {
- if (matchType.isInterface()) return false;
+ public PerObjectInterfaceTypeMunger(TypeX aspectType, Pointcut testPointcut) {
+ super(PerObjectInterface, null);
+ this.testPointcut = testPointcut;
+ this.interfaceType = AjcMemberMaker.perObjectInterfaceType(aspectType);
+ }
- //FIXME AV - cache that
- final boolean isPerThis;
- if (aspectType.getPerClause() instanceof PerFromSuper) {
- PerFromSuper ps = (PerFromSuper) aspectType.getPerClause();
- isPerThis = ((PerObject)ps.lookupConcretePerClause(aspectType)).isThis();
- } else {
- isPerThis = ((PerObject)aspectType.getPerClause()).isThis();
+ private TypePattern getTestTypePattern(ResolvedTypeX aspectType) {
+ if (lazyTestTypePattern == null) {
+ final boolean isPerThis;
+ if (aspectType.getPerClause() instanceof PerFromSuper) {
+ PerFromSuper ps = (PerFromSuper) aspectType.getPerClause();
+ isPerThis = ((PerObject) ps.lookupConcretePerClause(aspectType)).isThis();
+ } else {
+ isPerThis = ((PerObject) aspectType.getPerClause()).isThis();
+ }
+ PerThisOrTargetPointcutVisitor v = new PerThisOrTargetPointcutVisitor(!isPerThis, aspectType);
+ lazyTestTypePattern = v.getPerTypePointcut(testPointcut);
}
- PerThisOrTargetPointcutVisitor v = new PerThisOrTargetPointcutVisitor(
- !isPerThis,
- aspectType
- );
- TypePattern tp = v.getPerTypePointcut(testPointcut);
-
- if (true) return tp.matchesStatically(matchType);
-
-
- //FIXME ATAJ waiting Andy patch...
- // comment from Andy - this is hard to fix...
-
- // right now I filter @AJ aspect else it end up with duplicate members
- //return !matchType.isInterface() && !matchType.isAnnotationStyleAspect();
- Set aspects = (Set)s_advisedTypeToAspects.get(matchType);
- if (aspects == null) {
- //return false;
- // FIXME AV - #75442 see thread
- // back off on old style : it can happen for perTarget that target type is presented first to the weaver
- // while caller side is not thus we have advisedTypeToAspects still empty..
+ return lazyTestTypePattern;
+ }
- // note: needed only for perTarget if lateMunger is used (see PerObject)
- return !matchType.isInterface() && !matchType.isAnnotationStyleAspect();
- } else {
- return aspects.contains(aspectType);
- }
+ public void write(DataOutputStream s) throws IOException {
+ throw new RuntimeException("shouldn't be serialized");
+ }
+ public TypeX getInterfaceType() {
+ return interfaceType;
}
- private FuzzyBoolean isWithinType(ResolvedTypeX type) {
- return testPointcut.fastMatch(new FastMatchInfo(type, null));
+ public Pointcut getTestPointcut() {
+ return testPointcut;
}
+ public boolean matches(ResolvedTypeX matchType, ResolvedTypeX aspectType) {
+ if (matchType.isInterface()) return false;
+ return getTestTypePattern(aspectType).matchesStatically(matchType);
+ }
}
diff --git a/weaver/src/org/aspectj/weaver/PerTypeWithinTargetTypeMunger.java b/weaver/src/org/aspectj/weaver/PerTypeWithinTargetTypeMunger.java
index 965d7717e..107898a2d 100644
--- a/weaver/src/org/aspectj/weaver/PerTypeWithinTargetTypeMunger.java
+++ b/weaver/src/org/aspectj/weaver/PerTypeWithinTargetTypeMunger.java
@@ -21,17 +21,14 @@ import org.aspectj.weaver.patterns.Pointcut;
// PTWIMPL Target type munger adds the localAspectOf() method
public class PerTypeWithinTargetTypeMunger extends ResolvedTypeMunger {
- private ResolvedMember localAspectOfMethod;
private TypeX aspectType;
private PerTypeWithin testPointcut;
-
public PerTypeWithinTargetTypeMunger(TypeX aspectType, PerTypeWithin testPointcut) {
super(PerTypeWithinInterface, null);
this.aspectType = aspectType;
this.testPointcut = testPointcut;
}
-
public void write(DataOutputStream s) throws IOException {
throw new RuntimeException("shouldn't be serialized");
diff --git a/weaver/src/org/aspectj/weaver/ResolvedPointcutDefinition.java b/weaver/src/org/aspectj/weaver/ResolvedPointcutDefinition.java
index 21af036b5..79f7689ce 100644
--- a/weaver/src/org/aspectj/weaver/ResolvedPointcutDefinition.java
+++ b/weaver/src/org/aspectj/weaver/ResolvedPointcutDefinition.java
@@ -21,19 +21,40 @@ import org.aspectj.weaver.patterns.Pointcut;
public class ResolvedPointcutDefinition extends ResolvedMember {
private Pointcut pointcut;
-
- public ResolvedPointcutDefinition(
+
+ public ResolvedPointcutDefinition(
+ TypeX declaringType,
+ int modifiers,
+ String name,
+ TypeX[] parameterTypes,
+ Pointcut pointcut)
+ {
+ this(declaringType, modifiers, name, parameterTypes, ResolvedTypeX.VOID, pointcut);
+ }
+
+ /**
+ * An instance which can be given a specific returnType, used f.e. in if() pointcut for @AJ
+ *
+ * @param declaringType
+ * @param modifiers
+ * @param name
+ * @param parameterTypes
+ * @param returnType
+ * @param pointcut
+ */
+ public ResolvedPointcutDefinition(
TypeX declaringType,
int modifiers,
String name,
TypeX[] parameterTypes,
- Pointcut pointcut)
+ TypeX returnType,
+ Pointcut pointcut)
{
super(
POINTCUT,
declaringType,
modifiers,
- ResolvedTypeX.VOID,
+ returnType,
name,
parameterTypes);
this.pointcut = pointcut;
diff --git a/weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java b/weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java
index 5de34cf38..938411661 100644
--- a/weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java
+++ b/weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java
@@ -847,9 +847,10 @@ public class AtAjAttributes {
ElementNameValuePair pointcutExpr = getAnnotationElement(pointcut, VALUE);
if (pointcutExpr != null) {
- // semantic check: the method must return void
- if (!Type.VOID.equals(struct.method.getReturnType())) {
- reportWarning("Found @Pointcut on a method not returning void", struct);
+ // semantic check: the method must return void, or be "public static boolean" for if() support
+ if (!(Type.VOID.equals(struct.method.getReturnType())
+ || (Type.BOOLEAN.equals(struct.method.getReturnType()) && struct.method.isStatic() && struct.method.isPublic()))) {
+ reportWarning("Found @Pointcut on a method not returning 'void' or not 'public static boolean'", struct);
;//no need to stop
}
// semantic check: the method must not throw anything
@@ -888,6 +889,7 @@ public class AtAjAttributes {
struct.method.getModifiers(),
struct.method.getName(),
argumentTypes,
+ TypeX.forSignature(struct.method.getReturnType().getSignature()),
pc,
binding
)
@@ -1064,7 +1066,6 @@ public class AtAjAttributes {
// }
}
-
/**
* Compute the flag for the xxxJoinPoint extra argument
*
@@ -1072,17 +1073,30 @@ public class AtAjAttributes {
* @return
*/
private static int extractExtraArgument(Method method) {
- int extraArgument = 0;
Type[] methodArgs = method.getArgumentTypes();
+ String[] sigs = new String[methodArgs.length];
for (int i = 0; i < methodArgs.length; i++) {
- String methodArg = methodArgs[i].getSignature();
- if (AjcMemberMaker.TYPEX_JOINPOINT.getSignature().equals(methodArg)) {
+ sigs[i] = methodArgs[i].getSignature();
+ }
+ return extractExtraArgument(sigs);
+ }
+
+ /**
+ * Compute the flag for the xxxJoinPoint extra argument
+ *
+ * @param argumentSignatures
+ * @return
+ */
+ public static int extractExtraArgument(String[] argumentSignatures) {
+ int extraArgument = 0;
+ for (int i = 0; i < argumentSignatures.length; i++) {
+ if (AjcMemberMaker.TYPEX_JOINPOINT.getSignature().equals(argumentSignatures[i])) {
extraArgument |= Advice.ThisJoinPoint;
- } else if (AjcMemberMaker.TYPEX_PROCEEDINGJOINPOINT.getSignature().equals(methodArg)) {
+ } else if (AjcMemberMaker.TYPEX_PROCEEDINGJOINPOINT.getSignature().equals(argumentSignatures[i])) {
extraArgument |= Advice.ThisJoinPoint;
- } else if (AjcMemberMaker.TYPEX_STATICJOINPOINT.getSignature().equals(methodArg)) {
+ } else if (AjcMemberMaker.TYPEX_STATICJOINPOINT.getSignature().equals(argumentSignatures[i])) {
extraArgument |= Advice.ThisJoinPointStaticPart;
- } else if (AjcMemberMaker.TYPEX_ENCLOSINGSTATICJOINPOINT.getSignature().equals(methodArg)) {
+ } else if (AjcMemberMaker.TYPEX_ENCLOSINGSTATICJOINPOINT.getSignature().equals(argumentSignatures[i])) {
extraArgument |= Advice.ThisEnclosingJoinPointStaticPart;
}
}
@@ -1231,9 +1245,10 @@ public class AtAjAttributes {
private Pointcut m_lazyPointcut = null;
- public LazyResolvedPointcutDefinition(ResolvedTypeX declaringType, int modifiers, String name, TypeX[] parameterTypes,
+ public LazyResolvedPointcutDefinition(ResolvedTypeX declaringType, int modifiers, String name,
+ TypeX[] parameterTypes, TypeX returnType,
Pointcut pointcut, IScope binding) {
- super(declaringType, modifiers, name, parameterTypes, null);
+ super(declaringType, modifiers, name, parameterTypes, returnType, null);
m_pointcutUnresolved = pointcut;
m_binding = binding;
}
@@ -1328,7 +1343,7 @@ public class AtAjAttributes {
*/
private static Pointcut parsePointcut(String pointcutString, AjAttributeStruct location) {
try {
- Pointcut pointcut = Pointcut.fromString(pointcutString);
+ Pointcut pointcut = new PatternParser(pointcutString, location.context).parsePointcut();
pointcut.setLocation(location.context, -1, -1);//FIXME -1,-1 is not good enough
return pointcut;
} catch (ParserException e) {
diff --git a/weaver/src/org/aspectj/weaver/patterns/ExposedState.java b/weaver/src/org/aspectj/weaver/patterns/ExposedState.java
index e76be017b..03dd40e15 100644
--- a/weaver/src/org/aspectj/weaver/patterns/ExposedState.java
+++ b/weaver/src/org/aspectj/weaver/patterns/ExposedState.java
@@ -46,7 +46,7 @@ public class ExposedState {
//XXX add sanity checks
// Some checks added in ArgsPointcut and ThisOrTargetPointcut
// if (vars[i]!=null) {
-// if (!var.getType().equals(vars[i].getType()))
+// if (!var.getType().equals(vars[i].getType()))
// throw new RuntimeException("Shouldn't allow a slot to change type! Currently="+var.getType()+" New="+vars[i].getType());
// }
vars[i] = var;
diff --git a/weaver/src/org/aspectj/weaver/patterns/IfPointcut.java b/weaver/src/org/aspectj/weaver/patterns/IfPointcut.java
index 9a716e6e6..dc3ffc576 100644
--- a/weaver/src/org/aspectj/weaver/patterns/IfPointcut.java
+++ b/weaver/src/org/aspectj/weaver/patterns/IfPointcut.java
@@ -1,16 +1,15 @@
/* *******************************************************************
* Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * 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:
- * PARC initial implementation
+ * 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:
+ * PARC initial implementation
+ * Alexandre Vasseur if() implementation for @AJ style
* ******************************************************************/
-
-
package org.aspectj.weaver.patterns;
import java.io.DataOutputStream;
@@ -34,28 +33,45 @@ import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.ShadowMunger;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.WeaverMessages;
+import org.aspectj.weaver.TypeX;
+import org.aspectj.weaver.AjcMemberMaker;
+import org.aspectj.weaver.bcel.AtAjAttributes;
import org.aspectj.weaver.ast.Expr;
import org.aspectj.weaver.ast.Literal;
import org.aspectj.weaver.ast.Test;
import org.aspectj.weaver.ast.Var;
-
public class IfPointcut extends Pointcut {
public ResolvedMember testMethod;
public int extraParameterFlags;
-
+
+ /**
+ * A token source dump that looks like a pointcut (but is NOT parseable at all - just here to help debugging etc)
+ */
+ private String enclosingPointcutHint;
+
public Pointcut residueSource;
int baseArgsCount;
//XXX some way to compute args
-
public IfPointcut(ResolvedMember testMethod, int extraParameterFlags) {
this.testMethod = testMethod;
this.extraParameterFlags = extraParameterFlags;
this.pointcutKind = IF;
+ this.enclosingPointcutHint = null;
}
-
+
+ /**
+ * No-arg constructor for @AJ style, where the if() body is actually the @Pointcut annotated method
+ */
+ public IfPointcut(String enclosingPointcutHint) {
+ this.pointcutKind = IF;
+ this.enclosingPointcutHint = enclosingPointcutHint;
+ this.testMethod = null;// resolved during concretize
+ this.extraParameterFlags = -1;//allows to keep track of the @Aj style
+ }
+
public Set couldMatchKinds() {
return Shadow.ALL_SHADOW_KINDS;
}
@@ -122,19 +138,24 @@ public class IfPointcut extends Pointcut {
IfPointcut o = (IfPointcut)other;
return o.testMethod.equals(this.testMethod);
}
+
public int hashCode() {
int result = 17;
result = 37*result + testMethod.hashCode();
return result;
}
- public String toString() {
- return "if(" + testMethod + ")";
- }
+ public String toString() {
+ if (extraParameterFlags < 0) {
+ //@AJ style
+ return "if()";
+ } else {
+ return "if(" + testMethod + ")";//FIXME AV - bad, this makes it unparsable. Perhaps we can use if() for code style behind the scene!
+ }
+ }
//??? The implementation of name binding and type checking in if PCDs is very convoluted
// There has to be a better way...
-
private boolean findingResidue = false;
// Similar to lastMatchedShadowId - but only for if PCDs.
@@ -155,43 +176,68 @@ public class IfPointcut extends Pointcut {
Test ret = Literal.TRUE;
List args = new ArrayList();
- // If there are no args to sort out, don't bother with the recursive call
- if (baseArgsCount > 0) {
- ExposedState myState = new ExposedState(baseArgsCount);
- //??? we throw out the test that comes from this walk. All we want here
- // is bindings for the arguments
- residueSource.findResidue(shadow, myState);
-
-
- for (int i=0; i < baseArgsCount; i++) {
- Var v = myState.get(i);
- args.add(v);
- ret = Test.makeAnd(ret,
- Test.makeInstanceof(v,
- testMethod.getParameterTypes()[i].resolve(shadow.getIWorld())));
- }
- }
-
- // handle thisJoinPoint parameters
- if ((extraParameterFlags & Advice.ThisJoinPoint) != 0) {
- args.add(shadow.getThisJoinPointVar());
- }
-
- if ((extraParameterFlags & Advice.ThisJoinPointStaticPart) != 0) {
- args.add(shadow.getThisJoinPointStaticPartVar());
- }
-
- if ((extraParameterFlags & Advice.ThisEnclosingJoinPointStaticPart) != 0) {
- args.add(shadow.getThisEnclosingJoinPointStaticPartVar());
- }
-
+ // code style
+ if (extraParameterFlags >= 0) {
+ // If there are no args to sort out, don't bother with the recursive call
+ if (baseArgsCount > 0) {
+ ExposedState myState = new ExposedState(baseArgsCount);
+ //??? we throw out the test that comes from this walk. All we want here
+ // is bindings for the arguments
+ residueSource.findResidue(shadow, myState);
+
+
+ for (int i=0; i < baseArgsCount; i++) {
+ Var v = myState.get(i);
+ args.add(v);
+ ret = Test.makeAnd(ret,
+ Test.makeInstanceof(v,
+ testMethod.getParameterTypes()[i].resolve(shadow.getIWorld())));
+ }
+ }
+
+ // handle thisJoinPoint parameters
+ if ((extraParameterFlags & Advice.ThisJoinPoint) != 0) {
+ args.add(shadow.getThisJoinPointVar());
+ }
+
+ if ((extraParameterFlags & Advice.ThisJoinPointStaticPart) != 0) {
+ args.add(shadow.getThisJoinPointStaticPartVar());
+ }
+
+ if ((extraParameterFlags & Advice.ThisEnclosingJoinPointStaticPart) != 0) {
+ args.add(shadow.getThisEnclosingJoinPointStaticPartVar());
+ }
+ } else {
+ // @style is slightly different
+ int currentStateIndex = 0;
+ //FIXME AV - "args(jp)" test(jp, thejp) will fail here
+ for (int i = 0; i < testMethod.getParameterTypes().length; i++) {
+ String argSignature = testMethod.getParameterTypes()[i].getSignature();
+ if (AjcMemberMaker.TYPEX_JOINPOINT.getSignature().equals(argSignature)) {
+ args.add(shadow.getThisJoinPointVar());
+ } else if (AjcMemberMaker.TYPEX_PROCEEDINGJOINPOINT.getSignature().equals(argSignature)) {
+ args.add(shadow.getThisJoinPointVar());
+ } else if (AjcMemberMaker.TYPEX_STATICJOINPOINT.getSignature().equals(argSignature)) {
+ args.add(shadow.getThisJoinPointStaticPartVar());
+ } else if (AjcMemberMaker.TYPEX_ENCLOSINGSTATICJOINPOINT.getSignature().equals(argSignature)) {
+ args.add(shadow.getThisEnclosingJoinPointStaticPartVar());
+ } else {
+ // we don't use i as JoinPoint.* can be anywhere in the signature in @style
+ Var v = state.get(currentStateIndex++);
+ args.add(v);
+ ret = Test.makeAnd(ret,
+ Test.makeInstanceof(v,
+ testMethod.getParameterTypes()[i].resolve(shadow.getIWorld())));
+ }
+ }
+ }
+
ret = Test.makeAnd(ret, Test.makeCall(testMethod, (Expr[])args.toArray(new Expr[args.size()])));
// Remember...
ifLastMatchedShadowId = shadow.shadowId;
ifLastMatchedShadowResidue = ret;
return ret;
-
} finally {
findingResidue = false;
}
@@ -221,14 +267,56 @@ public class IfPointcut extends Pointcut {
null);
return Pointcut.makeMatchesNothing(Pointcut.CONCRETE);
}
-
+
if (partiallyConcretized != null) {
return partiallyConcretized;
}
- IfPointcut ret = new IfPointcut(testMethod, extraParameterFlags);
- ret.copyLocationFrom(this);
- partiallyConcretized = ret;
-
+
+ final IfPointcut ret;
+ if (extraParameterFlags < 0 && testMethod == null) {
+ // @AJ style, we need to find the testMethod in the aspect defining the "if()" enclosing pointcut
+ ResolvedPointcutDefinition def = bindings.peekEnclosingDefinitition();
+ if (def != null) {
+ ResolvedTypeX aspect = inAspect.getWorld().resolve(def.getDeclaringType());
+ ResolvedMember[] methods = aspect.getDeclaredJavaMethods();
+ for (int i = 0; i < methods.length; i++) {
+ ResolvedMember method = methods[i];
+ if (def.getName().equals(method.getName())
+ && def.getParameterTypes().length == method.getParameterTypes().length) {
+ boolean sameSig = true;
+ for (int j = 0; j < method.getParameterTypes().length; j++) {
+ TypeX argJ = method.getParameterTypes()[j];
+ if (!argJ.equals(def.getParameterTypes()[j])) {
+ sameSig = false;
+ break;
+ }
+ }
+ if (sameSig) {
+ testMethod = method;
+ break;
+ }
+ }
+ }
+ if (testMethod == null) {
+ inAspect.getWorld().showMessage(
+ IMessage.ERROR,
+ "Cannot find if() body from '" + def.toString() + "' for '" + enclosingPointcutHint + "'",
+ this.getSourceLocation(),
+ null
+ );
+ return Pointcut.makeMatchesNothing(Pointcut.CONCRETE);
+ }
+ } else {
+ testMethod = inAspect.getWorld().resolve(bindings.getAdviceSignature());
+ }
+ ret = new IfPointcut(enclosingPointcutHint);
+ ret.testMethod = testMethod;
+ } else {
+ ret = new IfPointcut(testMethod, extraParameterFlags);
+ }
+ ret.copyLocationFrom(this);
+ partiallyConcretized = ret;
+
// It is possible to directly code your pointcut expression in a per clause
// rather than defining a pointcut declaration and referencing it in your
// per clause. If you do this, we have problems (bug #62458). For now,
@@ -260,7 +348,24 @@ public class IfPointcut extends Pointcut {
return Pointcut.makeMatchesNothing(Pointcut.CONCRETE);
}
ret.baseArgsCount = def.getParameterTypes().length;
-
+
+ // for @style, we have implicit binding for JoinPoint.* things
+ //FIXME AV - will lead to failure for "args(jp)" test(jp, thejp) / see args() implementation
+ if (ret.extraParameterFlags < 0) {
+ ret.baseArgsCount = 0;
+ for (int i = 0; i < testMethod.getParameterTypes().length; i++) {
+ String argSignature = testMethod.getParameterTypes()[i].getSignature();
+ if (AjcMemberMaker.TYPEX_JOINPOINT.getSignature().equals(argSignature)
+ || AjcMemberMaker.TYPEX_PROCEEDINGJOINPOINT.getSignature().equals(argSignature)
+ || AjcMemberMaker.TYPEX_STATICJOINPOINT.getSignature().equals(argSignature)
+ || AjcMemberMaker.TYPEX_ENCLOSINGSTATICJOINPOINT.getSignature().equals(argSignature)) {
+ ;
+ } else {
+ ret.baseArgsCount++;
+ }
+ }
+ }
+
IntMap newBindings = IntMap.idMap(ret.baseArgsCount);
newBindings.copyContext(bindings);
ret.residueSource = def.getPointcut().concretize(inAspect, newBindings);
@@ -281,10 +386,11 @@ public class IfPointcut extends Pointcut {
return visitor.visit(this, data);
}
- private static class IfFalsePointcut extends IfPointcut {
+ public static class IfFalsePointcut extends IfPointcut {
public IfFalsePointcut() {
super(null,0);
+ this.pointcutKind = Pointcut.IF_FALSE;
}
public Set couldMatchKinds() {
@@ -355,10 +461,11 @@ public class IfPointcut extends Pointcut {
return ret;
}
- private static class IfTruePointcut extends IfPointcut {
+ public static class IfTruePointcut extends IfPointcut {
public IfTruePointcut() {
super(null,0);
+ this.pointcutKind = Pointcut.IF_TRUE;
}
public boolean alwaysTrue() {
diff --git a/weaver/src/org/aspectj/weaver/patterns/PatternParser.java b/weaver/src/org/aspectj/weaver/patterns/PatternParser.java
index 32ff9d1a9..d63484e0f 100644
--- a/weaver/src/org/aspectj/weaver/patterns/PatternParser.java
+++ b/weaver/src/org/aspectj/weaver/patterns/PatternParser.java
@@ -317,6 +317,33 @@ public class PatternParser {
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();
}
@@ -770,9 +797,9 @@ public class PatternParser {
if (previous != null) {
if (!isAdjacent(previous, tok)) break;
}
- if (tok.getString() == "*" || (tok.isIdentifier() && tok.getString()!="...")) {
+ if ("*".equals(tok.getString()) || (tok.isIdentifier() && !"...".equals(tok.getString()))) {
buf.append(tok.getString());
- } else if (tok.getString()=="...") {
+ } else if ("...".equals(tok.getString())) {
break;
} else if (tok.getLiteralKind() != null) {
//System.err.println("literal kind: " + tok.getString());
@@ -842,7 +869,7 @@ public class PatternParser {
if (previous != null) {
if (!isAdjacent(previous, tok)) break;
}
- if (tok.getString() == "*" || tok.isIdentifier()) {
+ if (tok.getString().equals("*") || tok.isIdentifier()) {
buf.append(tok.getString());
} else if (tok.getLiteralKind() != null) {
//System.err.println("literal kind: " + tok.getString());
@@ -1103,7 +1130,7 @@ public class PatternParser {
public String parseStringLiteral() {
IToken token = tokenSource.next();
String literalKind = token.getLiteralKind();
- if (literalKind == "string") {
+ if (literalKind.equals("string")) {
return token.getString();
}
@@ -1142,7 +1169,7 @@ public class PatternParser {
public boolean maybeEat(String token) {
IToken next = tokenSource.peek();
- if (next.getString() == token) {
+ if (next.getString().equals(token)) {
tokenSource.next();
return true;
} else {
@@ -1162,7 +1189,7 @@ public class PatternParser {
public boolean peek(String token) {
IToken next = tokenSource.peek();
- return next.getString() == token;
+ return next.getString().equals(token);
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/PerThisOrTargetPointcutVisitor.java b/weaver/src/org/aspectj/weaver/patterns/PerThisOrTargetPointcutVisitor.java
index 54eead76c..6eb953e7e 100644
--- a/weaver/src/org/aspectj/weaver/patterns/PerThisOrTargetPointcutVisitor.java
+++ b/weaver/src/org/aspectj/weaver/patterns/PerThisOrTargetPointcutVisitor.java
@@ -11,11 +11,9 @@
*******************************************************************************/
package org.aspectj.weaver.patterns;
-import org.aspectj.weaver.Member;
import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.ResolvedPointcutDefinition;
import org.aspectj.weaver.ResolvedTypeX;
-import org.aspectj.weaver.World;
/**
* A visitor that turns a pointcut into a type pattern equivalent for a perthis or pertarget matching:
diff --git a/weaver/src/org/aspectj/weaver/patterns/PointcutVisitor.java b/weaver/src/org/aspectj/weaver/patterns/PointcutVisitor.java
index 6f2acffd0..1abf102ff 100644
--- a/weaver/src/org/aspectj/weaver/patterns/PointcutVisitor.java
+++ b/weaver/src/org/aspectj/weaver/patterns/PointcutVisitor.java
@@ -610,11 +610,13 @@ public interface PointcutVisitor {
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) *)"
+// "@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++) {
diff --git a/weaver/src/org/aspectj/weaver/tools/PointcutParser.java b/weaver/src/org/aspectj/weaver/tools/PointcutParser.java
index 949165053..f1f12af67 100644
--- a/weaver/src/org/aspectj/weaver/tools/PointcutParser.java
+++ b/weaver/src/org/aspectj/weaver/tools/PointcutParser.java
@@ -24,6 +24,7 @@ import org.aspectj.weaver.patterns.ParserException;
import org.aspectj.weaver.patterns.PatternParser;
import org.aspectj.weaver.patterns.Pointcut;
import org.aspectj.weaver.patterns.ThisOrTargetPointcut;
+import org.aspectj.weaver.patterns.IfPointcut;
/**
* A PointcutParser can be used to build PointcutExpressions for a
@@ -142,9 +143,13 @@ public class PointcutParser {
throw new UnsupportedOperationException("handler is not supported by this parser");
break;
case Pointcut.IF:
+ if (((IfPointcut)pc).extraParameterFlags >= 0) {
+ throw new UnsupportedOperationException("if not supported for non @AspectJ style");
+ }
+ break;
case Pointcut.IF_FALSE:
case Pointcut.IF_TRUE:
- throw new UnsupportedOperationException("if is not supported by this parser");
+ break;
case Pointcut.KINDED:
validateKindedPointcut(((KindedPointcut)pc));
break;
diff --git a/weaver/testdata/visitor.pointcuts.txt b/weaver/testdata/visitor.pointcuts.txt
index f75db3d5c..17e4a7d9f 100644
--- a/weaver/testdata/visitor.pointcuts.txt
+++ b/weaver/testdata/visitor.pointcuts.txt
@@ -2340,3 +2340,60 @@ this(i)
target(foo)
set(Integer *)
call(* System.*(..))
+(args(x) && if())
+(execution(void IfPcd.main(..)) && if())
+if()
+(args(o) && if())
+(if() && execution(* LazyTjp.doit(..)))
+(if() && execution(* LazyTjp.doit2(..)))
+(if() && execution(* LazyTjp.doit3(..)))
+if(true)
+(execution(* doCommand(..)) && if())
+if(false)
+(within(IfFalse) && if(false))
+!if(true)
+(!if() && execution(* *(..)))
+(within(IfTrue) && !if(true))
+(execution(void m2()) && if())
+(execution(void main(..)) && !if())
+(execution(void main(..)) && if())
+(execution(void main(String)) && (!if() && args(a)))
+call(* ThisJoinPointAndVerifier.*(..))
+(if() && (lexicalScope() && !within(Trace+)))
+serverIdentification(FTPServer)
+(checkedCut() && if())
+(if() && if())
+(if() && (if() && call(void IfPCDExprJoinPointVisibleCE.main(..))))
+(if() && (if() && callMain(args)))
+ifFalse(Object)
+(this(t) && if())
+(!within(Aspect) && if())
+(if(true) && set(int BaseApp.i))
+(if(true) && get(int BaseApp.i))
+(if(true) && (call(void *.call(int)) && within(BaseApp)))
+(if(true) && call(void BaseApp.call(int)))
+(if(true) && (within(BaseApp) && execution(void *(int))))
+(if(true) && initialization(BaseApp.new(..)))
+(if(true) && call(void *.uncountedCall()))
+(if(true) && call(void BaseApp.uncountedCall()))
+(if(true) && execution(void BaseApp.uncountedCall()))
+(if() && (!within(A) && (!call(* A.*(..)) && (!initialization(new(..)) && !preinitialization(new(..))))))
+(hasEnclosingJoinPoint() && enclosingDiffers())
+!enclosingDiffers()
+(hasEnclosingJoinPoint() && !enclosingDiffers())
+hasDifferentEnclosingJoinPoint()
+(execution(static String PR590.staticMethod()) && if())
+(args(i) && (if() && safety()))
+(safety() && if())
+(if() && get(int AroundCasting.x))
+(call(String C.doit(Object)) && if())
+(execution(String C.doit(Object)) && if())
+(p() && if())
+(if() && (call(void C.foo(C)) && args(d)))
+(execution(* Test.a(..)) && if())
+set(@(Persisted) @(Classified) * *)
+(call(* *(..)) && @target(Classified))
+(call(* *(..)) && @target(classificationInfo))
+callToClassifiedObject(classification)
+@args(Classified, ..)
+classifiedArgument()
diff --git a/weaver/testsrc/org/aspectj/weaver/tools/PointcutParserTest.java b/weaver/testsrc/org/aspectj/weaver/tools/PointcutParserTest.java
index aea55aaf3..b5f442a03 100644
--- a/weaver/testsrc/org/aspectj/weaver/tools/PointcutParserTest.java
+++ b/weaver/testsrc/org/aspectj/weaver/tools/PointcutParserTest.java
@@ -65,10 +65,12 @@ public class PointcutParserTest extends TestCase {
public void testParseIfPCD() {
PointcutParser p = new PointcutParser();
try {
+ // AV - those 3 are supported for @style
p.parsePointcutExpression("if(true)");
- fail("Expected UnsupportedOperationException");
- } catch(UnsupportedOperationException ex) {
- assertTrue(ex.getMessage().startsWith("if pointcuts and reference pointcuts are not supported"));
+ p.parsePointcutExpression("if(true)");
+ p.parsePointcutExpression("if()");
+ } catch(Throwable t) {
+ fail(t.toString());
}
}