From: aclement Date: Tue, 31 May 2011 22:13:30 +0000 (+0000) Subject: 347684: testcode X-Git-Tag: V1_6_12M1~11 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=9002c6a3436d18d5223c050bde12e9c9bddaf3a7;p=aspectj.git 347684: testcode --- diff --git a/weaver/src/org/aspectj/weaver/bcel/AnnotationAccessFieldVar.java b/weaver/src/org/aspectj/weaver/bcel/AnnotationAccessFieldVar.java index 041e92c54..60aa84125 100644 --- a/weaver/src/org/aspectj/weaver/bcel/AnnotationAccessFieldVar.java +++ b/weaver/src/org/aspectj/weaver/bcel/AnnotationAccessFieldVar.java @@ -11,10 +11,10 @@ * ******************************************************************/ 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 vals = annotation.getValues(); - boolean doneAndDusted = false; - for (Iterator 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 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; + } } } diff --git a/weaver/src/org/aspectj/weaver/bcel/AnnotationAccessVar.java b/weaver/src/org/aspectj/weaver/bcel/AnnotationAccessVar.java index 1cb3d4c9f..54b6361de 100644 --- a/weaver/src/org/aspectj/weaver/bcel/AnnotationAccessVar.java +++ b/weaver/src/org/aspectj/weaver/bcel/AnnotationAccessVar.java @@ -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); } } diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java index cac3e930e..7fb6068b8 100644 --- a/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java +++ b/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java @@ -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; } }