]> source.dussan.org Git - aspectj.git/commitdiff
347684: testcode
authoraclement <aclement>
Tue, 31 May 2011 22:13:30 +0000 (22:13 +0000)
committeraclement <aclement>
Tue, 31 May 2011 22:13:30 +0000 (22:13 +0000)
weaver/src/org/aspectj/weaver/bcel/AnnotationAccessFieldVar.java
weaver/src/org/aspectj/weaver/bcel/AnnotationAccessVar.java
weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java

index 041e92c5497ca71d68f6af2328f36a3a734ee3af..60aa8412514dd927aa463bc74a3609b0e95c2e79 100644 (file)
  * ******************************************************************/
 package org.aspectj.weaver.bcel;
 
-import java.util.Iterator;
 import java.util.List;
 
 import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
+import org.aspectj.apache.bcel.classfile.annotation.ElementValue;
 import org.aspectj.apache.bcel.classfile.annotation.EnumElementValue;
 import org.aspectj.apache.bcel.classfile.annotation.NameValuePair;
 import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue;
@@ -38,72 +38,134 @@ class AnnotationAccessFieldVar extends BcelVar {
 
        private AnnotationAccessVar annoAccessor;
        private ResolvedType annoFieldOfInterest;
+       private String name;
+       private int elementValueType;
 
-       public AnnotationAccessFieldVar(AnnotationAccessVar aav, ResolvedType annoFieldOfInterest) {
+       public AnnotationAccessFieldVar(AnnotationAccessVar aav, ResolvedType annoFieldOfInterest, String name) {
                super(annoFieldOfInterest, 0);
                this.annoAccessor = aav;
+               this.name = name;
+               String sig = annoFieldOfInterest.getSignature();
+               if (sig.length() == 1) {
+                       switch (sig.charAt(0)) {
+                       case 'I':
+                               elementValueType = ElementValue.PRIMITIVE_INT;
+                               break;
+                       default:
+                               throw new IllegalStateException(sig);
+                       }
+               } else if (sig.equals("Ljava/lang/String;")) {
+                       elementValueType = ElementValue.STRING;
+               } else if (annoFieldOfInterest.isEnum()) {
+                       elementValueType = ElementValue.ENUM_CONSTANT;
+               } else {
+                       throw new IllegalStateException(sig);
+               }
                this.annoFieldOfInterest = annoFieldOfInterest;
        }
 
        @Override
        public void appendLoadAndConvert(InstructionList il, InstructionFactory fact, ResolvedType toType) {
-               // Only possible to do annotation field value extraction at
-               // MethodExecution
+               // Only possible to do annotation field value extraction at MethodExecution
                if (annoAccessor.getKind() != Shadow.MethodExecution) {
                        return;
                }
                String annotationOfInterestSignature = annoAccessor.getType().getSignature();
-               // So we have an entity that has an annotation on and within it is the
-               // value we want
+               // So we have an entity that has an annotation on and within it is the value we want
                Member holder = annoAccessor.getMember();
                AnnotationAJ[] annos = holder.getAnnotations();
-               for (int i = 0; i < annos.length; i++) {
-                       AnnotationGen annotation = ((BcelAnnotation) annos[i]).getBcelAnnotation();
+               for (AnnotationAJ anno : annos) {
+                       AnnotationGen annotation = ((BcelAnnotation) anno).getBcelAnnotation();
+                       boolean foundValueInAnnotationUsage = false;
                        if (annotation.getTypeSignature().equals(annotationOfInterestSignature)) {
-                               List<NameValuePair> vals = annotation.getValues();
-                               boolean doneAndDusted = false;
-                               for (Iterator<NameValuePair> iterator = vals.iterator(); iterator.hasNext();) {
-                                       NameValuePair object = iterator.next();
-                                       Object o = object.getValue();
+                               ResolvedMember[] annotationFields = toType.getWorld()
+                                               .resolve(UnresolvedType.forSignature(annotation.getTypeSignature())).getDeclaredMethods();
+                               // Check how many fields there are of the type we are looking for. If >1 then we'll need
+                               // to use the name to choose the right one
+                               int countOfType = 0;
+                               for (ResolvedMember annotationField : annotationFields) {
+                                       if (annotationField.getType().equals(annoFieldOfInterest)) {
+                                               countOfType++;
+                                       }
+                               }
+
+                               // this block deals with an annotation that has actual values (i.e. not falling back to default values)
+                               List<NameValuePair> nvps = annotation.getValues();
+                               for (NameValuePair nvp : nvps) {
+                                       // If multiple of the same type, match by name
+                                       if (countOfType > 1) {
+                                               if (!nvp.getNameString().equals(name)) {
+                                                       continue;
+                                               }
+                                       }
+                                       ElementValue o = nvp.getValue();
+                                       if (o.getElementValueType() != elementValueType) {
+                                               continue;
+                                       }
                                        if (o instanceof EnumElementValue) {
-                                               EnumElementValue v = (EnumElementValue) object.getValue();
+                                               EnumElementValue v = (EnumElementValue) o;
                                                String s = v.getEnumTypeString();
                                                ResolvedType rt = toType.getWorld().resolve(UnresolvedType.forSignature(s));
                                                if (rt.equals(toType)) {
                                                        il.append(fact.createGetStatic(rt.getName(), v.getEnumValueString(), Type.getType(rt.getSignature())));
-                                                       doneAndDusted = true;
+                                                       foundValueInAnnotationUsage = true;
                                                }
                                        } else if (o instanceof SimpleElementValue) {
-                                               // FIXASC types other than String will go bang bang at runtime
-                                               SimpleElementValue v = (SimpleElementValue) object.getValue();
-                                               il.append(fact.createConstant(v.getValueString()));
-                                               doneAndDusted = true;
-                                               // String s = v.getEnumTypeString();
-                                               // ResolvedType rt = toType.getWorld().resolve(UnresolvedType.forSignature(s));
-                                               // if (rt.equals(toType)) {
-                                               // il.append(fact.createGetStatic(rt.getName(), v.getEnumValueString(), Type.getType(rt.getSignature())));
-                                               // doneAndDusted = true;
-                                               // }
+                                               SimpleElementValue v = (SimpleElementValue) o;
+                                               switch (v.getElementValueType()) {
+                                               case ElementValue.PRIMITIVE_INT:
+                                                       il.append(fact.createConstant(v.getValueInt()));
+                                                       foundValueInAnnotationUsage = true;
+                                                       break;
+                                               case ElementValue.STRING:
+                                                       il.append(fact.createConstant(v.getValueString()));
+                                                       foundValueInAnnotationUsage = true;
+                                                       break;
+                                               default:
+                                                       throw new IllegalStateException("NYI: Unsupported annotation value binding for " + o);
+                                               }
+                                       }
+                                       if (foundValueInAnnotationUsage) {
+                                               break;
                                        }
                                }
-                               if (!doneAndDusted) {
-                                       ResolvedMember[] annotationFields = toType.getWorld()
-                                                       .resolve(UnresolvedType.forSignature(annotation.getTypeSignature())).getDeclaredMethods();
-
-                                       // ResolvedMember[] fs = rt.getDeclaredFields();
-                                       for (int ii = 0; ii < annotationFields.length; ii++) {
-                                               if (annotationFields[ii].getType().equals(annoFieldOfInterest)) {
-                                                       String dvalue = annotationFields[ii].getAnnotationDefaultValue();
-                                                       // form will be LBLAHBLAHBLAH;X where X is the field
-                                                       // within X
+                               // this block deals with default values
+                               if (!foundValueInAnnotationUsage) {
+                                       for (ResolvedMember annotationField : annotationFields) {
+                                               if (countOfType > 1) {
+                                                       if (!annotationField.getName().equals(name)) {
+                                                               continue;
+                                                       }
+                                               }
+                                               if (!annotationField.getType().getSignature().equals(annoFieldOfInterest.getSignature())) {
+                                                       continue;
+                                               }
+                                               if (annotationField.getType().getSignature().equals("I")) {
+                                                       int ivalue = Integer.parseInt(annotationField.getAnnotationDefaultValue());
+                                                       il.append(fact.createConstant(ivalue));
+                                                       foundValueInAnnotationUsage = true;
+                                                       break;
+                                               } else if (annotationField.getType().getSignature().equals("Ljava/lang/String;")) {
+                                                       String svalue = annotationField.getAnnotationDefaultValue();
+                                                       il.append(fact.createConstant(svalue));
+                                                       foundValueInAnnotationUsage = true;
+                                                       break;
+                                               } else {
+                                                       String dvalue = annotationField.getAnnotationDefaultValue();
+                                                       // form will be LBLAHBLAHBLAH;X where X is the field within X
                                                        String typename = dvalue.substring(0, dvalue.lastIndexOf(';') + 1);
                                                        String field = dvalue.substring(dvalue.lastIndexOf(';') + 1);
                                                        ResolvedType rt = toType.getWorld().resolve(UnresolvedType.forSignature(typename));
                                                        il.append(fact.createGetStatic(rt.getName(), field, Type.getType(rt.getSignature())));
+                                                       foundValueInAnnotationUsage = true;
+                                                       break;
                                                }
                                        }
                                }
                        }
+                       if (foundValueInAnnotationUsage) {
+                               break;
+                       }
                }
        }
 
index 1cb3d4c9fab450f1cc72bc1b4f17c65a960b48df..54b6361de6c0a2c9f4c9d5cbcc0ce5b5da8c2bfb 100644 (file)
@@ -25,8 +25,8 @@ import org.aspectj.apache.bcel.generic.Type;
 import org.aspectj.weaver.Member;
 import org.aspectj.weaver.ResolvedType;
 import org.aspectj.weaver.Shadow;
-import org.aspectj.weaver.UnresolvedType;
 import org.aspectj.weaver.Shadow.Kind;
+import org.aspectj.weaver.UnresolvedType;
 import org.aspectj.weaver.ast.Var;
 
 /**
@@ -123,8 +123,7 @@ public class AnnotationAccessVar extends BcelVar {
                                Field annotationCachingField = shadow.getEnclosingClass().getAnnotationCachingField(shadow, toType);
 
                                // Basic idea here is to check if the cached field is null, if it is then initialize it, otherwise use it
-                               il.append(fact
-                                               .createGetStatic(shadow.getEnclosingClass().getName(), annotationCachingField.getName(), jlAnnotation));
+                               il.append(fact.createGetStatic(shadow.getEnclosingClass().getName(), annotationCachingField.getName(), jlAnnotation));
                                il.append(InstructionConstants.DUP);
                                InstructionBranch ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null);
                                il.append(ifNonNull);
@@ -140,8 +139,7 @@ public class AnnotationAccessVar extends BcelVar {
                                il.append(fact.createInvoke("java/lang/reflect/Method", "getAnnotation", jlaAnnotation, new Type[] { jlClass },
                                                Constants.INVOKEVIRTUAL));
                                il.append(InstructionConstants.DUP);
-                               il.append(fact
-                                               .createPutStatic(shadow.getEnclosingClass().getName(), annotationCachingField.getName(), jlAnnotation));
+                               il.append(fact.createPutStatic(shadow.getEnclosingClass().getName(), annotationCachingField.getName(), jlAnnotation));
                                InstructionHandle ifNullElse = il.append(InstructionConstants.NOP);
                                ifNonNull.setTarget(ifNullElse);
 
@@ -231,10 +229,11 @@ public class AnnotationAccessVar extends BcelVar {
         * Return an object that can access a particular value of this annotation.
         * 
         * @param valueType The type from the annotation that is of interest
+        * @param the formal name expressed in the pointcut, can be used to disambiguate
         * @return a variable that represents access to that annotation value
         */
        @Override
-       public Var getAccessorForValue(ResolvedType valueType) {
-               return new AnnotationAccessFieldVar(this, valueType);
+       public Var getAccessorForValue(ResolvedType valueType, String formalName) {
+               return new AnnotationAccessFieldVar(this, valueType, formalName);
        }
 }
index cac3e930e4049ae1feb57b8ad248a70094b934c6..7fb6068b8e660828648e591ff9563544c80be141 100644 (file)
@@ -477,6 +477,24 @@ public final class LazyMethodGen implements Traceable {
                        body = null;
                        MethodGen gen = pack();
                        return gen.getMethod();
+               } catch (RuntimeException re) {
+                       if (re.getCause() instanceof ClassGenException) {
+                               enclosingClass
+                                               .getBcelObjectType()
+                                               .getResolvedTypeX()
+                                               .getWorld()
+                                               .showMessage(
+                                                               IMessage.ERROR,
+                                                               WeaverMessages.format(WeaverMessages.PROBLEM_GENERATING_METHOD, this.getClassName(),
+                                                                               this.getName(), re.getCause().getMessage()),
+                                                               this.getMemberView() == null ? null : this.getMemberView().getSourceLocation(), null);
+                               // throw e; PR 70201.... let the normal problem reporting
+                               // infrastructure deal with this rather than crashing.
+                               body = null;
+                               MethodGen gen = pack();
+                               return gen.getMethod();
+                       }
+                       throw re;
                }
        }