aboutsummaryrefslogtreecommitdiffstats
path: root/weaver
diff options
context:
space:
mode:
authoraclement <aclement>2006-09-22 10:49:37 +0000
committeraclement <aclement>2006-09-22 10:49:37 +0000
commit98a5d925536b291ca760ca510a2e06b7e3cff13e (patch)
treed349cbb016ddc7b55dae0c6eace09803ca799f4f /weaver
parent1138f942d5c2367ef8a6abb4d30e724730bc8f79 (diff)
downloadaspectj-98a5d925536b291ca760ca510a2e06b7e3cff13e.tar.gz
aspectj-98a5d925536b291ca760ca510a2e06b7e3cff13e.zip
154054 testcode and fix: noticing changes in around advice and forcing full builds
Diffstat (limited to 'weaver')
-rw-r--r--weaver/src/org/aspectj/weaver/CrosscuttingMembers.java87
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelMethod.java19
2 files changed, 95 insertions, 11 deletions
diff --git a/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java b/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java
index 7ee94d92d..258489e6e 100644
--- a/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java
+++ b/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java
@@ -20,6 +20,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import org.aspectj.weaver.bcel.BcelMethod;
import org.aspectj.weaver.bcel.BcelTypeMunger;
import org.aspectj.weaver.patterns.Declare;
import org.aspectj.weaver.patterns.DeclareAnnotation;
@@ -230,23 +231,51 @@ public class CrosscuttingMembers {
if (careAboutShadowMungers) {
// bug 129163: use set equality rather than list equality
Set theseShadowMungers = new HashSet();
- theseShadowMungers.addAll(shadowMungers);
+ Set theseInlinedAroundMungers = new HashSet();
+ for (Iterator iter = shadowMungers.iterator(); iter
+ .hasNext();) {
+ ShadowMunger munger = (ShadowMunger) iter.next();
+ if (munger instanceof Advice) {
+ Advice adviceMunger = (Advice)munger;
+ // bug 154054: if we're around advice that has been inlined
+ // then we need to do more checking than existing equals
+ // methods allow
+ if (!world.isXnoInline() && adviceMunger.getKind().equals(AdviceKind.Around)) {
+ theseInlinedAroundMungers.add(adviceMunger);
+ } else {
+ theseShadowMungers.add(adviceMunger);
+ }
+ } else {
+ theseShadowMungers.add(munger);
+ }
+ }
+ Set tempSet = new HashSet();
+ tempSet.addAll(other.shadowMungers);
Set otherShadowMungers = new HashSet();
- otherShadowMungers.addAll(other.shadowMungers);
-
- PointcutRewriter pr = new PointcutRewriter();
- for (Iterator iter = otherShadowMungers.iterator(); iter.hasNext();) {
+ Set otherInlinedAroundMungers = new HashSet();
+ for (Iterator iter = tempSet.iterator(); iter.hasNext();) {
ShadowMunger munger = (ShadowMunger) iter.next();
- Pointcut p = munger.getPointcut();
- Pointcut newP = pr.rewrite(p);
- if (p.m_ignoreUnboundBindingForNames.length!=0) {// *sigh* dirty fix for dirty hacky implementation pr149305
- newP.m_ignoreUnboundBindingForNames = p.m_ignoreUnboundBindingForNames;
+ if (munger instanceof Advice) {
+ Advice adviceMunger = (Advice)munger;
+ // bug 154054: if we're around advice that has been inlined
+ // then we need to do more checking than existing equals
+ // methods allow
+ if (!world.isXnoInline() && adviceMunger.getKind().equals(AdviceKind.Around)) {
+ otherInlinedAroundMungers.add(rewritePointcutInMunger(adviceMunger));
+ } else {
+ otherShadowMungers.add(rewritePointcutInMunger(adviceMunger));
+ }
+ } else {
+ otherShadowMungers.add(rewritePointcutInMunger(munger));
}
- munger.setPointcut(newP);
}
if (!theseShadowMungers.equals(otherShadowMungers)) {
changed = true;
}
+ if (!equivalent(theseInlinedAroundMungers,otherInlinedAroundMungers)) {
+ changed = true;
+ }
+
// replace the existing list of shadowmungers with the
// new ones in case anything like the sourcelocation has
// changed, however, don't want this flagged as a change
@@ -365,6 +394,44 @@ public class CrosscuttingMembers {
return changed;
}
+ private boolean equivalent(Set theseInlinedAroundMungers, Set otherInlinedAroundMungers) {
+ if (theseInlinedAroundMungers.size() != otherInlinedAroundMungers.size()) {
+ return false;
+ }
+ for (Iterator iter = theseInlinedAroundMungers.iterator(); iter.hasNext();) {
+ Advice thisAdvice = (Advice) iter.next();
+ boolean foundIt = false;
+ for (Iterator iterator = otherInlinedAroundMungers.iterator(); iterator.hasNext();) {
+ Advice otherAdvice = (Advice) iterator.next();
+ if (thisAdvice.equals(otherAdvice)) {
+ if(thisAdvice.getSignature() instanceof BcelMethod) {
+ if (((BcelMethod)thisAdvice.getSignature())
+ .isEquivalentTo(otherAdvice.getSignature()) ) {
+ foundIt = true;
+ continue;
+ }
+ }
+ return false;
+ }
+ }
+ if (!foundIt) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private ShadowMunger rewritePointcutInMunger(ShadowMunger munger) {
+ PointcutRewriter pr = new PointcutRewriter();
+ Pointcut p = munger.getPointcut();
+ Pointcut newP = pr.rewrite(p);
+ if (p.m_ignoreUnboundBindingForNames.length!=0) {// *sigh* dirty fix for dirty hacky implementation pr149305
+ newP.m_ignoreUnboundBindingForNames = p.m_ignoreUnboundBindingForNames;
+ }
+ munger.setPointcut(newP);
+ return munger;
+ }
+
public void setPerClause(PerClause perClause) {
if (this.shouldConcretizeIfNeeded) {
this.perClause = perClause.concretize(inAspect);
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java b/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java
index 2a2c94b1d..2bc6e9734 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java
@@ -44,7 +44,7 @@ import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.World;
import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter.GenericSignatureFormatException;
-final class BcelMethod extends ResolvedMemberImpl {
+public final class BcelMethod extends ResolvedMemberImpl {
private Method method;
private boolean isAjSynthetic;
@@ -423,4 +423,21 @@ final class BcelMethod extends ResolvedMemberImpl {
}
}
+ /**
+ * Returns whether or not the given object is equivalent to the
+ * current one. Returns true if getMethod().getCode().getCodeString()
+ * are equal. Allows for different line number tables.
+ */
+ // bug 154054: is similar to equals(Object) however
+ // doesn't require implementing equals in Method and Code
+ // which proved expensive. Currently used within
+ // CrosscuttingMembers.replaceWith() to decide if we need
+ // to do a full build
+ public boolean isEquivalentTo(Object other) {
+ if(! (other instanceof BcelMethod)) return false;
+ BcelMethod o = (BcelMethod)other;
+ return getMethod().getCode().getCodeString().equals(
+ o.getMethod().getCode().getCodeString());
+ }
+
}