summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraclement <aclement>2005-03-10 17:49:53 +0000
committeraclement <aclement>2005-03-10 17:49:53 +0000
commit5d8ffc2c706139a7e4622a6442f2e0fbf5ffe9e1 (patch)
tree5941eee69d955f825eb2d4ed9d7939996b2ea3fc
parent826e7ba5f34af654e2c895afcfcecf8d46c17d3c (diff)
downloadaspectj-5d8ffc2c706139a7e4622a6442f2e0fbf5ffe9e1.tar.gz
aspectj-5d8ffc2c706139a7e4622a6442f2e0fbf5ffe9e1.zip
Declare annotation: manages a set of annotations now
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelField.java52
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelMethod.java64
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java63
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java99
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java14
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<annotationTypes.length; i++) {
+ ResolvedTypeX aType = annotationTypes[i];
+ if (aType.equals(ofType)) return true;
}
return false;
}
- public Annotation[] getAnnotations() {
- return method.getAnnotations();
+ public AnnotationX[] getAnnotations() {
+ ensureAnnotationTypesRetrieved();
+ return annotations;
}
public ResolvedTypeX[] getAnnotationTypes() {
- if (resolvedAnnotations == null) {
- Annotation[] annotations = method.getAnnotations();
- resolvedAnnotations = new ResolvedTypeX[annotations.length];
- for (int i = 0; i < annotations.length; i++) {
- Annotation annotation = annotations[i];
+ ensureAnnotationTypesRetrieved();
+ return annotationTypes;
+ }
+
+ 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 looks like we are managing two 'bunches' of annotations, one
+ // here and one in the real 'method' - should we reduce it to one layer?
+ method.addAnnotation(annotation.getBcelAnnotation());
+ }
+
+ private void ensureAnnotationTypesRetrieved() {
+ if (annotationTypes == null) {
+ Annotation annos[] = method.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;
- }
+ }
+ }
}
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java b/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java
index 34f9c6577..6fc2d7e93 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java
@@ -29,6 +29,7 @@ import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
import org.aspectj.apache.bcel.classfile.annotation.ElementValue;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.weaver.AjAttribute;
+import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.ResolvedPointcutDefinition;
@@ -48,7 +49,8 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName {
private ResolvedTypeX superClass = null;
private ResolvedMember[] fields = null;
private ResolvedMember[] methods = null;
- private ResolvedTypeX[] resolvedAnnotations = null;
+ private ResolvedTypeX[] annotationTypes = null;
+ private AnnotationX[] annotations = null;
// strangely non-lazy
private ResolvedPointcutDefinition[] pointcuts = null;
@@ -225,6 +227,8 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName {
this.perClause = null;
this.weaverState = null;
this.lazyClassGen = null;
+ this.annotations = null;
+ this.annotationTypes = null;
isObject = (javaClass.getSuperclassNameIndex() == 0);
unpackAspectAttributes();
@@ -293,6 +297,23 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName {
return javaClass.isAnnotation();
}
+ public void addAnnotation(AnnotationX annotation) {
+
+ // 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] = getResolvedTypeX().getWorld().resolve(TypeX.forName(annotation.getTypeName()));
+ annotationTypes = ret2;
+ }
+
public boolean isAnnotationWithRuntimeRetention() {
if (!isAnnotation()) {
return false;
@@ -320,7 +341,7 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName {
}
public ISourceLocation getSourceLocation() {
- return getResolvedTypeX().getSourceContext().makeSourceLocation(0); //FIXME, we can do better than this
+ return getResolvedTypeX().getSourceContext().makeSourceLocation(0); //FIXME ??? we can do better than this
}
public AjAttribute.WeaverVersionInfo getWeaverVersionAttribute() {
@@ -346,26 +367,40 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName {
public boolean hasAnnotation(TypeX ofType) {
- Annotation[] annotationsOnThisType = javaClass.getAnnotations();
- for (int i = 0; i < annotationsOnThisType.length; i++) {
- Annotation a = annotationsOnThisType[i];
- if (a.getTypeName().equals(ofType.getName())) return true;
+ ensureAnnotationTypesRetrieved();
+ for (int i = 0; i < annotationTypes.length; i++) {
+ ResolvedTypeX annX = annotationTypes[i];
+ if (annX.equals(ofType)) return true;
}
return false;
}
- public ResolvedTypeX[] getAnnotationTypes() {
- if (resolvedAnnotations == null) {
- Annotation annotations[] = javaClass.getAnnotations();
- resolvedAnnotations = new ResolvedTypeX[annotations.length];
- for (int i = 0; i < annotations.length; i++) {
- Annotation annotation = annotations[i];
+ private void ensureAnnotationTypesRetrieved() {
+ if (annotationTypes == null) {
+ Annotation annos[] = javaClass.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 = getResolvedTypeX().getWorld().resolve(TypeX.forName(annotation.getTypeName()));
- resolvedAnnotations[i] = rtx;
+ annotationTypes[i] = rtx;
+ annotations[i] = new AnnotationX(annotation,getResolvedTypeX().getWorld());
}
}
- return resolvedAnnotations;
+ }
+
+ public ResolvedTypeX[] getAnnotationTypes() {
+ ensureAnnotationTypesRetrieved();
+ return annotationTypes;
}
+
+ /**
+ * Releases annotations wrapped in an annotationX
+ */
+ public AnnotationX[] getAnnotations() {
+ ensureAnnotationTypesRetrieved();
+ return annotations;
+ }
}
diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java
index 21c2e5059..f644a6501 100644
--- a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java
+++ b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java
@@ -36,6 +36,7 @@ import org.aspectj.apache.bcel.classfile.Field;
import org.aspectj.apache.bcel.classfile.JavaClass;
import org.aspectj.apache.bcel.classfile.Method;
import org.aspectj.apache.bcel.classfile.Unknown;
+import org.aspectj.apache.bcel.classfile.annotation.Annotation;
import org.aspectj.apache.bcel.generic.ClassGen;
import org.aspectj.apache.bcel.generic.ConstantPoolGen;
import org.aspectj.apache.bcel.generic.FieldGen;
@@ -47,6 +48,7 @@ import org.aspectj.apache.bcel.generic.ObjectType;
import org.aspectj.apache.bcel.generic.PUSH;
import org.aspectj.apache.bcel.generic.RETURN;
import org.aspectj.apache.bcel.generic.Type;
+import org.aspectj.apache.bcel.generic.annotation.AnnotationGen;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.SourceLocation;
@@ -63,6 +65,13 @@ import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.WeaverStateInfo;
import org.aspectj.weaver.World;
+/**
+ * Lazy lazy lazy.
+ * We don't unpack the underlying class unless necessary. Things
+ * like new methods and annotations accumulate in here until they
+ * must be written out, don't add them to the underlying MethodGen!
+ * Things are slightly different if this represents an Aspect.
+ */
public final class LazyClassGen {
// ---- JSR 45 info
@@ -197,11 +206,9 @@ public final class LazyClassGen {
private ClassGen myGen;
private ConstantPoolGen constantPoolGen;
- private List /*LazyMethodGen*/
- methodGens = new ArrayList();
- private List /*LazyClassGen*/
- classGens = new ArrayList();
-
+ private List /*LazyMethodGen*/ methodGens = new ArrayList();
+ private List /*LazyClassGen*/ classGens = new ArrayList();
+ private List /*AnnotationGen*/ annotations = new ArrayList();
private int childCounter = 0;
public int getNewGeneratedNameTag() {
@@ -374,28 +381,38 @@ public final class LazyClassGen {
public List getMethodGens() {
return methodGens; //???Collections.unmodifiableList(methodGens);
-
+ }
+
+ // FIXME asc Should be collection returned here
+ public Field[] getFieldGens() {
+ return myGen.getFields();
+ }
+
+ // FIXME asc How do the ones on the underlying class surface if this just returns new ones added?
+ // FIXME asc ...although no one calls this right now !
+ public List getAnnotations() {
+ return annotations;
}
private void writeBack(BcelWorld world) {
if (getConstantPoolGen().getSize() > 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;