]> source.dussan.org Git - aspectj.git/commitdiff
77166 - newarray joinpoint support. "-Xjoinpoints:arrayconstruction"
authoraclement <aclement>
Fri, 20 Jan 2006 09:40:54 +0000 (09:40 +0000)
committeraclement <aclement>
Fri, 20 Jan 2006 09:40:54 +0000 (09:40 +0000)
tests/src/org/aspectj/systemtest/ajc151/AllTestsAspectJ151.java
tests/src/org/aspectj/systemtest/ajc151/NewarrayJoinpointTests.java
tests/src/org/aspectj/systemtest/ajc151/newarray_joinpoint.xml
weaver/src/org/aspectj/weaver/JoinPointSignatureIterator.java
weaver/src/org/aspectj/weaver/Shadow.java
weaver/src/org/aspectj/weaver/World.java
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java

index 31d37c5d53507b061cd289d3f061d73e095238f1..1153be1b6c3b385f4508926b9365e5a214da3139 100644 (file)
@@ -19,6 +19,7 @@ public class AllTestsAspectJ151 {
                TestSuite suite = new TestSuite("AspectJ 1.5.1 tests");
                //$JUnit-BEGIN$
                suite.addTest(Ajc151Tests.suite());
+               suite.addTest(NewarrayJoinpointTests.suite());
         //$JUnit-END$
                return suite;
        }
index dbd0be4da19479226510b608525a2733a34ff56d..4db1340038abcf263d27de9e2689f88cfed88b97 100644 (file)
@@ -60,6 +60,9 @@ public class NewarrayJoinpointTests extends XMLBasedAjcTestCase {
   public void testUsingItForReal() { runTest("using it for real");}
   public void testDifferentiatingArrayTypes() { runTest("differentiating array types");}
   public void testStructureModel() { runTest("structure model");}
+  
+  
+  public void testOptionoff() { runTest("option deactivated - no match expected");}
 
   //
   public static Test suite() {
index fedc673220b9307480124ca8a132cee34289af48..b75d4adec64f872d4087806b87e1c982e6d0e237 100644 (file)
     <ajc-test dir="features151/newarrayjoinpoint" title="structure model">
         <compile files="Five.java" options="-1.5 -emacssym -Xjoinpoints:arrayconstruction"/>
     </ajc-test>
+    
+     <ajc-test dir="features151/newarrayjoinpoint" title="option deactivated - no match expected">
+        <compile files="One.java" options="-1.5 -showWeaveInfo">
+           <message kind="warning" line="9" text="advice defined in X has not been applied [Xlint:adviceDidNotMatch]"/>
+        </compile>
+    </ajc-test>
+    
 
 </suite>
\ No newline at end of file
index b11f41f808ee7a370b5cf8606f38d905de659517..265f6f4e082afc63e8e7d21e2acd0cd347068780 100644 (file)
@@ -96,7 +96,17 @@ public class JoinPointSignatureIterator implements Iterator {
                // Walk up hierarchy creating one member for each type up to and including the
        // first defining type
        ResolvedType originalDeclaringType = signaturesOfMember.getDeclaringType().resolve(world);
+       
+       if (world.isJoinpointArrayConstructionEnabled() && originalDeclaringType.isArray()) { // Aha, this must be the array constructor call join point - a 'special'...
+               Member m = signaturesOfMember;
+               ResolvedMember rm = new ResolvedMemberImpl(m.getKind(),m.getDeclaringType(),m.getModifiers(),m.getReturnType(),m.getName(),m.getParameterTypes());
+               discoveredSignatures.add(new JoinPointSignature(rm,originalDeclaringType));
+               couldBeFurtherAsYetUndiscoveredSignatures = false;
+               return;
+       }
+
        firstDefiningMember = (ResolvedMemberImpl) signaturesOfMember.resolve(world);
+       
        if (firstDefiningMember == null) {
                couldBeFurtherAsYetUndiscoveredSignatures = false;
                return;
index 4d28fbe5952cbdc79bae03d8930f4555bb927dc2..ab652b24cfecd9695031e550864045027b8d6f22 100644 (file)
@@ -142,7 +142,29 @@ public abstract class Shadow {
         return getSignature().getParameterTypes();
     }
     
+    public boolean isShadowForArrayConstructionJoinpoint() {
+       return (getKind()==ConstructorCall && signature.getDeclaringType().isArray());
+    }
+    
+    // will return the right length array of ints depending on how many dimensions the array has
+    public ResolvedType[] getArgumentTypesForArrayConstructionShadow() {
+       String s = signature.getDeclaringType().getSignature();
+               int pos = s.indexOf("[");
+               int dims = 1;
+               while (pos<s.length()) {
+                       pos++;
+                       if (pos<s.length()) dims+=(s.charAt(pos)=='['?1:0);
+               }
+               if (dims==1) return new ResolvedType[]{ResolvedType.INT};
+               ResolvedType[] someInts = new ResolvedType[dims];
+               for (int i = 0; i < dims;i++) someInts[i] = ResolvedType.INT;
+               return someInts;
+    }
+    
     public UnresolvedType[] getGenericArgTypes() {
+       if (isShadowForArrayConstructionJoinpoint()) {
+               return getArgumentTypesForArrayConstructionShadow();
+       }
        if (getKind() == FieldSet) return new UnresolvedType[] { getResolvedSignature().getGenericReturnType() };
         return getResolvedSignature().getGenericParameterTypes();      
     }
index a8193d2fadd709f643e0e26abee8b921a1e0468d..c470a0ec65e7a6cd5f19c02c939082bf96839264 100644 (file)
@@ -665,6 +665,7 @@ public abstract class World implements Dump.INode {
        }
        
        public void setOptionalJoinpoints(String jps) {
+               if (jps==null) return;
                if (jps.indexOf("arrayconstruction")!=-1) {
                        optionalJoinpoint_ArrayConstruction = true;
                }
index a2a887017e9a045d14a324409fa2e4fd2f901186..3e7f7a70df2084a34cdc72eb6ea6e04263e4ae6a 100644 (file)
@@ -29,6 +29,7 @@ import org.aspectj.apache.bcel.Constants;
 import org.aspectj.apache.bcel.classfile.Field;
 import org.aspectj.apache.bcel.classfile.Method;
 import org.aspectj.apache.bcel.classfile.annotation.Annotation;
+import org.aspectj.apache.bcel.generic.ANEWARRAY;
 import org.aspectj.apache.bcel.generic.BranchInstruction;
 import org.aspectj.apache.bcel.generic.CPInstruction;
 import org.aspectj.apache.bcel.generic.ConstantPoolGen;
@@ -44,8 +45,10 @@ import org.aspectj.apache.bcel.generic.InstructionList;
 import org.aspectj.apache.bcel.generic.InstructionTargeter;
 import org.aspectj.apache.bcel.generic.InvokeInstruction;
 import org.aspectj.apache.bcel.generic.LocalVariableInstruction;
+import org.aspectj.apache.bcel.generic.MULTIANEWARRAY;
 import org.aspectj.apache.bcel.generic.MethodGen;
 import org.aspectj.apache.bcel.generic.NEW;
+import org.aspectj.apache.bcel.generic.NEWARRAY;
 import org.aspectj.apache.bcel.generic.ObjectType;
 import org.aspectj.apache.bcel.generic.PUTFIELD;
 import org.aspectj.apache.bcel.generic.PUTSTATIC;
@@ -1881,7 +1884,40 @@ class BcelClassWeaver implements IClassWeaver {
                        } else {
                                        matchInvokeInstruction(mg, ih, ii, enclosingShadow, shadowAccumulator);
                        }
-               } 
+               } else if (world.isJoinpointArrayConstructionEnabled() && 
+                                  (i instanceof NEWARRAY || i instanceof ANEWARRAY || i instanceof MULTIANEWARRAY)) {
+                       if (canMatch(Shadow.ConstructorCall)) {
+                               boolean debug = false;
+                               if (debug) System.err.println("Found new array instruction: "+i);
+                               if (i instanceof ANEWARRAY) {
+                                       ANEWARRAY arrayInstruction = (ANEWARRAY)i;
+                                       ObjectType arrayType = arrayInstruction.getLoadClassType(clazz.getConstantPoolGen());
+                                       if (debug) System.err.println("Array type is "+arrayType);
+                                       BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world,mg,ih,enclosingShadow);
+                                       match(ctorCallShadow,shadowAccumulator);
+                               } else if (i instanceof NEWARRAY) {
+                                       NEWARRAY arrayInstruction = (NEWARRAY)i;
+                                       Type arrayType = arrayInstruction.getType();
+                                       if (debug) System.err.println("Array type is "+arrayType);
+                                       BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world,mg,ih,enclosingShadow);
+                                       match(ctorCallShadow,shadowAccumulator);
+                               } else if (i instanceof MULTIANEWARRAY) {
+                                       MULTIANEWARRAY arrayInstruction = (MULTIANEWARRAY)i;
+                                       ObjectType arrayType = arrayInstruction.getLoadClassType(clazz.getConstantPoolGen());
+                                       if (debug) System.err.println("Array type is "+arrayType);
+                                       BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world,mg,ih,enclosingShadow);
+                                       match(ctorCallShadow,shadowAccumulator);
+                               }
+                       }
+// see pr77166 if you are thinking about implementing this
+//             } else if (i instanceof AALOAD ) {
+//                     AALOAD arrayLoad = (AALOAD)i;
+//                     Type arrayType = arrayLoad.getType(clazz.getConstantPoolGen());
+//                     BcelShadow arrayLoadShadow = BcelShadow.makeArrayLoadCall(world,mg,ih,enclosingShadow);
+//                     match(arrayLoadShadow,shadowAccumulator);
+//             } else if (i instanceof AASTORE) {
+//                     // ... magic required
+               }
                // performance optimization... we only actually care about ASTORE instructions, 
                // since that's what every javac type thing ever uses to start a handler, but for
                // now we'll do this for everybody.
index 3ff0d17641e26b6edd2aa94436c72d6460521124..6d04fcd00723fbd9fd5af514dbe9d89e77b94087 100644 (file)
@@ -269,7 +269,8 @@ public class BcelShadow extends Shadow {
                // this up, every ShadowRange would have three instructionHandle points, the start of 
                // the arg-setup code, the start of the running code, and the end of the running code.
                if (getKind() == ConstructorCall) {
-                       deleteNewAndDup();
+                       if (!world.isJoinpointArrayConstructionEnabled() || !this.getSignature().getDeclaringType().isArray())
+                         deleteNewAndDup(); // no new/dup for new array construction
                        initializeArgVars();
                } else if (getKind() == PreInitialization) { // pr74952
                        ShadowRange range = getRange();
@@ -377,12 +378,14 @@ public class BcelShadow extends Shadow {
                                        Range.InsideBefore);
                          }
                          if (getKind() == ConstructorCall) {
-                               range.insert((Instruction) InstructionFactory.createDup(1), Range.InsideBefore);
-                               range.insert(
-                                       fact.createNew(
-                                               (ObjectType) BcelWorld.makeBcelType(
-                                                       getSignature().getDeclaringType())),
-                                       Range.InsideBefore);
+                               if (!world.isJoinpointArrayConstructionEnabled() || !this.getSignature().getDeclaringType().isArray()) {
+                                       range.insert((Instruction) InstructionFactory.createDup(1), Range.InsideBefore);
+                                       range.insert(
+                                               fact.createNew(
+                                                       (ObjectType) BcelWorld.makeBcelType(
+                                                               getSignature().getDeclaringType())),
+                                               Range.InsideBefore);
+                           }
                          }
                        }
                }
@@ -781,7 +784,51 @@ public class BcelShadow extends Shadow {
         retargetAllBranches(callHandle, r.getStart());                
         return s;
     }
+    
+    public static BcelShadow makeArrayConstructorCall(BcelWorld world,LazyMethodGen enclosingMethod,InstructionHandle arrayInstruction,BcelShadow enclosingShadow) {
+       final InstructionList body = enclosingMethod.getBody();
+       Member sig = world.makeJoinPointSignatureForArrayConstruction(enclosingMethod.getEnclosingClass(),arrayInstruction);
+       BcelShadow s = 
+                       new BcelShadow(
+                               world,
+                               ConstructorCall,
+                               sig,
+                enclosingMethod, 
+                enclosingShadow);
+        ShadowRange r = new ShadowRange(body);
+        r.associateWithShadow(s);
+        r.associateWithTargets(
+               Range.genStart(body, arrayInstruction),
+            Range.genEnd(body, arrayInstruction));
+        retargetAllBranches(arrayInstruction, r.getStart());                
+        return s;
+    }
 
+    // see pr77166
+//    public static BcelShadow makeArrayLoadCall(
+//            BcelWorld world,
+//            LazyMethodGen enclosingMethod,
+//            InstructionHandle arrayInstruction,
+//            BcelShadow enclosingShadow) 
+//    {
+//        final InstructionList body = enclosingMethod.getBody();
+//        Member sig = world.makeJoinPointSignatureForArrayLoad(enclosingMethod.getEnclosingClass(),arrayInstruction);
+//        BcelShadow s =
+//            new BcelShadow(
+//                world,
+//                MethodCall,
+//                sig,
+//                enclosingMethod,
+//                enclosingShadow);
+//        ShadowRange r = new ShadowRange(body);
+//        r.associateWithShadow(s);
+//        r.associateWithTargets(
+//             Range.genStart(body, arrayInstruction),
+//            Range.genEnd(body, arrayInstruction));                
+//        retargetAllBranches(arrayInstruction, r.getStart());
+//        return s;
+//    }
+    
     public static BcelShadow makeMethodCall(
             BcelWorld world,
             LazyMethodGen enclosingMethod,
index ae4e507e5cdd4f524f6d4883a1e5bf099959fdd3..04581891bc5a05a9249ad1d26a7ddd2b56314287 100644 (file)
@@ -81,8 +81,13 @@ public class ArgsPointcut extends NameBindingPointcut {
        }
        
        private ResolvedType[] getArgumentsToMatchAgainst(Shadow shadow) {
+               
+               if (shadow.isShadowForArrayConstructionJoinpoint()) {
+                  return shadow.getArgumentTypesForArrayConstructionShadow();
+               }
+               
                ResolvedType[] argumentsToMatchAgainst = shadow.getIWorld().resolve(shadow.getGenericArgTypes());
-
+               
                // special treatment for adviceexecution which may have synthetic arguments we
                // want to ignore.
                if (shadow.getKind() == Shadow.AdviceExecution) {