@@ -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; | |||
} |
@@ -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; | |||
} |
@@ -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) { |
@@ -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); |
@@ -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(); | |||
@@ -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() { |