Browse Source

329925: declare @field remove annotation

tags/V1_6_11M1
aclement 13 years ago
parent
commit
a10c68cd87

+ 133
- 142
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java View File

import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
* will iterate over the fields repeatedly until everything has been applied. * 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; boolean isChanged = false;
for (Iterator iter = itdFields.iterator(); iter.hasNext();) {
for (Iterator<ConcreteTypeMunger> iter = itdFields.iterator(); iter.hasNext();) {
BcelTypeMunger fieldMunger = (BcelTypeMunger) iter.next(); BcelTypeMunger fieldMunger = (BcelTypeMunger) iter.next();
ResolvedMember itdIsActually = fieldMunger.getSignature(); ResolvedMember itdIsActually = fieldMunger.getSignature();
List<DeclareAnnotation> worthRetrying = new ArrayList<DeclareAnnotation>();
Set<DeclareAnnotation> worthRetrying = new LinkedHashSet<DeclareAnnotation>();
boolean modificationOccured = false; boolean modificationOccured = false;


for (Iterator<DeclareAnnotation> iter2 = decaFs.iterator(); iter2.hasNext();) { for (Iterator<DeclareAnnotation> iter2 = decaFs.iterator(); iter2.hasNext();) {
DeclareAnnotation decaF = iter2.next(); DeclareAnnotation decaF = iter2.next();

if (decaF.matches(itdIsActually, world)) { 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 { } else {
if (!decaF.isStarredAnnotationPattern()) { if (!decaF.isStarredAnnotationPattern()) {
worthRetrying.add(decaF); // an annotation is specified worthRetrying.add(decaF); // an annotation is specified
for (Iterator<DeclareAnnotation> iter2 = worthRetrying.iterator(); iter2.hasNext();) { for (Iterator<DeclareAnnotation> iter2 = worthRetrying.iterator(); iter2.hasNext();) {
DeclareAnnotation decaF = iter2.next(); DeclareAnnotation decaF = iter2.next();
if (decaF.matches(itdIsActually, world)) { 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); worthRetrying.removeAll(forRemoval);
annotationHolder.addAnnotation(decaMC.getAnnotation()); annotationHolder.addAnnotation(decaMC.getAnnotation());
isChanged = true; isChanged = true;
AsmRelationshipProvider.addDeclareAnnotationRelationship(asmManager, decaMC.getSourceLocation(), AsmRelationshipProvider.addDeclareAnnotationRelationship(asmManager, decaMC.getSourceLocation(),
unMangledInterMethod.getSourceLocation());
unMangledInterMethod.getSourceLocation(), false);
reportMethodCtorWeavingMessage(clazz, unMangledInterMethod, decaMC, -1); reportMethodCtorWeavingMessage(clazz, unMangledInterMethod, decaMC, -1);
modificationOccured = true; modificationOccured = true;
} else { } else {
annotationHolder.addAnnotation(decaMC.getAnnotation()); annotationHolder.addAnnotation(decaMC.getAnnotation());
unMangledInterMethod.addAnnotation(decaMC.getAnnotation()); unMangledInterMethod.addAnnotation(decaMC.getAnnotation());
AsmRelationshipProvider.addDeclareAnnotationRelationship(asmManager, decaMC.getSourceLocation(), AsmRelationshipProvider.addDeclareAnnotationRelationship(asmManager, decaMC.getSourceLocation(),
unMangledInterMethod.getSourceLocation());
unMangledInterMethod.getSourceLocation(), false);
isChanged = true; isChanged = true;
modificationOccured = true; modificationOccured = true;
forRemoval.add(decaMC); forRemoval.add(decaMC);
} }


private boolean dontAddTwice(DeclareAnnotation decaF, AnnotationAJ[] dontAddMeTwice) { 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())) { if (ann != null && decaF.getAnnotation().getTypeName().equals(ann.getTypeName())) {
// dontAddMeTwice[i] = null; // incase it really has been added
// twice!
return true; return true;
} }
} }
return false; 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 * 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 * 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. * as well as on the interfieldinit method.
*/ */
private boolean weaveDeclareAtField(LazyClassGen clazz) { 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<Integer> reportedProblems = new ArrayList<Integer>();

List<DeclareAnnotation> allDecafs = world.getDeclareAnnotationOnFields(); List<DeclareAnnotation> allDecafs = world.getDeclareAnnotationOnFields();
if (allDecafs.isEmpty()) { if (allDecafs.isEmpty()) {
return false; 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(); List<BcelField> fields = clazz.getFieldGens();
if (fields != null) { if (fields != null) {
Set<DeclareAnnotation> unusedDecafs = new HashSet<DeclareAnnotation>(); 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 // Single first pass
List<DeclareAnnotation> worthRetrying = new ArrayList<DeclareAnnotation>();
Set<DeclareAnnotation> worthRetrying = new LinkedHashSet<DeclareAnnotation>();
boolean modificationOccured = false; boolean modificationOccured = false;

AnnotationAJ[] dontAddMeTwice = aBcelField.getAnnotations();
AnnotationAJ[] dontAddMeTwice = field.getAnnotations();


// go through all the declare @field statements // 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; 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 { } 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 // Multiple secondary passes
while (!worthRetrying.isEmpty() && modificationOccured) { while (!worthRetrying.isEmpty() && modificationOccured) {
modificationOccured = false; modificationOccured = false;
// lets have another go
// lets have another go with any remaining ones
List<DeclareAnnotation> forRemoval = new ArrayList<DeclareAnnotation>(); List<DeclareAnnotation> forRemoval = new ArrayList<DeclareAnnotation>();
for (Iterator<DeclareAnnotation> iter = worthRetrying.iterator(); iter.hasNext();) { for (Iterator<DeclareAnnotation> iter = worthRetrying.iterator(); iter.hasNext();) {
DeclareAnnotation decaF = iter.next(); 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); 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); worthRetrying.removeAll(forRemoval);
} }
checkUnusedDeclareAts(unusedDecafs, true); checkUnusedDeclareAts(unusedDecafs, true);
} }
return isChanged;
return typeIsChanged;
} }


// bug 99191 - put out an error message if the type doesn't exist // bug 99191 - put out an error message if the type doesn't exist
for (DeclareAnnotation declA : unusedDecaTs) { for (DeclareAnnotation declA : unusedDecaTs) {


// Error if an exact type pattern was specified // 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 (shouldCheck && declA.getKind() != DeclareAnnotation.AT_CONSTRUCTOR) {
if (declA.getSignaturePattern().isMatchOnAnyName()/* getName().isAny() */) {
if (declA.getSignaturePattern().isMatchOnAnyName()) {
shouldCheck = false; shouldCheck = false;
} else { } else {
List<ExactTypePattern> declaringTypePatterns = declA.getSignaturePattern().getExactDeclaringTypes(); List<ExactTypePattern> declaringTypePatterns = declA.getSignaturePattern().getExactDeclaringTypes();
} }


// TAG: WeavingMessage // 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)) { if (!getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)) {
BcelField theField = (BcelField) fields.get(fieldCounter);
world.getMessageHandler().handleMessage( world.getMessageHandler().handleMessage(
WeaveMessage.constructWeavingMessage( WeaveMessage.constructWeavingMessage(
WeaveMessage.WEAVEMESSAGE_ANNOTATES,
isRemove ? WeaveMessage.WEAVEMESSAGE_REMOVES_ANNOTATION : WeaveMessage.WEAVEMESSAGE_ANNOTATES,
new String[] { theField.getFieldAsIs().toString() + "' of type '" + clazz.getName(), 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()) }));
} }
} }



+ 74
- 43
weaver/src/org/aspectj/weaver/bcel/BcelField.java View File

import org.aspectj.util.GenericSignature; import org.aspectj.util.GenericSignature;
import org.aspectj.util.GenericSignatureParser; import org.aspectj.util.GenericSignatureParser;
import org.aspectj.weaver.AjAttribute; import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.AnnotationAJ; import org.aspectj.weaver.AnnotationAJ;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.ResolvedMemberImpl; import org.aspectj.weaver.ResolvedMemberImpl;
import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.World; import org.aspectj.weaver.World;
import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter.GenericSignatureFormatException; 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 { final class BcelField extends ResolvedMemberImpl {


public static int AccSynthetic = 0x1000; public static int AccSynthetic = 0x1000;
private final BcelObjectType bcelObjectType; private final BcelObjectType bcelObjectType;
private UnresolvedType genericFieldType = null; private UnresolvedType genericFieldType = null;
private boolean unpackedGenericSignature = false; private boolean unpackedGenericSignature = false;
private boolean annotationsAdded = false;
private boolean annotationsOnFieldObjectAreOutOfDate = false;


BcelField(BcelObjectType declaringType, Field field) { BcelField(BcelObjectType declaringType, Field field) {
super(FIELD, declaringType.getResolvedTypeX(), field.getModifiers(), field.getName(), field.getSignature()); super(FIELD, declaringType.getResolvedTypeX(), field.getModifiers(), field.getName(), field.getSignature());
checkedExceptions = UnresolvedType.NONE; checkedExceptions = UnresolvedType.NONE;
} }


// ----

private void unpackAttributes(World world) { private void unpackAttributes(World world) {
Attribute[] attrs = field.getAttributes(); Attribute[] attrs = field.getAttributes();
if (attrs != null && attrs.length > 0) { if (attrs != null && attrs.length > 0) {
List<AjAttribute> as = Utility.readAjAttributes(getDeclaringType().getClassName(), attrs, sourceContext, world, List<AjAttribute> as = Utility.readAjAttributes(getDeclaringType().getClassName(), attrs, sourceContext, world,
(bcelObjectType != null ? bcelObjectType.getWeaverVersionAttribute() : WeaverVersionInfo.CURRENT), (bcelObjectType != null ? bcelObjectType.getWeaverVersionAttribute() : WeaverVersionInfo.CURRENT),
new BcelConstantPoolReader(field.getConstantPool())); 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; isAjSynthetic = false;


isSynthetic = true; isSynthetic = true;
} }
} }

// in 1.5, synthetic is a modifier, not an attribute // in 1.5, synthetic is a modifier, not an attribute
if ((field.getModifiers() & AccSynthetic) != 0) { if ((field.getModifiers() & AccSynthetic) != 0) {
isSynthetic = true; isSynthetic = true;


@Override @Override
public boolean isAjSynthetic() { public boolean isAjSynthetic() {
return isAjSynthetic; // || getName().startsWith(NameMangler.PREFIX);
return isAjSynthetic;
} }


@Override @Override
@Override @Override
public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) { public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) {
ensureAnnotationTypesRetrieved(); 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; return null;
@Override @Override
public void addAnnotation(AnnotationAJ annotation) { public void addAnnotation(AnnotationAJ annotation) {
ensureAnnotationTypesRetrieved(); ensureAnnotationTypesRetrieved();

int len = annotations.length; int len = annotations.length;
AnnotationAJ[] ret = new AnnotationAJ[len + 1]; AnnotationAJ[] ret = new AnnotationAJ[len + 1];
System.arraycopy(annotations, 0, ret, 0, len); System.arraycopy(annotations, 0, ret, 0, len);
newAnnotationTypes[len] = annotation.getType(); newAnnotationTypes[len] = annotation.getType();
annotationTypes = newAnnotationTypes; 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; return field;
} }


// FIXME asc badly performing code ftw !
public Field getField(ConstantPool cpg) {
if (!annotationsAdded) {
public Field getField(ConstantPool cpool) {
if (!annotationsOnFieldObjectAreOutOfDate) {
return field; 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; return field;
} }



+ 33
- 0
weaver/src/org/aspectj/weaver/bcel/BcelMethod.java View File

bitflags |= HAS_ANNOTATIONS; 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 static final AnnotationAJ[] NO_PARAMETER_ANNOTATIONS = new AnnotationAJ[] {};


public void addParameterAnnotation(int param, AnnotationAJ anno) { public void addParameterAnnotation(int param, AnnotationAJ anno) {

+ 1
- 1
weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java View File



if (!problemReported) { if (!problemReported) {
AsmRelationshipProvider.addDeclareAnnotationRelationship(world.getModelAsAsmManager(), decA.getSourceLocation(), AsmRelationshipProvider.addDeclareAnnotationRelationship(world.getModelAsAsmManager(), decA.getSourceLocation(),
onType.getSourceLocation());
onType.getSourceLocation(), false);
// TAG: WeavingMessage // TAG: WeavingMessage
if (!getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)) { if (!getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)) {
getWorld().getMessageHandler().handleMessage( getWorld().getMessageHandler().handleMessage(

+ 35
- 9
weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java View File

import org.aspectj.bridge.IMessage; import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation; import org.aspectj.bridge.ISourceLocation;
import org.aspectj.weaver.AjAttribute; import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.AnnotationAJ; import org.aspectj.weaver.AnnotationAJ;
import org.aspectj.weaver.BCException; import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.Shadow; import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.WeaverMessages; import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.tools.Traceable; import org.aspectj.weaver.tools.Traceable;


/** /**
private InstructionList body; private InstructionList body;
private List<Attribute> attributes; private List<Attribute> attributes;
private List<AnnotationAJ> newAnnotations; private List<AnnotationAJ> newAnnotations;
private List<ResolvedType> annotationsForRemoval;
private AnnotationAJ[][] newParameterAnnotations; private AnnotationAJ[][] newParameterAnnotations;
private final LazyClassGen enclosingClass; private final LazyClassGen enclosingClass;
private BcelMethod memberView; 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) { public void addParameterAnnotation(int parameterNumber, AnnotationAJ anno) {
initialize(); initialize();
if (memberView == null) { if (memberView == null) {
public boolean hasAnnotation(UnresolvedType annotationType) { public boolean hasAnnotation(UnresolvedType annotationType) {
initialize(); initialize();
if (memberView == null) { if (memberView == null) {
if (annotationsForRemoval != null) {
for (ResolvedType at : annotationsForRemoval) {
if (at.equals(annotationType)) {
return false;
}
}
}
// Check local annotations first // Check local annotations first
if (newAnnotations != null) { if (newAnnotations != null) {
for (AnnotationAJ annotation : newAnnotations) { for (AnnotationAJ annotation : newAnnotations) {
savedMethod = gen.getMethod(); savedMethod = gen.getMethod();
return savedMethod; return savedMethod;
} catch (ClassGenException e) { } 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 // throw e; PR 70201.... let the normal problem reporting
// infrastructure deal with this rather than crashing. // infrastructure deal with this rather than crashing.
body = null; body = null;
for (int i = 0; i < newParameterAnnotations.length; i++) { for (int i = 0; i < newParameterAnnotations.length; i++) {
AnnotationAJ[] annos = newParameterAnnotations[i]; AnnotationAJ[] annos = newParameterAnnotations[i];
for (int j = 0; j < annos.length; j++) { 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; continue;
} }
gen.addExceptionHandler(jumpForward(r.getRealStart(), forDeletion), jumpForward(r.getRealEnd(), forDeletion), 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) { for (InstructionHandle handle : forDeletion) {

+ 37
- 12
weaver/src/org/aspectj/weaver/model/AsmRelationshipProvider.java View File

import org.aspectj.weaver.ResolvedPointcutDefinition; import org.aspectj.weaver.ResolvedPointcutDefinition;
import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.ResolvedTypeMunger; import org.aspectj.weaver.ResolvedTypeMunger;
import org.aspectj.weaver.ResolvedTypeMunger.Kind;
import org.aspectj.weaver.Shadow; import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.ShadowMunger; import org.aspectj.weaver.ShadowMunger;
import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.World; import org.aspectj.weaver.World;
import org.aspectj.weaver.ResolvedTypeMunger.Kind;
import org.aspectj.weaver.bcel.BcelShadow; import org.aspectj.weaver.bcel.BcelShadow;
import org.aspectj.weaver.bcel.BcelTypeMunger; import org.aspectj.weaver.bcel.BcelTypeMunger;
import org.aspectj.weaver.patterns.DeclareErrorOrWarning; import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
public static final String ANNOTATES = "annotates"; public static final String ANNOTATES = "annotates";
public static final String ANNOTATED_BY = "annotated by"; 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 * Add a relationship for a declare error or declare warning
*/ */
((sl.getColumn() == 0) ? ISourceLocation.NO_COLUMN : sl.getColumn()), sl.getContext(), sourceFileName); ((sl.getColumn() == 0) ? ISourceLocation.NO_COLUMN : sl.getColumn()), sl.getContext(), sourceFileName);
return sLoc; return sLoc;
} }
private static ISourceLocation createSourceLocation(String sourcefilename, ResolvedType aspect, ISourceLocation sl) { private static ISourceLocation createSourceLocation(String sourcefilename, ResolvedType aspect, ISourceLocation sl) {
ISourceLocation sLoc = new SourceLocation(getBinaryFile(aspect), sl.getLine(), sl.getEndLine(), ISourceLocation sLoc = new SourceLocation(getBinaryFile(aspect), sl.getLine(), sl.getEndLine(),
((sl.getColumn() == 0) ? ISourceLocation.NO_COLUMN : sl.getColumn()), sl.getContext(), sourcefilename); ((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. * 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, public static void addDeclareAnnotationRelationship(AsmManager model, ISourceLocation declareAnnotationLocation,
ISourceLocation annotatedLocation) {
ISourceLocation annotatedLocation, boolean isRemove) {
if (model == null) { if (model == null) {
return; return;
} }
} }


IRelationshipMap mapper = model.getRelationshipMap(); 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); IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATES, false, true);
foreward.addTarget(targetHandle); foreward.addTarget(targetHandle);


if (sourceNode.getSourceLocation() != null) { if (sourceNode.getSourceLocation() != null) {
model.addAspectInEffectThisBuild(sourceNode.getSourceLocation().getSourceFile()); model.addAspectInEffectThisBuild(sourceNode.getSourceLocation().getSourceFile());
} }
// }
} }


/** /**
ResolvedType aspect = munger.getDeclaringType(); ResolvedType aspect = munger.getDeclaringType();


// create the class file node // 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.... // create package ipe if one exists....
IProgramElement root = asm.getHierarchy().getRoot(); IProgramElement root = asm.getHierarchy().getRoot();
// null)); // null));


// add and create aspect ipe // 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); classFileNode.addChild(aspectNode);


String sourcefilename = getSourceFileName(aspect); String sourcefilename = getSourceFileName(aspect);
} }


private static IProgramElement createAdviceChild(AsmManager model, Advice advice) { 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); Collections.EMPTY_LIST);
adviceNode.setDetails(AsmRelationshipUtils.genPointcutDetails(advice.getPointcut())); adviceNode.setDetails(AsmRelationshipUtils.genPointcutDetails(advice.getPointcut()));
adviceNode.setBytecodeName(advice.getSignature().getName()); 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. * 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, public static void addDeclareAnnotationFieldRelationship(AsmManager model, ISourceLocation declareLocation,
String affectedTypeName, ResolvedMember affectedFieldName) {
String affectedTypeName, ResolvedMember affectedFieldName, boolean isRemove) {
if (model == null) { if (model == null) {
return; return;
} }
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) { if (fieldElem == null) {
return; return;
} }
} }


IRelationshipMap relmap = model.getRelationshipMap(); 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); IRelationship foreward = relmap.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATES, false, true);
foreward.addTarget(targetHandle); foreward.addTarget(targetHandle);
IRelationship back = relmap.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATED_BY, false, true); IRelationship back = relmap.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATED_BY, false, true);
back.addTarget(sourceHandle); back.addTarget(sourceHandle);
// }
} }


} }

Loading…
Cancel
Save