]> source.dussan.org Git - aspectj.git/commitdiff
further work on binary aspects (aspect path) tested correct behavior
authorjhugunin <jhugunin>
Mon, 10 Mar 2003 23:18:56 +0000 (23:18 +0000)
committerjhugunin <jhugunin>
Mon, 10 Mar 2003 23:18:56 +0000 (23:18 +0000)
for obvious forms of concrete aspects, next need to address abstract

18 files changed:
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompiler.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeDeclaration.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeFieldDeclaration.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.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/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseTypeMunger.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeFieldBinding.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeMemberFinder.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/problem/AjProblemReporter.java
org.aspectj.ajdt.core/testdata/src1/binary/client/Client.java [new file with mode: 0644]
org.aspectj.ajdt.core/testdata/src1/binary/lib/ConcreteA.aj [new file with mode: 0644]
org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BinaryFormsTestCase.java
tests/scripts/incr.py
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java

index c96192ff21879c913b03fc70b7651d2f6d1ef2d3..e74731c506450972c78ab4d0d476d85ff9bd93cd 100644 (file)
@@ -60,7 +60,7 @@ public class AjCompiler extends Compiler {
         */
        protected void process(CompilationUnitDeclaration unit, int i) {
                EclipseFactory world = 
-                       EclipseFactory.forLookupEnvironment(lookupEnvironment);
+                       EclipseFactory.fromLookupEnvironment(lookupEnvironment);
                world.showMessage(IMessage.INFO, "compiling " + new String(unit.getFileName()), null, null);
                super.process(unit, i);
                                
index c484d59a7c8e3f113b270c69b5307126181fb92b..142efe27fc1053e03b4bacf4afdf02037f8d7c30 100644 (file)
 
 package org.aspectj.ajdt.internal.compiler.ast;
 
-import org.aspectj.ajdt.internal.compiler.lookup.EclipseTypeMunger;
-import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
-import org.aspectj.ajdt.internal.compiler.lookup.InterTypeScope;
-import org.aspectj.weaver.AjAttribute;
-import org.aspectj.weaver.AjcMemberMaker;
-import org.aspectj.weaver.CrosscuttingMembers;
-import org.aspectj.weaver.Member;
-import org.aspectj.weaver.NameMangler;
-import org.aspectj.weaver.NewConstructorTypeMunger;
-import org.aspectj.weaver.ResolvedMember;
-import org.aspectj.weaver.ResolvedTypeX;
-import org.aspectj.weaver.Shadow;
-import org.aspectj.weaver.TypeX;
+import org.aspectj.ajdt.internal.compiler.lookup.*;
+import org.aspectj.weaver.*;
 import org.eclipse.jdt.internal.compiler.ClassFile;
 import org.eclipse.jdt.internal.compiler.CompilationResult;
-import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression;
-import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
-import org.eclipse.jdt.internal.compiler.ast.CastExpression;
-import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
-import org.eclipse.jdt.internal.compiler.ast.Expression;
-import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
-import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
-import org.eclipse.jdt.internal.compiler.ast.Statement;
-import org.eclipse.jdt.internal.compiler.ast.TypeReference;
-import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
-import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
-import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
 import org.eclipse.jdt.internal.compiler.parser.Parser;
 
-
+/**
+ * An inter-type constructor declaration.
+ * 
+ * This will generate two implementation methods in the aspect, the main one for the body
+ * of the constructor, and an additional <code>preMethod</code> for the code that 
+ * runs before the super constructor is called.
+ * 
+ * @author Jim Hugunin
+ */
 public class InterTypeConstructorDeclaration extends InterTypeDeclaration {    
        private MethodDeclaration preMethod;
        private ExplicitConstructorCall explicitConstructorCall = null;
index 07987f2040c922d9edb83aeb2bd692468a021785..8db871851318b28ee6b7099151f9c95ec173be28 100644 (file)
@@ -28,8 +28,12 @@ import org.eclipse.jdt.internal.compiler.ast.TypeReference;
 import org.eclipse.jdt.internal.compiler.lookup.*;
 import org.eclipse.jdt.internal.compiler.util.CharOperation;
 
+/**
+ * Base type for all inter-type declarations including methods, fields and constructors.
+ *
+ * @author Jim Hugunin
+ */
 public abstract class InterTypeDeclaration extends MethodDeclaration {
-       //public AstNode myDeclaration;
        public TypeReference onType;
        protected ReferenceBinding onTypeBinding;
 
@@ -37,8 +41,6 @@ public abstract class InterTypeDeclaration extends MethodDeclaration {
        protected int declaredModifiers;
        protected char[] declaredSelector;
 
-       //protected Set superMethodsCalled;
-
        public InterTypeDeclaration(CompilationResult result, TypeReference onType) {
                super(result);
                this.onType = onType;
@@ -59,7 +61,6 @@ public abstract class InterTypeDeclaration extends MethodDeclaration {
                
                
                ClassScope newParent = new InterTypeScope(upperScope, onTypeBinding);
-                       //interBinding.introducedField.declaringClass);
                scope.parent = newParent;
                this.scope.isStatic = Modifier.isStatic(declaredModifiers);
                super.resolve(newParent);
@@ -75,32 +76,15 @@ public abstract class InterTypeDeclaration extends MethodDeclaration {
                SuperFixerVisitor v = new SuperFixerVisitor(this, onTypeBinding);
                this.traverse(v, (ClassScope)null);
                munger.setSuperMethodsCalled(v.superMethodsCalled);
-//             HashSet set = new HashSet();
-//             for (Iterator i = v.superMethodsCalled.iterator(); i.hasNext(); ) {
-//                     MethodBinding b = (MethodBinding)i.next();
-//                     set.add(EclipseWorld.makeResolvedMember(b));
-//             }
-//             
-//             munger.setSuperMethodsCalled(set);
        }
 
        protected void resolveOnType(ClassScope classScope) {
                checkSpec();            
                onTypeBinding = (ReferenceBinding)onType.getTypeBinding(classScope);
                if (!onTypeBinding.isValidBinding()) {
-                       if (onTypeBinding instanceof ProblemReferenceBinding) {
-                               classScope.problemReporter().invalidType(onType, onTypeBinding);
-                       } else {
-                               //XXX trouble
-                       }
+                       classScope.problemReporter().invalidType(onType, onTypeBinding);
                        ignoreFurtherInvestigation = true;
                }
-               //??? this is not a friendly compiler limitation
-//             if (!(onTypeBinding instanceof SourceTypeBinding)) {
-//                     classScope.problemReporter().signalError(onType.sourceStart, onType.sourceEnd,
-//                                             "can only introduce on types available as source code (compiler limitation)");
-//                     ignoreFurtherInvestigation = true;
-//             }
        }
        
        
@@ -130,15 +114,12 @@ public abstract class InterTypeDeclaration extends MethodDeclaration {
        }
        
        protected int generateInfoAttributes(ClassFile classFile) {
-               //munger.getSignature().setPosition(sourceStart, sourceEnd);
-               
-               //System.out.println("generating effective for " + this);
                List l;;
                Shadow.Kind kind = getShadowKindForBody();
                if (kind != null) {
                        l = makeEffectiveSignatureAttribute(munger.getSignature(), kind, true);
                } else {
-                       l = new ArrayList(0); //AstUtil.getAjSyntheticAttribute();
+                       l = new ArrayList(0);
                }
 
                return classFile.generateMethodInfoAttribute(binding, l);
index fadc43d98360f442639cbce8f14665b9d8463ffe..583edca78045dbe6e0291e7377aee8737463327d 100644 (file)
@@ -25,9 +25,15 @@ import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
 import org.eclipse.jdt.internal.compiler.lookup.*;
 import org.eclipse.jdt.internal.compiler.parser.Parser;
 
+
 /**
+ * An inter-type field declaration.
+ * 
  * returnType encodes the type of the field
  * selector encodes the name
+ * statements is null until resolution when it is filled in from the initializer
+ * 
+ * @author Jim Hugunin
  */
 public class InterTypeFieldDeclaration extends InterTypeDeclaration {
        public Expression initialization;
index c3efffc9d69ac0558c9d697d33bc4dc5e4e8a3e5..e7158c5257888bacccaae4607ab8886f3ac66571 100644 (file)
@@ -28,7 +28,11 @@ import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
 import org.eclipse.jdt.internal.compiler.lookup.*;
 import org.eclipse.jdt.internal.compiler.parser.Parser;
 
-
+/**
+ * An inter-type method declaration.
+ *
+ * @author Jim Hugunin
+ */
 public class InterTypeMethodDeclaration extends InterTypeDeclaration {
        public InterTypeMethodDeclaration(CompilationResult result, TypeReference onType) {
                super(result, onType);
index 9713d31a3a25e471259d4236ac37245766a6c0be..83be983e820c017135209bbb8c9b9d9ffbc985fb 100644 (file)
@@ -23,7 +23,14 @@ import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
 import org.eclipse.jdt.internal.compiler.lookup.Scope;
 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 
-
+/**
+ * Used to represent any method call to a method named <code>proceed</code>.  During
+ * <code>resolvedType</code> it will be determined if this is actually in the body
+ * of an <code>around</code> advice and if not this will be treated like any other
+ * MessageSend.
+ * 
+ * @author Jim Hugunin
+ */
 public class Proceed extends MessageSend {
        public boolean inInner = false;
        
@@ -46,15 +53,13 @@ public class Proceed extends MessageSend {
 
        public TypeBinding resolveType(BlockScope scope) {
                // find out if I'm really in an around body or not
-               //??? there is a small performance issue here
+               //??? this could in theory be done by the parser, but that appears to be hard
                AdviceDeclaration aroundDecl = findEnclosingAround(scope);
                
                if (aroundDecl == null) {
                        return super.resolveType(scope);
                }
                
-
-
                constant = NotAConstant;
                binding = codegenBinding = aroundDecl.proceedMethodBinding;
                
@@ -125,7 +130,4 @@ public class Proceed extends MessageSend {
                
                return findEnclosingAround(scope.parent);
        }
-
-
-
 }
index 674d7e1fcabdeebb301e3d2abe2520974c318e64..522b8019789ce894aa8a9a73e3076e7380533193 100644 (file)
 
 package org.aspectj.ajdt.internal.compiler.lookup;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
+import java.util.*;
 
 import org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration;
 import org.aspectj.bridge.IMessage;
-import org.aspectj.bridge.MessageUtil;
-import org.aspectj.weaver.ResolvedTypeX;
-import org.aspectj.weaver.TypeX;
-import org.aspectj.weaver.patterns.DeclareParents;
-import org.aspectj.weaver.patterns.TypePattern;
-import org.aspectj.weaver.patterns.TypePatternList;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.bcel.BcelTypeMunger;
+import org.aspectj.weaver.patterns.*;
 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 import org.eclipse.jdt.internal.compiler.env.IBinaryType;
 import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.impl.ITypeRequestor;
-import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
-import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
-import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
-import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.*;
 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
 
+/**
+ * Overrides the default eclipse LookupEnvironment for two purposes.
+ * 
+ * 1. To provide some additional phases to <code>completeTypeBindings</code>
+ *    that weave declare parents and inter-type declarations at the correct time.
+ * 
+ * 2. To intercept the loading of new binary types to ensure the they will have
+ *    declare parents and inter-type declarations woven when appropriate.
+ * 
+ * @author Jim Hugunin
+ */
 public class AjLookupEnvironment extends LookupEnvironment {
        public EclipseFactory factory = null;
        
-       private boolean builtInterTypesAndPerClauses = false;
+//     private boolean builtInterTypesAndPerClauses = false;
        private List pendingTypesToWeave = new ArrayList();
        
        public AjLookupEnvironment(
@@ -56,7 +55,7 @@ public class AjLookupEnvironment extends LookupEnvironment {
        
        //??? duplicates some of super's code
        public void completeTypeBindings() {
-               builtInterTypesAndPerClauses = false;
+//             builtInterTypesAndPerClauses = false;
                //pendingTypesToWeave = new ArrayList();
                stepCompleted = BUILD_TYPE_HIERARCHY;
                
@@ -82,8 +81,6 @@ public class AjLookupEnvironment extends LookupEnvironment {
                        }
                }
                
-               
-               
                // need to build inter-type declarations for all AspectDeclarations at this point
                for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
                        SourceTypeBinding[] b = units[i].scope.topLevelTypes;
@@ -91,14 +88,15 @@ public class AjLookupEnvironment extends LookupEnvironment {
                                buildInterTypeAndPerClause(b[j].scope);
                        }
                }
-               builtInterTypesAndPerClauses = true;
-               doPendingWeaves();
+               factory.finishTypeMungers();
        
                // now do weaving
                Collection typeMungers = factory.getTypeMungers();
-               //System.out.println("typeMungers: " + typeMungers);
                
                Collection declareParents = factory.getDeclareParents();
+
+               doPendingWeaves();
+
                for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
                        weaveInterTypeDeclarations(units[i].scope, typeMungers, declareParents);
                        units[i] = null; // release unnecessary reference to the parsed unit
@@ -130,29 +128,24 @@ public class AjLookupEnvironment extends LookupEnvironment {
                        buildInterTypeAndPerClause(((SourceTypeBinding) memberTypes[i]).scope);
                }
        }
-       
-       
-       
                
        private void weaveInterTypeDeclarations(CompilationUnitScope unit, Collection typeMungers, Collection declareParents) {
-               for (int i = 0, length = unit.topLevelTypes.length; i < length; i++)
-                   weaveInterTypeDeclarations(unit.topLevelTypes[i], typeMungers, declareParents);
-       
-               //System.err.println("done with inter types");
+               for (int i = 0, length = unit.topLevelTypes.length; i < length; i++) {
+                   weaveInterTypeDeclarations(unit.topLevelTypes[i], typeMungers, declareParents, false);
+               }
        }
        
-       
        private void weaveInterTypeDeclarations(SourceTypeBinding sourceType) {
-               if (!builtInterTypesAndPerClauses) {
-                       pendingTypesToWeave.add(sourceType);
+               if (!factory.areTypeMungersFinished()) {
+                       if (!pendingTypesToWeave.contains(sourceType)) pendingTypesToWeave.add(sourceType);
                } else {
-                       //System.err.println("weaving: " + new String(sourceType.sourceName()) + ", " + world.getTypeMungers());
-                       weaveInterTypeDeclarations(sourceType, factory.getTypeMungers(), factory.getDeclareParents());
+                       weaveInterTypeDeclarations(sourceType, factory.getTypeMungers(), factory.getDeclareParents(), true);
                }
        }
        
        
-       private void weaveInterTypeDeclarations(SourceTypeBinding sourceType, Collection typeMungers, Collection declareParents) {
+       
+       private void weaveInterTypeDeclarations(SourceTypeBinding sourceType, Collection typeMungers, Collection declareParents, boolean skipInners) {
                ResolvedTypeX onType = factory.fromEclipse(sourceType);
                onType.clearInterTypeMungers();
                
@@ -161,29 +154,24 @@ public class AjLookupEnvironment extends LookupEnvironment {
                }
                
                for (Iterator i = typeMungers.iterator(); i.hasNext();) {
-                       Object o = i.next();
-                       if (o instanceof EclipseTypeMunger) {
-                               EclipseTypeMunger munger = (EclipseTypeMunger) o;
-                               if (munger.matches(onType)) {
-                                       onType.addInterTypeMunger(munger);
-                               }
-                       } else {
-                               //FIXME this needs to handle some binary form type mungers for aspect libs
-                               //???System.out.println("skipping: " + o);
+                       EclipseTypeMunger munger = (EclipseTypeMunger) i.next();
+                       if (munger.matches(onType)) {
+                               onType.addInterTypeMunger(munger);
                        }
                }
                
                for (Iterator i = onType.getInterTypeMungers().iterator(); i.hasNext();) {
                        EclipseTypeMunger munger = (EclipseTypeMunger) i.next();
+                       //System.err.println("applying: " + munger + " to " + new String(sourceType.sourceName));
                        munger.munge(sourceType);
                }
                
-               
+               if (skipInners) return;
 
                ReferenceBinding[] memberTypes = sourceType.memberTypes;
                for (int i = 0, length = memberTypes.length; i < length; i++) {
                        if (memberTypes[i] instanceof SourceTypeBinding) {
-                               weaveInterTypeDeclarations((SourceTypeBinding) memberTypes[i], typeMungers, declareParents);
+                               weaveInterTypeDeclarations((SourceTypeBinding) memberTypes[i], typeMungers, declareParents, false);
                        }
                }
        }
@@ -198,13 +186,8 @@ public class AjLookupEnvironment extends LookupEnvironment {
        }
 
        private void addParent(DeclareParents declareParents, SourceTypeBinding sourceType, TypePattern typePattern) {
-               //if (!typePattern.assertExactType(world.getMessageHandler())) return;
                if (typePattern == TypePattern.NO) return;  // already had an error here
                TypeX iType = typePattern.getExactType();
-//             if (iType == null) {
-//                     throw new RuntimeException("yikes: " + typePattern);
-//             }
-               //if (iType == ResolvedTypeX.MISSING || iType == null) return;
                ReferenceBinding b = (ReferenceBinding)factory.makeTypeBinding(iType); //"
                                
                if (b.isClass()) {
index f05fb8439e9fdeffcd55582979fad0f7cb830f4d..d1744dafbefe4e0444b5f4484d2e68a821c1c642 100644 (file)
@@ -42,13 +42,13 @@ public class EclipseFactory {
        //XXX currently unused
        private Map/*TypeBinding, ResolvedTypeX*/ bindingToResolvedTypeX = new HashMap();
        
-       public static EclipseFactory forLookupEnvironment(LookupEnvironment env) {
+       public static EclipseFactory fromLookupEnvironment(LookupEnvironment env) {
                AjLookupEnvironment aenv = (AjLookupEnvironment)env;
                return aenv.factory;
        }
        
        public static EclipseFactory fromScopeLookupEnvironment(Scope scope) {
-               return forLookupEnvironment(AstUtil.getCompilationUnitScope(scope).environment);
+               return fromLookupEnvironment(AstUtil.getCompilationUnitScope(scope).environment);
        }
        
        
@@ -69,50 +69,6 @@ public class EclipseFactory {
                getWorld().showMessage(kind, message, loc1, loc2);
        }
 
-       
-//    public Advice concreteAdvice(
-//             AjAttribute.AdviceAttribute attribute,
-//     Pointcut pointcut,
-//        Member signature)
-//    {
-//        return new EclipseAdvice(attribute, pointcut, signature);
-//    }
-//
-//    public ConcreteTypeMunger concreteTypeMunger(
-//             ResolvedTypeMunger munger, ResolvedTypeX aspectType)
-//     {
-//             return null;
-//     }
-
-//     protected ResolvedTypeX.ConcreteName resolveObjectType(ResolvedTypeX.Name typeX) {
-//             TypeBinding binding = makeTypeBinding(typeX);
-//             
-////           System.err.println("resolvedObjectType: " + typeX + 
-////                                           " found " + 
-////                                           (binding == null ? "null" : binding.getClass().getName()));
-//             
-//             if (!(binding instanceof SourceTypeBinding)) {
-//                     //System.err.println("missing: " + binding);
-//                     return null;
-//             }
-//             
-////           if (binding instanceof BinaryTypeBinding) {
-////                   //System.err.println("binary: " + typeX);
-////                   return new EclipseBinaryType(
-////                                   buildManager.bcelWorld.resolve(typeX), 
-////                                   this,
-////                                   (BinaryTypeBinding)binding);
-////           }
-//             
-//             return new EclipseSourceType(typeX, this,(SourceTypeBinding)binding);
-//     }
-//     
-       public EclipseSourceType lookupConcreteName(SourceTypeBinding b) {
-               throw new RuntimeException("unimplemented");
-       }
-                       
-
-
        public ResolvedTypeX fromEclipse(ReferenceBinding binding) {
                if (binding == null) return ResolvedTypeX.MISSING;
                //??? this seems terribly inefficient
@@ -174,13 +130,41 @@ public class EclipseFactory {
        public Collection getDeclareParents() {
                return getWorld().getDeclareParents();
        }
+       
+       public Collection finishedTypeMungers = null;
+       
+       public boolean areTypeMungersFinished() {
+               return finishedTypeMungers != null;
+       }
+       
+       public void finishTypeMungers() {
+               // make sure that type mungers are
+               finishedTypeMungers = new ArrayList();
+               Collection baseTypeMungers = 
+                       getWorld().getCrosscuttingMembersSet().getTypeMungers();
+               for (Iterator i = baseTypeMungers.iterator(); i.hasNext(); ) {
+                       ConcreteTypeMunger munger = (ConcreteTypeMunger) i.next();
+                       EclipseTypeMunger etm = makeEclipseTypeMunger(munger);
+                       if (etm != null) finishedTypeMungers.add(etm);
+               }               
+       }
+       
+       public EclipseTypeMunger makeEclipseTypeMunger(ConcreteTypeMunger concrete) {
+               if (concrete instanceof EclipseTypeMunger) return (EclipseTypeMunger)concrete;
+               if (EclipseTypeMunger.supportsKind(concrete.getMunger().getKind())) {
+                       return new EclipseTypeMunger(this, concrete.getMunger(), concrete.getAspectType(), null);
+               } else {
+                       return null;
+               }
+       }
 
        public Collection getTypeMungers() {
-               //XXX almost certainly the wrong types
-               return getWorld().getCrosscuttingMembersSet().getTypeMungers();
+               //??? assert finishedTypeMungers != null
+               return finishedTypeMungers;
        }
        
        public static ResolvedMember makeResolvedMember(MethodBinding binding) {
+               //System.err.println("member for: " + binding + ", " + new String(binding.declaringClass.sourceName));
                ResolvedMember ret =  new ResolvedMember(
                        binding.isConstructor() ? Member.CONSTRUCTOR : Member.METHOD,
                        fromBinding(binding.declaringClass),
index 886db4b4e1ba828ae3a67604e1dd1879d98b0478..f36c6eeff9f7fc38332bad95f2c8d894c51fdc09 100644 (file)
@@ -15,8 +15,7 @@ package org.aspectj.ajdt.internal.compiler.lookup;
 
 import java.util.*;
 
-import org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration;
-import org.aspectj.ajdt.internal.compiler.ast.PointcutDeclaration;
+import org.aspectj.ajdt.internal.compiler.ast.*;
 import org.aspectj.bridge.IMessage;
 import org.aspectj.bridge.ISourceLocation;
 import org.aspectj.weaver.*;
@@ -26,6 +25,11 @@ import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 import org.eclipse.jdt.internal.compiler.lookup.*;
 
+/**
+ * Supports viewing eclipse TypeDeclarations/SourceTypeBindings as a ResolvedTypeX
+ * 
+ * @author Jim Hugunin
+ */
 public class EclipseSourceType extends ResolvedTypeX.ConcreteName {
        protected ResolvedPointcutDefinition[] declaredPointcuts = null;
        protected ResolvedMember[] declaredMethods = null;
@@ -74,21 +78,32 @@ public class EclipseSourceType extends ResolvedTypeX.ConcreteName {
                List declaredMethods = new ArrayList();
                List declaredFields = new ArrayList();
                
-               MethodBinding[] methods = binding.methods();
-               for (int i=0, len=methods.length; i < len; i++) {
-                       MethodBinding m = methods[i];
-                       AbstractMethodDeclaration amd = m.sourceMethod();
-                       if (amd == null) continue; //???
-                       if (amd instanceof PointcutDeclaration) {
-                               PointcutDeclaration d = (PointcutDeclaration)amd;
-                               ResolvedPointcutDefinition df = d.makeResolvedPointcutDefinition();
-                               declaredPointcuts.add(df);
-                       } else {
-                               //XXX this doesn't handle advice quite right
-                               declaredMethods.add(eclipseWorld().makeResolvedMember(m));
+               binding.methods();  // the important side-effect of this call is to make sure bindings are completed
+               AbstractMethodDeclaration[] methods = declaration.methods;
+               if (methods != null) {
+                       for (int i=0, len=methods.length; i < len; i++) {
+                               AbstractMethodDeclaration amd = methods[i];
+                               if (amd == null || amd.ignoreFurtherInvestigation) continue;
+                               if (amd instanceof PointcutDeclaration) {
+                                       PointcutDeclaration d = (PointcutDeclaration)amd;
+                                       ResolvedPointcutDefinition df = d.makeResolvedPointcutDefinition();
+                                       declaredPointcuts.add(df);
+                               } else if (amd instanceof InterTypeDeclaration) {
+                                       // these are handled in a separate pass
+                                       continue;
+                               } else if (amd instanceof DeclareDeclaration) {
+                                       // these are handled in a separate pass
+                                       continue;
+                               } else if (amd instanceof AdviceDeclaration) {
+                                       // these are ignored during compilation and only used during weaving
+                                       continue;
+                               } else {
+                                       if (amd.binding == null || !amd.binding.isValidBinding()) continue;
+                                       declaredMethods.add(eclipseWorld().makeResolvedMember(amd.binding));
+                               }
                        }
                }
-               
+
                FieldBinding[] fields = binding.fields();
                for (int i=0, len=fields.length; i < len; i++) {
                        FieldBinding f = fields[i];
index b5363dd10706b9ad1c3764ec4997ffc6080a3a90..1b04e85cee11218e5ea88653d69068ff494d7278 100644 (file)
@@ -41,29 +41,26 @@ public class EclipseTypeMunger extends ConcreteTypeMunger {
                super(munger, aspectType);
                this.world = world;
                this.sourceMethod = sourceMethod;
+               TypeX targetTypeX = munger.getSignature().getDeclaringType();
+               targetBinding = (ReferenceBinding)world.makeTypeBinding(targetTypeX);
+       }
+       
+       public static boolean supportsKind(ResolvedTypeMunger.Kind kind) {
+               return kind == ResolvedTypeMunger.Field
+                       || kind == ResolvedTypeMunger.Method
+                       || kind == ResolvedTypeMunger.Constructor;
        }
 
        public String toString() {
                return "(EclipseTypeMunger " + getMunger() + ")";
        }
        
-       private boolean match(SourceTypeBinding sourceType) {
-               if (targetBinding == null) {
-                       TypeX targetTypeX = munger.getSignature().getDeclaringType();
-                       targetBinding = (ReferenceBinding)world.makeTypeBinding(targetTypeX);
-               }
-               //??? assumes instance uniqueness for ReferenceBindings
-               return targetBinding == sourceType;
-               
-       }
-       
        /**
         * Modifies signatures of a TypeBinding through its ClassScope,
         * i.e. adds Method|FieldBindings, plays with inheritance, ...
         */
        public boolean munge(SourceTypeBinding sourceType) {
-               if (!match(sourceType)) return false;
-               
+               if (sourceType != targetBinding) return false; //??? move this test elsewhere
                if (munger.getKind() == ResolvedTypeMunger.Field) {
                        mungeNewField(sourceType, (NewFieldTypeMunger)munger);
                } else if (munger.getKind() == ResolvedTypeMunger.Method) {
@@ -71,7 +68,7 @@ public class EclipseTypeMunger extends ConcreteTypeMunger {
                } else if (munger.getKind() == ResolvedTypeMunger.Constructor) {
                        mungeNewConstructor(sourceType, (NewConstructorTypeMunger)munger);
                } else {
-                       throw new RuntimeException("unimplemented");
+                       throw new RuntimeException("unimplemented: " + munger.getKind());
                }
                return true;
        }
index f10326be297d6a92bcb58d8950ebfb0ebcb594ea..b12211811a2405e369e6d64a82a3a0d4330821a1 100644 (file)
@@ -50,6 +50,7 @@ public class InterTypeFieldBinding extends FieldBinding {
        }
        
        public boolean canBeSeenBy(TypeBinding receiverType, InvocationSite invocationSite, Scope scope) {
+               //System.err.println("canBeSeenBy: " + this + ", " + isPublic());
                if (isPublic()) return true;    
        
                SourceTypeBinding invocationType = scope.invocationType();
index 37be6e4948d4a4dc0cc3b4aee32ec8d6df421cf6..abcee21b415110be7ad8fe2799a7509996fdb91b 100644 (file)
@@ -380,6 +380,7 @@ public class InterTypeMemberFinder implements IMemberFinder {
        
 
        public void addInterTypeField(FieldBinding binding) {
+               //System.err.println("adding: " + binding + " to " + this);
                interTypeFields.add(binding);
        }
        
index 9279a23b28f8c30243f8eff12309c658509db1ba..16bb99b1a8eceb6bd5f0623c7d649df73b559a8a 100644 (file)
@@ -127,6 +127,11 @@ public class AjProblemReporter extends ProblemReporter {
                        return;
                }
                
+               if (CharOperation.startsWith(abstractMethod.selector, "ajc$interField".toCharArray())) {
+                       //??? think through how this could go wrong
+                       return;
+               }
+               
                
                // if we implemented this method by an inter-type declaration, then there is no error
                //??? be sure this is always right
diff --git a/org.aspectj.ajdt.core/testdata/src1/binary/client/Client.java b/org.aspectj.ajdt.core/testdata/src1/binary/client/Client.java
new file mode 100644 (file)
index 0000000..181b786
--- /dev/null
@@ -0,0 +1,29 @@
+package client;
+
+import lib.ConcreteA;
+import org.aspectj.lang.*;
+
+public class Client {
+       public static void main(String[] args) {
+               C c = new C();
+               System.out.println(c.value);
+               ConcreteA.Marker m = c;
+               System.out.println(m.value);
+               try {
+                       new Client();
+               } catch (SoftException se) {
+                       System.out.println("se: " + se);
+               }
+       }
+       
+       
+       public Client() {
+               foo();
+       }
+       
+       private void foo() throws ConcreteA.MyException {
+               throw new ConcreteA.MyException();
+       }
+}
+
+class C implements ConcreteA.Marker { }
\ No newline at end of file
diff --git a/org.aspectj.ajdt.core/testdata/src1/binary/lib/ConcreteA.aj b/org.aspectj.ajdt.core/testdata/src1/binary/lib/ConcreteA.aj
new file mode 100644 (file)
index 0000000..02a09c8
--- /dev/null
@@ -0,0 +1,12 @@
+package lib;\r
+\r
+public aspect ConcreteA {\r
+    public interface Marker {}\r
+    \r
+    public String Marker.value = "public";\r
+    //private String Marker.pValue = "private";\r
+\r
+    public static class MyException extends Exception {}\r
+\r
+    declare soft: MyException: withincode(new(..));\r
+}
\ No newline at end of file
index 7c8c298a87c0a3b75a997eec92b845fbf8f4cd3e..07fb71daec07b05307bed38d000df17c49f31d74 100644 (file)
 package org.aspectj.ajdt.internal.compiler.batch;
 
 import java.io.IOException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.aspectj.testing.util.TestUtil;
 
 
 public class BinaryFormsTestCase extends CommandTestCase {
@@ -22,7 +25,38 @@ public class BinaryFormsTestCase extends CommandTestCase {
                super(name);
        }
        
-       public void testDummy() {}
+
+       public void testJar1() throws IOException {
+               List args = new ArrayList();
+               args.add("-outjar");
+               args.add("out/lib.jar");
+
+               args.add("-classpath");
+               args.add("../runtime/bin");
+               
+               args.add("-d");
+               args.add("out");
+               
+               args.add("testdata/src1/binary/lib/ConcreteA.aj");
+               
+               CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS);
+               
+               args = new ArrayList();
+               args.add("-aspectpath");
+               args.add("out/lib.jar");
+
+               args.add("-classpath");
+               args.add("../runtime/bin");
+               
+               args.add("-d");
+               args.add("out");
+               
+               args.add("testdata/src1/binary/client/Client.java");
+               
+               CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS);
+               
+               TestUtil.runMain("out;out/lib.jar", "client.Client");
+       }
 
 
        public void XXXtestJar1() throws IOException {
index 1e767aceb6f6059aae9ee03581597855fd505dd3..e4acce69f0c1f8e72ee5f19cd76f491703a8faaf 100644 (file)
@@ -115,6 +115,7 @@ def makeSet(errors):
        ret = {}\r
        for e in errors:\r
                loc = e.getISourceLocation()\r
+               if loc is None: continue  #???\r
                s = "%s:%i" % (loc.sourceFile.name[:-5], loc.line)\r
                ret[s] = s\r
        return ret.keys()\r
index 97bab6624e2011c990644f1ecbc08e082c45dfe7..e0e3f04d539bc63cc5d9912f9d0ac5b31c0b854e 100644 (file)
@@ -247,7 +247,12 @@ class BcelClassWeaver implements IClassWeaver {
         
         // start by munging all typeMungers
         for (Iterator i = typeMungers.iterator(); i.hasNext(); ) {
-               BcelTypeMunger munger = (BcelTypeMunger)i.next();
+               Object o = i.next();
+               if ( !(o instanceof BcelTypeMunger) ) {
+                       System.err.println("surprising: " + o);
+                       continue;
+               }
+               BcelTypeMunger munger = (BcelTypeMunger)o;
                isChanged |= munger.munge(this);
         }