diff options
author | aclement <aclement> | 2006-09-22 10:49:37 +0000 |
---|---|---|
committer | aclement <aclement> | 2006-09-22 10:49:37 +0000 |
commit | 98a5d925536b291ca760ca510a2e06b7e3cff13e (patch) | |
tree | d349cbb016ddc7b55dae0c6eace09803ca799f4f /weaver | |
parent | 1138f942d5c2367ef8a6abb4d30e724730bc8f79 (diff) | |
download | aspectj-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.java | 87 | ||||
-rw-r--r-- | weaver/src/org/aspectj/weaver/bcel/BcelMethod.java | 19 |
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()); + } + } |