summaryrefslogtreecommitdiffstats
path: root/weaver
diff options
context:
space:
mode:
authoraclement <aclement>2005-02-01 09:20:21 +0000
committeraclement <aclement>2005-02-01 09:20:21 +0000
commit756f85938f3e573b55fba70ee8e3e6254a7edf99 (patch)
treea67ec415063168bccccdf03248b46e83e8b8af56 /weaver
parent5622679b2f8e757b3cccd7f92841a0ecd481e50b (diff)
downloadaspectj-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.java104
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/KindedAnnotationAccessVar.java119
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;
}