import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
* will iterate over the fields repeatedly until everything has been applied.
*
*/
- private boolean weaveAtFieldRepeatedly(List<DeclareAnnotation> decaFs, List itdFields, List<Integer> reportedErrors) {
+ private boolean weaveAtFieldRepeatedly(List<DeclareAnnotation> decaFs, List<ConcreteTypeMunger> itdFields,
+ List<Integer> reportedErrors) {
boolean isChanged = false;
- for (Iterator iter = itdFields.iterator(); iter.hasNext();) {
+ for (Iterator<ConcreteTypeMunger> iter = itdFields.iterator(); iter.hasNext();) {
BcelTypeMunger fieldMunger = (BcelTypeMunger) iter.next();
ResolvedMember itdIsActually = fieldMunger.getSignature();
- List<DeclareAnnotation> worthRetrying = new ArrayList<DeclareAnnotation>();
+ Set<DeclareAnnotation> worthRetrying = new LinkedHashSet<DeclareAnnotation>();
boolean modificationOccured = false;
for (Iterator<DeclareAnnotation> iter2 = decaFs.iterator(); iter2.hasNext();) {
DeclareAnnotation decaF = iter2.next();
-
if (decaF.matches(itdIsActually, world)) {
- LazyMethodGen annotationHolder = locateAnnotationHolderForFieldMunger(clazz, fieldMunger);
- if (doesAlreadyHaveAnnotation(annotationHolder, itdIsActually, decaF, reportedErrors)) {
- continue; // skip this one...
- }
- annotationHolder.addAnnotation(decaF.getAnnotation());
- AsmRelationshipProvider.addDeclareAnnotationRelationship(world.getModelAsAsmManager(),
- decaF.getSourceLocation(), itdIsActually.getSourceLocation());
- isChanged = true;
- modificationOccured = true;
+ if (decaF.isRemover()) {
+ LazyMethodGen annotationHolder = locateAnnotationHolderForFieldMunger(clazz, fieldMunger);
+ if (annotationHolder.hasAnnotation(decaF.getAnnotationType())) {
+ isChanged = true;
+ // something to remove
+ annotationHolder.removeAnnotation(decaF.getAnnotationType());
+ AsmRelationshipProvider.addDeclareAnnotationRelationship(world.getModelAsAsmManager(),
+ decaF.getSourceLocation(), itdIsActually.getSourceLocation(), true);
+ } else {
+ worthRetrying.add(decaF);
+ }
+ } else {
+ LazyMethodGen annotationHolder = locateAnnotationHolderForFieldMunger(clazz, fieldMunger);
+ if (doesAlreadyHaveAnnotation(annotationHolder, itdIsActually, decaF, reportedErrors)) {
+ continue; // skip this one...
+ }
+ annotationHolder.addAnnotation(decaF.getAnnotation());
+ AsmRelationshipProvider.addDeclareAnnotationRelationship(world.getModelAsAsmManager(),
+ decaF.getSourceLocation(), itdIsActually.getSourceLocation(), false);
+ isChanged = true;
+ modificationOccured = true;
+ }
} else {
if (!decaF.isStarredAnnotationPattern()) {
worthRetrying.add(decaF); // an annotation is specified
for (Iterator<DeclareAnnotation> iter2 = worthRetrying.iterator(); iter2.hasNext();) {
DeclareAnnotation decaF = iter2.next();
if (decaF.matches(itdIsActually, world)) {
- LazyMethodGen annotationHolder = locateAnnotationHolderForFieldMunger(clazz, fieldMunger);
- if (doesAlreadyHaveAnnotation(annotationHolder, itdIsActually, decaF, reportedErrors)) {
- continue; // skip this one...
+ if (decaF.isRemover()) {
+ LazyMethodGen annotationHolder = locateAnnotationHolderForFieldMunger(clazz, fieldMunger);
+ if (annotationHolder.hasAnnotation(decaF.getAnnotationType())) {
+ isChanged = true;
+ // something to remove
+ annotationHolder.removeAnnotation(decaF.getAnnotationType());
+ AsmRelationshipProvider.addDeclareAnnotationRelationship(world.getModelAsAsmManager(),
+ decaF.getSourceLocation(), itdIsActually.getSourceLocation(), true);
+ forRemoval.add(decaF);
+ }
+ } else {
+ LazyMethodGen annotationHolder = locateAnnotationHolderForFieldMunger(clazz, fieldMunger);
+ if (doesAlreadyHaveAnnotation(annotationHolder, itdIsActually, decaF, reportedErrors)) {
+ continue; // skip this one...
+ }
+ annotationHolder.addAnnotation(decaF.getAnnotation());
+ AsmRelationshipProvider.addDeclareAnnotationRelationship(world.getModelAsAsmManager(),
+ decaF.getSourceLocation(), itdIsActually.getSourceLocation(), false);
+ isChanged = true;
+ modificationOccured = true;
+ forRemoval.add(decaF);
}
- annotationHolder.addAnnotation(decaF.getAnnotation());
- AsmRelationshipProvider.addDeclareAnnotationRelationship(world.getModelAsAsmManager(),
- decaF.getSourceLocation(), itdIsActually.getSourceLocation());
- isChanged = true;
- modificationOccured = true;
- forRemoval.add(decaF);
}
}
worthRetrying.removeAll(forRemoval);
annotationHolder.addAnnotation(decaMC.getAnnotation());
isChanged = true;
AsmRelationshipProvider.addDeclareAnnotationRelationship(asmManager, decaMC.getSourceLocation(),
- unMangledInterMethod.getSourceLocation());
+ unMangledInterMethod.getSourceLocation(), false);
reportMethodCtorWeavingMessage(clazz, unMangledInterMethod, decaMC, -1);
modificationOccured = true;
} else {
annotationHolder.addAnnotation(decaMC.getAnnotation());
unMangledInterMethod.addAnnotation(decaMC.getAnnotation());
AsmRelationshipProvider.addDeclareAnnotationRelationship(asmManager, decaMC.getSourceLocation(),
- unMangledInterMethod.getSourceLocation());
+ unMangledInterMethod.getSourceLocation(), false);
isChanged = true;
modificationOccured = true;
forRemoval.add(decaMC);
}
private boolean dontAddTwice(DeclareAnnotation decaF, AnnotationAJ[] dontAddMeTwice) {
- for (int i = 0; i < dontAddMeTwice.length; i++) {
- AnnotationAJ ann = dontAddMeTwice[i];
+ for (AnnotationAJ ann : dontAddMeTwice) {
if (ann != null && decaF.getAnnotation().getTypeName().equals(ann.getTypeName())) {
- // dontAddMeTwice[i] = null; // incase it really has been added
- // twice!
return true;
}
}
return false;
}
+ // BUGWARNING not getting enough warnings out on declare @field ? There is a potential problem here with warnings not
+ // coming out - this will occur if they are created on the second iteration round this loop.
+ // We currently deactivate error reporting for the second time round. A possible solution is to record what annotations
+ // were added by what decafs and check that to see if an error needs to be reported - this would be expensive so lets
+ // skip it for now
/**
- * Weave any declare @field statements into the fields of the supplied class
+ * Weave any declare @field statements into the fields of the supplied class. This will attempt to apply them to the ITDs too.
*
* Interesting case relating to public ITDd fields. The annotations are really stored against the interfieldinit method in the
* aspect, but the public field is placed in the target type and then is processed in the 2nd pass over fields that occurs. I
* as well as on the interfieldinit method.
*/
private boolean weaveDeclareAtField(LazyClassGen clazz) {
-
- // BUGWARNING not getting enough warnings out on declare @field ?
- // There is a potential problem here with warnings not coming out - this
- // will occur if they are created on the second iteration round this
- // loop.
- // We currently deactivate error reporting for the second time round.
- // A possible solution is to record what annotations were added by what
- // decafs and check that to see if an error needs to be reported - this
- // would be expensive so lets skip it for now
-
List<Integer> reportedProblems = new ArrayList<Integer>();
-
List<DeclareAnnotation> allDecafs = world.getDeclareAnnotationOnFields();
if (allDecafs.isEmpty()) {
return false;
}
-
- boolean isChanged = false;
- List<ConcreteTypeMunger> itdFields = getITDSubset(clazz, ResolvedTypeMunger.Field);
- if (itdFields != null) {
- isChanged = weaveAtFieldRepeatedly(allDecafs, itdFields, reportedProblems);
+ boolean typeIsChanged = false;
+ List<ConcreteTypeMunger> relevantItdFields = getITDSubset(clazz, ResolvedTypeMunger.Field);
+ if (relevantItdFields != null) {
+ typeIsChanged = weaveAtFieldRepeatedly(allDecafs, relevantItdFields, reportedProblems);
}
- List<DeclareAnnotation> decaFs = getMatchingSubset(allDecafs, clazz.getType());
- if (decaFs.isEmpty()) {
- return false; // nothing more to do
+ List<DeclareAnnotation> decafs = getMatchingSubset(allDecafs, clazz.getType());
+ if (decafs.isEmpty()) {
+ return typeIsChanged;
}
+
List<BcelField> fields = clazz.getFieldGens();
if (fields != null) {
Set<DeclareAnnotation> unusedDecafs = new HashSet<DeclareAnnotation>();
- unusedDecafs.addAll(decaFs);
- for (int fieldCounter = 0; fieldCounter < fields.size(); fieldCounter++) {
- BcelField aBcelField = fields.get(fieldCounter);// new
- // BcelField(clazz.getBcelObjectType(),fields[fieldCounter
- // ]);
- if (!aBcelField.getName().startsWith(NameMangler.PREFIX)) {
+ unusedDecafs.addAll(decafs);
+ for (BcelField field : fields) {
+ if (!field.getName().startsWith(NameMangler.PREFIX)) {
// Single first pass
- List<DeclareAnnotation> worthRetrying = new ArrayList<DeclareAnnotation>();
+ Set<DeclareAnnotation> worthRetrying = new LinkedHashSet<DeclareAnnotation>();
boolean modificationOccured = false;
-
- AnnotationAJ[] dontAddMeTwice = aBcelField.getAnnotations();
+ AnnotationAJ[] dontAddMeTwice = field.getAnnotations();
// go through all the declare @field statements
- for (DeclareAnnotation decaF : decaFs) {
- if (decaF.getAnnotation() == null) {
+ for (DeclareAnnotation decaf : decafs) {
+ if (decaf.getAnnotation() == null) {
return false;
}
- if (decaF.matches(aBcelField, world)) {
-
- if (!dontAddTwice(decaF, dontAddMeTwice)) {
- if (doesAlreadyHaveAnnotation(aBcelField, decaF, reportedProblems)) {
- // remove the declare @field since don't
- // want an error when
- // the annotation is already there
- unusedDecafs.remove(decaF);
- continue;
- }
-
- if (decaF.getAnnotation().isRuntimeVisible()) { // isAnnotationWithRuntimeRetention
- // (
- // clazz
- // .
- // getJavaClass(world))){
- // if(decaF.getAnnotationTypeX().
- // isAnnotationWithRuntimeRetention(world)){
- // it should be runtime visible, so put it
- // on the Field
- // Annotation a =
- // decaF.getAnnotationX().getBcelAnnotation
- // ();
- // AnnotationGen ag = new
- // AnnotationGen(a,clazz
- // .getConstantPoolGen(),true);
- // FieldGen myGen = new
- // FieldGen(fields[fieldCounter
- // ],clazz.getConstantPoolGen());
- // myGen.addAnnotation(ag);
- // Field newField = myGen.getField();
-
- aBcelField.addAnnotation(decaF.getAnnotation());
- // clazz.replaceField(fields[fieldCounter],
- // newField);
- // fields[fieldCounter]=newField;
-
+ if (decaf.matches(field, world)) {
+ if (decaf.isRemover()) {
+ AnnotationAJ annotation = decaf.getAnnotation();
+ if (field.hasAnnotation(annotation.getType())) {
+ // something to remove
+ typeIsChanged = true;
+ field.removeAnnotation(annotation);
+ AsmRelationshipProvider.addDeclareAnnotationFieldRelationship(world.getModelAsAsmManager(),
+ decaf.getSourceLocation(), clazz.getName(), field, true);
+ reportFieldAnnotationWeavingMessage(clazz, field, decaf, true);
} else {
- aBcelField.addAnnotation(decaF.getAnnotation());
+ worthRetrying.add(decaf);
}
+ unusedDecafs.remove(decaf);
+ } else {
+ if (!dontAddTwice(decaf, dontAddMeTwice)) {
+ if (doesAlreadyHaveAnnotation(field, decaf, reportedProblems)) {
+ // remove the declare @field since don't want an error when the annotation is already there
+ unusedDecafs.remove(decaf);
+ continue;
+ }
+ field.addAnnotation(decaf.getAnnotation());
+ }
+ AsmRelationshipProvider.addDeclareAnnotationFieldRelationship(world.getModelAsAsmManager(),
+ decaf.getSourceLocation(), clazz.getName(), field, false);
+ reportFieldAnnotationWeavingMessage(clazz, field, decaf, false);
+ typeIsChanged = true;
+ modificationOccured = true;
+ unusedDecafs.remove(decaf);
}
-
- AsmRelationshipProvider.addDeclareAnnotationFieldRelationship(world.getModelAsAsmManager(),
- decaF.getSourceLocation(), clazz.getName(), aBcelField);
- reportFieldAnnotationWeavingMessage(clazz, fields, fieldCounter, decaF);
- isChanged = true;
- modificationOccured = true;
- // remove the declare @field since have matched
- // against it
- unusedDecafs.remove(decaF);
- } else {
- if (!decaF.isStarredAnnotationPattern()) {
- worthRetrying.add(decaF); // an annotation is
- // specified that
- // might be put on
- // by a subsequent
- // decaf
- }
+ } else if (!decaf.isStarredAnnotationPattern() || decaf.isRemover()) {
+ worthRetrying.add(decaf); // an annotation is specified that might be put on by a subsequent decaf
}
}
// Multiple secondary passes
while (!worthRetrying.isEmpty() && modificationOccured) {
modificationOccured = false;
- // lets have another go
+ // lets have another go with any remaining ones
List<DeclareAnnotation> forRemoval = new ArrayList<DeclareAnnotation>();
for (Iterator<DeclareAnnotation> iter = worthRetrying.iterator(); iter.hasNext();) {
DeclareAnnotation decaF = iter.next();
- if (decaF.matches(aBcelField, world)) {
- // below code is for recursive things
- if (doesAlreadyHaveAnnotation(aBcelField, decaF, reportedProblems)) {
- // remove the declare @field since don't
- // want an error when
- // the annotation is already there
+
+ if (decaF.matches(field, world)) {
+ if (decaF.isRemover()) {
+ AnnotationAJ annotation = decaF.getAnnotation();
+ if (field.hasAnnotation(annotation.getType())) {
+ // something to remove
+ typeIsChanged = modificationOccured = true;
+ forRemoval.add(decaF);
+ field.removeAnnotation(annotation);
+ AsmRelationshipProvider.addDeclareAnnotationFieldRelationship(world.getModelAsAsmManager(),
+ decaF.getSourceLocation(), clazz.getName(), field, true);
+ reportFieldAnnotationWeavingMessage(clazz, field, decaF, true);
+ }
+ } else {
+ // below code is for recursive things
unusedDecafs.remove(decaF);
- continue; // skip this one...
+ if (doesAlreadyHaveAnnotation(field, decaF, reportedProblems)) {
+ continue;
+ }
+ field.addAnnotation(decaF.getAnnotation());
+ AsmRelationshipProvider.addDeclareAnnotationFieldRelationship(world.getModelAsAsmManager(),
+ decaF.getSourceLocation(), clazz.getName(), field, false);
+ typeIsChanged = modificationOccured = true;
+ forRemoval.add(decaF);
}
- aBcelField.addAnnotation(decaF.getAnnotation());
- AsmRelationshipProvider.addDeclareAnnotationFieldRelationship(world.getModelAsAsmManager(),
- decaF.getSourceLocation(), clazz.getName(), aBcelField);
- isChanged = true;
- modificationOccured = true;
- forRemoval.add(decaF);
- // remove the declare @field since have matched
- // against it
- unusedDecafs.remove(decaF);
}
}
worthRetrying.removeAll(forRemoval);
}
checkUnusedDeclareAts(unusedDecafs, true);
}
- return isChanged;
+ return typeIsChanged;
}
// bug 99191 - put out an error message if the type doesn't exist
for (DeclareAnnotation declA : unusedDecaTs) {
// Error if an exact type pattern was specified
- boolean shouldCheck = declA.isExactPattern() || declA.getSignaturePattern().getExactDeclaringTypes().size() != 0;// !=
- // null;//
- // instanceof
- // ExactTypePattern;
+ boolean shouldCheck = declA.isExactPattern() || declA.getSignaturePattern().getExactDeclaringTypes().size() != 0;
if (shouldCheck && declA.getKind() != DeclareAnnotation.AT_CONSTRUCTOR) {
- if (declA.getSignaturePattern().isMatchOnAnyName()/* getName().isAny() */) {
+ if (declA.getSignaturePattern().isMatchOnAnyName()) {
shouldCheck = false;
} else {
List<ExactTypePattern> declaringTypePatterns = declA.getSignaturePattern().getExactDeclaringTypes();
}
// TAG: WeavingMessage
- private void reportFieldAnnotationWeavingMessage(LazyClassGen clazz, List fields, int fieldCounter, DeclareAnnotation decaF) {
+ private void reportFieldAnnotationWeavingMessage(LazyClassGen clazz, BcelField theField, DeclareAnnotation decaf,
+ boolean isRemove) {
if (!getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)) {
- BcelField theField = (BcelField) fields.get(fieldCounter);
world.getMessageHandler().handleMessage(
WeaveMessage.constructWeavingMessage(
- WeaveMessage.WEAVEMESSAGE_ANNOTATES,
+ isRemove ? WeaveMessage.WEAVEMESSAGE_REMOVES_ANNOTATION : WeaveMessage.WEAVEMESSAGE_ANNOTATES,
new String[] { theField.getFieldAsIs().toString() + "' of type '" + clazz.getName(),
- clazz.getFileName(), decaF.getAnnotationString(), "field", decaF.getAspect().toString(),
- Utility.beautifyLocation(decaF.getSourceLocation()) }));
+ clazz.getFileName(), decaf.getAnnotationString(), "field", decaf.getAspect().toString(),
+ Utility.beautifyLocation(decaf.getSourceLocation()) }));
}
}
import org.aspectj.util.GenericSignature;
import org.aspectj.util.GenericSignatureParser;
import org.aspectj.weaver.AjAttribute;
+import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.AnnotationAJ;
-import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.ResolvedMemberImpl;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.World;
-import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter.GenericSignatureFormatException;
+/**
+ * An AspectJ Field object that is backed by a Bcel Field object.
+ *
+ * @author PARC
+ * @author Andy Clement
+ */
final class BcelField extends ResolvedMemberImpl {
public static int AccSynthetic = 0x1000;
private final BcelObjectType bcelObjectType;
private UnresolvedType genericFieldType = null;
private boolean unpackedGenericSignature = false;
- private boolean annotationsAdded = false;
+ private boolean annotationsOnFieldObjectAreOutOfDate = false;
BcelField(BcelObjectType declaringType, Field field) {
super(FIELD, declaringType.getResolvedTypeX(), field.getModifiers(), field.getName(), field.getSignature());
checkedExceptions = UnresolvedType.NONE;
}
- // ----
-
private void unpackAttributes(World world) {
Attribute[] attrs = field.getAttributes();
if (attrs != null && attrs.length > 0) {
List<AjAttribute> as = Utility.readAjAttributes(getDeclaringType().getClassName(), attrs, sourceContext, world,
(bcelObjectType != null ? bcelObjectType.getWeaverVersionAttribute() : WeaverVersionInfo.CURRENT),
new BcelConstantPoolReader(field.getConstantPool()));
- as.addAll(AtAjAttributes.readAj5FieldAttributes(field, this, world.resolve(getDeclaringType()), sourceContext, world
- .getMessageHandler()));
-
- for (AjAttribute a : as) {
- if (a instanceof AjAttribute.AjSynthetic) {
- isAjSynthetic = true;
- } else {
- throw new BCException("weird field attribute " + a);
- }
- }
+ as.addAll(AtAjAttributes.readAj5FieldAttributes(field, this, world.resolve(getDeclaringType()), sourceContext,
+ world.getMessageHandler()));
+
+ // FIXME this code has no effect!!!??? it is set to false immediately after the block
+ // for (AjAttribute a : as) {
+ // if (a instanceof AjAttribute.AjSynthetic) {
+ // isAjSynthetic = true;
+ // } else {
+ // throw new BCException("weird field attribute " + a);
+ // }
+ // }
}
isAjSynthetic = false;
isSynthetic = true;
}
}
-
// in 1.5, synthetic is a modifier, not an attribute
if ((field.getModifiers() & AccSynthetic) != 0) {
isSynthetic = true;
@Override
public boolean isAjSynthetic() {
- return isAjSynthetic; // || getName().startsWith(NameMangler.PREFIX);
+ return isAjSynthetic;
}
@Override
@Override
public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) {
ensureAnnotationTypesRetrieved();
- for (int i = 0; i < annotations.length; i++) {
- if (annotations[i].getTypeName().equals(ofType.getName())) {
- return annotations[i];
+ for (AnnotationAJ annotation : annotations) {
+ if (annotation.getTypeName().equals(ofType.getName())) {
+ return annotation;
}
}
return null;
@Override
public void addAnnotation(AnnotationAJ annotation) {
ensureAnnotationTypesRetrieved();
-
int len = annotations.length;
AnnotationAJ[] ret = new AnnotationAJ[len + 1];
System.arraycopy(annotations, 0, ret, 0, len);
newAnnotationTypes[len] = annotation.getType();
annotationTypes = newAnnotationTypes;
- annotationsAdded = true;
+ annotationsOnFieldObjectAreOutOfDate = true;
+ }
+
+ public void removeAnnotation(AnnotationAJ annotation) {
+ ensureAnnotationTypesRetrieved();
+
+ int len = annotations.length;
+ AnnotationAJ[] ret = new AnnotationAJ[len - 1];
+ int p = 0;
+ for (AnnotationAJ anno : annotations) {
+ if (!anno.getType().equals(annotation.getType())) {
+ ret[p++] = anno;
+ }
+ }
+ annotations = ret;
+
+ ResolvedType[] newAnnotationTypes = new ResolvedType[len - 1];
+ p = 0;
+ for (ResolvedType anno : annotationTypes) {
+ if (!anno.equals(annotation.getType())) {
+ newAnnotationTypes[p++] = anno;
+ }
+ }
+ annotationTypes = newAnnotationTypes;
+
+ annotationsOnFieldObjectAreOutOfDate = true;
}
/**
return field;
}
- // FIXME asc badly performing code ftw !
- public Field getField(ConstantPool cpg) {
- if (!annotationsAdded) {
+ public Field getField(ConstantPool cpool) {
+ if (!annotationsOnFieldObjectAreOutOfDate) {
return field;
}
- FieldGen fg = new FieldGen(field, cpg);
- List<AnnotationGen> alreadyHas = fg.getAnnotations();
- if (annotations != null) {
- for (int i = 0; i < annotations.length; i++) {
- AnnotationAJ array_element = annotations[i];
- boolean alreadyHasIt = false;
- for (AnnotationGen gen : alreadyHas) {
- if (gen.getTypeName().equals(array_element.getTypeName())) {
- alreadyHasIt = true;
- break;
- }
- }
- if (!alreadyHasIt) {
- fg.addAnnotation(new AnnotationGen(((BcelAnnotation) array_element).getBcelAnnotation(), cpg, true));
- }
- }
+ FieldGen newFieldGen = new FieldGen(field, cpool);
+ newFieldGen.removeAnnotations();
+ // List<AnnotationGen> alreadyHas = fg.getAnnotations();
+ // if (annotations != null) {
+ // fg.removeAnnotations();
+ for (AnnotationAJ annotation : annotations) {
+ newFieldGen.addAnnotation(new AnnotationGen(((BcelAnnotation) annotation).getBcelAnnotation(), cpool, true));
}
- field = fg.getField();
- annotationsAdded = false; // we are now correct again
+ // for (int i = 0; i < annotations.length; i++) {
+ // AnnotationAJ array_element = annotations[i];
+ // boolean alreadyHasIt = false;
+ // for (AnnotationGen gen : alreadyHas) {
+ // if (gen.getTypeName().equals(array_element.getTypeName())) {
+ // alreadyHasIt = true;
+ // break;
+ // }
+ // }
+ // if (!alreadyHasIt) {
+ // fg.addAnnotation(new AnnotationGen(((BcelAnnotation) array_element).getBcelAnnotation(), cpg, true));
+ // // }
+ // // }
+ // }
+ field = newFieldGen.getField();
+ annotationsOnFieldObjectAreOutOfDate = false; // we are now correct again
return field;
}
bitflags |= HAS_ANNOTATIONS;
}
+ public void removeAnnotation(ResolvedType annotationType) {
+ ensureAnnotationsRetrieved();
+ if ((bitflags & HAS_ANNOTATIONS) == 0) {
+ // nothing to do, why did we get called?
+ } else {
+ int len = annotations.length;
+ if (len == 1) {
+ bitflags &= ~HAS_ANNOTATIONS;
+ annotations = null;
+ annotationTypes = null;
+ return;
+ }
+ AnnotationAJ[] ret = new AnnotationAJ[len - 1];
+ int p = 0;
+ for (AnnotationAJ annotation : annotations) {
+ if (!annotation.getType().equals(annotationType)) {
+ ret[p++] = annotation;
+ }
+ }
+ annotations = ret;
+
+ ResolvedType[] newAnnotationTypes = new ResolvedType[len - 1];
+ p = 0;
+ for (AnnotationAJ annotation : annotations) {
+ if (!annotation.getType().equals(annotationType)) {
+ newAnnotationTypes[p++] = annotationType;
+ }
+ }
+ annotationTypes = newAnnotationTypes;
+ }
+ bitflags |= HAS_ANNOTATIONS;
+ }
+
public static final AnnotationAJ[] NO_PARAMETER_ANNOTATIONS = new AnnotationAJ[] {};
public void addParameterAnnotation(int param, AnnotationAJ anno) {
if (!problemReported) {
AsmRelationshipProvider.addDeclareAnnotationRelationship(world.getModelAsAsmManager(), decA.getSourceLocation(),
- onType.getSourceLocation());
+ onType.getSourceLocation(), false);
// TAG: WeavingMessage
if (!getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)) {
getWorld().getMessageHandler().handleMessage(
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.weaver.AjAttribute;
+import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.AnnotationAJ;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.WeaverMessages;
-import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.tools.Traceable;
/**
private InstructionList body;
private List<Attribute> attributes;
private List<AnnotationAJ> newAnnotations;
+ private List<ResolvedType> annotationsForRemoval;
private AnnotationAJ[][] newParameterAnnotations;
private final LazyClassGen enclosingClass;
private BcelMethod memberView;
}
}
+ public void removeAnnotation(ResolvedType annotationType) {
+ initialize();
+ if (memberView == null) {
+ // If member view is null, we manage them in newAnnotations
+ if (annotationsForRemoval == null) {
+ annotationsForRemoval = new ArrayList<ResolvedType>();
+ }
+ annotationsForRemoval.add(annotationType);
+ } else {
+ memberView.removeAnnotation(annotationType);
+ }
+ }
+
public void addParameterAnnotation(int parameterNumber, AnnotationAJ anno) {
initialize();
if (memberView == null) {
public boolean hasAnnotation(UnresolvedType annotationType) {
initialize();
if (memberView == null) {
+ if (annotationsForRemoval != null) {
+ for (ResolvedType at : annotationsForRemoval) {
+ if (at.equals(annotationType)) {
+ return false;
+ }
+ }
+ }
// Check local annotations first
if (newAnnotations != null) {
for (AnnotationAJ annotation : newAnnotations) {
savedMethod = gen.getMethod();
return savedMethod;
} catch (ClassGenException e) {
- enclosingClass.getBcelObjectType().getResolvedTypeX().getWorld().showMessage(
- IMessage.ERROR,
- WeaverMessages.format(WeaverMessages.PROBLEM_GENERATING_METHOD, this.getClassName(), this.getName(), e
- .getMessage()), this.getMemberView() == null ? null : this.getMemberView().getSourceLocation(), null);
+ enclosingClass
+ .getBcelObjectType()
+ .getResolvedTypeX()
+ .getWorld()
+ .showMessage(
+ IMessage.ERROR,
+ WeaverMessages.format(WeaverMessages.PROBLEM_GENERATING_METHOD, this.getClassName(), this.getName(),
+ e.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;
for (int i = 0; i < newParameterAnnotations.length; i++) {
AnnotationAJ[] annos = newParameterAnnotations[i];
for (int j = 0; j < annos.length; j++) {
- gen.addParameterAnnotation(i, new AnnotationGen(((BcelAnnotation) annos[j]).getBcelAnnotation(), gen
- .getConstantPool(), true));
+ gen.addParameterAnnotation(i,
+ new AnnotationGen(((BcelAnnotation) annos[j]).getBcelAnnotation(), gen.getConstantPool(), true));
}
}
}
continue;
}
gen.addExceptionHandler(jumpForward(r.getRealStart(), forDeletion), jumpForward(r.getRealEnd(), forDeletion),
- jumpForward(r.getHandler(), forDeletion), (r.getCatchType() == null) ? null : (ObjectType) BcelWorld
- .makeBcelType(r.getCatchType()));
+ jumpForward(r.getHandler(), forDeletion),
+ (r.getCatchType() == null) ? null : (ObjectType) BcelWorld.makeBcelType(r.getCatchType()));
}
for (InstructionHandle handle : forDeletion) {
import org.aspectj.weaver.ResolvedPointcutDefinition;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.ResolvedTypeMunger;
+import org.aspectj.weaver.ResolvedTypeMunger.Kind;
import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.ShadowMunger;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.World;
-import org.aspectj.weaver.ResolvedTypeMunger.Kind;
import org.aspectj.weaver.bcel.BcelShadow;
import org.aspectj.weaver.bcel.BcelTypeMunger;
import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
public static final String ANNOTATES = "annotates";
public static final String ANNOTATED_BY = "annotated by";
+ // public static final String REMOVES_ANNOTATION = "removes annotation";
+ // public static final String ANNOTATION_REMOVED_BY = "annotated removed by";
+
/**
* Add a relationship for a declare error or declare warning
*/
((sl.getColumn() == 0) ? ISourceLocation.NO_COLUMN : sl.getColumn()), sl.getContext(), sourceFileName);
return sLoc;
}
-
+
private static ISourceLocation createSourceLocation(String sourcefilename, ResolvedType aspect, ISourceLocation sl) {
ISourceLocation sLoc = new SourceLocation(getBinaryFile(aspect), sl.getLine(), sl.getEndLine(),
((sl.getColumn() == 0) ? ISourceLocation.NO_COLUMN : sl.getColumn()), sl.getContext(), sourcefilename);
* this method if that is the case as they will look the entities up in the structure model.
*/
public static void addDeclareAnnotationRelationship(AsmManager model, ISourceLocation declareAnnotationLocation,
- ISourceLocation annotatedLocation) {
+ ISourceLocation annotatedLocation, boolean isRemove) {
if (model == null) {
return;
}
}
IRelationshipMap mapper = model.getRelationshipMap();
+ // if (isRemove) {
+ // IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, REMOVES_ANNOTATION, false,
+ // true);
+ // foreward.addTarget(targetHandle);
+ //
+ // IRelationship back = mapper
+ // .get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATION_REMOVED_BY, false, true);
+ // back.addTarget(sourceHandle);
+ // if (sourceNode.getSourceLocation() != null) {
+ // model.addAspectInEffectThisBuild(sourceNode.getSourceLocation().getSourceFile());
+ // }
+ // } else {
IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATES, false, true);
foreward.addTarget(targetHandle);
if (sourceNode.getSourceLocation() != null) {
model.addAspectInEffectThisBuild(sourceNode.getSourceLocation().getSourceFile());
}
+ // }
}
/**
ResolvedType aspect = munger.getDeclaringType();
// create the class file node
- IProgramElement classFileNode = new ProgramElement(asm, sourceFileNode.getName(), IProgramElement.Kind.FILE, munger
- .getBinarySourceLocation(aspect.getSourceLocation()), 0, null, null);
+ IProgramElement classFileNode = new ProgramElement(asm, sourceFileNode.getName(), IProgramElement.Kind.FILE,
+ munger.getBinarySourceLocation(aspect.getSourceLocation()), 0, null, null);
// create package ipe if one exists....
IProgramElement root = asm.getHierarchy().getRoot();
// null));
// add and create aspect ipe
- IProgramElement aspectNode = new ProgramElement(asm, aspect.getSimpleName(), IProgramElement.Kind.ASPECT, munger
- .getBinarySourceLocation(aspect.getSourceLocation()), aspect.getModifiers(), null, null);
+ IProgramElement aspectNode = new ProgramElement(asm, aspect.getSimpleName(), IProgramElement.Kind.ASPECT,
+ munger.getBinarySourceLocation(aspect.getSourceLocation()), aspect.getModifiers(), null, null);
classFileNode.addChild(aspectNode);
String sourcefilename = getSourceFileName(aspect);
}
private static IProgramElement createAdviceChild(AsmManager model, Advice advice) {
- IProgramElement adviceNode = new ProgramElement(model, advice.getKind().getName(), IProgramElement.Kind.ADVICE, advice
- .getBinarySourceLocation(advice.getSourceLocation()), advice.getSignature().getModifiers(), null,
+ IProgramElement adviceNode = new ProgramElement(model, advice.getKind().getName(), IProgramElement.Kind.ADVICE,
+ advice.getBinarySourceLocation(advice.getSourceLocation()), advice.getSignature().getModifiers(), null,
Collections.EMPTY_LIST);
adviceNode.setDetails(AsmRelationshipUtils.genPointcutDetails(advice.getPointcut()));
adviceNode.setBytecodeName(advice.getSignature().getName());
* number info for it, we have to dig through the structure model under the fields' type in order to locate it.
*/
public static void addDeclareAnnotationFieldRelationship(AsmManager model, ISourceLocation declareLocation,
- String affectedTypeName, ResolvedMember affectedFieldName) {
+ String affectedTypeName, ResolvedMember affectedFieldName, boolean isRemove) {
if (model == null) {
return;
}
return;
}
- IProgramElement fieldElem = hierarchy.findElementForSignature(typeElem, IProgramElement.Kind.FIELD, affectedFieldName
- .getName());
+ IProgramElement fieldElem = hierarchy.findElementForSignature(typeElem, IProgramElement.Kind.FIELD,
+ affectedFieldName.getName());
if (fieldElem == null) {
return;
}
}
IRelationshipMap relmap = model.getRelationshipMap();
+ // if (isRemove) {
+ // IRelationship foreward = relmap.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, REMOVES_ANNOTATION, false,
+ // true);
+ // foreward.addTarget(targetHandle);
+ // IRelationship back = relmap
+ // .get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATION_REMOVED_BY, false, true);
+ // back.addTarget(sourceHandle);
+ // } else {
IRelationship foreward = relmap.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATES, false, true);
foreward.addTarget(targetHandle);
IRelationship back = relmap.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATED_BY, false, true);
back.addTarget(sourceHandle);
+ // }
}
}