From 5d8ffc2c706139a7e4622a6442f2e0fbf5ffe9e1 Mon Sep 17 00:00:00 2001 From: aclement Date: Thu, 10 Mar 2005 17:49:53 +0000 Subject: [PATCH] Declare annotation: manages a set of annotations now --- .../org/aspectj/weaver/bcel/BcelField.java | 52 +++++++--- .../org/aspectj/weaver/bcel/BcelMethod.java | 64 +++++++++--- .../aspectj/weaver/bcel/BcelObjectType.java | 63 +++++++++--- .../org/aspectj/weaver/bcel/LazyClassGen.java | 99 +++++++++++++++---- .../aspectj/weaver/bcel/LazyMethodGen.java | 14 +++ 5 files changed, 231 insertions(+), 61 deletions(-) diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelField.java b/weaver/src/org/aspectj/weaver/bcel/BcelField.java index 042947543..0f415ffb2 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelField.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelField.java @@ -21,6 +21,7 @@ import org.aspectj.apache.bcel.classfile.Field; import org.aspectj.apache.bcel.classfile.Synthetic; import org.aspectj.apache.bcel.classfile.annotation.Annotation; import org.aspectj.weaver.AjAttribute; +import org.aspectj.weaver.AnnotationX; import org.aspectj.weaver.BCException; import org.aspectj.weaver.ResolvedMember; import org.aspectj.weaver.ResolvedTypeX; @@ -32,7 +33,8 @@ final class BcelField extends ResolvedMember { private Field field; private boolean isAjSynthetic; private boolean isSynthetic = false; - private ResolvedTypeX[] resolvedAnnotations; + private ResolvedTypeX[] annotationTypes; + private AnnotationX[] annotations; private World world; BcelField(BcelObjectType declaringType, Field field) { @@ -89,15 +91,43 @@ final class BcelField extends ResolvedMember { } public ResolvedTypeX[] getAnnotationTypes() { - if (resolvedAnnotations == null) { - Annotation[] annotations = field.getAnnotations(); - resolvedAnnotations = new ResolvedTypeX[annotations.length]; - for (int i = 0; i < annotations.length; i++) { - Annotation annotation = annotations[i]; + ensureAnnotationTypesRetrieved(); + return annotationTypes; + } + + private void ensureAnnotationTypesRetrieved() { + if (annotationTypes == null) { + Annotation annos[] = field.getAnnotations(); + annotationTypes = new ResolvedTypeX[annos.length]; + annotations = new AnnotationX[annos.length]; + for (int i = 0; i < annos.length; i++) { + Annotation annotation = annos[i]; ResolvedTypeX rtx = world.resolve(TypeX.forName(annotation.getTypeName())); - resolvedAnnotations[i] = rtx; + annotationTypes[i] = rtx; + annotations[i] = new AnnotationX(annotation,world); } - } - return resolvedAnnotations; - } -} + } + } + + public void addAnnotation(AnnotationX annotation) { + ensureAnnotationTypesRetrieved(); + // Add it to the set of annotations + int len = annotations.length; + AnnotationX[] ret = new AnnotationX[len+1]; + System.arraycopy(annotations, 0, ret, 0, len); + ret[len] = annotation; + annotations = ret; + + // Add it to the set of annotation types + len = annotationTypes.length; + ResolvedTypeX[] ret2 = new ResolvedTypeX[len+1]; + System.arraycopy(annotationTypes,0,ret2,0,len); + ret2[len] =world.resolve(TypeX.forName(annotation.getTypeName())); + annotationTypes = ret2; + // FIXME asc this call here suggests we are managing the annotations at + // too many levels, here in BcelField we keep a set and in the lower 'field' + // object we keep a set - we should think about reducing this to one + // level?? + field.addAnnotation(annotation.getBcelAnnotation()); + } +} \ No newline at end of file diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java b/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java index 3b9a6daff..69e67b7a2 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java @@ -25,6 +25,7 @@ import org.aspectj.apache.bcel.classfile.annotation.Annotation; import org.aspectj.bridge.ISourceLocation; import org.aspectj.bridge.SourceLocation; import org.aspectj.weaver.AjAttribute; +import org.aspectj.weaver.AnnotationX; import org.aspectj.weaver.BCException; import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.ResolvedMember; @@ -38,6 +39,10 @@ final class BcelMethod extends ResolvedMember { private Method method; private boolean isAjSynthetic; private ShadowMunger associatedShadowMunger; + + private ResolvedTypeX[] annotationTypes = null; + private AnnotationX[] annotations = null; + private AjAttribute.EffectiveSignatureAttribute effectiveSignature; private AjAttribute.MethodDeclarationLineNumberAttribute declarationLineNumber; private ResolvedTypeX[] resolvedAnnotations; @@ -115,7 +120,7 @@ final class BcelMethod extends ResolvedMember { return isAjSynthetic; // || getName().startsWith(NameMangler.PREFIX); } - //FIXME needs an isSynthetic method + //FIXME ??? needs an isSynthetic method public ShadowMunger getAssociatedShadowMunger() { return associatedShadowMunger; @@ -157,28 +162,55 @@ final class BcelMethod extends ResolvedMember { } public boolean hasAnnotation(TypeX ofType) { - Annotation[] anns = method.getAnnotations(); - for (int i = 0; i < anns.length; i++) { - Annotation annotation = anns[i]; - if (annotation.getTypeName().equals(ofType.getName())) return true; + ensureAnnotationTypesRetrieved(); + for (int i=0; i Short.MAX_VALUE) { - // PR 59208 - // we've generated a class that is just toooooooooo big (you've been generating programs - // again haven't you? come on, admit it, no-one writes classes this big by hand). - // create an empty myGen so that we can give back a return value that doesn't upset the - // rest of the process. - myGen = new ClassGen(myGen.getClassName(), myGen.getSuperclassName(), - myGen.getFileName(), myGen.getAccessFlags(), myGen.getInterfaceNames()); - // raise an error against this compilation unit. - getWorld().showMessage( - IMessage.ERROR, - WeaverMessages.format(WeaverMessages.CLASS_TOO_BIG, - this.getClassName()), - new SourceLocation(new File(myGen.getFileName()),0), null - ); + reportClassTooBigProblem(); return; } + if (annotations.size()>0) { + for (Iterator iter = annotations.iterator(); iter.hasNext();) { + AnnotationGen element = (AnnotationGen) iter.next(); + myGen.addAnnotation(element); + } +// Attribute[] annAttributes = org.aspectj.apache.bcel.classfile.Utility.getAnnotationAttributes(getConstantPoolGen(),annotations); +// for (int i = 0; i < annAttributes.length; i++) { +// Attribute attribute = annAttributes[i]; +// System.err.println("Adding attribute for "+attribute); +// myGen.addAttribute(attribute); +// } + } + // Add a weaver version attribute to the file being produced myGen.addAttribute(BcelAttributes.bcelAttribute(new AjAttribute.WeaverVersionInfo(),getConstantPoolGen())); @@ -431,6 +448,26 @@ public final class LazyClassGen { } } + /** + * + */ + private void reportClassTooBigProblem() { + // PR 59208 + // we've generated a class that is just toooooooooo big (you've been generating programs + // again haven't you? come on, admit it, no-one writes classes this big by hand). + // create an empty myGen so that we can give back a return value that doesn't upset the + // rest of the process. + myGen = new ClassGen(myGen.getClassName(), myGen.getSuperclassName(), + myGen.getFileName(), myGen.getAccessFlags(), myGen.getInterfaceNames()); + // raise an error against this compilation unit. + getWorld().showMessage( + IMessage.ERROR, + WeaverMessages.format(WeaverMessages.CLASS_TOO_BIG, + this.getClassName()), + new SourceLocation(new File(myGen.getFileName()),0), null + ); + } + private static boolean hasSourceDebugExtensionAttribute(ClassGen gen) { ConstantPoolGen pool = gen.getConstantPool(); Attribute[] attrs = gen.getAttributes(); @@ -848,4 +885,26 @@ public final class LazyClassGen { myGen.setAccessFlags(Utility.makePublic(myGen.getAccessFlags())); } + + public boolean hasAnnotation(TypeX t) { + + // annotations on the real thing + AnnotationGen agens[] = myGen.getAnnotations(); + if (agens==null) return false; + for (int i = 0; i < agens.length; i++) { + AnnotationGen gen = agens[i]; + if (t.equals(TypeX.forSignature(gen.getTypeSignature()))) return true; + } + + // annotations added during this weave + + return false; + } + + public void addAnnotation(Annotation a) { + if (!hasAnnotation(TypeX.forSignature(a.getTypeSignature()))) { + annotations.add(new AnnotationGen(a,getConstantPoolGen(),true)); + } + } + } diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java index f4b24adff..d97fefac6 100644 --- a/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java +++ b/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java @@ -53,6 +53,7 @@ import org.aspectj.apache.bcel.generic.annotation.AnnotationGen; import org.aspectj.bridge.IMessage; import org.aspectj.bridge.ISourceLocation; import org.aspectj.weaver.AjAttribute; +import org.aspectj.weaver.AnnotationX; import org.aspectj.weaver.BCException; import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.Member; @@ -178,6 +179,19 @@ public final class LazyMethodGen { } } + public void addAnnotation(AnnotationX ax) { + initialize(); +// if (!hasAnnotation(TypeX.forSignature(a.getTypeSignature()))) { + AnnotationGen ag = new AnnotationGen(ax.getBcelAnnotation(),enclosingClass.getConstantPoolGen(),true); + AnnotationGen[] newAnnotations = new AnnotationGen[annotations.length+1]; + System.arraycopy(annotations,0,newAnnotations,0,annotations.length); + newAnnotations[annotations.length]=ag; + annotations = newAnnotations; + // FIXME asc does this mean we are managing two levels of annotations again? + // one here and one in the memberView??!? + memberView.addAnnotation(ax); + } + private void initialize() { if (returnType != null) return; -- 2.39.5