diff options
author | jhugunin <jhugunin> | 2003-03-10 23:18:56 +0000 |
---|---|---|
committer | jhugunin <jhugunin> | 2003-03-10 23:18:56 +0000 |
commit | cd8bd2c7cef6d403d6a60c7f3deb104b2898364b (patch) | |
tree | dbe8d190c2625714e8b05e0c16a25c4aae6c7f1c | |
parent | 7139ac48be452e260c39f5c75ed845b661725cc9 (diff) | |
download | aspectj-cd8bd2c7cef6d403d6a60c7f3deb104b2898364b.tar.gz aspectj-cd8bd2c7cef6d403d6a60c7f3deb104b2898364b.zip |
further work on binary aspects (aspect path) tested correct behavior
for obvious forms of concrete aspects, next need to address abstract
18 files changed, 240 insertions, 198 deletions
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompiler.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompiler.java index c96192ff2..e74731c50 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompiler.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompiler.java @@ -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); diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java index c484d59a7..142efe27f 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java @@ -13,41 +13,23 @@ 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; diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeDeclaration.java index 07987f204..8db871851 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeDeclaration.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeDeclaration.java @@ -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); diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeFieldDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeFieldDeclaration.java index fadc43d98..583edca78 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeFieldDeclaration.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeFieldDeclaration.java @@ -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; diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java index c3efffc9d..e7158c525 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java @@ -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); diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java index 9713d31a3..83be983e8 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java @@ -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); } - - - } 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 674d7e1fc..522b80197 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 @@ -13,37 +13,36 @@ 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()) { diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java index f05fb8439..d1744dafb 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java @@ -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), diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java index 886db4b4e..f36c6eeff 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java @@ -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]; diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseTypeMunger.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseTypeMunger.java index b5363dd10..1b04e85ce 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseTypeMunger.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseTypeMunger.java @@ -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; } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeFieldBinding.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeFieldBinding.java index f10326be2..b12211811 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeFieldBinding.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeFieldBinding.java @@ -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(); diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeMemberFinder.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeMemberFinder.java index 37be6e494..abcee21b4 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeMemberFinder.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeMemberFinder.java @@ -380,6 +380,7 @@ public class InterTypeMemberFinder implements IMemberFinder { public void addInterTypeField(FieldBinding binding) { + //System.err.println("adding: " + binding + " to " + this); interTypeFields.add(binding); } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/problem/AjProblemReporter.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/problem/AjProblemReporter.java index 9279a23b2..16bb99b1a 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/problem/AjProblemReporter.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/problem/AjProblemReporter.java @@ -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 index 000000000..181b78628 --- /dev/null +++ b/org.aspectj.ajdt.core/testdata/src1/binary/client/Client.java @@ -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 index 000000000..02a09c87d --- /dev/null +++ b/org.aspectj.ajdt.core/testdata/src1/binary/lib/ConcreteA.aj @@ -0,0 +1,12 @@ +package lib;
+
+public aspect ConcreteA {
+ public interface Marker {}
+
+ public String Marker.value = "public";
+ //private String Marker.pValue = "private";
+
+ public static class MyException extends Exception {}
+
+ declare soft: MyException: withincode(new(..));
+}
\ No newline at end of file diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BinaryFormsTestCase.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BinaryFormsTestCase.java index 7c8c298a8..07fb71dae 100644 --- a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BinaryFormsTestCase.java +++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BinaryFormsTestCase.java @@ -13,7 +13,10 @@ 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 { diff --git a/tests/scripts/incr.py b/tests/scripts/incr.py index 1e767aceb..e4acce69f 100644 --- a/tests/scripts/incr.py +++ b/tests/scripts/incr.py @@ -115,6 +115,7 @@ def makeSet(errors): ret = {}
for e in errors:
loc = e.getISourceLocation()
+ if loc is None: continue #???
s = "%s:%i" % (loc.sourceFile.name[:-5], loc.line)
ret[s] = s
return ret.keys()
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java index 97bab6624..e0e3f04d5 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java @@ -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); } |