diff options
author | aclement <aclement> | 2005-02-01 09:20:21 +0000 |
---|---|---|
committer | aclement <aclement> | 2005-02-01 09:20:21 +0000 |
commit | 756f85938f3e573b55fba70ee8e3e6254a7edf99 (patch) | |
tree | a67ec415063168bccccdf03248b46e83e8b8af56 /weaver | |
parent | 5622679b2f8e757b3cccd7f92841a0ecd481e50b (diff) | |
download | aspectj-756f85938f3e573b55fba70ee8e3e6254a7edf99.tar.gz aspectj-756f85938f3e573b55fba70ee8e3e6254a7edf99.zip |
Annotation Binding - now complete for @annotation (for *all* kinded PCDs)Root_AspectJ5_Development
Diffstat (limited to 'weaver')
-rw-r--r-- | weaver/src/org/aspectj/weaver/bcel/BcelShadow.java | 104 | ||||
-rw-r--r-- | weaver/src/org/aspectj/weaver/bcel/KindedAnnotationAccessVar.java | 119 |
2 files changed, 154 insertions, 69 deletions
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java index bcc0fd05d..7e4b93135 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java @@ -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() { diff --git a/weaver/src/org/aspectj/weaver/bcel/KindedAnnotationAccessVar.java b/weaver/src/org/aspectj/weaver/bcel/KindedAnnotationAccessVar.java index c86f7e328..27a2eacd9 100644 --- a/weaver/src/org/aspectj/weaver/bcel/KindedAnnotationAccessVar.java +++ b/weaver/src/org/aspectj/weaver/bcel/KindedAnnotationAccessVar.java @@ -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; } |