]> source.dussan.org Git - aspectj.git/commitdiff
fix for Bugzilla Bug 41175
authorjhugunin <jhugunin>
Fri, 8 Aug 2003 00:26:22 +0000 (00:26 +0000)
committerjhugunin <jhugunin>
Fri, 8 Aug 2003 00:26:22 +0000 (00:26 +0000)
   binary aspect-declared methods conflict, lost their exception clauses

larger fix to address more issues with aspect-declared methods in bytecode form
also addressed declared exception issue more generally

this fix should be more stable than a smaller hack that just fixed this specific bug
report would have been.  added a few tests to match increased scope.

29 files changed:
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java
org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BinaryFormsTestCase.java
tests/ajcTests.xml
tests/ajcTestsFailing.xml
tests/bugs/DeclaredExceptions.java [new file with mode: 0644]
tests/bugs/interfaceLibrary/lib.jar
tests/bugs/interfaceLibrary/libClass.jar
tests/new/interfaceLibrary/aspectOnly.jar
tests/new/interfaceLibrary/aspectedInterfaceOnly.jar
tests/new/interfaceLibrary/aspectedInterfaceOnlyBinary.jar
tests/new/interfaceLibrary/interfaceOnly.jar
weaver/src/org/aspectj/weaver/AjAttribute.java
weaver/src/org/aspectj/weaver/AjcMemberMaker.java
weaver/src/org/aspectj/weaver/CrosscuttingMembersSet.java
weaver/src/org/aspectj/weaver/ResolvedMember.java
weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java
weaver/src/org/aspectj/weaver/ResolvedTypeX.java
weaver/src/org/aspectj/weaver/WeaverStateInfo.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/WeaverStateKind.java [deleted file]
weaver/src/org/aspectj/weaver/World.java
weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java
weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java
weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java

index 9ddf959d8582bb197fa24ce52879dfee71ab2890..a1c8c8e02c7ba439ad63c1df3396421a89f8c6d1 100644 (file)
@@ -212,8 +212,8 @@ public class InterTypeConstructorDeclaration extends InterTypeDeclaration {
                
                ResolvedMember signature =
                        new ResolvedMember(Member.CONSTRUCTOR, declaringTypeX, declaredModifiers, 
-                                       ResolvedTypeX.VOID, "<init>", bindingAsMember.getParameterTypes());
-               signature.setCheckedExceptions(world.fromEclipse(binding.thrownExceptions));                    
+                                       ResolvedTypeX.VOID, "<init>", bindingAsMember.getParameterTypes(),
+                                       world.fromEclipse(binding.thrownExceptions));                   
                ResolvedMember syntheticInterMember =
                        AjcMemberMaker.interConstructor(declaringTypeX,  signature, aspectType);
                
index 662a5bc3f8856348c74679878b9f7295808e1656..2039fd54ca9dcc947b98f99a576425f934e81f46 100644 (file)
@@ -86,8 +86,8 @@ public class InterTypeMethodDeclaration extends InterTypeDeclaration {
                binding = classScope.referenceContext.binding.resolveTypesFor(binding);
                ResolvedMember sig = new ResolvedMember(Member.METHOD, EclipseFactory.fromBinding(onTypeBinding),
                        declaredModifiers, EclipseFactory.fromBinding(binding.returnType), new String(declaredSelector),
-                       EclipseFactory.fromBindings(binding.parameters));
-               sig.setCheckedExceptions(world.fromEclipse(binding.thrownExceptions));
+                       EclipseFactory.fromBindings(binding.parameters),
+                       world.fromEclipse(binding.thrownExceptions));
                
                NewMethodTypeMunger myMunger = new NewMethodTypeMunger(sig, null);
                setMunger(myMunger);
index 868499adc6439248eb00deb52c2e99a80d93bb7a..daacbc4e58dc08fda65811447a2cb457a9d138dd 100644 (file)
@@ -43,6 +43,7 @@ public class AjLookupEnvironment extends LookupEnvironment {
        
 //     private boolean builtInterTypesAndPerClauses = false;
        private List pendingTypesToWeave = new ArrayList();
+       private Map dangerousInterfaces = new HashMap();
        
        public AjLookupEnvironment(
                ITypeRequestor typeRequestor,
@@ -151,16 +152,49 @@ public class AjLookupEnvironment extends LookupEnvironment {
                }
        }
        
-       
-       
        private void weaveInterTypeDeclarations(SourceTypeBinding sourceType, Collection typeMungers, Collection declareParents, boolean skipInners) {
-//             if (new String(sourceType.sourceName()).equals("Target")) {
-//                     Thread.currentThread().dumpStack();
-//             }
-//             
-//             System.out.println("weaving types: " + new String(sourceType.sourceName()));
-//             System.out.println("  mungers: " + typeMungers);
                ResolvedTypeX onType = factory.fromEclipse(sourceType);
+               WeaverStateInfo info = onType.getWeaverState();
+
+               if (info != null && !info.isOldStyle()) {               
+                       Collection mungers = 
+                               onType.getWeaverState().getTypeMungers(onType);
+                               
+                       //System.out.println("mungers: " + mungers);
+                       for (Iterator i = mungers.iterator(); i.hasNext(); ) {
+                               ConcreteTypeMunger m = (ConcreteTypeMunger)i.next();
+                               EclipseTypeMunger munger = factory.makeEclipseTypeMunger(m);
+                               if (munger.munge(sourceType)) {
+                                       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());
+                                               }
+                                       }
+                               }
+                               
+                       }
+                       
+                       return;
+               }
+               
+               //System.out.println("dangerousInterfaces: " + dangerousInterfaces);
+               
+               for (Iterator i = dangerousInterfaces.entrySet().iterator(); i.hasNext();) {
+                       Map.Entry entry = (Map.Entry) i.next();
+                       ResolvedTypeX interfaceType = (ResolvedTypeX)entry.getKey();
+                       if (onType.isTopmostImplementor(interfaceType)) {
+                               factory.showMessage(IMessage.ERROR, 
+                                       onType + ": " + entry.getValue(),
+                                       onType.getSourceLocation(), null);
+                       }
+               }
+               
+               boolean needOldStyleWarning = (info != null && info.isOldStyle());
+               
                onType.clearInterTypeMungers();
                
                for (Iterator i = declareParents.iterator(); i.hasNext();) {
@@ -170,6 +204,12 @@ public class AjLookupEnvironment extends LookupEnvironment {
                for (Iterator i = typeMungers.iterator(); i.hasNext();) {
                        EclipseTypeMunger munger = (EclipseTypeMunger) i.next();
                        if (munger.matches(onType)) {
+                               if (needOldStyleWarning) {
+                                       factory.showMessage(IMessage.WARNING, 
+                                               "The class for " + onType + " should be recompiled with ajc-1.1.1 for best results",
+                                               onType.getSourceLocation(), null);
+                                       needOldStyleWarning = false;
+                               }
                                onType.addInterTypeMunger(munger);
                        }
                }
index 76de3640912c3ebe714654462b250147237b291d..e9f9f04029ce47027f91d3a7483b29cca5e24cee 100644 (file)
@@ -192,8 +192,8 @@ public class EclipseFactory {
                        binding.modifiers,
                        fromBinding(binding.returnType),
                        new String(binding.selector),
-                       fromBindings(binding.parameters));
-               ret.setCheckedExceptions(fromBindings(binding.thrownExceptions));
+                       fromBindings(binding.parameters),
+                       fromBindings(binding.thrownExceptions));
                return ret;
        }
 
index e965ea031f031efda50bdc5b268324facfd0478f..60f317f1f3f0ff56cd587416ecbca58a8686a6cd 100644 (file)
@@ -66,8 +66,8 @@ public class EclipseSourceType extends ResolvedTypeX.ConcreteName {
                return declaration instanceof AspectDeclaration;
        }
 
-       public boolean isWovenBy(ResolvedTypeX aspectType) {
-               return false;
+       public WeaverStateInfo getWeaverState() {
+               return null;
        }
        
        public ResolvedTypeX getSuperclass() {
index c98a12a11752da821c9d40e5f885e51107721a51..0382c9a1fe773d77e04d6cea3ce8b1a18ecc433a 100644 (file)
@@ -101,7 +101,7 @@ public class BinaryFormsTestCase extends CommandTestCase {
                
                args.add("testdata/src1/binary/client/Client1.java");
                
-               CommandTestCase.runCompiler(args, new int[] {9, 11, 15, 17});
+               CommandTestCase.runCompiler(args, new int[] {15, 17, 22});
                
                args = new ArrayList();
                args.add("-classpath");
index 2ae8559aea615d20a4ac42fda253c7514352a082..1a73d999071ee8f3cd7c8e9bcbf4c1d754e707d0 100644 (file)
                <compile 
                        files="Client.java" 
                        classpath="aspectedInterfaceOnly.jar">
+                       <message kind="error" line="0" text="LibraryAspect"/>
                        <message kind="error" line="9" text="LibraryInterface"/>
                        </compile>
                </ajc-test>
                        </compile>
                </ajc-test>
                
+       <ajc-test dir="bugs"
+               pr="41175"
+               title="reflective check of declared exceptions from aspect-declared methods">
+               <compile files="DeclaredExceptions.java"/>
+               <run class="DeclaredExceptions"/>
+               </ajc-test>
+
+       <ajc-test dir="bugs/interfaceLibrary"
+               pr="41175"
+               title="exception clause for aspect-declared interface methods - positive binary">
+               <compile files="Client.java" aspectpath="lib.jar"/>
+               <run class="Client"/>
+               </ajc-test>
+
+       <ajc-test dir="bugs/interfaceLibrary"
+               pr="41175"
+               title="exception clause for aspect-declared interface methods - negative binary">
+               <compile files="ClientCE.java" aspectpath="lib.jar">
+                       <message kind="error" file="ClientCE.java" line="5"/>
+                       </compile>
+               </ajc-test>
+
+       <ajc-test dir="bugs/interfaceLibrary"
+               pr="41175"
+               title="exception clause for aspect-declared class methods - positive binary">
+               <compile files="ClassClient.java" aspectpath="libClass.jar"/>
+               <run class="ClassClient"/>
+               </ajc-test>
+
+       <ajc-test dir="bugs/interfaceLibrary"
+               pr="41175"
+               title="exception clause for aspect-declared class methods - negative binary">
+               <compile files="ClassClientCE.java" aspectpath="libClass.jar">
+                       <message kind="error" file="ClassClientCE.java" line="5"/>
+                       </compile>
+               </ajc-test>
+               
 </suite>
index 8b5d79788f1f542d74ef5aa4ab017d922308eed4..5439341a11113c438c6251fe18d7ff6d03fe5946 100644 (file)
                <run class="Client"/>
                </ajc-test>
 
-       <ajc-test dir="bugs/interfaceLibrary"
-               pr="41175"
-               title="exception clause for aspect-declared interface methods - positive binary">
-               <compile files="Client.java" aspectpath="lib.jar"/>
-               <run class="Client"/>
-               </ajc-test>
-
-       <ajc-test dir="bugs/interfaceLibrary"
-               pr="41175"
-               title="exception clause for aspect-declared interface methods - negative binary">
-               <compile files="ClientCE.java" aspectpath="lib.jar">
-                       <message kind="error" file="ClientCE.java" line="5"/>
-                       </compile>
-               </ajc-test>
-
-       <ajc-test dir="bugs/interfaceLibrary"
-               pr="41175"
-               title="exception clause for aspect-declared class methods - positive binary">
-               <compile files="ClassClient.java" aspectpath="libClass.jar"/>
-               <run class="Client"/>
-               </ajc-test>
-
-       <ajc-test dir="bugs/interfaceLibrary"
-               pr="41175"
-               title="exception clause for aspect-declared class methods - negative binary">
-               <compile files="ClassClientCE.java" aspectpath="libClass.jar">
-                       <message kind="error" file="ClassClientCE.java" line="5"/>
-                       </compile>
-               </ajc-test>
-
        <ajc-test dir="new/pointcutLibrary" title="libraries-pointcuts compiles"
                comment="interim test just to show library compiles...">
                <compile files="langlib/Pointcuts.java"/>
diff --git a/tests/bugs/DeclaredExceptions.java b/tests/bugs/DeclaredExceptions.java
new file mode 100644 (file)
index 0000000..9baec0c
--- /dev/null
@@ -0,0 +1,28 @@
+import java.lang.reflect.Method;
+import java.io.*;
+import org.aspectj.testing.Tester;
+
+public class DeclaredExceptions {
+       public static void main(String[] args) throws Exception {
+               Class c = C.class;
+               Method m = c.getDeclaredMethod("m", new Class[0]);
+               Tester.checkEqual(m.getExceptionTypes().length, 1);
+               Tester.checkEqual(m.getExceptionTypes()[0], IOException.class);
+               
+               c = I.class;
+               m = c.getDeclaredMethod("m", new Class[0]);
+               Tester.checkEqual(m.getExceptionTypes().length, 1);
+               Tester.checkEqual(m.getExceptionTypes()[0], IOException.class);
+       }
+}
+
+interface I {}
+
+class C {}
+
+aspect A {
+       public void C.m() throws IOException {
+       }
+       
+       public void I.m() throws IOException { }
+}
\ No newline at end of file
index 496514a291b9c6aa9c7fe28a3320c51b23697983..57acb6aadf3ea00c553f2ea596ae230ecf2bcfd5 100644 (file)
Binary files a/tests/bugs/interfaceLibrary/lib.jar and b/tests/bugs/interfaceLibrary/lib.jar differ
index 720435d6292bdf0467afd689b1091f995f59835f..ee68ce1c092822224466b66dd7352782e1b97de7 100644 (file)
Binary files a/tests/bugs/interfaceLibrary/libClass.jar and b/tests/bugs/interfaceLibrary/libClass.jar differ
index 4aaffb64563fc62d26bef09ab3f7e98f59976eb9..eb6505b8c37f6e66b605e02430b2158d862e5122 100644 (file)
Binary files a/tests/new/interfaceLibrary/aspectOnly.jar and b/tests/new/interfaceLibrary/aspectOnly.jar differ
index 9cb969b9d12def7ce24052733e4e9edbf36242ae..1b83933208d0544d35dfa5f03473d952bd423514 100644 (file)
Binary files a/tests/new/interfaceLibrary/aspectedInterfaceOnly.jar and b/tests/new/interfaceLibrary/aspectedInterfaceOnly.jar differ
index 9cb969b9d12def7ce24052733e4e9edbf36242ae..fe334d0764b5e00e6d3c20647ac48124e70ac8a9 100644 (file)
Binary files a/tests/new/interfaceLibrary/aspectedInterfaceOnlyBinary.jar and b/tests/new/interfaceLibrary/aspectedInterfaceOnlyBinary.jar differ
index ede6fc868f7ffd886fbaa2fdaa68ea49069690ba..15c0fa5599bd96757ea41f57b449a1496d7d008b 100644 (file)
Binary files a/tests/new/interfaceLibrary/interfaceOnly.jar and b/tests/new/interfaceLibrary/interfaceOnly.jar differ
index f981d21b261c5b8ccc54ab2a4a12cde7f4467203..217f042806a03381a432db4f2dabba7b45667f2f 100644 (file)
@@ -88,7 +88,7 @@ public abstract class AjAttribute {
                        if (name.equals(Aspect.AttributeName)) {
                                return new Aspect(PerClause.readPerClause(s, context));
                        } else if (name.equals(WeaverState.AttributeName)) {
-                               return new WeaverState(WeaverStateKind.read(s));
+                               return new WeaverState(WeaverStateInfo.read(s, context));
                        } else if (name.equals(AdviceAttribute.AttributeName)) {
                                return AdviceAttribute.read(s, context);
                        } else if (name.equals(PointcutDeclarationAttribute.AttributeName)) {
@@ -162,15 +162,15 @@ public abstract class AjAttribute {
                public String getNameString() {
                        return AttributeName;
                }
-               private WeaverStateKind kind;
-               public WeaverState(WeaverStateKind kind) {
+               private WeaverStateInfo kind;
+               public WeaverState(WeaverStateInfo kind) {
                        this.kind = kind;
                }
                public void write(DataOutputStream s) throws IOException {
                        kind.write(s);
                }
                
-               public WeaverStateKind reify() {
+               public WeaverStateInfo reify() {
                        return kind;
                }
        }
index ae29a0d4ccb2ec8f3c4c00b704ae0b1a783800f1..308b020b9612ba0fd5b5045292d66b653ba9de91 100644 (file)
@@ -232,8 +232,8 @@ public class AjcMemberMaker {
                        Modifier.PUBLIC,
                        method.getReturnType(),
                        NameMangler.superDispatchMethod(baseType, method.getName()),
-                       method.getParameterTypes());
-                       //XXX needs thrown exceptions to be correct
+                       method.getParameterTypes(),
+                       method.getExceptions());
        }
        
        public static ResolvedMember inlineAccessMethodForMethod(TypeX aspectType, ResolvedMember method) {
@@ -249,8 +249,7 @@ public class AjcMemberMaker {
                        
                        NameMangler.inlineAccessMethodForMethod(method.getName(),
                                                                                                method.getDeclaringType(), aspectType),
-                       paramTypes);
-                       //XXX needs thrown exceptions to be correct
+                       paramTypes, method.getExceptions());
        }
        
        public static ResolvedMember inlineAccessMethodForFieldGet(TypeX aspectType, Member field) {
@@ -382,7 +381,8 @@ public class AjcMemberMaker {
                                Modifier.PUBLIC,
                                ResolvedTypeX.VOID,
                                "<init>",
-                               constructor.getParameterTypes());
+                               constructor.getParameterTypes(),
+                               constructor.getExceptions());
                //System.out.println("ret: " + ret + " mods: " + Modifier.toString(modifiers));
                if (Modifier.isPublic(constructor.getModifiers()))
                        return ret;
@@ -429,7 +429,8 @@ public class AjcMemberMaker {
                return new ResolvedMember(Member.METHOD, aspectType, PUBLIC_STATIC,
                        field.getReturnType(),
                        NameMangler.interFieldGetDispatcher(aspectType, field.getDeclaringType(), field.getName()),
-                       field.isStatic() ? TypeX.NONE : new TypeX[] {field.getDeclaringType()}
+                       field.isStatic() ? TypeX.NONE : new TypeX[] {field.getDeclaringType()},
+                       TypeX.NONE
                        );
        }
        
@@ -451,7 +452,7 @@ public class AjcMemberMaker {
                        makePublicNonFinal(field.getModifiers()),
                        field.getReturnType(), 
                        NameMangler.interFieldClassField(field.getModifiers(), aspectType, field.getDeclaringType(), field.getName()),
-                       TypeX.NONE
+                       TypeX.NONE, TypeX.NONE
                        );
        }
        
@@ -464,7 +465,7 @@ public class AjcMemberMaker {
                return new ResolvedMember(Member.FIELD, onClass, makePublicNonFinal(field.getModifiers()),
                        field.getReturnType(), 
                        NameMangler.interFieldInterfaceField(aspectType, field.getDeclaringType(), field.getName()),
-                       TypeX.NONE
+                       TypeX.NONE, TypeX.NONE
                        );
        }
        
@@ -478,7 +479,7 @@ public class AjcMemberMaker {
                return new ResolvedMember(Member.METHOD, onType, modifiers,
                        ResolvedTypeX.VOID,
                        NameMangler.interFieldInterfaceSetter(aspectType, field.getDeclaringType(), field.getName()),
-                       new TypeX[] {field.getReturnType()}
+                       new TypeX[] {field.getReturnType()}, TypeX.NONE
                        );
        }
        
@@ -492,7 +493,7 @@ public class AjcMemberMaker {
                return new ResolvedMember(Member.METHOD, onType, modifiers,
                        field.getReturnType(), 
                        NameMangler.interFieldInterfaceGetter(aspectType, field.getDeclaringType(), field.getName()),
-                       TypeX.NONE
+                       TypeX.NONE, TypeX.NONE
                        );
        }
        
@@ -514,7 +515,7 @@ public class AjcMemberMaker {
                        modifiers,
                        meth.getReturnType(), 
                        NameMangler.interMethod(meth.getModifiers(), aspectType, meth.getDeclaringType(), meth.getName()),
-                       meth.getParameterTypes());      
+                       meth.getParameterTypes(), meth.getExceptions());        
        }
 
        /**
@@ -530,7 +531,7 @@ public class AjcMemberMaker {
                return new ResolvedMember(Member.METHOD, aspectType, PUBLIC_STATIC,
                        meth.getReturnType(), 
                        NameMangler.interMethodDispatcher(aspectType, meth.getDeclaringType(), meth.getName()),
-                       paramTypes);
+                       paramTypes, meth.getExceptions());
        }
 
        /**
@@ -552,7 +553,7 @@ public class AjcMemberMaker {
                return new ResolvedMember(Member.METHOD, aspectType, modifiers,
                        meth.getReturnType(), 
                        NameMangler.interMethodBody(aspectType, meth.getDeclaringType(), meth.getName()),
-                       paramTypes);
+                       paramTypes, meth.getExceptions());
        }
        
        
@@ -568,7 +569,7 @@ public class AjcMemberMaker {
                        ret.getModifiers(),
                        ret.getReturnType(),
                        ret.getName(),
-                       freshParams);
+                       freshParams, ret.getExceptions());
        }
 
        public static ResolvedMember toObjectConversionMethod(TypeX fromType) {
@@ -580,7 +581,7 @@ public class AjcMemberMaker {
                                PUBLIC_STATIC,
                                TypeX.OBJECT,
                                name,
-                               new TypeX[] { fromType });
+                               new TypeX[] { fromType }, TypeX.NONE);
                } else {
                        return null;
                }
index 5b2e8413153f4532b6730327f84770941fff1e5d..ec81a0cf2979851ac3c4c0f06975be6eb29b4041 100644 (file)
@@ -66,6 +66,10 @@ public class CrosscuttingMembersSet {
                return isAspect;
        }
        
+       public boolean containsAspect(TypeX aspectType) {
+               return members.containsKey(aspectType);
+       }
+       
        //XXX only for testing
        public void addFixedCrosscuttingMembers(ResolvedTypeX aspectType) {
                members.put(aspectType, aspectType.crosscuttingMembers);
index 60164e167be27ae490f7d2fce5f643816f1fc2e0..d1a4e9633a7c527601c47eced020dd2cf57bec3c 100644 (file)
@@ -34,7 +34,19 @@ public class ResolvedMember extends Member implements IHasPosition {
        protected int start, end;
        protected ISourceContext sourceContext = null;
     
-    // ----
+    //XXX deprecate this in favor of the constructor below
+       public ResolvedMember(
+               Kind kind,
+               TypeX declaringType,
+               int modifiers,
+               TypeX returnType,
+               String name,
+               TypeX[] parameterTypes)
+       {
+               super(kind, declaringType, modifiers, returnType, name, parameterTypes);
+       }
+
+    
     
        public ResolvedMember(
                Kind kind,
@@ -42,9 +54,11 @@ public class ResolvedMember extends Member implements IHasPosition {
                int modifiers,
                TypeX returnType,
                String name,
-               TypeX[] parameterTypes) 
+               TypeX[] parameterTypes,
+               TypeX[] checkedExceptions) 
        {
                super(kind, declaringType, modifiers, returnType, name, parameterTypes);
+               this.checkedExceptions = checkedExceptions;
        }
     
        public ResolvedMember(
index 086ade7b2b30f94e60f29a910bf3b0cd29c97e9b..a732cf82ca9da80344d778e0100074dd4c7f63a2 100644 (file)
@@ -54,7 +54,7 @@ public abstract class ResolvedTypeMunger {
        //System.err.println("matching: " + this + " to " + matchType + " onType = " + onType);
                if (matchType.equals(onType)) { 
                        if (!onType.isExposedToWeaver()) {
-                               if (!onType.isWovenBy(aspectType)) {
+                               if (onType.getWeaverState() != null) {
                                        if (matchType.getWorld().getLint().typeNotExposedToWeaver.isEnabled()) {
                                                matchType.getWorld().getLint().typeNotExposedToWeaver.signal(
                                                        matchType.getName(), signature.getSourceLocation());
@@ -183,4 +183,18 @@ public abstract class ResolvedTypeMunger {
                return null;
        }
 
+       public boolean changesPublicSignature() {
+               return kind == Field || kind == Method || kind == Constructor;
+       }
+       
+       public boolean needsAccessToTopmostImplementor() {
+               if (kind == Field) {
+                       return true;
+               } else if (kind == Method) {
+                       return !signature.isAbstract();
+               } else {
+                       return false;
+               }
+       }
+
 }
index a9b6fa6546a1da48cf7f99037307bd70909dbabd..1861254a583382b9178b5fa5580aacee03567327 100644 (file)
@@ -575,8 +575,8 @@ public abstract class ResolvedTypeX extends TypeX {
                        return delegate.isExposedToWeaver();  //??? where does this belong
                }
                
-               public boolean isWovenBy(ResolvedTypeX aspectType) {
-                       return delegate.isWovenBy(aspectType);
+               public WeaverStateInfo getWeaverState() {
+                       return delegate.getWeaverState();
                }
 
                public ResolvedMember[] getDeclaredFields() {
@@ -684,7 +684,7 @@ public abstract class ResolvedTypeX extends TypeX {
 
 //             public abstract ISourceLocation getSourceLocation();
 
-               public abstract boolean isWovenBy(ResolvedTypeX aspectType);
+               public abstract WeaverStateInfo getWeaverState();
 
 //             public ISourceContext getSourceContext() {
 //                     return sourceContext;
@@ -1270,8 +1270,7 @@ public abstract class ResolvedTypeX extends TypeX {
        
        public ISourceLocation getSourceLocation() { return null; }
        public boolean isExposedToWeaver() { return false; }
-       public boolean isWovenBy(ResolvedTypeX aspectType) {
-               return false;
+       public WeaverStateInfo getWeaverState() {
+               return null;
        }
-
 }
diff --git a/weaver/src/org/aspectj/weaver/WeaverStateInfo.java b/weaver/src/org/aspectj/weaver/WeaverStateInfo.java
new file mode 100644 (file)
index 0000000..20b5347
--- /dev/null
@@ -0,0 +1,121 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     PARC     initial implementation 
+ * ******************************************************************/
+
+
+package org.aspectj.weaver;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.aspectj.bridge.IMessage;
+import org.aspectj.util.TypeSafeEnum;
+import org.aspectj.weaver.bcel.BcelTypeMunger;
+
+public class WeaverStateInfo {
+       private List/*Entry*/ typeMungers;
+       private boolean oldStyle;
+       
+       public WeaverStateInfo() {
+               this(new ArrayList(), false);
+       }
+       
+       private WeaverStateInfo(List typeMungers, boolean oldStyle) {
+               this.typeMungers = typeMungers;
+               this.oldStyle = oldStyle;
+       }
+       
+       private static final int UNTOUCHED=0, WOVEN=2, EXTENDED=3;
+       
+       public static final WeaverStateInfo read(DataInputStream s, ISourceContext context) throws IOException {
+               byte b = s.readByte();
+               
+               switch(b) {
+                       case UNTOUCHED:
+                               throw new RuntimeException("unexpected UNWOVEN");
+                       case WOVEN: 
+                               return new WeaverStateInfo(Collections.EMPTY_LIST, true);
+                       case EXTENDED:
+                               int n = s.readShort();
+                               List l = new ArrayList();
+                               for (int i=0; i < n; i++) {
+                                       TypeX aspectType = TypeX.read(s);
+                                       ResolvedTypeMunger typeMunger = 
+                                               ResolvedTypeMunger.read(s, context);
+                                       l.add(new Entry(aspectType, typeMunger));
+                               }
+                               return new WeaverStateInfo(l, false);
+               } 
+               throw new RuntimeException("bad WeaverState.Kind: " + b);
+       }
+       
+       private static class Entry {
+               public TypeX aspectType;
+               public ResolvedTypeMunger typeMunger;
+               public Entry(TypeX aspectType, ResolvedTypeMunger typeMunger) {
+                       this.aspectType = aspectType;
+                       this.typeMunger = typeMunger;
+               }
+               
+               public String toString() {
+                       return "<" + aspectType + ", " + typeMunger + ">";
+               }
+       } 
+
+       public void write(DataOutputStream s) throws IOException {
+               if (oldStyle) throw new RuntimeException("shouldn't be writing this");
+               
+               s.writeByte(EXTENDED);
+               int n = typeMungers.size();
+               s.writeShort(n);
+               for (int i=0; i < n; i++) {
+                       Entry e = (Entry)typeMungers.get(i);
+                       e.aspectType.write(s);
+                       e.typeMunger.write(s);
+               }
+       }
+
+       public void addConcreteMunger(ConcreteTypeMunger munger) {
+               typeMungers.add(new Entry(munger.getAspectType(), munger.getMunger()));
+       }
+       
+       public String toString() {
+               return "WeaverStateInfo(" + typeMungers + ", " + oldStyle + ")";
+       }
+       
+
+       public List getTypeMungers(ResolvedTypeX onType) {
+               World world = onType.getWorld();
+               List ret = new ArrayList();
+               for (Iterator i = typeMungers.iterator(); i.hasNext();) {
+                       Entry entry = (Entry) i.next();
+                       ResolvedTypeX aspectType = world.resolve(entry.aspectType, true);
+                       if (aspectType == ResolvedTypeX.MISSING) {
+                               world.showMessage(IMessage.ERROR, "aspect " + entry.aspectType + 
+                                       " is needed when using type " + onType,
+                                       onType.getSourceLocation(), null);
+                               continue;
+                       }
+                       
+                       ret.add(new BcelTypeMunger(entry.typeMunger, aspectType));
+               }
+               return ret;
+       }
+
+       public boolean isOldStyle() {
+               return oldStyle;
+       }
+}
diff --git a/weaver/src/org/aspectj/weaver/WeaverStateKind.java b/weaver/src/org/aspectj/weaver/WeaverStateKind.java
deleted file mode 100644 (file)
index 1960c8d..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Common Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/cpl-v10.html 
- *  
- * Contributors: 
- *     PARC     initial implementation 
- * ******************************************************************/
-
-
-package org.aspectj.weaver;
-
-import java.io.DataInputStream;
-import java.io.IOException;
-
-import org.aspectj.util.TypeSafeEnum;
-
-public class WeaverStateKind extends TypeSafeEnum {
-       private WeaverStateKind(String name, int key) {
-               super(name, key);
-       }
-       
-       public static final WeaverStateKind read(DataInputStream s) throws IOException {
-               byte b = s.readByte();
-               switch(b) {
-                       case 0: return Untouched;
-                       case 2: return Woven;
-               }
-               throw new RuntimeException("bad WeaverState.Kind: " + b);
-       }
-
-       
-       public static final WeaverStateKind Untouched = new WeaverStateKind("Untouched", 0);
-       public static final WeaverStateKind Woven = new WeaverStateKind("Woven", 2);
-       
-       
-       public byte[] getBytes() {
-               return new byte[] { getKey(), };
-       }
-
-       public boolean isWoven() {
-               return this == Woven;
-       }
-
-}
index ebfb681701230d1fa2fb7e195dec7c4cc82601b2..792201dd03c355997e798e5a433ce9934549c0b5 100644 (file)
@@ -374,5 +374,4 @@ public abstract class World {
         
                return ret;
        }
-
 }
index 8666df8f5d781c96f7fbb746e97b7f792a40e661..88b1e9b7cbc7c97d336a52b583ce2d14f2424cf5 100644 (file)
@@ -107,8 +107,7 @@ public class BcelAdvice extends Advice {
 
                if (concreteAspect.getWorld().isXnoInline()) return false;
        //System.err.println("isWoven? " + ((BcelObjectType)concreteAspect).getLazyClassGen().getWeaverState());
-       return BcelWorld.getBcelObjectType(concreteAspect).getLazyClassGen().getWeaverState() 
-                       == WeaverStateKind.Woven;
+       return BcelWorld.getBcelObjectType(concreteAspect).getLazyClassGen().isWoven();
     }
 
     public void implementOn(Shadow s) {
index 5595b45db06c5c59f982d6728a4f9673302e4b3c..866502e99c2d96d882fe200149525a9667cd032d 100644 (file)
@@ -61,7 +61,7 @@ import org.aspectj.weaver.ResolvedMember;
 import org.aspectj.weaver.ResolvedTypeX;
 import org.aspectj.weaver.Shadow;
 import org.aspectj.weaver.ShadowMunger;
-import org.aspectj.weaver.WeaverStateKind;
+import org.aspectj.weaver.WeaverStateInfo;
 
 class BcelClassWeaver implements IClassWeaver {
     
@@ -75,7 +75,7 @@ class BcelClassWeaver implements IClassWeaver {
                List typeMungers) 
        {
                boolean b =  new BcelClassWeaver(world, clazz, shadowMungers, typeMungers).weave();
-               //System.err.println(clazz.getClassName() + ", " + clazz.getWeaverState());
+               //System.out.println(clazz.getClassName() + ", " + clazz.getType().getWeaverState());
                //clazz.print();
                return b;
        }
@@ -241,7 +241,7 @@ class BcelClassWeaver implements IClassWeaver {
     // ----
     
     public boolean weave() {
-        if (clazz.getWeaverState().isWoven()) {
+        if (clazz.isWoven()) {
                world.showMessage(IMessage.ERROR, 
                                "class \'" + clazz.getType().getName() + "\' is already woven",
                                ty.getSourceLocation(), null);
@@ -309,7 +309,7 @@ class BcelClassWeaver implements IClassWeaver {
                
                // finally, if we changed, we add in the introduced methods.
         if (isChanged) {
-               clazz.setWeaverState(WeaverStateKind.Woven);
+               clazz.getOrCreateWeaverStateInfo();
                        weaveInAddedMethods();
         }
         
index 864f127d6ccdc0d90068c493d21154339f1adde9..81d8f1b8ce161904b8a6cd3a781c47228c87a340 100644 (file)
@@ -32,7 +32,7 @@ import org.aspectj.weaver.ResolvedMember;
 import org.aspectj.weaver.ResolvedPointcutDefinition;
 import org.aspectj.weaver.ResolvedTypeX;
 import org.aspectj.weaver.TypeX;
-import org.aspectj.weaver.WeaverStateKind;
+import org.aspectj.weaver.WeaverStateInfo;
 import org.aspectj.weaver.World;
 import org.aspectj.weaver.patterns.PerClause;
 
@@ -51,7 +51,7 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName {
     // strangely non-lazy
     private ResolvedPointcutDefinition[] pointcuts = null;
        private PerClause perClause = null;
-       private WeaverStateKind weaverState = null;
+       private WeaverStateInfo weaverState = null;
        private List typeMungers = Collections.EMPTY_LIST;
        private List declares = Collections.EMPTY_LIST;
        private ResolvedMember[] privilegedAccess = null;
@@ -212,18 +212,11 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName {
         unpackAspectAttributes();
     }
 
-       //XXX we've lost information so that we don't know who wove into this
-       //    class, only that someone did.  For better error messages we should
-       //    probably expand the information in weaverState
-       public boolean isWovenBy(ResolvedTypeX aspectType) {
-               return weaverState == WeaverStateKind.Woven;
-       }
-
-       public WeaverStateKind getWeaverState() {
+       public WeaverStateInfo getWeaverState() {
                return weaverState;
        }
 
-       public void setWeaverState(WeaverStateKind weaverState) {
+       void setWeaverState(WeaverStateInfo weaverState) {
                this.weaverState = weaverState;
        }
        
index d75d94efe33793b71166acc7c17ea83260489a34..5b9de1855379fd89f8139b222a06c928a0b2d8ac 100644 (file)
@@ -36,6 +36,7 @@ import org.aspectj.weaver.ResolvedMember;
 import org.aspectj.weaver.ResolvedTypeMunger;
 import org.aspectj.weaver.ResolvedTypeX;
 import org.aspectj.weaver.TypeX;
+import org.aspectj.weaver.WeaverStateInfo;
 import org.aspectj.weaver.patterns.Pointcut;
 
 
@@ -51,21 +52,31 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
        }
 
        public boolean munge(BcelClassWeaver weaver) {
+               boolean changed = false;
+               
                if (munger.getKind() == ResolvedTypeMunger.Field) {
-                       return mungeNewField(weaver, (NewFieldTypeMunger)munger);
+                       changed = mungeNewField(weaver, (NewFieldTypeMunger)munger);
                } else if (munger.getKind() == ResolvedTypeMunger.Method) {
-                       return mungeNewMethod(weaver, (NewMethodTypeMunger)munger);
+                       changed = mungeNewMethod(weaver, (NewMethodTypeMunger)munger);
                } else if (munger.getKind() == ResolvedTypeMunger.PerObjectInterface) {
-                       return mungePerObjectInterface(weaver, (PerObjectInterfaceTypeMunger)munger);
+                       changed = mungePerObjectInterface(weaver, (PerObjectInterfaceTypeMunger)munger);
                } else if (munger.getKind() == ResolvedTypeMunger.PrivilegedAccess) {
-                       return mungePrivilegedAccess(weaver, (PrivilegedAccessMunger)munger);
+                       changed = mungePrivilegedAccess(weaver, (PrivilegedAccessMunger)munger);
                } else if (munger.getKind() == ResolvedTypeMunger.Constructor) {
-                       return mungeNewConstructor(weaver, (NewConstructorTypeMunger)munger);
+                       changed = mungeNewConstructor(weaver, (NewConstructorTypeMunger)munger);
                } else if (munger.getKind() == ResolvedTypeMunger.Parent) {
-                       return mungeNewParent(weaver, (NewParentTypeMunger)munger);
+                       changed = mungeNewParent(weaver, (NewParentTypeMunger)munger);
                } else {
                        throw new RuntimeException("unimplemented");
                }
+               
+               if (changed && munger.changesPublicSignature()) {
+                       WeaverStateInfo info = 
+                               weaver.getLazyClassGen().getOrCreateWeaverStateInfo();
+                       info.addConcreteMunger(this);
+               }
+               
+               return changed;
        }
 
 
index a5b5c06fb10a1d45b99adcb301afeaf0d6a12d53..0c30e841102fdf04bbf7d3b6215d6fa8f6810a44 100644 (file)
@@ -19,6 +19,7 @@ import java.io.IOException;
 import java.io.PrintStream;
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
@@ -49,7 +50,7 @@ import org.aspectj.weaver.BCException;
 import org.aspectj.weaver.Member;
 import org.aspectj.weaver.NameMangler;
 import org.aspectj.weaver.TypeX;
-import org.aspectj.weaver.WeaverStateKind;
+import org.aspectj.weaver.WeaverStateInfo;
 
 public final class LazyClassGen {
 
@@ -152,8 +153,13 @@ public final class LazyClassGen {
     }
 
     private void writeBack() {
-       addAjcInitializers();
+       if (myType != null && myType.getWeaverState() != null) {
+                       myGen.addAttribute(BcelAttributes.bcelAttribute(
+                               new AjAttribute.WeaverState(myType.getWeaverState()), 
+                               getConstantPoolGen()));
+       }
        
+       addAjcInitializers();
        
         int len = methodGens.size();
         myGen.setMethods(new Method[0]);
@@ -305,29 +311,17 @@ public final class LazyClassGen {
         return myGen.getClassName();
     }
 
-       public WeaverStateKind getWeaverState() {
-               WeaverStateKind kind = myType.getWeaverState();
-               if (kind == null) return WeaverStateKind.Untouched;
-               return kind;
+       public boolean isWoven() {
+               return myType.getWeaverState() != null;
        }
-
-       public void setWeaverState(WeaverStateKind s) {
-               Attribute[] attributes = myGen.getAttributes();
-               if (attributes != null) {
-                       for (int i = attributes.length - 1; i >=0; i--) {
-                               Attribute a = attributes[i];
-                               if (a instanceof Unknown) {
-                                       Unknown u = (Unknown) a;
-                                       if (u.getName().equals(AjAttribute.WeaverState.AttributeName)) {
-                                               myGen.removeAttribute(u);
-                                       }
-                               }
-                       }
-               }
-               myGen.addAttribute(BcelAttributes.bcelAttribute(
-                       new AjAttribute.WeaverState(s), 
-                       getConstantPoolGen()));
-               myType.setWeaverState(s);
+       
+       public WeaverStateInfo getOrCreateWeaverStateInfo() {
+               WeaverStateInfo ret = myType.getWeaverState();
+               if (ret != null) return ret;
+               
+               ret = new WeaverStateInfo();
+               myType.setWeaverState(ret);
+               return ret;
        }
 
     public InstructionFactory getFactory() {
@@ -531,4 +525,5 @@ public final class LazyClassGen {
        public void forcePublic() {
                myGen.setAccessFlags(Utility.makePublic(myGen.getAccessFlags()));
        }
+
 }