瀏覽代碼

refactoring

tags/V1_6_6
aclement 14 年之前
父節點
當前提交
5a88b84f70

+ 119
- 139
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java 查看文件

@@ -14,7 +14,6 @@ package org.aspectj.weaver.bcel;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -97,8 +96,8 @@ class BcelClassWeaver implements IClassWeaver {
* This is called from {@link BcelWeaver} to perform the per-class weaving process.
*
*/
public static boolean weave(BcelWorld world, LazyClassGen clazz, List shadowMungers, List typeMungers, List lateTypeMungers,
boolean inReweavableMode) {
public static boolean weave(BcelWorld world, LazyClassGen clazz, List<ShadowMunger> shadowMungers,
List<ConcreteTypeMunger> typeMungers, List lateTypeMungers, boolean inReweavableMode) {
BcelClassWeaver classWeaver = new BcelClassWeaver(world, clazz, shadowMungers, typeMungers, lateTypeMungers);
classWeaver.setReweavableMode(inReweavableMode);
boolean b = classWeaver.weave();
@@ -112,7 +111,7 @@ class BcelClassWeaver implements IClassWeaver {

private final LazyClassGen clazz;
private final List<ShadowMunger> shadowMungers;
private final List typeMungers;
private final List<ConcreteTypeMunger> typeMungers;
private final List lateTypeMungers;

private final BcelObjectType ty; // alias of clazz.getType()
@@ -120,19 +119,17 @@ class BcelClassWeaver implements IClassWeaver {
private final ConstantPool cpg; // alias of clazz.getConstantPoolGen()
private final InstructionFactory fact; // alias of clazz.getFactory();

private final List addedLazyMethodGens = new ArrayList();
private final Set addedDispatchTargets = new HashSet();
private final List<LazyMethodGen> addedLazyMethodGens = new ArrayList<LazyMethodGen>();
private final Set<ResolvedMember> addedDispatchTargets = new HashSet<ResolvedMember>();

private boolean inReweavableMode = false;

private List addedSuperInitializersAsList = null; // List<IfaceInitList>
private final Map addedSuperInitializers = new HashMap(); // Interface ->
// IfaceInitList
private final List addedThisInitializers = new ArrayList(); // List<NewFieldMunger>
private final List addedClassInitializers = new ArrayList(); // List<NewFieldMunger
// >
private List<IfaceInitList> addedSuperInitializersAsList = null;
private final Map<ResolvedType, IfaceInitList> addedSuperInitializers = new HashMap<ResolvedType, IfaceInitList>();
private final List<ConcreteTypeMunger> addedThisInitializers = new ArrayList<ConcreteTypeMunger>();
private final List<ConcreteTypeMunger> addedClassInitializers = new ArrayList<ConcreteTypeMunger>();

private final Map mapToAnnotations = new HashMap();
private final Map<ResolvedMember, ResolvedType[]> mapToAnnotations = new HashMap<ResolvedMember, ResolvedType[]>();

// private BcelShadow clinitShadow = null;

@@ -140,9 +137,10 @@ class BcelClassWeaver implements IClassWeaver {
* This holds the initialization and pre-initialization shadows for this class that were actually matched by mungers (if no
* match, then we don't even create the shadows really).
*/
private final List initializationShadows = new ArrayList(1);
private final List<BcelShadow> initializationShadows = new ArrayList<BcelShadow>();

private BcelClassWeaver(BcelWorld world, LazyClassGen clazz, List shadowMungers, List typeMungers, List lateTypeMungers) {
private BcelClassWeaver(BcelWorld world, LazyClassGen clazz, List shadowMungers, List<ConcreteTypeMunger> typeMungers,
List lateTypeMungers) {
super();
// assert world == clazz.getType().getWorld()
this.world = world;
@@ -244,7 +242,7 @@ class BcelClassWeaver implements IClassWeaver {
private boolean addSuperInitializer(ResolvedType onType) {
if (onType.isRawType() || onType.isParameterizedType())
onType = onType.getGenericType();
IfaceInitList l = (IfaceInitList) addedSuperInitializers.get(onType);
IfaceInitList l = addedSuperInitializers.get(onType);
if (l != null)
return false;
l = new IfaceInitList(onType);
@@ -264,7 +262,7 @@ class BcelClassWeaver implements IClassWeaver {
if (onType == ty.getResolvedTypeX()) {
addedThisInitializers.add(cm);
} else {
IfaceInitList l = (IfaceInitList) addedSuperInitializers.get(onType);
IfaceInitList l = addedSuperInitializers.get(onType);
l.list.add(cm);
}
}
@@ -272,7 +270,7 @@ class BcelClassWeaver implements IClassWeaver {

private static class IfaceInitList implements PartialOrder.PartialComparable {
final ResolvedType onType;
List list = new ArrayList();
List<ConcreteTypeMunger> list = new ArrayList<ConcreteTypeMunger>();

IfaceInitList(ResolvedType onType) {
this.onType = onType;
@@ -421,9 +419,10 @@ class BcelClassWeaver implements IClassWeaver {
return false;
}

Set aspectsAffectingType = null;
if (inReweavableMode || clazz.getType().isAspect())
aspectsAffectingType = new HashSet();
Set<String> aspectsAffectingType = null;
if (inReweavableMode || clazz.getType().isAspect()) {
aspectsAffectingType = new HashSet<String>();
}

boolean isChanged = false;

@@ -432,8 +431,7 @@ class BcelClassWeaver implements IClassWeaver {
isChanged = true;

// start by munging all typeMungers
for (Iterator i = typeMungers.iterator(); i.hasNext();) {
Object o = i.next();
for (ConcreteTypeMunger o : typeMungers) {
if (!(o instanceof BcelTypeMunger)) {
// ???System.err.println("surprising: " + o);
continue;
@@ -455,7 +453,7 @@ class BcelClassWeaver implements IClassWeaver {
// sort according to: Major: type hierarchy
// within each list: dominates
// don't forget to sort addedThisInitialiers according to dominates
addedSuperInitializersAsList = new ArrayList(addedSuperInitializers.values());
addedSuperInitializersAsList = new ArrayList<IfaceInitList>(addedSuperInitializers.values());
addedSuperInitializersAsList = PartialOrder.sort(addedSuperInitializersAsList);
if (addedSuperInitializersAsList == null) {
throw new BCException("circularity in inter-types");
@@ -469,21 +467,22 @@ class BcelClassWeaver implements IClassWeaver {
// now go through each method, and match against each method. This
// sets up each method's {@link LazyMethodGen#matchedShadows} field,
// and it also possibly adds to {@link #initializationShadows}.
List methodGens = new ArrayList(clazz.getMethodGens());
for (Iterator i = methodGens.iterator(); i.hasNext();) {
LazyMethodGen mg = (LazyMethodGen) i.next();
if (!mg.hasBody())
List<LazyMethodGen> methodGens = new ArrayList<LazyMethodGen>(clazz.getMethodGens());
for (LazyMethodGen member : methodGens) {
if (!member.hasBody()) {
continue;
}
if (world.isJoinpointSynchronizationEnabled() && world.areSynchronizationPointcutsInUse()
&& mg.getMethod().isSynchronized()) {
transformSynchronizedMethod(mg);
&& member.getMethod().isSynchronized()) {
transformSynchronizedMethod(member);
}
boolean shadowMungerMatched = match(mg);
boolean shadowMungerMatched = match(member);
if (shadowMungerMatched) {
// For matching mungers, add their declaring aspects to the list
// that affected this type
if (inReweavableMode || clazz.getType().isAspect())
aspectsAffectingType.addAll(findAspectsForMungers(mg));
if (inReweavableMode || clazz.getType().isAspect()) {
aspectsAffectingType.addAll(findAspectsForMungers(member));
}
isChanged = true;
}
}
@@ -871,14 +870,15 @@ class BcelClassWeaver implements IClassWeaver {
private boolean weaveDeclareAtMethodCtor(LazyClassGen clazz) {
List reportedProblems = new ArrayList();

List allDecams = world.getDeclareAnnotationOnMethods();
if (allDecams.isEmpty())
return false; // nothing to do
List<DeclareAnnotation> allDecams = world.getDeclareAnnotationOnMethods();
if (allDecams.isEmpty()) {
return false;
}

boolean isChanged = false;

// deal with ITDs
List itdMethodsCtors = getITDSubset(clazz, ResolvedTypeMunger.Method);
List<ConcreteTypeMunger> itdMethodsCtors = getITDSubset(clazz, ResolvedTypeMunger.Method);
itdMethodsCtors.addAll(getITDSubset(clazz, ResolvedTypeMunger.Constructor));
if (!itdMethodsCtors.isEmpty()) {
// Can't use the subset called 'decaMs' as it won't be right for
@@ -887,23 +887,22 @@ class BcelClassWeaver implements IClassWeaver {
}

// deal with all the other methods...
List members = clazz.getMethodGens();
List decaMs = getMatchingSubset(allDecams, clazz.getType());
List<LazyMethodGen> members = clazz.getMethodGens();
List<DeclareAnnotation> decaMs = getMatchingSubset(allDecams, clazz.getType());
if (decaMs.isEmpty())
return false; // nothing to do
if (!members.isEmpty()) {
Set unusedDecams = new HashSet();
Set<DeclareAnnotation> unusedDecams = new HashSet<DeclareAnnotation>();
unusedDecams.addAll(decaMs);
for (int memberCounter = 0; memberCounter < members.size(); memberCounter++) {
LazyMethodGen mg = (LazyMethodGen) members.get(memberCounter);
LazyMethodGen mg = members.get(memberCounter);
if (!mg.getName().startsWith(NameMangler.PREFIX)) {

// Single first pass
List worthRetrying = new ArrayList();
List<DeclareAnnotation> worthRetrying = new ArrayList<DeclareAnnotation>();
boolean modificationOccured = false;
List /* AnnotationGen */annotationsToAdd = null;
for (Iterator iter = decaMs.iterator(); iter.hasNext();) {
DeclareAnnotation decaM = (DeclareAnnotation) iter.next();
List<AnnotationGen> annotationsToAdd = null;
for (DeclareAnnotation decaM : decaMs) {

if (decaM.matches(mg.getMemberView(), world)) {
if (doesAlreadyHaveAnnotation(mg.getMemberView(), decaM, reportedProblems)) {
@@ -913,8 +912,9 @@ class BcelClassWeaver implements IClassWeaver {
continue; // skip this one...
}

if (annotationsToAdd == null)
annotationsToAdd = new ArrayList();
if (annotationsToAdd == null) {
annotationsToAdd = new ArrayList<AnnotationGen>();
}
AnnotationGen a = ((BcelAnnotation) decaM.getAnnotation()).getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a, clazz.getConstantPool(), true);
annotationsToAdd.add(ag);
@@ -942,9 +942,8 @@ class BcelClassWeaver implements IClassWeaver {
while (!worthRetrying.isEmpty() && modificationOccured) {
modificationOccured = false;
// lets have another go
List forRemoval = new ArrayList();
for (Iterator iter = worthRetrying.iterator(); iter.hasNext();) {
DeclareAnnotation decaM = (DeclareAnnotation) iter.next();
List<DeclareAnnotation> forRemoval = new ArrayList<DeclareAnnotation>();
for (DeclareAnnotation decaM : worthRetrying) {
if (decaM.matches(mg.getMemberView(), world)) {
if (doesAlreadyHaveAnnotation(mg.getMemberView(), decaM, reportedProblems)) {
// remove the declare @method since don't
@@ -955,7 +954,7 @@ class BcelClassWeaver implements IClassWeaver {
}

if (annotationsToAdd == null) {
annotationsToAdd = new ArrayList();
annotationsToAdd = new ArrayList<AnnotationGen>();
}
AnnotationGen a = ((BcelAnnotation) decaM.getAnnotation()).getBcelAnnotation();
// create copy to get the annotation type into the right constant pool
@@ -977,8 +976,7 @@ class BcelClassWeaver implements IClassWeaver {
if (annotationsToAdd != null) {
Method oldMethod = mg.getMethod();
MethodGen myGen = new MethodGen(oldMethod, clazz.getClassName(), clazz.getConstantPool(), false);
for (Iterator iter = annotationsToAdd.iterator(); iter.hasNext();) {
AnnotationGen a = (AnnotationGen) iter.next();
for (AnnotationGen a : annotationsToAdd) {
myGen.addAnnotation(a);
}
Method newMethod = myGen.getMethod();
@@ -1040,10 +1038,9 @@ class BcelClassWeaver implements IClassWeaver {
* Looks through a list of declare annotation statements and only returns those that could possibly match on a field/method/ctor
* in type.
*/
private List getMatchingSubset(List declareAnnotations, ResolvedType type) {
List subset = new ArrayList();
for (Iterator iter = declareAnnotations.iterator(); iter.hasNext();) {
DeclareAnnotation da = (DeclareAnnotation) iter.next();
private List<DeclareAnnotation> getMatchingSubset(List<DeclareAnnotation> declareAnnotations, ResolvedType type) {
List<DeclareAnnotation> subset = new ArrayList<DeclareAnnotation>();
for (DeclareAnnotation da : declareAnnotations) {
if (da.couldEverMatch(type)) {
subset.add(da);
}
@@ -1054,31 +1051,29 @@ class BcelClassWeaver implements IClassWeaver {
/**
* Get a subset of all the type mungers defined on this aspect
*/
private List getITDSubset(LazyClassGen clazz, ResolvedTypeMunger.Kind wantedKind) {
List subset = new ArrayList();
Collection c = clazz.getBcelObjectType().getTypeMungers();
for (Iterator iter = c.iterator(); iter.hasNext();) {
BcelTypeMunger typeMunger = (BcelTypeMunger) iter.next();
if (typeMunger.getMunger().getKind() == wantedKind)
private List<ConcreteTypeMunger> getITDSubset(LazyClassGen clazz, ResolvedTypeMunger.Kind wantedKind) {
List<ConcreteTypeMunger> subset = new ArrayList<ConcreteTypeMunger>();
for (ConcreteTypeMunger typeMunger : clazz.getBcelObjectType().getTypeMungers()) {
if (typeMunger.getMunger().getKind() == wantedKind) {
subset.add(typeMunger);
}
}
return subset;
}

public LazyMethodGen locateAnnotationHolderForFieldMunger(LazyClassGen clazz, BcelTypeMunger fieldMunger) {
NewFieldTypeMunger nftm = (NewFieldTypeMunger) fieldMunger.getMunger();
ResolvedMember lookingFor = AjcMemberMaker.interFieldInitializer(nftm.getSignature(), clazz.getType());
List meths = clazz.getMethodGens();
for (Iterator iter = meths.iterator(); iter.hasNext();) {
LazyMethodGen element = (LazyMethodGen) iter.next();
if (element.getName().equals(lookingFor.getName()))
return element;
public LazyMethodGen locateAnnotationHolderForFieldMunger(LazyClassGen clazz, ConcreteTypeMunger fieldMunger) {
NewFieldTypeMunger newFieldMunger = (NewFieldTypeMunger) fieldMunger.getMunger();
ResolvedMember lookingFor = AjcMemberMaker.interFieldInitializer(newFieldMunger.getSignature(), clazz.getType());
for (LazyMethodGen method : clazz.getMethodGens()) {
if (method.getName().equals(lookingFor.getName())) {
return method;
}
}
return null;
}

// FIXME asc refactor this to neaten it up
public LazyMethodGen locateAnnotationHolderForMethodCtorMunger(LazyClassGen clazz, BcelTypeMunger methodCtorMunger) {
public LazyMethodGen locateAnnotationHolderForMethodCtorMunger(LazyClassGen clazz, ConcreteTypeMunger methodCtorMunger) {
ResolvedTypeMunger rtMunger = methodCtorMunger.getMunger();
ResolvedMember lookingFor = null;
if (rtMunger instanceof NewMethodTypeMunger) {
@@ -1091,17 +1086,14 @@ class BcelClassWeaver implements IClassWeaver {
} else {
throw new BCException("Not sure what this is: " + methodCtorMunger);
}
List meths = clazz.getMethodGens();
String name = lookingFor.getName();
String paramSignature = lookingFor.getParameterSignature();
for (Iterator iter = meths.iterator(); iter.hasNext();) {
LazyMethodGen element = (LazyMethodGen) iter.next();
if (element.getName().equals(name) && element.getParameterSignature().equals(paramSignature)) {
return element;
for (LazyMethodGen member : clazz.getMethodGens()) {
if (member.getName().equals(name) && member.getParameterSignature().equals(paramSignature)) {
return member;
}
}
return null;

}

/**
@@ -1165,11 +1157,13 @@ class BcelClassWeaver implements IClassWeaver {
* Applies some set of declare @method/@ctor constructs (List<DeclareAnnotation>) to some bunch of ITDmembers
* (List<BcelTypeMunger>. It will iterate over the fields repeatedly until everything has been applied.
*/
private boolean weaveAtMethodOnITDSRepeatedly(List decaMCs, List itdsForMethodAndConstructor, List reportedErrors) {
private boolean weaveAtMethodOnITDSRepeatedly(List<DeclareAnnotation> decaMCs,
List<ConcreteTypeMunger> itdsForMethodAndConstructor, List reportedErrors) {
boolean isChanged = false;
AsmManager asmManager = world.getModelAsAsmManager();
for (Iterator iter = itdsForMethodAndConstructor.iterator(); iter.hasNext();) {
BcelTypeMunger methodctorMunger = (BcelTypeMunger) iter.next();
for (ConcreteTypeMunger methodctorMunger : itdsForMethodAndConstructor) {
// for (Iterator iter = itdsForMethodAndConstructor.iterator(); iter.hasNext();) {
// BcelTypeMunger methodctorMunger = (BcelTypeMunger) iter.next();
ResolvedMember unMangledInterMethod = methodctorMunger.getSignature();
List worthRetrying = new ArrayList();
boolean modificationOccured = false;
@@ -1253,9 +1247,10 @@ class BcelClassWeaver implements IClassWeaver {

List reportedProblems = new ArrayList();

List allDecafs = world.getDeclareAnnotationOnFields();
if (allDecafs.isEmpty())
return false; // nothing to do
List<DeclareAnnotation> allDecafs = world.getDeclareAnnotationOnFields();
if (allDecafs.isEmpty()) {
return false;
}

boolean isChanged = false;
List itdFields = getITDSubset(clazz, ResolvedTypeMunger.Field);
@@ -1263,27 +1258,26 @@ class BcelClassWeaver implements IClassWeaver {
isChanged = weaveAtFieldRepeatedly(allDecafs, itdFields, reportedProblems);
}

List decaFs = getMatchingSubset(allDecafs, clazz.getType());
List<DeclareAnnotation> decaFs = getMatchingSubset(allDecafs, clazz.getType());
if (decaFs.isEmpty())
return false; // nothing more to do
List fields = clazz.getFieldGens();
List<BcelField> fields = clazz.getFieldGens();
if (fields != null) {
Set unusedDecafs = new HashSet();
Set<DeclareAnnotation> unusedDecafs = new HashSet<DeclareAnnotation>();
unusedDecafs.addAll(decaFs);
for (int fieldCounter = 0; fieldCounter < fields.size(); fieldCounter++) {
BcelField aBcelField = (BcelField) fields.get(fieldCounter);// new
BcelField aBcelField = fields.get(fieldCounter);// new
// BcelField(clazz.getBcelObjectType(),fields[fieldCounter
// ]);
if (!aBcelField.getName().startsWith(NameMangler.PREFIX)) {
// Single first pass
List worthRetrying = new ArrayList();
List<DeclareAnnotation> worthRetrying = new ArrayList<DeclareAnnotation>();
boolean modificationOccured = false;

AnnotationAJ[] dontAddMeTwice = aBcelField.getAnnotations();

// go through all the declare @field statements
for (Iterator iter = decaFs.iterator(); iter.hasNext();) {
DeclareAnnotation decaF = (DeclareAnnotation) iter.next();
for (DeclareAnnotation decaF : decaFs) {
if (decaF.getAnnotation() == null) {
return false;
}
@@ -1484,17 +1478,14 @@ class BcelClassWeaver implements IClassWeaver {
return false;
}

private Set findAspectsForMungers(LazyMethodGen mg) {
Set aspectsAffectingType = new HashSet();
for (Iterator iter = mg.matchedShadows.iterator(); iter.hasNext();) {
BcelShadow aShadow = (BcelShadow) iter.next();
// Mungers in effect on that shadow
for (Iterator iter2 = aShadow.getMungers().iterator(); iter2.hasNext();) {
ShadowMunger aMunger = (ShadowMunger) iter2.next();
if (aMunger instanceof BcelAdvice) {
BcelAdvice bAdvice = (BcelAdvice) aMunger;
if (bAdvice.getConcreteAspect() != null) {
aspectsAffectingType.add(bAdvice.getConcreteAspect().getName());
private Set<String> findAspectsForMungers(LazyMethodGen mg) {
Set<String> aspectsAffectingType = new HashSet<String>();
for (BcelShadow shadow : mg.matchedShadows) {
for (ShadowMunger munger : shadow.getMungers()) {
if (munger instanceof BcelAdvice) {
BcelAdvice bcelAdvice = (BcelAdvice) munger;
if (bcelAdvice.getConcreteAspect() != null) {
aspectsAffectingType.add(bcelAdvice.getConcreteAspect().getName());
}
} else {
// It is a 'Checker' - we don't need to remember aspects
@@ -1521,9 +1512,8 @@ class BcelClassWeaver implements IClassWeaver {
return inlinedSomething;
}

private void positionAndImplement(List initializationShadows) {
for (Iterator i = initializationShadows.iterator(); i.hasNext();) {
BcelShadow s = (BcelShadow) i.next();
private void positionAndImplement(List<BcelShadow> initializationShadows) {
for (BcelShadow s : initializationShadows) {
positionInitializationShadow(s);
// s.getEnclosingMethod().print();
s.implement();
@@ -2097,7 +2087,7 @@ class BcelClassWeaver implements IClassWeaver {
InstructionList ret = new InstructionList();
InstructionList sourceList = donor.getBody();

Map srcToDest = new HashMap();
Map<InstructionHandle, InstructionHandle> srcToDest = new HashMap<InstructionHandle, InstructionHandle>();
ConstantPool donorCpg = donor.getEnclosingClass().getConstantPool();
ConstantPool recipientCpg = recipient.getEnclosingClass().getConstantPool();

@@ -2154,8 +2144,8 @@ class BcelClassWeaver implements IClassWeaver {
}

// second pass: retarget branch instructions, copy ranges and tags
Map tagMap = new HashMap();
Map shadowMap = new HashMap();
Map<Tag, Tag> tagMap = new HashMap<Tag, Tag>();
Map<BcelShadow, BcelShadow> shadowMap = new HashMap<BcelShadow, BcelShadow>();
for (InstructionHandle dest = ret.getStart(), src = sourceList.getStart(); dest != null; dest = dest.getNext(), src = src
.getNext()) {
Instruction inst = dest.getInstruction();
@@ -2164,7 +2154,7 @@ class BcelClassWeaver implements IClassWeaver {
if (inst instanceof InstructionBranch) {
InstructionBranch branch = (InstructionBranch) inst;
InstructionHandle oldTarget = branch.getTarget();
InstructionHandle newTarget = (InstructionHandle) srcToDest.get(oldTarget);
InstructionHandle newTarget = srcToDest.get(oldTarget);
if (newTarget == null) {
// assert this is a GOTO
// this was a return instruction we previously replaced
@@ -2174,7 +2164,7 @@ class BcelClassWeaver implements IClassWeaver {
InstructionSelect select = (InstructionSelect) branch;
InstructionHandle[] oldTargets = select.getTargets();
for (int k = oldTargets.length - 1; k >= 0; k--) {
select.setTarget(k, (InstructionHandle) srcToDest.get(oldTargets[k]));
select.setTarget(k, srcToDest.get(oldTargets[k]));
}
}
}
@@ -2182,12 +2172,12 @@ class BcelClassWeaver implements IClassWeaver {

// copy over tags and range attributes

Iterator tIter = src.getTargeters().iterator();
Iterator<InstructionTargeter> tIter = src.getTargeters().iterator();
while (tIter.hasNext()) {
InstructionTargeter old = (InstructionTargeter) tIter.next();
InstructionTargeter old = tIter.next();
if (old instanceof Tag) {
Tag oldTag = (Tag) old;
Tag fresh = (Tag) tagMap.get(oldTag);
Tag fresh = tagMap.get(oldTag);
if (fresh == null) {
fresh = oldTag.copy();
if (old instanceof LocalVariableTag) {
@@ -2212,8 +2202,7 @@ class BcelClassWeaver implements IClassWeaver {
ExceptionRange er = (ExceptionRange) old;
if (er.getStart() == src) {
ExceptionRange freshEr = new ExceptionRange(recipient.getBody(), er.getCatchType(), er.getPriority());
freshEr.associateWithTargets(dest, (InstructionHandle) srcToDest.get(er.getEnd()),
(InstructionHandle) srcToDest.get(er.getHandler()));
freshEr.associateWithTargets(dest, srcToDest.get(er.getEnd()), srcToDest.get(er.getHandler()));
}
} else if (old instanceof ShadowRange) {
ShadowRange oldRange = (ShadowRange) old;
@@ -2224,8 +2213,8 @@ class BcelClassWeaver implements IClassWeaver {
BcelShadow freshShadow = oldShadow.copyInto(recipient, freshEnclosing);
ShadowRange freshRange = new ShadowRange(recipient.getBody());
freshRange.associateWithShadow(freshShadow);
freshRange.associateWithTargets(dest, (InstructionHandle) srcToDest.get(oldRange.getEnd()));
shadowMap.put(oldRange, freshRange);
freshRange.associateWithTargets(dest, srcToDest.get(oldRange.getEnd()));
shadowMap.put(oldShadow, freshShadow); // oldRange, freshRange
// recipient.matchedShadows.add(freshShadow);
// XXX should go through the NEW copied shadow and
// update
@@ -2441,8 +2430,8 @@ class BcelClassWeaver implements IClassWeaver {
}
});

for (Iterator i = addedLazyMethodGens.iterator(); i.hasNext();) {
clazz.addMethodGen((LazyMethodGen) i.next());
for (LazyMethodGen addedMember : addedLazyMethodGens) {
clazz.addMethodGen(addedMember);
}
}

@@ -2490,7 +2479,7 @@ class BcelClassWeaver implements IClassWeaver {

private boolean match(LazyMethodGen mg) {
BcelShadow enclosingShadow;
List shadowAccumulator = new ArrayList();
List<BcelShadow> shadowAccumulator = new ArrayList<BcelShadow>();

boolean startsAngly = mg.getName().charAt(0) == '<';
// we want to match ajsynthetic constructors...
@@ -2645,7 +2634,7 @@ class BcelClassWeaver implements IClassWeaver {
return ret;
}

private void match(LazyMethodGen mg, InstructionHandle ih, BcelShadow enclosingShadow, List shadowAccumulator) {
private void match(LazyMethodGen mg, InstructionHandle ih, BcelShadow enclosingShadow, List<BcelShadow> shadowAccumulator) {
Instruction i = ih.getInstruction();

// Exception handlers (pr230817)
@@ -2747,28 +2736,19 @@ class BcelClassWeaver implements IClassWeaver {
}
} else if (world.isJoinpointArrayConstructionEnabled() && i.isArrayCreationInstruction()) {
if (canMatch(Shadow.ConstructorCall)) {
boolean debug = false;
if (debug)
System.err.println("Found new array instruction: " + i);
if (i.opcode == Constants.ANEWARRAY) {
// ANEWARRAY arrayInstruction = (ANEWARRAY)i;
ObjectType arrayType = i.getLoadClassType(clazz.getConstantPool());
if (debug)
System.err.println("Array type is " + arrayType);
BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world, mg, ih, enclosingShadow);
match(ctorCallShadow, shadowAccumulator);
} else if (i.opcode == Constants.NEWARRAY) {
// NEWARRAY arrayInstruction = (NEWARRAY)i;
Type arrayType = i.getType();
if (debug)
System.err.println("Array type is " + arrayType);
BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world, mg, ih, enclosingShadow);
match(ctorCallShadow, shadowAccumulator);
} else if (i instanceof MULTIANEWARRAY) {
MULTIANEWARRAY arrayInstruction = (MULTIANEWARRAY) i;
ObjectType arrayType = arrayInstruction.getLoadClassType(clazz.getConstantPool());
if (debug)
System.err.println("Array type is " + arrayType);
BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world, mg, ih, enclosingShadow);
match(ctorCallShadow, shadowAccumulator);
}
@@ -2927,7 +2907,7 @@ class BcelClassWeaver implements IClassWeaver {
private void fixAnnotationsForResolvedMember(ResolvedMember rm, ResolvedMember declaredSig) {
try {
UnresolvedType memberHostType = declaredSig.getDeclaringType();
ResolvedType[] annotations = (ResolvedType[]) mapToAnnotations.get(rm);
ResolvedType[] annotations = mapToAnnotations.get(rm);
String methodName = declaredSig.getName();
// FIXME asc shouldnt really rely on string names !
if (annotations == null) {
@@ -3030,7 +3010,7 @@ class BcelClassWeaver implements IClassWeaver {
private static boolean checkedXsetForLowLevelContextCapturing = false;
private static boolean captureLowLevelContext = false;

private boolean match(BcelShadow shadow, List shadowAccumulator) {
private boolean match(BcelShadow shadow, List<BcelShadow> shadowAccumulator) {
// System.err.println("match: " + shadow);
if (captureLowLevelContext) { // duplicate blocks - one with context
// capture, one without, seems faster
@@ -3060,7 +3040,7 @@ class BcelClassWeaver implements IClassWeaver {
boolean isMatched = false;
int max = shadowMungers.size();
for (int i = 0; i < max; i++) {
ShadowMunger munger = (ShadowMunger) shadowMungers.get(i);
ShadowMunger munger = shadowMungers.get(i);
if (munger.match(shadow, world)) {
shadow.addMunger(munger);
isMatched = true;
@@ -3079,17 +3059,16 @@ class BcelClassWeaver implements IClassWeaver {
// ----

private void implement(LazyMethodGen mg) {
List shadows = mg.matchedShadows;
if (shadows == null)
List<BcelShadow> shadows = mg.matchedShadows;
if (shadows == null) {
return;
}
// We depend on a partial order such that inner shadows are earlier on
// the list
// than outer shadows. That's fine. This order is preserved if:
// the list than outer shadows. That's fine. This order is preserved if:

// A preceeds B iff B.getStart() is LATER THAN A.getStart().

for (Iterator i = shadows.iterator(); i.hasNext();) {
BcelShadow shadow = (BcelShadow) i.next();
for (BcelShadow shadow : shadows) {
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.IMPLEMENTING_ON_SHADOW,
shadow);
shadow.implement();
@@ -3122,6 +3101,7 @@ class BcelClassWeaver implements IClassWeaver {
return inReweavableMode;
}

@Override
public String toString() {
return "BcelClassWeaver instance for : " + clazz;
}

+ 8
- 6
weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java 查看文件

@@ -310,18 +310,18 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
return typeVars;
}

// Aspect related
public Collection getTypeMungers() {
public Collection<ConcreteTypeMunger> getTypeMungers() {
return typeMungers;
}

public Collection getDeclares() {
public Collection<Declare> getDeclares() {
return declares;
}

public Collection getPrivilegedAccesses() {
if (privilegedAccess == null)
return Collections.EMPTY_LIST;
public Collection<ResolvedMember> getPrivilegedAccesses() {
if (privilegedAccess == null) {
return Collections.emptyList();
}
return Arrays.asList(privilegedAccess);
}

@@ -825,6 +825,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
return isGenericType;
}

@Override
public String toString() {
return (javaClass == null ? "BcelObjectType" : "BcelObjectTypeFor:" + className);
}
@@ -884,6 +885,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
return hasBeenWoven;
}

@Override
public boolean copySourceContext() {
return false;
}

+ 40
- 17
weaver/src/org/aspectj/weaver/bcel/BcelShadow.java 查看文件

@@ -128,7 +128,7 @@ public class BcelShadow extends Shadow {
private final BcelWorld world;
private final LazyMethodGen enclosingMethod;

// SECRETAPI - for testing, this will tell us if the optimization succeeded *on the last shadow processed*
// TESTING this will tell us if the optimisation succeeded *on the last shadow processed*
public static boolean appliedLazyTjpOptimization;

// Some instructions have a target type that will vary
@@ -164,6 +164,7 @@ public class BcelShadow extends Shadow {

// ---- overridden behaviour

@Override
public World getIWorld() {
return world;
}
@@ -266,12 +267,12 @@ public class BcelShadow extends Shadow {
private void retargetFrom(InstructionHandle old, InstructionHandle fresh) {
InstructionTargeter[] sources = old.getTargetersArray();
if (sources != null) {
for (int i = sources.length - 1; i >= 0; i--) {
if (sources[i] instanceof ExceptionRange) {
ExceptionRange it = (ExceptionRange) sources[i];
for (InstructionTargeter targeter : sources) {
if (targeter instanceof ExceptionRange) {
ExceptionRange it = (ExceptionRange) targeter;
it.updateTarget(old, fresh, it.getBody());
} else {
sources[i].updateTarget(old, fresh);
targeter.updateTarget(old, fresh);
}
}
}
@@ -286,6 +287,7 @@ public class BcelShadow extends Shadow {
badAdvice.add(advice);
}

@Override
protected void prepareForMungers() {
// if we're a constructor call, we need to remove the new:dup or the new:dup_x1:swap,
// and store all our
@@ -337,8 +339,7 @@ public class BcelShadow extends Shadow {
isThisJoinPointLazy = true;// world.isXlazyTjp(); // lazy is default now

badAdvice = null;
for (Iterator iter = mungers.iterator(); iter.hasNext();) {
ShadowMunger munger = (ShadowMunger) iter.next();
for (ShadowMunger munger : mungers) {
munger.specializeOn(this);
}

@@ -452,6 +453,7 @@ public class BcelShadow extends Shadow {
}

// overrides
@Override
public UnresolvedType getEnclosingType() {
return getEnclosingClass().getType();
}
@@ -862,6 +864,7 @@ public class BcelShadow extends Shadow {
private Map/* <UnresolvedType,BcelVar> */<ResolvedType, AnnotationAccessVar> withincodeAnnotationVars = null;
private boolean allArgVarsInitialized = false;

@Override
public Var getThisVar() {
if (!hasThis()) {
throw new IllegalStateException("no this");
@@ -870,6 +873,7 @@ public class BcelShadow extends Shadow {
return thisVar;
}

@Override
public Var getThisAnnotationVar(UnresolvedType forAnnotationType) {
if (!hasThis()) {
throw new IllegalStateException("no this");
@@ -882,6 +886,7 @@ public class BcelShadow extends Shadow {
return v;
}

@Override
public Var getTargetVar() {
if (!hasTarget()) {
throw new IllegalStateException("no target");
@@ -890,6 +895,7 @@ public class BcelShadow extends Shadow {
return targetVar;
}

@Override
public Var getTargetAnnotationVar(UnresolvedType forAnnotationType) {
if (!hasTarget()) {
throw new IllegalStateException("no target");
@@ -902,11 +908,13 @@ public class BcelShadow extends Shadow {
return v;
}

@Override
public Var getArgVar(int i) {
ensureInitializedArgVar(i);
return argVars[i];
}

@Override
public Var getArgAnnotationVar(int i, UnresolvedType forAnnotationType) {
initializeArgAnnotationVars();

@@ -916,16 +924,19 @@ public class BcelShadow extends Shadow {
return v;
}

@Override
public Var getKindedAnnotationVar(UnresolvedType forAnnotationType) {
initializeKindedAnnotationVars();
return kindedAnnotationVars.get(forAnnotationType);
}

@Override
public Var getWithinAnnotationVar(UnresolvedType forAnnotationType) {
initializeWithinAnnotationVars();
return withinAnnotationVars.get(forAnnotationType);
}

@Override
public Var getWithinCodeAnnotationVar(UnresolvedType forAnnotationType) {
initializeWithinCodeAnnotationVars();
return withincodeAnnotationVars.get(forAnnotationType);
@@ -939,10 +950,12 @@ public class BcelShadow extends Shadow {

// private BcelVar thisEnclosingJoinPointStaticPartVar = null;

@Override
public final Var getThisJoinPointStaticPartVar() {
return getThisJoinPointStaticPartBcelVar();
}

@Override
public final Var getThisEnclosingJoinPointStaticPartVar() {
return getThisEnclosingJoinPointStaticPartBcelVar();
}
@@ -965,6 +978,7 @@ public class BcelShadow extends Shadow {
}
}

@Override
public Var getThisJoinPointVar() {
requireThisJoinPoint(false, false);
return thisJoinPointVar;
@@ -1133,6 +1147,7 @@ public class BcelShadow extends Shadow {
}

// ??? need to better understand all the enclosing variants
@Override
public Member getEnclosingCodeSignature() {
if (getKind().isEnclosingKind()) {
return getSignature();
@@ -1439,12 +1454,12 @@ public class BcelShadow extends Shadow {
foundMember = AjcMemberMaker.interConstructor(relevantType, foundMember, typeMunger.getAspectType());
} else {
foundMember = AjcMemberMaker.interMethod(foundMember, typeMunger.getAspectType(), false);
// ResolvedMember o = AjcMemberMaker.interMethodBody(fakerm, typeMunger.getAspectType());
// // Object os = o.getAnnotations();
// ResolvedMember foundMember2 = findMethod(typeMunger.getAspectType(), o);
// Object os2 = foundMember2.getAnnotations();
// int stop = 1;
// foundMember = foundMember2;
// ResolvedMember o = AjcMemberMaker.interMethodBody(fakerm, typeMunger.getAspectType());
// // Object os = o.getAnnotations();
// ResolvedMember foundMember2 = findMethod(typeMunger.getAspectType(), o);
// Object os2 = foundMember2.getAnnotations();
// int stop = 1;
// foundMember = foundMember2;
// foundMember = AjcMemberMaker.interMethod(foundMember, typeMunger.getAspectType());
}
// in the above.. what about if it's on an Interface? Can that happen?
@@ -1523,10 +1538,8 @@ public class BcelShadow extends Shadow {

if (annotationHolder == null) {
// check the ITD'd dooberries
List<BcelTypeMunger> mungers = relevantType.resolve(world).getInterTypeMungers();
for (BcelTypeMunger typeMunger : mungers) {
// for (Iterator<ConcreteTypeMunger> iter = mungers.iterator(); iter.hasNext();) {
// BcelTypeMunger typeMunger = (BcelTypeMunger) iter.next();
List<ConcreteTypeMunger> mungers = relevantType.resolve(world).getInterTypeMungers();
for (ConcreteTypeMunger typeMunger : mungers) {
if (typeMunger.getMunger() instanceof NewFieldTypeMunger) {
ResolvedMember fakerm = typeMunger.getSignature();
// if (fakerm.hasAnnotations())
@@ -2028,6 +2041,7 @@ public class BcelShadow extends Shadow {

// this is the same for both per and non-per
weaveAfter(new BcelAdvice(null, null, null, 0, 0, 0, null, null) {
@Override
public InstructionList getAdviceInstructions(BcelShadow s, BcelVar extraArgVar, InstructionHandle ifNoAdvice) {
InstructionList exitInstructions = new InstructionList();
if (munger.hasDynamicTests()) {
@@ -2669,12 +2683,14 @@ public class BcelShadow extends Shadow {
private static class UsesThisVisitor extends AbstractPatternNodeVisitor {
boolean usesThis = false;

@Override
public Object visit(ThisOrTargetPointcut node, Object data) {
if (node.isThis() && node.isBinding())
usesThis = true;
return node;
}

@Override
public Object visit(AndPointcut node, Object data) {
if (!usesThis)
node.getLeft().accept(this, data);
@@ -2683,12 +2699,14 @@ public class BcelShadow extends Shadow {
return node;
}

@Override
public Object visit(NotPointcut node, Object data) {
if (!usesThis)
node.getNegatedPointcut().accept(this, data);
return node;
}

@Override
public Object visit(OrPointcut node, Object data) {
if (!usesThis)
node.getLeft().accept(this, data);
@@ -2701,12 +2719,14 @@ public class BcelShadow extends Shadow {
private static class UsesTargetVisitor extends AbstractPatternNodeVisitor {
boolean usesTarget = false;

@Override
public Object visit(ThisOrTargetPointcut node, Object data) {
if (!node.isThis() && node.isBinding())
usesTarget = true;
return node;
}

@Override
public Object visit(AndPointcut node, Object data) {
if (!usesTarget)
node.getLeft().accept(this, data);
@@ -2715,12 +2735,14 @@ public class BcelShadow extends Shadow {
return node;
}

@Override
public Object visit(NotPointcut node, Object data) {
if (!usesTarget)
node.getNegatedPointcut().accept(this, data);
return node;
}

@Override
public Object visit(OrPointcut node, Object data) {
if (!usesTarget)
node.getLeft().accept(this, data);
@@ -3260,6 +3282,7 @@ public class BcelShadow extends Shadow {
return getEnclosingClass().getFactory();
}

@Override
public ISourceLocation getSourceLocation() {
int sourceLine = getSourceLine();
if (sourceLine == 0 || sourceLine == -1) {

+ 143
- 152
weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java 查看文件

@@ -756,36 +756,39 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
return !bcelObjectType.isInterface();
}

private boolean mungeNewMethod(BcelClassWeaver weaver, NewMethodTypeMunger munger) {
World w = weaver.getWorld();
private boolean mungeNewMethod(BcelClassWeaver classWeaver, NewMethodTypeMunger munger) {
World world = classWeaver.getWorld();

// Resolving it will sort out the tvars
ResolvedMember unMangledInterMethod = munger.getSignature().resolve(w);
// do matching on the unMangled one, but actually add them to the
// mangled method
ResolvedMember interMethodBody = munger.getDeclaredInterMethodBody(aspectType, w);
ResolvedMember interMethodDispatcher = munger.getDeclaredInterMethodDispatcher(aspectType, w);
ResolvedMember unMangledInterMethod = munger.getSignature().resolve(world);
// do matching on the unMangled one, but actually add them to the mangled method
ResolvedMember interMethodBody = munger.getDeclaredInterMethodBody(aspectType, world);
ResolvedMember interMethodDispatcher = munger.getDeclaredInterMethodDispatcher(aspectType, world);
ResolvedMember memberHoldingAnyAnnotations = interMethodDispatcher;
ResolvedType onType = weaver.getWorld().resolve(unMangledInterMethod.getDeclaringType(), munger.getSourceLocation());
LazyClassGen gen = weaver.getLazyClassGen();
boolean mungingInterface = gen.isInterface();
LazyClassGen classGen = classWeaver.getLazyClassGen();

if (onType.isRawType())
ResolvedType onType = world.resolve(unMangledInterMethod.getDeclaringType(), munger.getSourceLocation());
if (onType.isRawType()) {
onType = onType.getGenericType();

boolean onInterface = onType.isInterface();
}

// Simple checks, can't ITD on annotations or enums
if (onType.isAnnotation()) {
signalError(WeaverMessages.ITDM_ON_ANNOTATION_NOT_ALLOWED, weaver, onType);
signalError(WeaverMessages.ITDM_ON_ANNOTATION_NOT_ALLOWED, classWeaver, onType);
return false;
}

if (onType.isEnum()) {
signalError(WeaverMessages.ITDM_ON_ENUM_NOT_ALLOWED, weaver, onType);
signalError(WeaverMessages.ITDM_ON_ENUM_NOT_ALLOWED, classWeaver, onType);
return false;
}

if (onInterface && gen.getLazyMethodGen(unMangledInterMethod.getName(), unMangledInterMethod.getSignature(), true) != null) {
boolean mungingInterface = classGen.isInterface();
boolean onInterface = onType.isInterface();

if (onInterface
&& classGen.getLazyMethodGen(unMangledInterMethod.getName(), unMangledInterMethod.getSignature(), true) != null) {
// this is ok, we could be providing the default implementation of a
// method
// that the target has already declared
@@ -793,22 +796,20 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
}

// If we are processing the intended ITD target type (might be an interface)
if (onType.equals(gen.getType())) {
if (onType.equals(classGen.getType())) {
ResolvedMember mangledInterMethod = AjcMemberMaker.interMethod(unMangledInterMethod, aspectType, onInterface);

LazyMethodGen newMethod = makeMethodGen(gen, mangledInterMethod);
LazyMethodGen newMethod = makeMethodGen(classGen, mangledInterMethod);
if (mungingInterface) {
// we want the modifiers of the ITD to be used for all
// *implementors* of the
// interface, but the method itself we add to the interface must
// be public abstract
// we want the modifiers of the ITD to be used for all *implementors* of the
// interface, but the method itself we add to the interface must be public abstract
newMethod.setAccessFlags(Modifier.PUBLIC | Modifier.ABSTRACT);
}

// pr98901
// For copying the annotations across, we have to discover the real
// member in the aspect which is holding them.
if (weaver.getWorld().isInJava5Mode()) {
if (classWeaver.getWorld().isInJava5Mode()) {
AnnotationAJ annotationsOnRealMember[] = null;
ResolvedType toLookOn = aspectType;
if (aspectType.isRawType()) {
@@ -824,38 +825,24 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
}
Set<ResolvedType> addedAnnotations = new HashSet<ResolvedType>();
if (annotationsOnRealMember != null) {
for (int i = 0; i < annotationsOnRealMember.length; i++) {
AnnotationAJ annotationX = annotationsOnRealMember[i];
AnnotationGen a = ((BcelAnnotation) annotationX).getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a, weaver.getLazyClassGen().getConstantPool(), true);
newMethod.addAnnotation(new BcelAnnotation(ag, weaver.getWorld()));
addedAnnotations.add(annotationX.getType());
for (AnnotationAJ anno : annotationsOnRealMember) {
AnnotationGen a = ((BcelAnnotation) anno).getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a, classGen.getConstantPool(), true);
newMethod.addAnnotation(new BcelAnnotation(ag, classWeaver.getWorld()));
addedAnnotations.add(anno.getType());
}
}
if (realMember != null) {
AnnotationAJ[][] pAnnos = realMember.getParameterAnnotations();
int offset = newMethod.isStatic() ? 0 : 1;
if (pAnnos != null && pAnnos.length != 0) {
int param = 0;
for (int i = offset; i < pAnnos.length; i++) {
AnnotationAJ[] annosOnParam = pAnnos[i];
if (annosOnParam != null && annosOnParam.length > 0) {
for (int j = 0; j < annosOnParam.length; j++) {
newMethod.addParameterAnnotation(param, annosOnParam[j]);
}
}
param++;
}
}
copyOverParameterAnnotations(newMethod, realMember);
}
// the code below was originally added to cope with the case where an aspect declares an annotation on an ITD
// declared within itself (an unusual situation). However, it also addresses the case where we may not find the
// annotation on the real representation of the ITD. This can happen in a load-time weaving situation where
// we couldn't add the annotation in time - and so here we recheck the declare annotations. Not quite ideal but
// works. pr288635
List<DeclareAnnotation> allDecams = w.getDeclareAnnotationOnMethods();
List<DeclareAnnotation> allDecams = world.getDeclareAnnotationOnMethods();
for (DeclareAnnotation declareAnnotationMC : allDecams) {
if (declareAnnotationMC.matches(unMangledInterMethod, w)) {
if (declareAnnotationMC.matches(unMangledInterMethod, world)) {
// && newMethod.getEnclosingClass().getType() == aspectType) {
AnnotationAJ annotation = declareAnnotationMC.getAnnotation();
if (!addedAnnotations.contains(annotation.getType())) {
@@ -869,7 +856,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
// isnt abstract)
if (!onInterface && !Modifier.isAbstract(mangledInterMethod.getModifiers())) {
InstructionList body = newMethod.getBody();
InstructionFactory fact = gen.getFactory();
InstructionFactory fact = classGen.getFactory();
int pos = 0;

if (!unMangledInterMethod.isStatic()) {
@@ -882,13 +869,13 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
body.append(InstructionFactory.createLoad(paramType, pos));
pos += paramType.getSize();
}
body.append(Utility.createInvoke(fact, weaver.getWorld(), interMethodBody));
body.append(Utility.createInvoke(fact, classWeaver.getWorld(), interMethodBody));
body.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(mangledInterMethod.getReturnType())));

if (weaver.getWorld().isInJava5Mode()) { // Don't need bridge
if (classWeaver.getWorld().isInJava5Mode()) { // Don't need bridge
// methods if not in
// 1.5 mode.
createAnyBridgeMethodsForCovariance(weaver, munger, unMangledInterMethod, onType, gen, paramTypes);
createAnyBridgeMethodsForCovariance(classWeaver, munger, unMangledInterMethod, onType, classGen, paramTypes);
}

} else {
@@ -897,20 +884,20 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
// RuntimeException("bas");
}

if (weaver.getWorld().isInJava5Mode()) {
if (world.isInJava5Mode()) {
String basicSignature = mangledInterMethod.getSignature();
String genericSignature = ((ResolvedMemberImpl) mangledInterMethod).getSignatureForAttribute();
if (!basicSignature.equals(genericSignature)) {
// Add a signature attribute to it
newMethod.addAttribute(createSignatureAttribute(gen.getConstantPool(), genericSignature));
newMethod.addAttribute(createSignatureAttribute(classGen.getConstantPool(), genericSignature));
}
}
// XXX make sure to check that we set exceptions properly on this
// guy.
weaver.addLazyMethodGen(newMethod);
weaver.getLazyClassGen().warnOnAddedMethod(newMethod.getMethod(), getSignature().getSourceLocation());
classWeaver.addLazyMethodGen(newMethod);
classWeaver.getLazyClassGen().warnOnAddedMethod(newMethod.getMethod(), getSignature().getSourceLocation());

addNeededSuperCallMethods(weaver, onType, munger.getSuperMethodsCalled());
addNeededSuperCallMethods(classWeaver, onType, munger.getSuperMethodsCalled());

return true;

@@ -919,11 +906,11 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
// This means the 'gen' should be the top most implementor
// - if it is *not* then something went wrong after we worked
// out that it was the top most implementor (see pr49657)
if (!gen.getType().isTopmostImplementor(onType)) {
ResolvedType rtx = gen.getType().getTopmostImplementor(onType);
if (!classGen.getType().isTopmostImplementor(onType)) {
ResolvedType rtx = classGen.getType().getTopmostImplementor(onType);
if (!rtx.isExposedToWeaver()) {
ISourceLocation sLoc = munger.getSourceLocation();
weaver.getWorld().getMessageHandler().handleMessage(
classWeaver.getWorld().getMessageHandler().handleMessage(
MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_NON_EXPOSED_IMPLEMENTOR, rtx,
getAspectType().getName()), (sLoc == null ? getAspectType().getSourceLocation() : sLoc)));
} else {
@@ -937,10 +924,10 @@ public class BcelTypeMunger extends ConcreteTypeMunger {

ResolvedMember mangledInterMethod = AjcMemberMaker.interMethod(unMangledInterMethod, aspectType, false);

LazyMethodGen mg = makeMethodGen(gen, mangledInterMethod);
LazyMethodGen mg = makeMethodGen(classGen, mangledInterMethod);

// From 98901#29 - need to copy annotations across
if (weaver.getWorld().isInJava5Mode()) {
if (classWeaver.getWorld().isInJava5Mode()) {
AnnotationAJ annotationsOnRealMember[] = null;
ResolvedType toLookOn = aspectType;
if (aspectType.isRawType())
@@ -955,25 +942,12 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
for (int i = 0; i < annotationsOnRealMember.length; i++) {
AnnotationAJ annotationX = annotationsOnRealMember[i];
AnnotationGen a = ((BcelAnnotation) annotationX).getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a, weaver.getLazyClassGen().getConstantPool(), true);
mg.addAnnotation(new BcelAnnotation(ag, weaver.getWorld()));
AnnotationGen ag = new AnnotationGen(a, classWeaver.getLazyClassGen().getConstantPool(), true);
mg.addAnnotation(new BcelAnnotation(ag, classWeaver.getWorld()));
}
}

AnnotationAJ[][] pAnnos = realMember.getParameterAnnotations();
int offset = mg.isStatic() ? 0 : 1;
if (pAnnos != null && pAnnos.length != 0) {
int param = 0;
for (int i = offset; i < pAnnos.length; i++) {
AnnotationAJ[] annosOnParam = pAnnos[i];
if (annosOnParam != null && annosOnParam.length > 0) {
for (int j = 0; j < annosOnParam.length; j++) {
mg.addParameterAnnotation(param, annosOnParam[j]);
}
}
param++;
}
}
copyOverParameterAnnotations(mg, realMember);
}

if (mungingInterface) {
@@ -988,7 +962,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
Type returnType = BcelWorld.makeBcelType(mangledInterMethod.getReturnType());

InstructionList body = mg.getBody();
InstructionFactory fact = gen.getFactory();
InstructionFactory fact = classGen.getFactory();
int pos = 0;

if (!mangledInterMethod.isStatic()) {
@@ -1001,7 +975,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
pos += paramType.getSize();
}

body.append(Utility.createInvoke(fact, weaver.getWorld(), interMethodBody));
body.append(Utility.createInvoke(fact, classWeaver.getWorld(), interMethodBody));
Type t = BcelWorld.makeBcelType(interMethodBody.getReturnType());
if (!t.equals(returnType)) {
body.append(fact.createCast(t, returnType));
@@ -1009,81 +983,40 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
body.append(InstructionFactory.createReturn(returnType));
mg.definingType = onType;

if (weaver.getWorld().isInJava5Mode()) {
if (world.isInJava5Mode()) {
String basicSignature = mangledInterMethod.getSignature();
String genericSignature = ((ResolvedMemberImpl) mangledInterMethod).getSignatureForAttribute();
if (!basicSignature.equals(genericSignature)) {
// Add a signature attribute to it
mg.addAttribute(createSignatureAttribute(gen.getConstantPool(), genericSignature));
mg.addAttribute(createSignatureAttribute(classGen.getConstantPool(), genericSignature));
}
}

weaver.addOrReplaceLazyMethodGen(mg);
classWeaver.addOrReplaceLazyMethodGen(mg);

addNeededSuperCallMethods(weaver, onType, munger.getSuperMethodsCalled());
addNeededSuperCallMethods(classWeaver, onType, munger.getSuperMethodsCalled());

// Work out if we need a bridge method for the new method added
// to the topmostimplementor.
if (munger.getDeclaredSignature() != null) { // Check if the
// munger being
// processed is
// a
// parameterized
// form of some
// original
// munger.
// Work out if we need a bridge method for the new method added to the topmostimplementor.

// Check if the munger being processed is a parameterized form of the original munger
if (munger.getDeclaredSignature() != null) {
boolean needsbridging = false;
ResolvedMember mungerSignature = munger.getSignature();
ResolvedMember toBridgeTo = munger.getDeclaredSignature().parameterizedWith(null,
munger.getSignature().getDeclaringType().resolve(getWorld()), false, munger.getTypeVariableAliases());
mungerSignature.getDeclaringType().resolve(getWorld()), false, munger.getTypeVariableAliases());
if (!toBridgeTo.getReturnType().getErasureSignature().equals(
munger.getSignature().getReturnType().getErasureSignature()))
mungerSignature.getReturnType().getErasureSignature()))
needsbridging = true;
UnresolvedType[] originalParams = toBridgeTo.getParameterTypes();
UnresolvedType[] newParams = munger.getSignature().getParameterTypes();
UnresolvedType[] newParams = mungerSignature.getParameterTypes();
for (int ii = 0; ii < originalParams.length; ii++) {
if (!originalParams[ii].getErasureSignature().equals(newParams[ii].getErasureSignature()))
needsbridging = true;
}
if (needsbridging) {
ResolvedMember bridgerMethod = AjcMemberMaker.bridgerToInterMethod(unMangledInterMethod, gen.getType());
ResolvedMember bridgingSetter = AjcMemberMaker.interMethodBridger(toBridgeTo, aspectType, false); // pr250493

// FIXME asc ----------------8<---------------- extract
// method
LazyMethodGen bridgeMethod = makeMethodGen(gen, bridgingSetter);
paramTypes = BcelWorld.makeBcelTypes(bridgingSetter.getParameterTypes());
Type[] bridgingToParms = BcelWorld.makeBcelTypes(unMangledInterMethod.getParameterTypes());
returnType = BcelWorld.makeBcelType(bridgingSetter.getReturnType());
body = bridgeMethod.getBody();
fact = gen.getFactory();
pos = 0;

if (!bridgingSetter.isStatic()) {
body.append(InstructionFactory.createThis());
pos++;
}
for (int i = 0, len = paramTypes.length; i < len; i++) {
Type paramType = paramTypes[i];
body.append(InstructionFactory.createLoad(paramType, pos));
if (!bridgingSetter.getParameterTypes()[i].getErasureSignature().equals(
unMangledInterMethod.getParameterTypes()[i].getErasureSignature())) {
// System.err.println("Putting in cast from "+
// paramType+" to "+bridgingToParms[i]);
body.append(fact.createCast(paramType, bridgingToParms[i]));
}
pos += paramType.getSize();
}

body.append(Utility.createInvoke(fact, weaver.getWorld(), bridgerMethod));
body.append(InstructionFactory.createReturn(returnType));
gen.addMethodGen(bridgeMethod);
// mg.definingType = onType;
// FIXME asc (see above)
// ---------------------8<--------------- extract method
createBridge(classWeaver, unMangledInterMethod, classGen, toBridgeTo);
}

}

return true;
}
} else {
@@ -1091,6 +1024,62 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
}
}

private void copyOverParameterAnnotations(LazyMethodGen receiverMethod, ResolvedMember donorMethod) {
AnnotationAJ[][] pAnnos = donorMethod.getParameterAnnotations();
if (pAnnos != null) {
int offset = receiverMethod.isStatic() ? 0 : 1;
int param = 0;
for (int i = offset; i < pAnnos.length; i++) {
AnnotationAJ[] annosOnParam = pAnnos[i];
if (annosOnParam != null) {
for (AnnotationAJ anno : annosOnParam) {
receiverMethod.addParameterAnnotation(param, anno);
}
}
param++;
}
}
}

private void createBridge(BcelClassWeaver weaver, ResolvedMember unMangledInterMethod, LazyClassGen classGen,
ResolvedMember toBridgeTo) {
Type[] paramTypes;
Type returnType;
InstructionList body;
InstructionFactory fact;
int pos;
ResolvedMember bridgerMethod = AjcMemberMaker.bridgerToInterMethod(unMangledInterMethod, classGen.getType());
ResolvedMember bridgingSetter = AjcMemberMaker.interMethodBridger(toBridgeTo, aspectType, false); // pr250493

LazyMethodGen bridgeMethod = makeMethodGen(classGen, bridgingSetter);
paramTypes = BcelWorld.makeBcelTypes(bridgingSetter.getParameterTypes());
Type[] bridgingToParms = BcelWorld.makeBcelTypes(unMangledInterMethod.getParameterTypes());
returnType = BcelWorld.makeBcelType(bridgingSetter.getReturnType());
body = bridgeMethod.getBody();
fact = classGen.getFactory();
pos = 0;
if (!bridgingSetter.isStatic()) {
body.append(InstructionFactory.createThis());
pos++;
}
for (int i = 0, len = paramTypes.length; i < len; i++) {
Type paramType = paramTypes[i];
body.append(InstructionFactory.createLoad(paramType, pos));
if (!bridgingSetter.getParameterTypes()[i].getErasureSignature().equals(
unMangledInterMethod.getParameterTypes()[i].getErasureSignature())) {
// System.err.println("Putting in cast from "+
// paramType+" to "+bridgingToParms[i]);
body.append(fact.createCast(paramType, bridgingToParms[i]));
}
pos += paramType.getSize();
}

body.append(Utility.createInvoke(fact, weaver.getWorld(), bridgerMethod));
body.append(InstructionFactory.createReturn(returnType));
classGen.addMethodGen(bridgeMethod);
// mg.definingType = onType;
}

/**
* Helper method to create a signature attribute based on a string signature: e.g. "Ljava/lang/Object;LI<Ljava/lang/Double;>;"
*/
@@ -1243,34 +1232,36 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
}

private boolean mungeMethodDelegate(BcelClassWeaver weaver, MethodDelegateTypeMunger munger) {
ResolvedMember introduced = munger.getSignature();
World world = weaver.getWorld();

LazyClassGen gen = weaver.getLazyClassGen();

ResolvedType fromType = weaver.getWorld().resolve(introduced.getDeclaringType(), munger.getSourceLocation());
if (fromType.isRawType())
fromType = fromType.getGenericType();

if (gen.getType().isAnnotation() || gen.getType().isEnum()) {
// don't signal error as it could be a consequence of a wild type
// pattern
// don't signal error as it could be a consequence of a wild type pattern
return false;
}

ResolvedMember introduced = munger.getSignature();

ResolvedType fromType = world.resolve(introduced.getDeclaringType(), munger.getSourceLocation());
if (fromType.isRawType()) {
fromType = fromType.getGenericType();
}

boolean shouldApply = munger.matches(weaver.getLazyClassGen().getType(), aspectType);

if (shouldApply) {
Type bcelReturnType = BcelWorld.makeBcelType(introduced.getReturnType());

// If no implementation class was specified, the intention was that
// the types matching the pattern
// already implemented the interface, let's check that now!
if (munger.getImplClassName() == null && !munger.specifiesDelegateFactoryMethod()) {
boolean isOK = false;
List/* LazyMethodGen */existingMethods = gen.getMethodGens();
for (Iterator i = existingMethods.iterator(); i.hasNext() && !isOK;) {
LazyMethodGen m = (LazyMethodGen) i.next();
List<LazyMethodGen> existingMethods = gen.getMethodGens();
for (LazyMethodGen m : existingMethods) {
if (m.getName().equals(introduced.getName())
&& m.getParameterSignature().equals(introduced.getParameterSignature())
&& m.getReturnType().equals(BcelWorld.makeBcelType(introduced.getReturnType()))) {
&& m.getReturnType().equals(bcelReturnType)) {
isOK = true;
}
}
@@ -1288,28 +1279,28 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
return true;
}

LazyMethodGen mg = new LazyMethodGen(introduced.getModifiers() - Modifier.ABSTRACT, BcelWorld.makeBcelType(introduced
.getReturnType()), introduced.getName(), BcelWorld.makeBcelTypes(introduced.getParameterTypes()), BcelWorld
LazyMethodGen mg = new LazyMethodGen(introduced.getModifiers() - Modifier.ABSTRACT, bcelReturnType, introduced
.getName(), BcelWorld.makeBcelTypes(introduced.getParameterTypes()), BcelWorld
.makeBcelTypesAsClassNames(introduced.getExceptions()), gen);

// annotation copy from annotation on ITD interface
if (weaver.getWorld().isInJava5Mode()) {
AnnotationAJ annotationsOnRealMember[] = null;
ResolvedType toLookOn = weaver.getWorld().lookupOrCreateName(introduced.getDeclaringType());
if (fromType.isRawType())
if (fromType.isRawType()) {
toLookOn = fromType.getGenericType();
}
// lookup the method
ResolvedMember[] ms = toLookOn.getDeclaredJavaMethods();
for (int i = 0; i < ms.length; i++) {
ResolvedMember m = ms[i];
for (ResolvedMember m : ms) {
if (introduced.getName().equals(m.getName()) && introduced.getSignature().equals(m.getSignature())) {
annotationsOnRealMember = m.getAnnotations();
break;
}
}
if (annotationsOnRealMember != null) {
for (int i = 0; i < annotationsOnRealMember.length; i++) {
AnnotationAJ annotationX = annotationsOnRealMember[i];
AnnotationGen a = ((BcelAnnotation) annotationX).getBcelAnnotation();
for (AnnotationAJ anno : annotationsOnRealMember) {
AnnotationGen a = ((BcelAnnotation) anno).getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a, weaver.getLazyClassGen().getConstantPool(), true);
mg.addAnnotation(new BcelAnnotation(ag, weaver.getWorld()));
}
@@ -1390,7 +1381,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
pos += paramType.getSize();
}
body.append(Utility.createInvoke(fact, Constants.INVOKEINTERFACE, introduced));
body.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(introduced.getReturnType())));
body.append(InstructionFactory.createReturn(bcelReturnType));

mg.getBody().append(body);
weaver.addLazyMethodGen(mg);

+ 3
- 1
weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java 查看文件

@@ -1354,6 +1354,7 @@ public class BcelWeaver {
this.inAspect = advice.getDeclaringAspect();
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof AdviceLocation)) {
return false;
@@ -1368,6 +1369,7 @@ public class BcelWeaver {
return true;
}

@Override
public int hashCode() {
return 37 + 17 * lineNo + 17 * inAspect.hashCode();
}
@@ -1768,7 +1770,7 @@ public class BcelWeaver {
}

List<ShadowMunger> shadowMungers = fastMatch(shadowMungerList, classType.getResolvedTypeX());
List typeMungers = classType.getResolvedTypeX().getInterTypeMungers();
List<ConcreteTypeMunger> typeMungers = classType.getResolvedTypeX().getInterTypeMungers();

classType.getResolvedTypeX().checkInterTypeMungers();


+ 83
- 119
weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java 查看文件

@@ -76,18 +76,17 @@ import org.aspectj.weaver.tools.Traceable;
* <p>
* We stay away from targeters for rangey things like Shadows and Exceptions.
*/

public final class LazyMethodGen implements Traceable {
private static final int ACC_SYNTHETIC = 0x1000;

private int accessFlags;
private int modifiers;
private Type returnType;
private final String name;
private Type[] argumentTypes;
// private final String[] argumentNames;
private String[] declaredExceptions;
private InstructionList body; // leaving null for abstracts
private List attributes;
private List<Attribute> attributes;
private List<AnnotationAJ> newAnnotations;
private AnnotationAJ[][] newParameterAnnotations;
private final LazyClassGen enclosingClass;
@@ -95,6 +94,8 @@ public final class LazyMethodGen implements Traceable {
private AjAttribute.EffectiveSignatureAttribute effectiveSignature;
int highestLineNumber = 0;
boolean wasPackedOptimally = false;
private Method savedMethod = null;
private static final AnnotationAJ[] NO_ANNOTATIONAJ = new AnnotationAJ[] {};

/*
* We use LineNumberTags and not Gens.
@@ -116,51 +117,36 @@ public final class LazyMethodGen implements Traceable {
* LineNumberTag to have external line numbers.
*/
String fromFilename = null;

private int maxLocals;

private boolean canInline = true;
// private boolean hasExceptionHandlers;

private boolean isSynthetic = false;

/**
* only used by {@link BcelClassWeaver}
*/
List /* ShadowMungers */matchedShadows;

// Used for interface introduction
// this is the type of the interface the method is technically on
List<BcelShadow> matchedShadows;
// Used for interface introduction - this is the type of the interface the method is technically on
public ResolvedType definingType = null;

public LazyMethodGen(int accessFlags, Type returnType, String name, Type[] paramTypes, String[] declaredExceptions,
public LazyMethodGen(int modifiers, Type returnType, String name, Type[] paramTypes, String[] declaredExceptions,
LazyClassGen enclosingClass) {
// System.err.println("raw create of: " + name + ", " +
// enclosingClass.getName() + ", " + returnType);
this.memberView = null; // ??? should be okay, since constructed ones
// aren't woven into
this.accessFlags = accessFlags;
this.memberView = null; // should be okay, since constructed ones aren't woven into
this.modifiers = modifiers;
this.returnType = returnType;
this.name = name;
this.argumentTypes = paramTypes;
// this.argumentNames = Utility.makeArgNames(paramTypes.length);
this.declaredExceptions = declaredExceptions;
if (!Modifier.isAbstract(accessFlags)) {
if (!Modifier.isAbstract(modifiers)) {
body = new InstructionList();
setMaxLocals(calculateMaxLocals());
} else {
body = null;
}
this.attributes = new ArrayList();
this.attributes = new ArrayList<Attribute>();
this.enclosingClass = enclosingClass;
assertGoodBody();

// @AJ advice are not inlined by default since requires further analysis
// and weaving ordering control
// TODO AV - improve - note: no room for improvement as long as aspects
// are reweavable
// since the inlined version with wrappers and an to be done annotation
// to keep
// @AJ advice are not inlined by default since requires further analysis and weaving ordering control
// TODO AV - improve - note: no room for improvement as long as aspects are reweavable
// since the inlined version with wrappers and an to be done annotation to keep
// inline state will be garbaged due to reweavable impl
if (memberView != null && isAdviceMethod()) {
if (enclosingClass.getType().isAnnotationStyleAspect()) {
@@ -171,17 +157,13 @@ public final class LazyMethodGen implements Traceable {
}

private int calculateMaxLocals() {
int ret = 0;
if (!Modifier.isStatic(accessFlags))
ret++;
for (int i = 0, len = argumentTypes.length; i < len; i++) {
ret += argumentTypes[i].getSize();
int ret = Modifier.isStatic(modifiers) ? 0 : 1; // will there be a 'this'?
for (Type type : argumentTypes) {
ret += type.getSize();
}
return ret;
}

private Method savedMethod = null;

// build from an existing method, lazy build saves most work for
// initialization
public LazyMethodGen(Method m, LazyClassGen enclosingClass) {
@@ -196,7 +178,7 @@ public final class LazyMethodGen implements Traceable {
}
this.memberView = new BcelMethod(enclosingClass.getBcelObjectType(), m);

this.accessFlags = m.getModifiers();
this.modifiers = m.getModifiers();
this.name = m.getName();

// @AJ advice are not inlined by default since requires further analysis
@@ -226,7 +208,7 @@ public final class LazyMethodGen implements Traceable {
// this.memberView = new BcelMethod(enclosingClass.getBcelObjectType(),
// m);
this.memberView = m;
this.accessFlags = savedMethod.getModifiers();
this.modifiers = savedMethod.getModifiers();
this.name = m.getName();

// @AJ advice are not inlined by default since requires further analysis
@@ -278,8 +260,6 @@ public final class LazyMethodGen implements Traceable {
}
}

private static final AnnotationAJ[] NO_ANNOTATIONAJ = new AnnotationAJ[] {};

public void addParameterAnnotation(int parameterNumber, AnnotationAJ anno) {
initialize();
if (memberView == null) {
@@ -325,18 +305,14 @@ public final class LazyMethodGen implements Traceable {
}

private void initialize() {
if (returnType != null)
if (returnType != null) {
return;

// System.err.println("initializing: " + getName() + ", " +
// enclosingClass.getName() + ", " + returnType + ", " +
// savedMethod);
}

MethodGen gen = new MethodGen(savedMethod, enclosingClass.getName(), enclosingClass.getConstantPool(), true);

this.returnType = gen.getReturnType();
this.argumentTypes = gen.getArgumentTypes();

this.declaredExceptions = gen.getExceptions();
this.attributes = gen.getAttributes();
// this.annotations = gen.getAnnotations();
@@ -357,17 +333,11 @@ public final class LazyMethodGen implements Traceable {
} else {
// body = new InstructionList(savedMethod.getCode().getCode());
body = gen.getInstructionList();

unpackHandlers(gen);

ensureAllLineNumberSetup();
highestLineNumber = gen.getHighestlinenumber();

}
assertGoodBody();

// System.err.println("initialized: " + this.getClassName() + "." +
// this.getName());
}

// XXX we're relying on the javac promise I've just made up that we won't
@@ -429,20 +399,18 @@ public final class LazyMethodGen implements Traceable {
* them may be extracted out into other methods - and it'd be useful for them to maintain the source line number for debugging.
*/
public void ensureAllLineNumberSetup() {
LineNumberTag lr = null;
LineNumberTag lastKnownLineNumberTag = null;
boolean skip = false;
for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) {
Iterator tIter = ih.getTargeters().iterator();
skip = false;
while (tIter.hasNext()) {
InstructionTargeter targeter = (InstructionTargeter) tIter.next();
for (InstructionTargeter targeter : ih.getTargeters()) {
if (targeter instanceof LineNumberTag) {
lr = (LineNumberTag) targeter;
lastKnownLineNumberTag = (LineNumberTag) targeter;
skip = true;
}
}
if (lr != null && !skip) {
ih.addTargeter(lr);
if (lastKnownLineNumberTag != null && !skip) {
ih.addTargeter(lastKnownLineNumberTag);
}
}
}
@@ -566,8 +534,7 @@ public final class LazyMethodGen implements Traceable {
if (enclosingClass != null && enclosingClass.getType() != null) {
context = enclosingClass.getType().getSourceContext();
}
List as = Utility.readAjAttributes(getClassName(), (Attribute[]) attributes.toArray(new Attribute[] {}), context, null,
weaverVersion);
List as = Utility.readAjAttributes(getClassName(), attributes.toArray(new Attribute[] {}), context, null, weaverVersion);
if (!as.isEmpty()) {
out.println(" " + as.get(0)); // XXX assuming exactly one
// attribute, munger...
@@ -575,7 +542,7 @@ public final class LazyMethodGen implements Traceable {
}

private class BodyPrinter {
Map labelMap = new HashMap();
Map<InstructionHandle, String> labelMap = new HashMap<InstructionHandle, String>();

InstructionList body;
PrintStream out;
@@ -606,9 +573,9 @@ public final class LazyMethodGen implements Traceable {
// boolean hasPendingTargeters = false;
int lcounter = 0;
for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) {
Iterator tIter = ih.getTargeters().iterator();
Iterator<InstructionTargeter> tIter = ih.getTargeters().iterator();
while (tIter.hasNext()) {
InstructionTargeter t = (InstructionTargeter) tIter.next();// targeters
InstructionTargeter t = tIter.next();// targeters
// [
// i
// ]
@@ -685,7 +652,7 @@ public final class LazyMethodGen implements Traceable {
out.println(getRangeString(r, labelMap));
}

String getRangeString(Range r, Map labelMap) {
String getRangeString(Range r, Map<InstructionHandle, String> labelMap) {
if (r instanceof ExceptionRange) {
ExceptionRange er = (ExceptionRange) r;
return er.toString() + " -> " + labelMap.get(er.getHandler());
@@ -718,7 +685,7 @@ public final class LazyMethodGen implements Traceable {

void printInstruction(InstructionHandle h, int depth) {
printDepth(depth);
printLabel((String) labelMap.get(h), depth);
printLabel(labelMap.get(h), depth);

Instruction inst = h.getInstruction();
if (inst.isConstantPoolInstruction()) {
@@ -823,21 +790,21 @@ public final class LazyMethodGen implements Traceable {
}

public int getAccessFlags() {
return accessFlags;
return modifiers;
}

public int getAccessFlagsWithoutSynchronized() {
if (isSynchronized())
return accessFlags - Modifier.SYNCHRONIZED;
return accessFlags;
return modifiers - Modifier.SYNCHRONIZED;
return modifiers;
}

public boolean isSynchronized() {
return (accessFlags & Modifier.SYNCHRONIZED) != 0;
return (modifiers & Modifier.SYNCHRONIZED) != 0;
}

public void setAccessFlags(int newFlags) {
this.accessFlags = newFlags;
this.modifiers = newFlags;
}

public Type[] getArgumentTypes() {
@@ -884,12 +851,13 @@ public final class LazyMethodGen implements Traceable {
}

public boolean hasBody() {
if (savedMethod != null)
if (savedMethod != null) {
return savedMethod.getCode() != null;
}
return body != null;
}

public List/* Attribute */getAttributes() {
public List<Attribute> getAttributes() {
return attributes;
}

@@ -918,13 +886,12 @@ public final class LazyMethodGen implements Traceable {
gen.addException(declaredExceptions[i]);
}

for (int i = 0, len = attributes.size(); i < len; i++) {
gen.addAttribute((Attribute) attributes.get(i));
for (Attribute attr : attributes) {
gen.addAttribute(attr);
}

if (newAnnotations != null) {
for (Iterator iter = newAnnotations.iterator(); iter.hasNext();) {
AnnotationAJ element = (AnnotationAJ) iter.next();
for (AnnotationAJ element : newAnnotations) {
gen.addAnnotation(new AnnotationGen(((BcelAnnotation) element).getBcelAnnotation(), gen.getConstantPool(), true));
}
}
@@ -1001,7 +968,7 @@ public final class LazyMethodGen implements Traceable {
*/
public void packBody(MethodGen gen) {
InstructionList fresh = gen.getInstructionList();
Map map = copyAllInstructionsExceptRangeInstructionsInto(fresh);
Map<InstructionHandle, InstructionHandle> map = copyAllInstructionsExceptRangeInstructionsInto(fresh);

// at this point, no rangeHandles are in fresh. Let's use that...

@@ -1132,10 +1099,10 @@ public final class LazyMethodGen implements Traceable {

int currLine = -1;
int lineNumberOffset = (fromFilename == null) ? 0 : getEnclosingClass().getSourceDebugExtensionOffset(fromFilename);
Map localVariables = new HashMap();
Map<LocalVariableTag, LVPosition> localVariables = new HashMap<LocalVariableTag, LVPosition>();
LinkedList exceptionList = new LinkedList();
Set forDeletion = new HashSet();
Set branchInstructions = new HashSet();
Set<InstructionHandle> forDeletion = new HashSet<InstructionHandle>();
Set<BranchHandle> branchInstructions = new HashSet<BranchHandle>();
// OPTIMIZE sort out in here: getRange()/insertHandler() and type of
// exceptionList
while (iHandle != null) {
@@ -1149,8 +1116,7 @@ public final class LazyMethodGen implements Traceable {
ExceptionRange er = (ExceptionRange) r;
if (er.getStart() == iHandle) {
if (!er.isEmpty()) {
// order is important, insert handlers in order of
// start
// order is important, insert handlers in order of start
insertHandler(er, exceptionList);
}
}
@@ -1158,7 +1124,7 @@ public final class LazyMethodGen implements Traceable {
forDeletion.add(iHandle);
} else {
if (inst instanceof InstructionBranch) {
branchInstructions.add(iHandle);
branchInstructions.add((BranchHandle) iHandle);
}

InstructionTargeter[] targeters = iHandle.getTargetersArray();
@@ -1173,7 +1139,7 @@ public final class LazyMethodGen implements Traceable {
}
} else if (targeter instanceof LocalVariableTag) {
LocalVariableTag lvt = (LocalVariableTag) targeter;
LVPosition p = (LVPosition) localVariables.get(lvt);
LVPosition p = localVariables.get(lvt);
// If we don't know about it, create a new position
// and store
// If we do know about it - update its end position
@@ -1190,9 +1156,8 @@ public final class LazyMethodGen implements Traceable {
}
iHandle = iHandle.getNext();
}
for (Iterator iterator = branchInstructions.iterator(); iterator.hasNext();) {
BranchHandle iBranch = (BranchHandle) iterator.next();
handleBranchInstruction(iBranch, forDeletion);
for (BranchHandle branchHandle : branchInstructions) {
handleBranchInstruction(branchHandle, forDeletion);
}
// now add exception handlers
for (Iterator iter = exceptionList.iterator(); iter.hasNext();) {
@@ -1269,7 +1234,7 @@ public final class LazyMethodGen implements Traceable {
}
}

private void addExceptionHandlers(MethodGen gen, Map map, LinkedList exnList) {
private void addExceptionHandlers(MethodGen gen, Map<InstructionHandle, InstructionHandle> map, LinkedList exnList) {
// now add exception handlers
for (Iterator iter = exnList.iterator(); iter.hasNext();) {
ExceptionRange r = (ExceptionRange) iter.next();
@@ -1316,7 +1281,11 @@ public final class LazyMethodGen implements Traceable {
return target;
}

private void handleBranchInstruction(BranchHandle branchHandle, Set handlesForDeletion) {
/**
* Process a branch instruction with respect to instructions that are about to be deleted. If the target for the branch is a
* candidate for deletion, move it to the next valid instruction after the deleted target.
*/
private void handleBranchInstruction(BranchHandle branchHandle, Set<InstructionHandle> handlesForDeletion) {
InstructionBranch branchInstruction = (InstructionBranch) branchHandle.getInstruction();
InstructionHandle target = branchInstruction.getTarget(); // old target

@@ -1329,7 +1298,7 @@ public final class LazyMethodGen implements Traceable {

if (branchInstruction instanceof InstructionSelect) {
// Either LOOKUPSWITCH or TABLESWITCH
InstructionSelect iSelect = ((InstructionSelect) branchInstruction);
InstructionSelect iSelect = (InstructionSelect) branchInstruction;
InstructionHandle[] targets = iSelect.getTargets();
for (int k = targets.length - 1; k >= 0; k--) {
InstructionHandle oneTarget = targets[k];
@@ -1366,19 +1335,20 @@ public final class LazyMethodGen implements Traceable {
* Make copies of all instructions, append them to the new list and associate old instruction references with the new ones,
* i.e., a 1:1 mapping.
*/
private Map copyAllInstructionsExceptRangeInstructionsInto(InstructionList intoList) {
HashMap map = new HashMap();
private Map<InstructionHandle, InstructionHandle> copyAllInstructionsExceptRangeInstructionsInto(InstructionList intoList) {
Map<InstructionHandle, InstructionHandle> map = new HashMap<InstructionHandle, InstructionHandle>();
for (InstructionHandle ih = getBody().getStart(); ih != null; ih = ih.getNext()) {
if (Range.isRangeHandle(ih)) {
continue;
}
Instruction i = ih.getInstruction();
Instruction c = Utility.copyInstruction(i);
Instruction inst = ih.getInstruction();
Instruction copy = Utility.copyInstruction(inst);

if (c instanceof InstructionBranch)
map.put(ih, intoList.append((InstructionBranch) c));
else
map.put(ih, intoList.append(c));
if (copy instanceof InstructionBranch) {
map.put(ih, intoList.append((InstructionBranch) copy));
} else {
map.put(ih, intoList.append(copy));
}
}
return map;
}
@@ -1413,13 +1383,13 @@ public final class LazyMethodGen implements Traceable {
// else return ih;
// }
// }
private static InstructionHandle remap(InstructionHandle ih, Map map) {
private static InstructionHandle remap(InstructionHandle handle, Map<InstructionHandle, InstructionHandle> map) {
while (true) {
Object ret = map.get(ih);
InstructionHandle ret = map.get(handle);
if (ret == null) {
ih = ih.getNext();
handle = handle.getNext();
} else {
return (InstructionHandle) ret;
return ret;
}
}
}
@@ -1517,12 +1487,13 @@ public final class LazyMethodGen implements Traceable {
}

public static void assertGoodBody(InstructionList il, String from) {
if (true)
if (true) {
return; // only to be enabled for debugging
}
if (il == null)
return;
Set body = new HashSet();
Stack ranges = new Stack();
Stack<Range> ranges = new Stack<Range>();
for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) {
body.add(ih);
if (ih.getInstruction() instanceof InstructionBranch) {
@@ -1539,7 +1510,7 @@ public final class LazyMethodGen implements Traceable {
}
}

private static void assertGoodHandle(InstructionHandle ih, Set body, Stack ranges, String from) {
private static void assertGoodHandle(InstructionHandle ih, Set body, Stack<Range> ranges, String from) {
Instruction inst = ih.getInstruction();
if ((inst instanceof InstructionBranch) ^ (ih instanceof BranchHandle)) {
throw new BCException("bad instruction/handle pair in " + from);
@@ -1551,7 +1522,8 @@ public final class LazyMethodGen implements Traceable {
}
}

private static void assertGoodBranchInstruction(BranchHandle ih, InstructionBranch inst, Set body, Stack ranges, String from) {
private static void assertGoodBranchInstruction(BranchHandle ih, InstructionBranch inst, Set body, Stack<Range> ranges,
String from) {
if (ih.getTarget() != inst.getTarget()) {
throw new BCException("bad branch instruction/handle pair in " + from);
}
@@ -1570,8 +1542,9 @@ public final class LazyMethodGen implements Traceable {

/** ih is an InstructionHandle or a BranchInstruction */
private static void assertInBody(Object ih, Set body, String from) {
if (!body.contains(ih))
if (!body.contains(ih)) {
throw new BCException("thing not in body in " + from);
}
}

private static void assertGoodRangeHandle(InstructionHandle ih, Set body, Stack ranges, String from) {
@@ -1726,7 +1699,7 @@ public final class LazyMethodGen implements Traceable {

public void forcePublic() {
markAsChanged();
accessFlags = Utility.makePublic(accessFlags);
modifiers = Utility.makePublic(modifiers);
}

public boolean getCanInline() {
@@ -1737,17 +1710,8 @@ public final class LazyMethodGen implements Traceable {
this.canInline = canInline;
}

/**
* Adds an attribute to the method
*
* @param attr
*/
public void addAttribute(Attribute attr) {
attributes.add(attr);
// Attribute[] newAttributes = new Attribute[attributes.length + 1];
// System.arraycopy(attributes, 0, newAttributes, 0, attributes.length);
// newAttributes[attributes.length] = attr;
// attributes = newAttributes;
public void addAttribute(Attribute attribute) {
attributes.add(attribute);
}

public String toTraceString() {

Loading…
取消
儲存