From c86fa6de889e521ebe8224d1a7579269c53ac357 Mon Sep 17 00:00:00 2001 From: aclement Date: Mon, 3 Oct 2005 14:10:07 +0000 Subject: [PATCH] pr83717: allows ITD incremental compilation with reweavable. Also commented some iffy/complex areas of the code --- .../compiler/lookup/AjLookupEnvironment.java | 81 +++++++++++++------ .../systemtest/ajc150/GenericsTests.java | 8 +- 2 files changed, 59 insertions(+), 30 deletions(-) diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java index 89099dc57..cb6f5e4ba 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java @@ -81,6 +81,23 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC // private boolean builtInterTypesAndPerClauses = false; private List pendingTypesToWeave = new ArrayList(); + + // Q: What are dangerousInterfaces? + // A: An interface is considered dangerous if an ITD has been made upon it and that ITD + // requires the top most implementors of the interface to be woven *and yet* the aspect + // responsible for the ITD is not in the 'world'. + // Q: Err, how can that happen? + // A: When a type is on the inpath, it is 'processed' when completing type bindings. At this + // point we look at any type mungers it was affected by previously (stored in the weaver + // state info attribute). Effectively we are working with a type munger and yet may not have its + // originating aspect in the world. This is a problem if, for example, the aspect supplied + // a 'body' for a method targetting an interface - since the top most implementors should + // be woven by the munger from the aspect. When this happens we store the interface name here + // in the map - if we later process a type that is the topMostImplementor of a dangerous + // interface then we put out an error message. + + /** interfaces targetted by ITDs that have to be implemented by accessing the topMostImplementor + * of the interface, yet the aspect where the ITD originated is not in the world */ private Map dangerousInterfaces = new HashMap(); public AjLookupEnvironment( @@ -416,39 +433,29 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC private void weaveInterTypeDeclarations(SourceTypeBinding sourceType, Collection typeMungers, Collection declareParents, Collection declareAnnotationOnTypes, boolean skipInners) { + ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_INTERTYPE_DECLARATIONS, sourceType.sourceName); + ResolvedType onType = factory.fromEclipse(sourceType); // AMC we shouldn't need this when generic sigs are fixed?? if (onType.isRawType()) onType = onType.getGenericType(); + WeaverStateInfo info = onType.getWeaverState(); - - if (info != null && !info.isOldStyle()) { - Collection mungers = - onType.getWeaverState().getTypeMungers(onType); - - //System.out.println(onType + " mungers: " + mungers); - for (Iterator i = mungers.iterator(); i.hasNext(); ) { - ConcreteTypeMunger m = (ConcreteTypeMunger)i.next(); - EclipseTypeMunger munger = factory.makeEclipseTypeMunger(m); - if (munger.munge(sourceType,onType)) { - if (onType.isInterface() && - munger.getMunger().needsAccessToTopmostImplementor()) - { - if (!onType.getWorld().getCrosscuttingMembersSet().containsAspect(munger.getAspectType())) { - dangerousInterfaces.put(onType, - "implementors of " + onType + " must be woven by " + - munger.getAspectType()); - } - } - } - - } + + // this test isnt quite right - there will be a case where we fail to flag a problem + // with a 'dangerous interface' because the type is reweavable when we should have + // because the type wasn't going to be rewoven... if that happens, we should perhaps + // move this test and dangerous interface processing to the end of this method and + // make it conditional on whether any of the typeMungers passed into here actually + // matched this type. + if (info != null && !info.isOldStyle() && !info.isReweavable()) { + processTypeMungersFromExistingWeaverState(sourceType,onType); CompilationAndWeavingContext.leavingPhase(tok); return; } - //System.out.println("dangerousInterfaces: " + dangerousInterfaces); - + // Check if the type we are looking at is the topMostImplementor of a dangerous interface - + // report a problem if it is. for (Iterator i = dangerousInterfaces.entrySet().iterator(); i.hasNext();) { Map.Entry entry = (Map.Entry) i.next(); ResolvedType interfaceType = (ResolvedType)entry.getKey(); @@ -568,6 +575,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC // future generations to enjoy. Method source is commented out at the end of this module // doDeclareAnnotationOnFields(); + if (skipInners) { CompilationAndWeavingContext.leavingPhase(tok); return; @@ -581,6 +589,31 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC } CompilationAndWeavingContext.leavingPhase(tok); } + + /** + * Called when we discover we are weaving intertype declarations on some type that has + * an existing 'WeaverStateInfo' object - this is typically some previously woven type + * that has been passed on the inpath. + * + * sourceType and onType are the 'same type' - the former is the 'Eclipse' version and + * the latter is the 'Weaver' version. + */ + private void processTypeMungersFromExistingWeaverState(SourceTypeBinding sourceType,ResolvedType onType) { + Collection previouslyAppliedMungers = onType.getWeaverState().getTypeMungers(onType); + + for (Iterator i = previouslyAppliedMungers.iterator(); i.hasNext(); ) { + ConcreteTypeMunger m = (ConcreteTypeMunger)i.next(); + EclipseTypeMunger munger = factory.makeEclipseTypeMunger(m); + if (munger.munge(sourceType,onType)) { + if (onType.isInterface() && munger.getMunger().needsAccessToTopmostImplementor()) { + if (!onType.getWorld().getCrosscuttingMembersSet().containsAspect(munger.getAspectType())) { + dangerousInterfaces.put(onType, "implementors of "+onType+" must be woven by "+munger.getAspectType()); + } + } + } + + } + } private boolean doDeclareParents(DeclareParents declareParents, SourceTypeBinding sourceType) { ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_DECLARE_PARENTS, sourceType.sourceName); diff --git a/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java b/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java index f5066272a..437b6e2fc 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java +++ b/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java @@ -378,12 +378,8 @@ public class GenericsTests extends XMLBasedAjcTestCase { public void testBinaryWeavingITDsA() {runTest("binary weaving ITDs - A");} public void testBinaryWeavingITDsB() {runTest("binary weaving ITDs - B");} public void testBinaryWeavingITDs1() {runTest("binary weaving ITDs - 1");} - // ?? Looks like reweavable files dont process their type mungers correctly. - // See AjLookupEnvironment.weaveInterTypeDeclarations(SourceTypeBinding,typeMungers,declareparents,...) - // it seems to process any it discovers from the weaver state info then not apply new ones (the ones - // passed in!) -// public void testBinaryWeavingITDs2() {runTest("binary weaving ITDs - 2");} -// public void testBinaryWeavingITDs3() {runTest("binary weaving ITDs - 3");} + public void testBinaryWeavingITDs2() {runTest("binary weaving ITDs - 2");} + public void testBinaryWeavingITDs3() {runTest("binary weaving ITDs - 3");} public void testGenericITFSharingTypeVariable() {runTest("generic intertype field declaration, sharing type variable");} -- 2.39.5