aboutsummaryrefslogtreecommitdiffstats
path: root/org.aspectj.matcher
diff options
context:
space:
mode:
authoraclement <aclement>2011-09-14 00:05:18 +0000
committeraclement <aclement>2011-09-14 00:05:18 +0000
commit363c363afffc7152e96da039ef767db111bb8245 (patch)
tree8c1079119ef631fbc48ece863e68004a8ca028ca /org.aspectj.matcher
parente72228e3682ad8cb6503d2c0b1c06ac059ae7e1a (diff)
downloadaspectj-363c363afffc7152e96da039ef767db111bb8245.tar.gz
aspectj-363c363afffc7152e96da039ef767db111bb8245.zip
354470
Diffstat (limited to 'org.aspectj.matcher')
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/patterns/HasMemberTypePattern.java9
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/patterns/HasMemberTypePatternForPerThisMatching.java65
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/patterns/PerThisOrTargetPointcutVisitor.java12
3 files changed, 81 insertions, 5 deletions
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/HasMemberTypePattern.java b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/HasMemberTypePattern.java
index 43a7582af..6aa55a45a 100644
--- a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/HasMemberTypePattern.java
+++ b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/HasMemberTypePattern.java
@@ -24,6 +24,7 @@ import org.aspectj.weaver.CompressingDataOutputStream;
import org.aspectj.weaver.ConcreteTypeMunger;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.Member;
+import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.WeaverMessages;
@@ -50,7 +51,7 @@ public class HasMemberTypePattern extends TypePattern {
return hasMethod(type);
}
}
-
+
public ISignaturePattern getSignaturePattern() {
return signaturePattern;
}
@@ -77,10 +78,10 @@ public class HasMemberTypePattern extends TypePattern {
return false;
}
- private boolean hasMethod(ResolvedType type) {
+ protected boolean hasMethod(ResolvedType type) {
// TODO what about ITDs
World world = type.getWorld();
- for (Iterator iter = type.getMethods(true, true); iter.hasNext();) {
+ for (Iterator<ResolvedMember> iter = type.getMethods(true, true); iter.hasNext();) {
Member method = (Member) iter.next();
if (method.getName().startsWith(declareAtPrefix)) {
continue;
@@ -94,7 +95,7 @@ public class HasMemberTypePattern extends TypePattern {
return true;
}
}
- // try itds before we give up
+ // try itds before we give up (this doesnt find annotations - the signature returned may not include them)
List<ConcreteTypeMunger> mungers = type.getInterTypeMungersIncludingSupers();
for (Iterator<ConcreteTypeMunger> iter = mungers.iterator(); iter.hasNext();) {
ConcreteTypeMunger munger = iter.next();
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/HasMemberTypePatternForPerThisMatching.java b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/HasMemberTypePatternForPerThisMatching.java
new file mode 100644
index 000000000..128338f8e
--- /dev/null
+++ b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/HasMemberTypePatternForPerThisMatching.java
@@ -0,0 +1,65 @@
+/* *******************************************************************
+ * Copyright (c) 2011 Contributors.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement Initial implementation
+ * ******************************************************************/
+package org.aspectj.weaver.patterns;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.aspectj.weaver.CompressingDataOutputStream;
+import org.aspectj.weaver.ConcreteTypeMunger;
+import org.aspectj.weaver.ResolvedType;
+
+/**
+ * pr354470. This is a special subtype of HasMemberTypePattern. In order to optimize this situation: <br>
+ * <code><pre>
+ * aspect X perthis(transactional()) {<br>
+ * pointcut transactional: execution(@Foo * *(..));<br>
+ * </pre></code>
+ * <p>
+ * When this occurs we obviously only want an aspect instance when there is a method annotated with @Foo. For a regular execution
+ * pointcut we couldn't really do this due to the multiple joinpoint signatures for each joinpoint (and so lots of types get the
+ * ajcMightHaveAspect interface). However, for an execution pointcut involving an annotation we can do something clever. Annotations
+ * must match against the first primary joinpoint signature - so when computing the type pattern to use for matching when processing
+ * the perthis() clause above, we can use the HasMemberTypePattern - because that effectively does what we want. We want an aspect
+ * instance if the type hasmethod(...) with the appropriate annotation. This would be great... but breaks in the face of ITDs. If
+ * the method that hasmethod() would match is introduced via an ITD we come unstuck, the code in HasMemberTypePattern.hasMethod()
+ * does look at ITDs but it won't see annotations, they aren't visible (at least through EclipseResolvedMember objects). And so this
+ * subclass is created to say 'if the supertype thinks it is a match, great, but if it doesnt then if there are ITDs on the target,
+ * they might match so just say 'true''. Note that returning true is just confirming whether the 'mightHaveAspect' interface (and
+ * friends) are getting added.
+ *
+ * @author Andy Clement
+ */
+public class HasMemberTypePatternForPerThisMatching extends HasMemberTypePattern {
+
+ public HasMemberTypePatternForPerThisMatching(SignaturePattern aSignaturePattern) {
+ super(aSignaturePattern);
+ }
+
+ protected boolean hasMethod(ResolvedType type) {
+ boolean b = super.hasMethod(type);
+ if (b) {
+ return true;
+ }
+ // If there are ITDs, have to be safe and just assume one of them might match
+ List<ConcreteTypeMunger> mungers = type.getInterTypeMungersIncludingSupers();
+ if (mungers.size() != 0) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void write(CompressingDataOutputStream s) throws IOException {
+ throw new IllegalAccessError("Should never be called, these are transient and don't get serialized");
+ }
+}
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/PerThisOrTargetPointcutVisitor.java b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/PerThisOrTargetPointcutVisitor.java
index e1cc54341..0020cefdc 100644
--- a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/PerThisOrTargetPointcutVisitor.java
+++ b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/PerThisOrTargetPointcutVisitor.java
@@ -90,7 +90,17 @@ public class PerThisOrTargetPointcutVisitor extends AbstractPatternNodeVisitor {
} else if (node.getKind().equals(Shadow.ConstructorExecution) || node.getKind().equals(Shadow.Initialization)
|| node.getKind().equals(Shadow.MethodExecution) || node.getKind().equals(Shadow.PreInitialization)
|| node.getKind().equals(Shadow.StaticInitialization)) {
- return node.getSignature().getDeclaringType();
+ SignaturePattern signaturePattern = node.getSignature();
+ boolean isStarAnnotation = signaturePattern.isStarAnnotation();
+ // For a method execution joinpoint, we check for an annotation pattern. If there is one we know it will be matched
+ // against the 'primary' joinpoint (the one in the type) - 'super'joinpoints can't match it. If this situation occurs
+ // we can re-use the HasMemberTypePattern to guard on whether the perthis/target should match. pr354470
+ if (!m_isTarget && node.getKind().equals(Shadow.MethodExecution)) {
+ if (!isStarAnnotation) {
+ return new HasMemberTypePatternForPerThisMatching(signaturePattern);
+ }
+ }
+ return signaturePattern.getDeclaringType();
} else if (node.getKind().equals(Shadow.ConstructorCall) || node.getKind().equals(Shadow.FieldGet)
|| node.getKind().equals(Shadow.FieldSet) || node.getKind().equals(Shadow.MethodCall)) {
if (m_isTarget) {