From 508cdf93dea3dff570b1a92f1485cee4fd78703c Mon Sep 17 00:00:00 2001 From: aclement Date: Wed, 5 Jan 2005 16:43:16 +0000 Subject: [PATCH] Changed order processing for weaving to match the recent changes in source order processing. Before weaving decp on type A, we look at supertypes and superinterfaces of A. --- .../org/aspectj/weaver/bcel/BcelWeaver.java | 85 +++++++++++++++---- 1 file changed, 68 insertions(+), 17 deletions(-) diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java index badb21f66..c466d46eb 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java @@ -839,12 +839,28 @@ public class BcelWeaver implements IWeaver { } requestor.addingTypeMungers(); - //XXX this isn't quite the right place for this... - for (Iterator i = input.getClassFileIterator(); i.hasNext(); ) { - UnwovenClassFile classFile = (UnwovenClassFile)i.next(); - String className = classFile.getClassName(); - addTypeMungers(className); - } + + // We process type mungers in two groups, first mungers that change the type + // hierarchy, then 'normal' ITD type mungers. + + + // Process the types in a predictable order (rather than the order encountered). + // For class A, the order is superclasses of A then superinterfaces of A + // (and this mechanism is applied recursively) + List typesToProcess = new ArrayList(); + for (Iterator iter = input.getClassFileIterator(); iter.hasNext();) { + UnwovenClassFile clf = (UnwovenClassFile) iter.next(); + typesToProcess.add(clf.getClassName()); + } + while (typesToProcess.size()>0) { + weaveParentsFor(typesToProcess,(String)typesToProcess.get(0)); + } + + for (Iterator i = input.getClassFileIterator(); i.hasNext(); ) { + UnwovenClassFile classFile = (UnwovenClassFile)i.next(); + String className = classFile.getClassName(); + addNormalTypeMungers(className); + } requestor.weavingAspects(); // first weave into aspects @@ -877,6 +893,37 @@ public class BcelWeaver implements IWeaver { return wovenClassNames; } + /** + * 'typeToWeave' is one from the 'typesForWeaving' list. This routine ensures we process + * supertypes (classes/interfaces) of 'typeToWeave' that are in the + * 'typesForWeaving' list before 'typeToWeave' itself. 'typesToWeave' is then removed from + * the 'typesForWeaving' list. + * + * Note: Future gotcha in here ... when supplying partial hierarchies, this algorithm may + * break down. If you have a hierarchy A>B>C and only give A and C to the weaver, it + * may choose to weave them in either order - but you'll probably have other problems if + * you are supplying partial hierarchies like that ! + */ + private void weaveParentsFor(List typesForWeaving,String typeToWeave) { + // Look at the supertype first + ResolvedTypeX rtx = world.resolve(typeToWeave); + ResolvedTypeX superType = rtx.getSuperclass(); + if (superType!=null && typesForWeaving.contains(superType.getClassName())) { + weaveParentsFor(typesForWeaving,superType.getClassName()); + } + + // Then look at the superinterface list + ResolvedTypeX[] interfaceTypes = rtx.getDeclaredInterfaces(); + for (int i = 0; i < interfaceTypes.length; i++) { + ResolvedTypeX rtxI = interfaceTypes[i]; + if (typesForWeaving.contains(rtxI.getClassName())) { + weaveParentsFor(typesForWeaving,rtxI.getClassName()); + } + } + weaveParentTypeMungers(rtx); // Now do this type + typesForWeaving.remove(typeToWeave); // and remove it from the list of those to process + } + public void prepareToProcessReweavableState() { if (inReweavableMode) world.showMessage(IMessage.INFO, @@ -941,8 +988,12 @@ public class BcelWeaver implements IWeaver { } - public void addTypeMungers(String typeName) { - weave(world.resolve(typeName)); + public void addParentTypeMungers(String typeName) { + weaveParentTypeMungers(world.resolve(typeName)); + } + + public void addNormalTypeMungers(String typeName) { + weaveNormalTypeMungers(world.resolve(typeName)); } public UnwovenClassFile[] getClassFilesFor(LazyClassGen clazz) { @@ -958,7 +1009,7 @@ public class BcelWeaver implements IWeaver { return ret; } - public void weave(ResolvedTypeX onType) { + public void weaveParentTypeMungers(ResolvedTypeX onType) { onType.clearInterTypeMungers(); // need to do any declare parents before the matching below @@ -970,20 +1021,20 @@ public class BcelWeaver implements IWeaver { //System.err.println("need to do declare parents for: " + onType); for (Iterator j = newParents.iterator(); j.hasNext(); ) { ResolvedTypeX newParent = (ResolvedTypeX)j.next(); - if (newParent.isClass()) { - world.showMessage(IMessage.ERROR, - WeaverMessages.format(WeaverMessages.DECP_BINARY_LIMITATION,onType.getName()), - p.getSourceLocation(), null); - continue; - } - + + // We set it here so that the following matching for ITDs can succeed - we + // still haven't done the necessary changes to the class file itself + // (like transform super calls) - that is done in BcelTypeMunger.mungeNewParent() classType.addParent(newParent); ResolvedTypeMunger newParentMunger = new NewParentTypeMunger(newParent); + newParentMunger.setSourceLocation(p.getSourceLocation()); onType.addInterTypeMunger(new BcelTypeMunger(newParentMunger, xcutSet.findAspectDeclaringParents(p))); } } } - + } + + public void weaveNormalTypeMungers(ResolvedTypeX onType) { for (Iterator i = typeMungerList.iterator(); i.hasNext(); ) { ConcreteTypeMunger m = (ConcreteTypeMunger)i.next(); if (m.matches(onType)) { -- 2.39.5