]> source.dussan.org Git - aspectj.git/commitdiff
implementation of new xlint: pr111667
authoraclement <aclement>
Wed, 30 Nov 2005 17:23:35 +0000 (17:23 +0000)
committeraclement <aclement>
Wed, 30 Nov 2005 17:23:35 +0000 (17:23 +0000)
tests/src/org/aspectj/systemtest/ajc150/Ajc150Tests.java
tests/src/org/aspectj/systemtest/ajc150/ajc150.xml
weaver/src/org/aspectj/weaver/Lint.java
weaver/src/org/aspectj/weaver/Shadow.java
weaver/src/org/aspectj/weaver/World.java
weaver/src/org/aspectj/weaver/XlintDefault.properties

index 603cc05b32f6404c741f596fa21ba73a0d4509e9..b7113cd44612612fab583fdd550f43c2b5134078 100644 (file)
@@ -81,7 +81,7 @@ public class Ajc150Tests extends org.aspectj.testing.XMLBasedAjcTestCase {
 
   public void testVarargsITD_pr110906() { runTest("ITD varargs problem");}
   public void testBadRenderer_pr86903() { runTest("bcelrenderer bad");}
-  //public void testLintForAdviceSorting_pr111667() { runTest("lint for advice sorting");}
+  public void testLintForAdviceSorting_pr111667() { runTest("lint for advice sorting");}
   
   public void testIncompatibleClassChangeError_pr113630_1() {runTest("IncompatibleClassChangeError - errorscenario");}
   public void testIncompatibleClassChangeError_pr113630_2() {runTest("IncompatibleClassChangeError - workingscenario");}
index 027648cf89b57468b031a414999e99fe36210274..1b24aa99254b788c2b5729d3807e6ec85fae2c52 100644 (file)
@@ -87,7 +87,8 @@
     </ajc-test>
     
     <ajc-test dir="bugs150/pr111667" pr="111667" title="lint for advice sorting">
-     <compile files="A.java,X.java,Y.java" options="-1.5">
+     <compile files="A.java,X.java,Y.java" options="-1.5 -Xlint:warning">
+       <message kind="warning" line="9" text="at this shadow method-execution(void A.m1()) no precedence is specified between advice applying from aspect X and aspect Y [Xlint:unorderedAdviceAtShadow]"/>
      </compile>
     </ajc-test>
 
index 5380ecfdf6e08b459599d18db61cf3ef09e4f2b3..92dc373c53e3160611d6554f0991d560f2c9e66e 100644 (file)
@@ -108,6 +108,9 @@ public class Lint {
        public final Kind aspectExcludedByConfiguration = 
                new Kind("aspectExcludedByConfiguration","aspect {0} exluded for class loader {1}");
        
+       public final Kind unorderedAdviceAtShadow =
+               new Kind("unorderedAdviceAtShadow","at this shadow {0} no precedence is specified between advice applying from aspect {1} and aspect {2}");
+       
        // there are a lot of messages in the cant find type family - I'm defining an umbrella lint warning that
        // allows a user to control their severity (for e.g. ltw or binary weaving)
        public final Kind cantFindType =
index 5de7a60ef231bca815b731dd08aa940b68326628..4dc7a9703ba4b170b3f60eb76690cb02bedc6e22 100644 (file)
@@ -406,7 +406,12 @@ public abstract class Shadow {
     } 
     
        private void sortMungers() {
+               
                List sorted = PartialOrder.sort(mungers);
+               
+               // Bunch of code to work out whether to report xlints for advice that isn't ordered at this Joinpoint
+               possiblyReportUnorderedAdvice(sorted);
+               
                if (sorted == null) {
                        // this means that we have circular dependencies
                        for (Iterator i = mungers.iterator(); i.hasNext(); ) {
@@ -418,6 +423,61 @@ public abstract class Shadow {
                }
                mungers = sorted;
        }
+
+    // not quite optimal... but the xlint is ignore by default
+       private void possiblyReportUnorderedAdvice(List sorted) {
+               if (sorted!=null && getIWorld().getLint().unorderedAdviceAtShadow.isEnabled() && mungers.size()>1) {
+                       
+                       // Stores a set of strings of the form 'aspect1:aspect2' which indicates there is no
+                       // precedence specified between the two aspects at this shadow.
+                       Set clashingAspects = new HashSet();
+                       int max = mungers.size();
+                       
+                       // Compare every pair of advice mungers
+                       for (int i = max-1; i >=0; i--) {
+                               for (int j=0; j<i; j++) {
+                                 Object a = mungers.get(i);
+                                 Object b = mungers.get(j);
+                                 
+                                 // Make sure they are the right type
+                                 if (a instanceof BcelAdvice && b instanceof BcelAdvice) {
+                                         BcelAdvice adviceA = (BcelAdvice)a;
+                                         BcelAdvice adviceB = (BcelAdvice)b;
+                                         if (!adviceA.concreteAspect.equals(adviceB.concreteAspect)) {
+                                                 AdviceKind adviceKindA = adviceA.getKind();
+                                                 AdviceKind adviceKindB = adviceB.getKind();
+                                                 
+                                                 // make sure they are the nice ones (<6) and not any synthetic advice ones we
+                                                 // create to support other features of the language.
+                                                 if (adviceKindA.getKey()<(byte)6 && adviceKindB.getKey()<(byte)6 && 
+                                                     adviceKindA.getPrecedence() == adviceKindB.getPrecedence()) {
+                                                         
+                                                         // Ask the world if it knows about precedence between these
+                                                         Integer order = getIWorld().getPrecedenceIfAny(
+                                                                         adviceA.concreteAspect,
+                                                                         adviceB.concreteAspect);
+                                                         
+                                                         if (order!=null && 
+                                                             order.equals(new Integer(0))) {
+                                                                 String key = adviceA.getDeclaringAspect()+":"+adviceB.getDeclaringAspect();
+                                                                 String possibleExistingKey = adviceB.getDeclaringAspect()+":"+adviceA.getDeclaringAspect();
+                                                                 if (!clashingAspects.contains(possibleExistingKey)) clashingAspects.add(key);
+                                                         }
+                                                 }
+                                         }
+                                 }
+                               }                               
+                   }
+                       for (Iterator iter = clashingAspects.iterator(); iter.hasNext();) {
+                               String element = (String) iter.next();
+                               String aspect1 = element.substring(0,element.indexOf(":"));
+                               String aspect2 = element.substring(element.indexOf(":")+1);
+                               getIWorld().getLint().unorderedAdviceAtShadow.signal(
+                                                 new String[]{this.toString(),aspect1,aspect2},
+                                                 this.getSourceLocation(),null);
+                       }                 
+               }
+       }
        
        /** Prepare the shadow for implementation.  After this is done, the shadow
         * should be in such a position that each munger simply needs to be implemented.
index 5101d7641dc17abd2e73c39818df565a59c10acd..b353a7241305533901780e8f9fbc66611a4a5d6e 100644 (file)
@@ -498,6 +498,9 @@ public abstract class World implements Dump.INode {
        public int compareByPrecedence(ResolvedType aspect1, ResolvedType aspect2) {
                return precedenceCalculator.compareByPrecedence(aspect1, aspect2);
        }
+       public Integer getPrecedenceIfAny(ResolvedType aspect1, ResolvedType aspect2) {
+               return precedenceCalculator.getPrecedenceIfAny(aspect1, aspect2);
+       }
                
        /**
         * compares by precedence with the additional rule that a super-aspect is 
@@ -811,6 +814,10 @@ public abstract class World implements Dump.INode {
                        }
                }
                
+               public Integer getPrecedenceIfAny(ResolvedType aspect1,ResolvedType aspect2) {
+                       return (Integer)cachedResults.get(new PrecedenceCacheKey(aspect1,aspect2));
+               }
+               
                public int compareByPrecedenceAndHierarchy(ResolvedType firstAspect, ResolvedType secondAspect) {
                        if (firstAspect.equals(secondAspect)) return 0;
                        
index 2e0f7baacf3a5336e35007a4c7d06a4f9fc56bc7..2fc6d25d26e503fbda4d7f338973abe9809dc679 100644 (file)
@@ -37,3 +37,5 @@ unmatchedTargetKind = warning
 
 cantFindType = error
 cantFindTypeAffectingJPMatch = warning
+
+unorderedAdviceAtShadow=ignore