]> source.dussan.org Git - aspectj.git/commitdiff
Annotation Binding - now complete for @annotation (for *all* kinded PCDs) Root_AspectJ5_Development
authoraclement <aclement>
Tue, 1 Feb 2005 09:20:21 +0000 (09:20 +0000)
committeraclement <aclement>
Tue, 1 Feb 2005 09:20:21 +0000 (09:20 +0000)
tests/src/org/aspectj/systemtest/ajc150/AnnotationBinding.java
weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
weaver/src/org/aspectj/weaver/bcel/KindedAnnotationAccessVar.java

index b1fd803bce0a79f4aa60d07bbd84e41e9e9ba122..1aff11ace09e4ae073459bec0acbcc1549071c9a 100644 (file)
@@ -113,17 +113,90 @@ public class AnnotationBinding extends TestUtils {
   
   ///////////////////////////////////// @ANNOTATION and SET
   
-//  // 'set() && @annotation()' 
-//  public void testFieldAnnotationBinding1() {
-//     CompilationResult cR = ajc(baseDir,new String[]{"FieldAnnBinding1.aj","-1.5"});
-//     System.err.println(cR);
-//     assertMessages(cR,new EmptyMessageSpec()); 
-//     RunResult rR = run("FieldAnnBinding1");
-//     System.err.println(rR.getStdErr());
-//  }
+  // 'set() && @annotation()' 
+  public void testFieldAnnotationBinding1() {
+       CompilationResult cR = ajc(baseDir,new String[]{"FieldAnnBinding1.aj","-1.5"});
+       assertMessages(cR,new EmptyMessageSpec()); 
+       RunResult rR = run("FieldAnnBinding1");
+  }
   
-
+  // 'get() && @annotation()' 
+  public void testFieldAnnotationBinding2() {
+       CompilationResult cR = ajc(baseDir,new String[]{"FieldAnnBinding2.aj","-1.5"});
+       assertMessages(cR,new EmptyMessageSpec()); 
+       RunResult rR = run("FieldAnnBinding2");
+  }
+  
+  // 'get() && @annotation()' when using array fields
+  public void testFieldAnnotationBinding3() {
+       CompilationResult cR = ajc(baseDir,new String[]{"FieldAnnBinding3.aj","-1.5"});
+       assertMessages(cR,new EmptyMessageSpec()); 
+       RunResult rR = run("FieldAnnBinding3");
+  }
+  
+  ///////////////////////////////////// @ANNOTATION and CTOR-CALL
+  
+  // 'ctor-call(new) && @annotation()' 
+  public void testCtorCallAnnotationBinding1() {
+       CompilationResult cR = ajc(baseDir,new String[]{"CtorAnnBinding1.aj","-1.5"});
+       assertMessages(cR,new EmptyMessageSpec()); 
+       RunResult rR = run("CtorAnnBinding1");
+  }
+  
+  ///////////////////////////////////// @ANNOTATION and CTOR-CALL
+  
+  // 'ctor-execution() && @annotation()' 
+  public void testCtorExecAnnotationBinding1() {
+       CompilationResult cR = ajc(baseDir,new String[]{"CtorAnnBinding2.aj","-1.5"});
+       assertMessages(cR,new EmptyMessageSpec()); 
+       RunResult rR = run("CtorAnnBinding2");
+  }
+  
+  
+  ///////////////////////////////////// @ANNOTATION and STATICINITIALIZATION
   
+  // 'staticinitialization() && @annotation()' 
+  public void testStaticInitAnnotationBinding1() {
+       CompilationResult cR = ajc(baseDir,new String[]{"StaticInitBinding.aj","-1.5"});
+       assertMessages(cR,new EmptyMessageSpec()); 
+       RunResult rR = run("StaticInitBinding");
+  }
+  
+  ///////////////////////////////////// @ANNOTATION and PREINITIALIZATION
+  
+  // 'preinitialization() && @annotation()' 
+  public void testPreInitAnnotationBinding1() {
+       CompilationResult cR = ajc(baseDir,new String[]{"PreInitBinding.aj","-1.5"});
+       assertMessages(cR,new EmptyMessageSpec()); 
+       RunResult rR = run("PreInitBinding");
+  }
+  
+  ///////////////////////////////////// @ANNOTATION and INITIALIZATION
+  
+  // 'initialization() && @annotation()' 
+  public void testInitAnnotationBinding1() {
+       CompilationResult cR = ajc(baseDir,new String[]{"InitBinding.aj","-1.5"});
+       assertMessages(cR,new EmptyMessageSpec()); 
+       RunResult rR = run("InitBinding");
+  }
+  
+  ///////////////////////////////////// @ANNOTATION and ADVICEEXECUTION
+  
+  // 'adviceexecution() && @annotation()' 
+  public void testAdviceExecAnnotationBinding1() {
+       CompilationResult cR = ajc(baseDir,new String[]{"AdviceExecBinding.aj","-1.5"});
+       assertMessages(cR,new EmptyMessageSpec()); 
+       RunResult rR = run("AdviceExecBinding");
+  }
+  
+  ///////////////////////////////////// @ANNOTATION and HANDLER
+  
+  // 'handler() && @annotation()' 
+  public void testHandlerAnnotationBinding1() {
+       CompilationResult cR = ajc(baseDir,new String[]{"HandlerBinding.aj","-1.5"});
+       assertMessages(cR,new EmptyMessageSpec()); 
+       RunResult rR = run("HandlerBinding");
+  }
   
 
   ///////////////////////////////////// @ANNOTATION complex tests
@@ -132,7 +205,6 @@ public class AnnotationBinding extends TestUtils {
   public void testPackageNamedTypesNoBinding() {
        CompilationResult cR = ajc(new File(baseDir,"complexExample"),
                        new String[]{"A.java","B.java","Color.java","X.java","-1.5","-d","."});
-       System.err.println(cR.getStandardError());
        assertMessages(cR,new EmptyMessageSpec());
        RunResult rR = run("a.b.c.A");
   }
index bcc0fd05d67953b3fc00f707888c7dfadf363aff..7e4b93135c309cce5fe024a46f5adcdf5817c19e 100644 (file)
@@ -1307,55 +1307,97 @@ public class BcelShadow extends Shadow {
        // Then create one BcelVar entry in the map for each annotation, keyed by
        // annotation type (TypeX).
        
-       // !!! Refactor these once all shadow kinds added - there is lots of commonality
-       if (getKind() == Shadow.MethodCall) {
-               ResolvedMember rm[] = getSignature().getDeclaringType().getDeclaredMethods(world);
+       // !!! PREAJ5FINAL Refactor these once all shadow kinds added - there is lots of commonality
+       ResolvedTypeX[] annotations = null;
+       TypeX relevantType = null;
+       
+       if (getKind() == Shadow.StaticInitialization) {
+               relevantType = getSignature().getDeclaringType();
+               annotations  = relevantType.resolve(world).getAnnotationTypes();
+       }
+       if (getKind() == Shadow.ExceptionHandler) {
+               relevantType = getSignature().getParameterTypes()[0];
+               annotations  =  relevantType.resolve(world).getAnnotationTypes();
+       }
+       if (getKind() == Shadow.MethodCall  || getKind() == Shadow.ConstructorCall) {
+               relevantType = getSignature().getDeclaringType();
+               ResolvedMember rm[] = relevantType.getDeclaredMethods(world);
                ResolvedMember found = null;
                String searchString = getSignature().getName()+getSignature().getParameterSignature();
-               for (int i = 0; i < rm.length; i++) {
+               for (int i = 0; i < rm.length && found==null; i++) {
                                ResolvedMember member = rm[i];
                                if ((member.getName()+member.getParameterSignature()).equals(searchString)) {
                                        found = member;
                                }
                        }
-               ResolvedTypeX[] anns = found.getAnnotationTypes();
-               for (int i = 0; i < anns.length; i++) {
-                               ResolvedTypeX typeX = anns[i];
-                       kindedAnnotationVars.put(typeX,
-                                       new KindedAnnotationAccessVar(typeX.resolve(world),getSignature().getDeclaringType(),getSignature()));
+               annotations = found.getAnnotationTypes();
+       }
+       if (getKind() == Shadow.MethodExecution || getKind() == Shadow.ConstructorExecution || 
+               getKind() == Shadow.AdviceExecution) {
+               relevantType = getSignature().getDeclaringType();
+               ResolvedMember rm[] = relevantType.getDeclaredMethods(world);
+               ResolvedMember found = null;
+               String searchString = getSignature().getName()+getSignature().getParameterSignature();
+               for (int i = 0; i < rm.length && found==null; i++) {
+                               ResolvedMember member = rm[i];
+                               if ((member.getName()+member.getParameterSignature()).equals(searchString)) {
+                                       found = member;
+                               }
                        }
+               annotations = found.getAnnotationTypes();
        }
-       if (getKind() == Shadow.MethodExecution) {
-               ResolvedMember rm[] = getSignature().getDeclaringType().getDeclaredMethods(world);
+       if (getKind() == Shadow.PreInitialization || getKind() == Shadow.Initialization) {
+               relevantType = getSignature().getDeclaringType();
+               ResolvedMember rm[] = relevantType.getDeclaredMethods(world);
                ResolvedMember found = null;
                String searchString = getSignature().getName()+getSignature().getParameterSignature();
-               for (int i = 0; i < rm.length; i++) {
+               for (int i = 0; i < rm.length && found==null; i++) {
                                ResolvedMember member = rm[i];
                                if ((member.getName()+member.getParameterSignature()).equals(searchString)) {
                                        found = member;
                                }
                        }
-               ResolvedTypeX[] anns = found.getAnnotationTypes();
-               for (int i = 0; i < anns.length; i++) {
-                               ResolvedTypeX typeX = anns[i];
-                       kindedAnnotationVars.put(typeX,new KindedAnnotationAccessVar(typeX.resolve(world),getSignature().getDeclaringType(),getSignature()));
+               annotations = found.getAnnotationTypes();
+       }
+       if (getKind() == Shadow.FieldSet) {
+               relevantType = getSignature().getDeclaringType();
+               ResolvedMember rm[] = relevantType.getDeclaredFields(world);
+               ResolvedMember found = null;
+               for (int i = 0; i < rm.length && found==null; i++) {
+                               ResolvedMember member = rm[i];
+                               if ( member.getName().equals(getSignature().getName()) &&
+                                    member.getType().equals(getSignature().getType()))  {
+                                       found = member;
+                               }
                        }
+               annotations = found.getAnnotationTypes();
        }
-//     if (getKind() == Shadow.FieldSet) {
-//             ResolvedMember rm[] = this.getTargetType().getDeclaredFields(world);
-//             ResolvedMember found = null;
-//             for (int i = 0; i < rm.length; i++) {
-//                             ResolvedMember member = rm[i];
-//                             if ((member.getName()+member.getParameterSignature()).equals(getSignature().getName()+getSignature().getParameterSignature())) {
-//                                     found = member;
-//                             }
-//                     }
-//             ResolvedTypeX[] anns = found.getAnnotationTypes();
-//             for (int i = 0; i < anns.length; i++) {
-//                             ResolvedTypeX typeX = anns[i];
-//                     kindedAnnotationVars.put(typeX,new KindedAnnotationAccessVar(typeX.resolve(world),(BcelVar)getTargetVar(),getSignature()));
-//                     }
-//     }
+       if (getKind() == Shadow.FieldGet) {
+               relevantType = getSignature().getDeclaringType();
+               ResolvedMember rm[] = relevantType.getDeclaredFields(world);
+               ResolvedMember found = null;
+               for (int i = 0; i < rm.length && found==null; i++) {
+                               ResolvedMember member = rm[i];
+                               if ( member.getName().equals(getSignature().getName()) &&
+                                    member.getType().equals(getSignature().getType()))  {
+                                       found = member;
+                               }
+                       }
+               annotations = found.getAnnotationTypes();
+       }
+       
+       if (annotations == null) {
+               // We can't have recognized the shadow - should blow up now to be on the safe side
+               throw new BCException("Didn't recognize shadow: "+getKind());
+       }
+       
+               for (int i = 0; i < annotations.length; i++) {
+                       ResolvedTypeX aTX = annotations[i];
+               kindedAnnotationVars.put(aTX,
+                               new KindedAnnotationAccessVar(getKind(),aTX.resolve(world),relevantType,getSignature()));
+               }
+
+       
        
     }
     public void initializeWithinAnnotationVars() {
index c86f7e3285f8f07d2bc8dfecd440c2a4bb30d419..27a2eacd995d5be673acc8e3b5abf8cc704c1658 100644 (file)
@@ -22,34 +22,34 @@ import org.aspectj.apache.bcel.generic.ObjectType;
 import org.aspectj.apache.bcel.generic.Type;
 import org.aspectj.weaver.Member;
 import org.aspectj.weaver.ResolvedTypeX;
+import org.aspectj.weaver.Shadow;
 import org.aspectj.weaver.TypeX;
+import org.aspectj.weaver.Shadow.Kind;
 
-/**
- */
 //  Might need to create a mini hierarchy depending on how much can be shared 
 // amongst kinded pointcut variants of this class.
-public class KindedAnnotationAccessVar extends BcelVar {
 
+/**
+ * Represents access to an annotation on an element, relating to some 'kinded' pointcut.  
+ * Depending on the kind of pointcut the element might be a field or a method or a ...
+ * 
+ */
+public class KindedAnnotationAccessVar extends BcelVar {
 
-       private Member stackField;
-       private int index;
-       TypeX target;
-       Member sig;
+       private Kind kind;       // What kind of shadow are we at?
+       private TypeX target;    // The type upon which we want to ask for 'member'
+       private Member member;   // For method call/execution and field get/set contains the member that has the annotation
 
-//     public KindedAnnotationAccessVar(ResolvedTypeX type, Member stackField, int index) {
-//             super(type, 0);
-//             this.stackField = stackField;
-//             this.index = index;
-//     }
        
-       public KindedAnnotationAccessVar(ResolvedTypeX type,TypeX theTargetIsStoredHere,Member sig) {
+       public KindedAnnotationAccessVar(Kind kind, ResolvedTypeX type,TypeX theTargetIsStoredHere,Member sig) {
                super(type,0);
-               target = theTargetIsStoredHere;
-               this.sig = sig;
+               this.kind = kind;
+               target = theTargetIsStoredHere; 
+               this.member = sig;
        }
 
        public String toString() {
-               return "KindedAnnotationAccessVar(" + getType() + " " + stackField + "." + index + ")";
+               return "KindedAnnotationAccessVar(" + getType() +")";
        }
 
     public Instruction createLoad(InstructionFactory fact) {
@@ -67,6 +67,11 @@ public class KindedAnnotationAccessVar extends BcelVar {
                il.append(createLoadInstructions(getType(), fact));
        }
 
+       // PREAJ5FINAL Refactor all this stuff - there is a lot of commonality
+       // PREAJ5FINAL Decide on inclusion of the exception handlers for getDeclaredXXX methods
+       // PREAJ5FINAL Optimization to share result of getDeclaredXXX if accessing multiple annos at a join point
+       
+       // ASC 31Jan05 Please don't look inside this method - it isnt finished yet.
        public InstructionList createLoadInstructions(ResolvedTypeX toType, InstructionFactory fact) {
                
                // We ought to build an exception handler for the NoSuchMethodException that can be thrown
@@ -89,33 +94,71 @@ public class KindedAnnotationAccessVar extends BcelVar {
                Type jlClassArray = BcelWorld.makeBcelType(TypeX.forSignature("[Ljava.lang.Class;"));
                
                Type jlaAnnotation = BcelWorld.makeBcelType(TypeX.forSignature("Ljava.lang.annotation.Annotation;"));
-               Type jlrMethod = BcelWorld.makeBcelType(TypeX.forSignature("Ljava.lang.reflect.Method;"));
                
+               if (kind==Shadow.MethodCall || kind==Shadow.MethodExecution || 
+                       kind==Shadow.PreInitialization || kind==Shadow.Initialization || 
+                       kind==Shadow.ConstructorCall || kind==Shadow.ConstructorExecution ||
+                       kind==Shadow.AdviceExecution) {
+                       Type jlrMethod = BcelWorld.makeBcelType(TypeX.forSignature("Ljava.lang.reflect.Method;"));
                
                // Calls getClass
-               // System.err.println("What is the class of target? "+target.getType());
+                       
+               // Variant (1) Use the target directly
                il.append(fact.createConstant(BcelWorld.makeBcelType(target)));
-//             il.append(target.createLoad(fact));
-//        il.append(fact.createInvoke("java/lang/Object","getClass",jlClass,new Type[]{},Constants.INVOKEVIRTUAL));
+               
+               
+               // Variant (2) Ask the target for its class (could give a different answer at runtime)
+        // il.append(target.createLoad(fact));
+        // il.append(fact.createInvoke("java/lang/Object","getClass",jlClass,new Type[]{},Constants.INVOKEVIRTUAL));
     
-       //      il.append(fact.createConstant(new ObjectType(toType.getClassName())));
-        il.append(fact.createConstant(sig.getName()));
-        
-
-               Type[] paramTypes = BcelWorld.makeBcelTypes(sig.getParameterTypes());
-        
-               buildArray(il,fact,jlClass,paramTypes,1);
-        
-        // Calls getDeclaredMethod
-        il.append(fact.createInvoke("java/lang/Class","getDeclaredMethod",jlrMethod,new Type[]{jlString,jlClassArray},Constants.INVOKEVIRTUAL));
-        
-        // !!! OPTIMIZATION: Cache the result of getDeclaredMethod() and use it 
-        // again for other annotations on the same signature at this join point
-        // Calls getAnnotation
-        String ss = toType.getName();
-        il.append(fact.createConstant(new ObjectType(toType.getName())));              
-               il.append(fact.createInvoke("java/lang/reflect/Method","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
-               il.append(Utility.createConversion(fact,jlaAnnotation,BcelWorld.makeBcelType(toType)));
+           // il.append(fact.createConstant(new ObjectType(toType.getClassName())));
+       
+      
+                 if (kind==Shadow.MethodCall || kind==Shadow.MethodExecution || kind==Shadow.AdviceExecution) {
+                       il.append(fact.createConstant(member.getName()));
+                       Type[] paramTypes = BcelWorld.makeBcelTypes(member.getParameterTypes());
+                       buildArray(il,fact,jlClass,paramTypes,1);
+                       // Calls getDeclaredMethod
+                       il.append(fact.createInvoke("java/lang/Class","getDeclaredMethod",jlrMethod,new Type[]{jlString,jlClassArray},Constants.INVOKEVIRTUAL));
+                       // !!! OPTIMIZATION: Cache the result of getDeclaredMethod() and use it 
+               // again for other annotations on the same signature at this join point
+               // Calls getAnnotation
+               String ss = toType.getName();
+               il.append(fact.createConstant(new ObjectType(toType.getName())));               
+                       il.append(fact.createInvoke("java/lang/reflect/Method","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
+                       il.append(Utility.createConversion(fact,jlaAnnotation,BcelWorld.makeBcelType(toType)));
+                 } else { // init/preinit/ctor-call/ctor-exec
+                       Type[] paramTypes = BcelWorld.makeBcelTypes(member.getParameterTypes());
+                       buildArray(il,fact,jlClass,paramTypes,1);
+                       Type jlrCtor = BcelWorld.makeBcelType(TypeX.forSignature("Ljava.lang.reflect.Constructor;"));
+                       il.append(fact.createInvoke("java/lang/Class","getDeclaredConstructor",jlrCtor,new Type[]{jlClassArray},Constants.INVOKEVIRTUAL));
+               
+                       // !!! OPTIMIZATION: Cache the result of getDeclaredMethod() and use it 
+                       // again for other annotations on the same signature at this join point
+                       // Calls getAnnotation
+                       String ss = toType.getName();
+                       il.append(fact.createConstant(new ObjectType(toType.getName())));               
+                       il.append(fact.createInvoke("java/lang/reflect/Constructor","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
+                       il.append(Utility.createConversion(fact,jlaAnnotation,BcelWorld.makeBcelType(toType)));
+                 }
+               } else if (kind == Shadow.FieldSet || kind == Shadow.FieldGet) {
+                       Type jlrField = BcelWorld.makeBcelType(TypeX.forSignature("Ljava.lang.reflect.Field;"));
+                       il.append(fact.createConstant(BcelWorld.makeBcelType(target))); // Stick the target on the stack
+                       il.append(fact.createConstant(member.getName())); // Stick what we are after on the stack
+                       il.append(fact.createInvoke("java/lang/Class","getDeclaredField",jlrField,new Type[]{jlString},Constants.INVOKEVIRTUAL));
+                       String ss = toType.getName();
+               il.append(fact.createConstant(new ObjectType(toType.getName())));               
+                       il.append(fact.createInvoke("java/lang/reflect/Field","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
+                       il.append(Utility.createConversion(fact,jlaAnnotation,BcelWorld.makeBcelType(toType)));
+               } else if (kind == Shadow.StaticInitialization || kind==Shadow.ExceptionHandler) {
+                       il.append(fact.createConstant(BcelWorld.makeBcelType(target)));
+                       String ss = toType.getName();
+               il.append(fact.createConstant(new ObjectType(toType.getName())));               
+                       il.append(fact.createInvoke("java/lang/Class","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
+                       il.append(Utility.createConversion(fact,jlaAnnotation,BcelWorld.makeBcelType(toType)));
+               } else {
+                       throw new RuntimeException("Don't understand this kind "+kind);
+               }
                return il;
                
        }