From 7c1a5d72a8549771b076af20b4caff8e1da903bd Mon Sep 17 00:00:00 2001 From: acolyer Date: Thu, 4 Aug 2005 13:19:20 +0000 Subject: [PATCH] changed Member to be an interface with impl MemberImpl. changed ResolvedMember to be an interface with impl ResolvedMemberImpl --- .../compiler/ast/IfMethodDeclaration.java | 4 +- .../internal/compiler/ast/IfPseudoToken.java | 4 +- .../ast/InterTypeConstructorDeclaration.java | 4 +- .../ast/InterTypeFieldDeclaration.java | 2 +- .../ast/InterTypeMethodDeclaration.java | 3 +- .../compiler/lookup/EclipseFactory.java | 7 +- .../compiler/lookup/EclipseShadow.java | 4 +- .../compiler/lookup/PrivilegedHandler.java | 3 +- .../src/org/aspectj/weaver/AjAttribute.java | 10 +- .../org/aspectj/weaver/AjcMemberMaker.java | 106 +- .../aspectj/weaver/CrosscuttingMembers.java | 2 +- weaver/src/org/aspectj/weaver/Member.java | 900 ++--------------- weaver/src/org/aspectj/weaver/MemberImpl.java | 922 ++++++++++++++++++ .../weaver/NewConstructorTypeMunger.java | 6 +- .../aspectj/weaver/NewFieldTypeMunger.java | 2 +- .../aspectj/weaver/NewMethodTypeMunger.java | 2 +- .../org/aspectj/weaver/ResolvedMember.java | 522 ++-------- .../weaver/ResolvedPointcutDefinition.java | 2 +- .../src/org/aspectj/weaver/ResolvedType.java | 57 +- .../aspectj/weaver/ResolvedTypeMunger.java | 2 +- .../org/aspectj/weaver/WeaverMessages.java | 1 + .../bcel/BcelAccessForInlineMunger.java | 2 +- .../aspectj/weaver/bcel/BcelClassWeaver.java | 14 +- .../org/aspectj/weaver/bcel/BcelField.java | 28 +- .../org/aspectj/weaver/bcel/BcelMethod.java | 27 +- .../org/aspectj/weaver/bcel/BcelRenderer.java | 5 +- .../org/aspectj/weaver/bcel/BcelShadow.java | 27 +- .../aspectj/weaver/bcel/BcelTypeMunger.java | 8 +- .../org/aspectj/weaver/bcel/BcelWorld.java | 61 +- .../org/aspectj/weaver/bcel/LazyClassGen.java | 3 +- .../aspectj/weaver/bcel/LazyMethodGen.java | 26 +- .../weaver/patterns/CflowPointcut.java | 5 +- .../patterns/ConcreteCflowPointcut.java | 5 +- .../aspectj/weaver/patterns/IfPointcut.java | 3 +- .../org/aspectj/weaver/patterns/PerCflow.java | 4 +- .../weaver/patterns/SignaturePattern.java | 324 +++--- .../weaver/patterns/WithincodePointcut.java | 18 + .../aspectj/weaver/weaver-messages.properties | 3 +- weaver/testsrc/fluffy/Base.java | 3 + weaver/testsrc/fluffy/Derived.java | 3 + .../org/aspectj/weaver/MemberTestCase.java | 32 +- .../ResolvedMemberSignaturesTestCase15.java | 286 ++++++ .../weaver/bcel/ArgsWeaveTestCase.java | 4 +- .../weaver/bcel/AroundWeaveTestCase.java | 2 +- .../aspectj/weaver/bcel/MegaZipTestCase.java | 3 +- .../weaver/bcel/PointcutResidueTestCase.java | 4 +- .../aspectj/weaver/bcel/TjpWeaveTestCase.java | 14 +- .../weaver/bcel/WeaveOrderTestCase.java | 2 +- .../aspectj/weaver/bcel/WorldTestCase.java | 16 +- .../patterns/SignaturePatternTestCase.java | 45 +- .../weaver/patterns/WithinTestCase.java | 4 +- 51 files changed, 1891 insertions(+), 1655 deletions(-) create mode 100644 weaver/src/org/aspectj/weaver/MemberImpl.java create mode 100644 weaver/testsrc/org/aspectj/weaver/ResolvedMemberSignaturesTestCase15.java diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfMethodDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfMethodDeclaration.java index b0f406cf9..17c74be76 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfMethodDeclaration.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfMethodDeclaration.java @@ -15,7 +15,7 @@ package org.aspectj.ajdt.internal.compiler.ast; import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory; import org.aspectj.weaver.Member; -import org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedMemberImpl; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.patterns.IfPointcut; import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile; @@ -50,7 +50,7 @@ public class IfMethodDeclaration extends AjMethodDeclaration { //XXX this is where we should remove unavailable args if we're in a cflow EclipseFactory factory = EclipseFactory.fromScopeLookupEnvironment(scope); - ifPointcut.testMethod = new ResolvedMember( + ifPointcut.testMethod = new ResolvedMemberImpl( Member.METHOD, factory.fromBinding(binding.declaringClass), this.modifiers, ResolvedType.BOOLEAN, diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfPseudoToken.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfPseudoToken.java index 14f708b51..580594949 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfPseudoToken.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfPseudoToken.java @@ -16,7 +16,7 @@ package org.aspectj.ajdt.internal.compiler.ast; import java.lang.reflect.Modifier; import org.aspectj.weaver.Member; -import org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedMemberImpl; import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.patterns.IfPointcut; import org.aspectj.weaver.patterns.Pointcut; @@ -71,7 +71,7 @@ public class IfPseudoToken extends PseudoToken { } else if (expr instanceof TrueLiteral) { return IfPointcut.makeIfTruePointcut(Pointcut.SYMBOLIC); } else { - pointcut = new IfPointcut(new ResolvedMember(Member.METHOD, UnresolvedType.OBJECT, 0, "if_", "()V"), 0); + pointcut = new IfPointcut(new ResolvedMemberImpl(Member.METHOD, UnresolvedType.OBJECT, 0, "if_", "()V"), 0); } return pointcut; 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 82dd5cdc3..d524dcfbd 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 @@ -221,7 +221,7 @@ public class InterTypeConstructorDeclaration extends InterTypeDeclaration { ResolvedMember bindingAsMember = world.makeResolvedMember(binding); ResolvedMember signature = - new ResolvedMember(Member.CONSTRUCTOR, declaringTypeX, declaredModifiers, + new ResolvedMemberImpl(Member.CONSTRUCTOR, declaringTypeX, declaredModifiers, ResolvedType.VOID, "", bindingAsMember.getParameterTypes(), world.fromEclipse(binding.thrownExceptions)); ResolvedMember syntheticInterMember = @@ -253,7 +253,7 @@ public class InterTypeConstructorDeclaration extends InterTypeDeclaration { world.makeResolvedMember(explicitConstructor)); } else { ((NewConstructorTypeMunger)munger).setExplicitConstructor( - new ResolvedMember(Member.CONSTRUCTOR, + new ResolvedMemberImpl(Member.CONSTRUCTOR, world.fromBinding(onTypeBinding.superclass()), 0, ResolvedType.VOID, "", UnresolvedType.NONE)); } 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 7b33c9ab1..464f8f177 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 @@ -174,7 +174,7 @@ public class InterTypeFieldDeclaration extends InterTypeDeclaration { declaringType = declaringType.getGenericType(); } ResolvedMember sig = - new ResolvedMember(Member.FIELD, declaringType, + new ResolvedMemberImpl(Member.FIELD, declaringType, declaredModifiers, world.fromBinding(binding.returnType), new String(declaredSelector), UnresolvedType.NONE); 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 e868d796b..f20476fdd 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 @@ -23,6 +23,7 @@ import org.aspectj.weaver.Member; import org.aspectj.weaver.NameMangler; import org.aspectj.weaver.NewMethodTypeMunger; import org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedMemberImpl; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.Shadow; import org.aspectj.weaver.UnresolvedType; @@ -124,7 +125,7 @@ public class InterTypeMethodDeclaration extends InterTypeDeclaration { if (isTargetAnnotation(classScope,"method")) return null; // Error message output in isTargetAnnotation if (isTargetEnum(classScope,"method")) return null; // Error message output in isTargetEnum - ResolvedMember sig = new ResolvedMember(Member.METHOD, world.fromBinding(onTypeBinding), + ResolvedMemberImpl sig = new ResolvedMemberImpl(Member.METHOD, world.fromBinding(onTypeBinding), declaredModifiers, world.fromBinding(binding.returnType), new String(declaredSelector), world.fromBindings(binding.parameters), world.fromEclipse(binding.thrownExceptions)); 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 4ebc962e3..b853c14a0 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 @@ -33,6 +33,7 @@ import org.aspectj.weaver.IHasPosition; import org.aspectj.weaver.Member; import org.aspectj.weaver.ReferenceType; import org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedMemberImpl; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.Shadow; import org.aspectj.weaver.TypeFactory; @@ -373,7 +374,7 @@ public class EclipseFactory { // AMC these next two lines shouldn't be needed once we sort out generic types properly in the world map ResolvedType realDeclaringType = world.resolve(fromBinding(declaringType)); if (realDeclaringType.isRawType()) realDeclaringType = realDeclaringType.getGenericType(); - ResolvedMember ret = new ResolvedMember( + ResolvedMember ret = new ResolvedMemberImpl( binding.isConstructor() ? Member.CONSTRUCTOR : Member.METHOD, realDeclaringType, binding.modifiers, @@ -392,7 +393,7 @@ public class EclipseFactory { // AMC these next two lines shouldn't be needed once we sort out generic types properly in the world map ResolvedType realDeclaringType = world.resolve(fromBinding(receiverType)); if (realDeclaringType.isRawType()) realDeclaringType = realDeclaringType.getGenericType(); - return new ResolvedMember( + return new ResolvedMemberImpl( Member.FIELD, realDeclaringType, binding.modifiers, @@ -671,7 +672,7 @@ public class EclipseFactory { } public ResolvedMember fromBinding(MethodBinding binding) { - return new ResolvedMember(Member.METHOD,fromBinding(binding.declaringClass),binding.modifiers, + return new ResolvedMemberImpl(Member.METHOD,fromBinding(binding.declaringClass),binding.modifiers, fromBinding(binding.returnType),CharOperation.charToString(binding.selector),fromBindings(binding.parameters)); } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseShadow.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseShadow.java index f610a8007..4bb3a5829 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseShadow.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseShadow.java @@ -65,7 +65,7 @@ public class EclipseShadow extends Shadow { public Member getEnclosingCodeSignature() { if (context instanceof TypeDeclaration) { - return new Member(Member.STATIC_INITIALIZATION, getEnclosingType(), 0, + return new MemberImpl(Member.STATIC_INITIALIZATION, getEnclosingType(), 0, ResolvedType.VOID, "", UnresolvedType.NONE); } else if (context instanceof AbstractMethodDeclaration) { return world.makeResolvedMember(((AbstractMethodDeclaration)context).binding); @@ -170,7 +170,7 @@ public class EclipseShadow extends Shadow { world.makeResolvedMember(e.binding), astNode, context); } else if (astNode instanceof TypeDeclaration) { return new EclipseShadow(world, Shadow.StaticInitialization, - new Member(Member.STATIC_INITIALIZATION, + new MemberImpl(Member.STATIC_INITIALIZATION, world.fromBinding(((TypeDeclaration)astNode).binding), 0, ResolvedType.VOID, "", UnresolvedType.NONE), astNode, context); diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/PrivilegedHandler.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/PrivilegedHandler.java index 084d63153..d997cdec7 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/PrivilegedHandler.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/PrivilegedHandler.java @@ -25,6 +25,7 @@ import org.aspectj.weaver.AjcMemberMaker; import org.aspectj.weaver.Lint; import org.aspectj.weaver.Member; import org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedMemberImpl; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.World; @@ -77,7 +78,7 @@ public class PrivilegedHandler implements IPrivilegedHandler { public void notePrivilegedTypeAccess(ReferenceBinding type, ASTNode location) { ResolvedMember key = - new ResolvedMember(Member.STATIC_INITIALIZATION, + new ResolvedMemberImpl(Member.STATIC_INITIALIZATION, inAspect.factory.fromEclipse(type), 0, ResolvedType.VOID, "", UnresolvedType.NONE); checkWeaveAccess(key.getDeclaringType(), location); diff --git a/weaver/src/org/aspectj/weaver/AjAttribute.java b/weaver/src/org/aspectj/weaver/AjAttribute.java index 01b60c581..30afb8c64 100644 --- a/weaver/src/org/aspectj/weaver/AjAttribute.java +++ b/weaver/src/org/aspectj/weaver/AjAttribute.java @@ -452,7 +452,7 @@ public abstract class AjAttribute { s.readByte(), s.readInt(), s.readInt(), context, s.readBoolean(), - ResolvedMember.readResolvedMemberArray(s, context), + ResolvedMemberImpl.readResolvedMemberArray(s, context), FileUtil.readBooleanArray(s), UnresolvedType.readArray(s)); } else { @@ -473,7 +473,7 @@ public abstract class AjAttribute { if (kind == AdviceKind.Around) { s.writeBoolean(proceedInInners); - ResolvedMember.writeArray(proceedCallSignatures, s); + ResolvedMemberImpl.writeArray(proceedCallSignatures, s); FileUtil.writeBooleanArray(formalsUnchangedToProceed, s); UnresolvedType.writeArray(declaredExceptions, s); } @@ -563,7 +563,7 @@ public abstract class AjAttribute { this.accessedMembers = accessedMembers; } public void write(DataOutputStream s) throws IOException { - ResolvedMember.writeArray(accessedMembers, s); + ResolvedMemberImpl.writeArray(accessedMembers, s); } public ResolvedMember[] getAccessedMembers() { @@ -571,7 +571,7 @@ public abstract class AjAttribute { } public static PrivilegedAttribute read(VersionedDataInputStream s, ISourceContext context) throws IOException { - return new PrivilegedAttribute(ResolvedMember.readResolvedMemberArray(s, context)); + return new PrivilegedAttribute(ResolvedMemberImpl.readResolvedMemberArray(s, context)); } } @@ -599,7 +599,7 @@ public abstract class AjAttribute { public static EffectiveSignatureAttribute read(VersionedDataInputStream s, ISourceContext context) throws IOException { return new EffectiveSignatureAttribute( - ResolvedMember.readResolvedMember(s, context), + ResolvedMemberImpl.readResolvedMember(s, context), Shadow.Kind.read(s), s.readBoolean()); } diff --git a/weaver/src/org/aspectj/weaver/AjcMemberMaker.java b/weaver/src/org/aspectj/weaver/AjcMemberMaker.java index dc5db0a71..622ef79b1 100644 --- a/weaver/src/org/aspectj/weaver/AjcMemberMaker.java +++ b/weaver/src/org/aspectj/weaver/AjcMemberMaker.java @@ -46,7 +46,7 @@ public class AjcMemberMaker { UnresolvedType.forName("org.aspectj.lang.NoAspectBoundException"); public static ResolvedMember ajcPreClinitMethod(UnresolvedType declaringType) { - return new ResolvedMember( + return new ResolvedMemberImpl( Member.METHOD, declaringType, PRIVATE_STATIC, @@ -55,7 +55,7 @@ public class AjcMemberMaker { } public static ResolvedMember ajcPostClinitMethod(UnresolvedType declaringType) { - return new ResolvedMember( + return new ResolvedMemberImpl( Member.METHOD, declaringType, PRIVATE_STATIC, @@ -64,7 +64,7 @@ public class AjcMemberMaker { } public static Member noAspectBoundExceptionInit() { - return new ResolvedMember( + return new ResolvedMemberImpl( Member.METHOD, NO_ASPECT_BOUND_EXCEPTION, Modifier.PUBLIC, @@ -73,7 +73,7 @@ public class AjcMemberMaker { } public static Member noAspectBoundExceptionInit2() { - return new ResolvedMember( + return new ResolvedMemberImpl( Member.METHOD, NO_ASPECT_BOUND_EXCEPTION, Modifier.PUBLIC, @@ -82,7 +82,7 @@ public class AjcMemberMaker { } public static Member noAspectBoundExceptionInitWithCause() { - return new ResolvedMember( + return new ResolvedMemberImpl( Member.METHOD, NO_ASPECT_BOUND_EXCEPTION, Modifier.PUBLIC, @@ -92,7 +92,7 @@ public class AjcMemberMaker { public static ResolvedMember perCflowPush(UnresolvedType declaringType) { - return new ResolvedMember( + return new ResolvedMemberImpl( Member.METHOD, declaringType, PUBLIC_STATIC, @@ -101,7 +101,7 @@ public class AjcMemberMaker { } public static ResolvedMember perCflowField(UnresolvedType declaringType) { - return new ResolvedMember( + return new ResolvedMemberImpl( Member.FIELD, declaringType, PUBLIC_STATIC_FINAL, @@ -110,7 +110,7 @@ public class AjcMemberMaker { } public static ResolvedMember perSingletonField(UnresolvedType declaringType) { - return new ResolvedMember( + return new ResolvedMemberImpl( Member.FIELD, declaringType, PUBLIC_STATIC_FINAL, @@ -120,7 +120,7 @@ public class AjcMemberMaker { public static ResolvedMember initFailureCauseField(UnresolvedType declaringType) { - return new ResolvedMember( + return new ResolvedMemberImpl( Member.FIELD, declaringType, PRIVATE_STATIC, @@ -133,7 +133,7 @@ public class AjcMemberMaker { if (!UnresolvedType.SERIALIZABLE.resolve(aspectType.getWorld()).isAssignableFrom(aspectType)) { modifiers |= Modifier.TRANSIENT; } - return new ResolvedMember( + return new ResolvedMemberImpl( Member.FIELD, declaringType, modifiers, @@ -148,7 +148,7 @@ public class AjcMemberMaker { if (!isSerializableAspect(aspectType)) { modifiers |= Modifier.TRANSIENT; } - return new ResolvedMember(Member.FIELD, declaringType, modifiers, + return new ResolvedMemberImpl(Member.FIELD, declaringType, modifiers, aspectType, NameMangler.perTypeWithinFieldForTarget(aspectType), UnresolvedType.NONE); } @@ -159,7 +159,7 @@ public class AjcMemberMaker { if (!isSerializableAspect(aspectType)) { modifiers |= Modifier.TRANSIENT; } - return new ResolvedMember(Member.FIELD, declaringType, modifiers, + return new ResolvedMemberImpl(Member.FIELD, declaringType, modifiers, UnresolvedType.forSignature("Ljava/lang/String;"), NameMangler.PERTYPEWITHIN_WITHINTYPEFIELD, UnresolvedType.NONE); } @@ -168,7 +168,7 @@ public class AjcMemberMaker { } public static ResolvedMember perObjectBind(UnresolvedType declaringType) { - return new ResolvedMember( + return new ResolvedMemberImpl( Member.METHOD, declaringType, PUBLIC_STATIC, @@ -179,7 +179,7 @@ public class AjcMemberMaker { // PTWIMPL ResolvedMember for getInstance() method, declared in aspect public static ResolvedMember perTypeWithinGetInstance(UnresolvedType declaringType) { // private static a.X ajc$getInstance(java.lang.Class) throws java/lang/Exception - ResolvedMember rm = new ResolvedMember( + ResolvedMemberImpl rm = new ResolvedMemberImpl( Member.METHOD, declaringType, PRIVATE_STATIC, @@ -193,7 +193,7 @@ public class AjcMemberMaker { public static ResolvedMember perTypeWithinCreateAspectInstance(UnresolvedType declaringType) { // public static a.X ajc$createAspectInstance(java.lang.String) - ResolvedMember rm = new ResolvedMember( + ResolvedMemberImpl rm = new ResolvedMemberImpl( Member.METHOD, declaringType, PUBLIC_STATIC, @@ -210,7 +210,7 @@ public class AjcMemberMaker { } public static ResolvedMember perObjectInterfaceGet(UnresolvedType aspectType) { - return new ResolvedMember( + return new ResolvedMemberImpl( Member.METHOD, perObjectInterfaceType(aspectType), Modifier.PUBLIC | Modifier.ABSTRACT, @@ -219,7 +219,7 @@ public class AjcMemberMaker { } public static ResolvedMember perObjectInterfaceSet(UnresolvedType aspectType) { - return new ResolvedMember( + return new ResolvedMemberImpl( Member.METHOD, perObjectInterfaceType(aspectType), Modifier.PUBLIC | Modifier.ABSTRACT, @@ -229,7 +229,7 @@ public class AjcMemberMaker { // PTWIMPL ResolvedMember for localAspectOf() method, declared in matched type public static ResolvedMember perTypeWithinLocalAspectOf(UnresolvedType shadowType,UnresolvedType aspectType) { - return new ResolvedMember( + return new ResolvedMemberImpl( Member.METHOD, shadowType,//perTypeWithinInterfaceType(aspectType), Modifier.PUBLIC | Modifier.STATIC, @@ -239,13 +239,13 @@ public class AjcMemberMaker { public static ResolvedMember perSingletonAspectOfMethod(UnresolvedType declaringType) { - return new ResolvedMember(Member.METHOD, + return new ResolvedMemberImpl(Member.METHOD, declaringType, PUBLIC_STATIC, "aspectOf", "()" + declaringType.getSignature()); } public static ResolvedMember perSingletonHasAspectMethod(UnresolvedType declaringType) { - return new ResolvedMember(Member.METHOD, + return new ResolvedMemberImpl(Member.METHOD, declaringType, PUBLIC_STATIC, "hasAspect", "()Z"); }; @@ -259,27 +259,27 @@ public class AjcMemberMaker { }; public static ResolvedMember perObjectAspectOfMethod(UnresolvedType declaringType) { - return new ResolvedMember(Member.METHOD, + return new ResolvedMemberImpl(Member.METHOD, declaringType, PUBLIC_STATIC, "aspectOf", "(Ljava/lang/Object;)" + declaringType.getSignature()); } public static ResolvedMember perObjectHasAspectMethod(UnresolvedType declaringType) { - return new ResolvedMember(Member.METHOD, + return new ResolvedMemberImpl(Member.METHOD, declaringType, PUBLIC_STATIC, "hasAspect", "(Ljava/lang/Object;)Z"); }; // PTWIMPL ResolvedMember for aspectOf(), declared in aspect public static ResolvedMember perTypeWithinAspectOfMethod(UnresolvedType declaringType) { - return new ResolvedMember(Member.METHOD, + return new ResolvedMemberImpl(Member.METHOD, declaringType, PUBLIC_STATIC, "aspectOf", "(Ljava/lang/Class;)" + declaringType.getSignature()); } // PTWIMPL ResolvedMember for hasAspect(), declared in aspect public static ResolvedMember perTypeWithinHasAspectMethod(UnresolvedType declaringType) { - return new ResolvedMember(Member.METHOD, + return new ResolvedMemberImpl(Member.METHOD, declaringType, PUBLIC_STATIC, "hasAspect", "(Ljava/lang/Class;)Z"); }; @@ -288,7 +288,7 @@ public class AjcMemberMaker { public static ResolvedMember privilegedAccessMethodForMethod(UnresolvedType aspectType, ResolvedMember method) { String sig = method.getDeclaredSignature(); - return new ResolvedMember(Member.METHOD, + return new ResolvedMemberImpl(Member.METHOD, method.getDeclaringType(), Modifier.PUBLIC | (method.isStatic() ? Modifier.STATIC : 0), NameMangler.privilegedAccessMethodForMethod(method.getName(), @@ -305,7 +305,7 @@ public class AjcMemberMaker { sig = "(" + field.getDeclaringType().getSignature() + ")" + field.getReturnType().getSignature(); } - return new ResolvedMember(Member.METHOD, + return new ResolvedMemberImpl(Member.METHOD, field.getDeclaringType(), PUBLIC_STATIC, //Modifier.PUBLIC | (field.isStatic() ? Modifier.STATIC : 0), NameMangler.privilegedAccessMethodForFieldGet(field.getName(), @@ -321,7 +321,7 @@ public class AjcMemberMaker { sig = "(" + field.getDeclaringType().getSignature() + field.getReturnType().getSignature() + ")V"; } - return new ResolvedMember(Member.METHOD, + return new ResolvedMemberImpl(Member.METHOD, field.getDeclaringType(), PUBLIC_STATIC, //Modifier.PUBLIC | (field.isStatic() ? Modifier.STATIC : 0), NameMangler.privilegedAccessMethodForFieldSet(field.getName(), @@ -332,7 +332,7 @@ public class AjcMemberMaker { // --- inline accessors //??? can eclipse handle a transform this weird without putting synthetics into the mix public static ResolvedMember superAccessMethod(UnresolvedType baseType, ResolvedMember method) { - return new ResolvedMember(Member.METHOD, + return new ResolvedMemberImpl(Member.METHOD, baseType, Modifier.PUBLIC, method.getReturnType(), @@ -346,7 +346,7 @@ public class AjcMemberMaker { if (!method.isStatic()) { paramTypes = UnresolvedType.insert(method.getDeclaringType(), paramTypes); } - return new ResolvedMember(Member.METHOD, + return new ResolvedMemberImpl(Member.METHOD, aspectType, PUBLIC_STATIC, //??? what about privileged and super access //???Modifier.PUBLIC | (method.isStatic() ? Modifier.STATIC : 0), @@ -365,7 +365,7 @@ public class AjcMemberMaker { sig = "(" + field.getDeclaringType().getSignature() + ")" + field.getReturnType().getSignature(); } - return new ResolvedMember(Member.METHOD, + return new ResolvedMemberImpl(Member.METHOD, aspectType, PUBLIC_STATIC, //Modifier.PUBLIC | (field.isStatic() ? Modifier.STATIC : 0), NameMangler.inlineAccessMethodForFieldGet(field.getName(), @@ -381,7 +381,7 @@ public class AjcMemberMaker { sig = "(" + field.getDeclaringType().getSignature() + field.getReturnType().getSignature() + ")V"; } - return new ResolvedMember(Member.METHOD, + return new ResolvedMemberImpl(Member.METHOD, aspectType, PUBLIC_STATIC, //Modifier.PUBLIC | (field.isStatic() ? Modifier.STATIC : 0), NameMangler.inlineAccessMethodForFieldSet(field.getName(), @@ -394,7 +394,7 @@ public class AjcMemberMaker { // --- runtimeLibrary api stuff public static Member cflowStackPeekInstance() { - return new Member( + return new MemberImpl( Member.METHOD, CFLOW_STACK_TYPE, 0, @@ -403,7 +403,7 @@ public class AjcMemberMaker { } public static Member cflowStackPushInstance() { - return new Member( + return new MemberImpl( Member.METHOD, CFLOW_STACK_TYPE, 0, @@ -412,7 +412,7 @@ public class AjcMemberMaker { } public static Member cflowStackIsValid() { - return new Member( + return new MemberImpl( Member.METHOD, CFLOW_STACK_TYPE, 0, @@ -420,7 +420,7 @@ public class AjcMemberMaker { "()Z"); } public static Member cflowStackInit() { - return new Member( + return new MemberImpl( Member.CONSTRUCTOR, CFLOW_STACK_TYPE, 0, @@ -428,7 +428,7 @@ public class AjcMemberMaker { "()V"); } public static Member aroundClosurePreInitializationField() { - return new Member( + return new MemberImpl( Member.FIELD, AROUND_CLOSURE_TYPE, 0, @@ -436,7 +436,7 @@ public class AjcMemberMaker { "[Ljava/lang/Object;"); } public static Member aroundClosurePreInitializationGetter() { - return new Member( + return new MemberImpl( Member.METHOD, AROUND_CLOSURE_TYPE, 0, @@ -450,7 +450,7 @@ public class AjcMemberMaker { UnresolvedType targetType, UnresolvedType[] paramTypes) { - return new ResolvedMember( + return new ResolvedMemberImpl( Member.METHOD, aspectType, PUBLIC_STATIC_FINAL, @@ -464,7 +464,7 @@ public class AjcMemberMaker { UnresolvedType targetType, UnresolvedType[] paramTypes) { - return new ResolvedMember( + return new ResolvedMemberImpl( Member.METHOD, aspectType, PUBLIC_STATIC_FINAL, @@ -480,7 +480,7 @@ public class AjcMemberMaker { // int modifiers) // { ResolvedMember ret = - new ResolvedMember( + new ResolvedMemberImpl( Member.CONSTRUCTOR, targetType, Modifier.PUBLIC, @@ -499,7 +499,7 @@ public class AjcMemberMaker { } public static ResolvedMember interFieldInitializer(ResolvedMember field, UnresolvedType aspectType) { - return new ResolvedMember(Member.METHOD, aspectType, PUBLIC_STATIC, + return new ResolvedMemberImpl(Member.METHOD, aspectType, PUBLIC_STATIC, NameMangler.interFieldInitializer(aspectType, field.getDeclaringType(), field.getName()), field.isStatic() ? "()V" : "(" + field.getDeclaringType().getSignature() + ")V" ); @@ -518,7 +518,7 @@ public class AjcMemberMaker { * This static method goes on the aspect that declares the inter-type field */ public static ResolvedMember interFieldSetDispatcher(ResolvedMember field, UnresolvedType aspectType) { - return new ResolvedMember(Member.METHOD, aspectType, PUBLIC_STATIC, + return new ResolvedMemberImpl(Member.METHOD, aspectType, PUBLIC_STATIC, ResolvedType.VOID, NameMangler.interFieldSetDispatcher(aspectType, field.getDeclaringType(), field.getName()), field.isStatic() ? new UnresolvedType[] {field.getReturnType()} @@ -530,7 +530,7 @@ public class AjcMemberMaker { * This static method goes on the aspect that declares the inter-type field */ public static ResolvedMember interFieldGetDispatcher(ResolvedMember field, UnresolvedType aspectType) { - return new ResolvedMember(Member.METHOD, aspectType, PUBLIC_STATIC, + return new ResolvedMemberImpl(Member.METHOD, aspectType, PUBLIC_STATIC, field.getReturnType(), NameMangler.interFieldGetDispatcher(aspectType, field.getDeclaringType(), field.getName()), field.isStatic() ? UnresolvedType.NONE : new UnresolvedType[] {field.getDeclaringType()}, @@ -552,7 +552,7 @@ public class AjcMemberMaker { * is declared onto */ public static ResolvedMember interFieldClassField(ResolvedMember field, UnresolvedType aspectType) { - return new ResolvedMember(Member.FIELD, field.getDeclaringType(), + return new ResolvedMemberImpl(Member.FIELD, field.getDeclaringType(), makePublicNonFinal(field.getModifiers()), field.getReturnType(), NameMangler.interFieldClassField(field.getModifiers(), aspectType, field.getDeclaringType(), field.getName()), @@ -566,7 +566,7 @@ public class AjcMemberMaker { * is declared onto */ public static ResolvedMember interFieldInterfaceField(ResolvedMember field, UnresolvedType onClass, UnresolvedType aspectType) { - return new ResolvedMember(Member.FIELD, onClass, makePublicNonFinal(field.getModifiers()), + return new ResolvedMemberImpl(Member.FIELD, onClass, makePublicNonFinal(field.getModifiers()), field.getReturnType(), NameMangler.interFieldInterfaceField(aspectType, field.getDeclaringType(), field.getName()), UnresolvedType.NONE, UnresolvedType.NONE @@ -580,7 +580,7 @@ public class AjcMemberMaker { public static ResolvedMember interFieldInterfaceSetter(ResolvedMember field, ResolvedType onType, UnresolvedType aspectType) { int modifiers = Modifier.PUBLIC; if (onType.isInterface()) modifiers |= Modifier.ABSTRACT; - return new ResolvedMember(Member.METHOD, onType, modifiers, + return new ResolvedMemberImpl(Member.METHOD, onType, modifiers, ResolvedType.VOID, NameMangler.interFieldInterfaceSetter(aspectType, field.getDeclaringType(), field.getName()), new UnresolvedType[] {field.getReturnType()}, UnresolvedType.NONE @@ -594,7 +594,7 @@ public class AjcMemberMaker { public static ResolvedMember interFieldInterfaceGetter(ResolvedMember field, ResolvedType onType, UnresolvedType aspectType) { int modifiers = Modifier.PUBLIC; if (onType.isInterface()) modifiers |= Modifier.ABSTRACT; - return new ResolvedMember(Member.METHOD, onType, modifiers, + return new ResolvedMemberImpl(Member.METHOD, onType, modifiers, field.getReturnType(), NameMangler.interFieldInterfaceGetter(aspectType, field.getDeclaringType(), field.getName()), UnresolvedType.NONE, UnresolvedType.NONE @@ -616,7 +616,7 @@ public class AjcMemberMaker { int modifiers = makePublicNonFinal(meth.getModifiers()); if (onInterface) modifiers |= Modifier.ABSTRACT; - return new ResolvedMember(Member.METHOD, meth.getDeclaringType(), + return new ResolvedMemberImpl(Member.METHOD, meth.getDeclaringType(), modifiers, meth.getReturnType(), NameMangler.interMethod(meth.getModifiers(), aspectType, meth.getDeclaringType(), meth.getName()), @@ -634,7 +634,7 @@ public class AjcMemberMaker { paramTypes = UnresolvedType.insert(meth.getDeclaringType(), paramTypes); } - return new ResolvedMember(Member.METHOD, aspectType, PUBLIC_STATIC, + return new ResolvedMemberImpl(Member.METHOD, aspectType, PUBLIC_STATIC, meth.getReturnType(), NameMangler.interMethodDispatcher(aspectType, meth.getDeclaringType(), meth.getName()), paramTypes, meth.getExceptions()); @@ -657,7 +657,7 @@ public class AjcMemberMaker { } - return new ResolvedMember(Member.METHOD, aspectType, modifiers, + return new ResolvedMemberImpl(Member.METHOD, aspectType, modifiers, meth.getReturnType(), NameMangler.interMethodBody(aspectType, meth.getDeclaringType(), meth.getName()), paramTypes, meth.getExceptions()); @@ -670,7 +670,7 @@ public class AjcMemberMaker { UnresolvedType[] params = ret.getParameterTypes(); UnresolvedType[] freshParams = UnresolvedType.add(params, aspectType); - return new ResolvedMember( + return new ResolvedMemberImpl( ret.getKind(), ret.getDeclaringType(), ret.getModifiers(), @@ -682,7 +682,7 @@ public class AjcMemberMaker { public static ResolvedMember toObjectConversionMethod(UnresolvedType fromType) { if (fromType.isPrimitiveType()) { String name = fromType.toString() + "Object"; - return new ResolvedMember( + return new ResolvedMemberImpl( Member.METHOD, CONVERSIONS_TYPE, PUBLIC_STATIC, @@ -697,7 +697,7 @@ public class AjcMemberMaker { // AMC next two lines should not be needed when sig for generic type is changed ResolvedType declaringType = resolvedTypeX; if (declaringType.isRawType()) declaringType = declaringType.getGenericType(); - return new ResolvedMember( + return new ResolvedMemberImpl( Member.CONSTRUCTOR, declaringType, Modifier.PUBLIC, diff --git a/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java b/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java index a57961db9..85dfd3664 100644 --- a/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java +++ b/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java @@ -157,7 +157,7 @@ public class CrosscuttingMembers { typeToExpose = UnresolvedType.forSignature(typeToExpose.getErasureSignature()); } } - ResolvedMember member = new ResolvedMember( + ResolvedMember member = new ResolvedMemberImpl( Member.STATIC_INITIALIZATION, typeToExpose, 0, ResolvedType.VOID, "", UnresolvedType.NONE); addTypeMunger(world.concreteTypeMunger( new PrivilegedAccessMunger(member), inAspect)); diff --git a/weaver/src/org/aspectj/weaver/Member.java b/weaver/src/org/aspectj/weaver/Member.java index d84947505..8cdd3dfe8 100644 --- a/weaver/src/org/aspectj/weaver/Member.java +++ b/weaver/src/org/aspectj/weaver/Member.java @@ -1,5 +1,6 @@ /* ******************************************************************* * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * 2005 Contributors * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Common Public License v1.0 @@ -7,549 +8,18 @@ * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: - * PARC initial implementation + * PARC initial implementation + * AMC extracted as interface * ******************************************************************/ - - package org.aspectj.weaver; import java.io.DataInputStream; import java.io.IOException; -import java.lang.reflect.Modifier; -import java.util.ArrayList; import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; import org.aspectj.util.TypeSafeEnum; -public class Member implements Comparable, AnnotatedElement { - - private final Kind kind; - protected UnresolvedType declaringType; - protected final int modifiers; // protected because ResolvedMember uses it - private final UnresolvedType returnType; - private final String name; - private final UnresolvedType[] parameterTypes; - private final String signature; - private final String declaredSignature; // TODO asc Is this redundant? Is it needed for generics? - private String paramSignature; - - public Member( - Kind kind, - UnresolvedType declaringType, - int modifiers, - String name, - String signature) - { - this.kind = kind; - this.declaringType = declaringType; - this.modifiers = modifiers; - this.name = name; - this.signature = signature; - this.declaredSignature = signature; - if (kind == FIELD) { - this.returnType = UnresolvedType.forSignature(signature); - this.parameterTypes = UnresolvedType.NONE; - } else { - Object[] returnAndParams = signatureToTypes(signature,false); - this.returnType = (UnresolvedType) returnAndParams[0]; - this.parameterTypes = (UnresolvedType[]) returnAndParams[1]; - signature = typesToSignature(returnType,parameterTypes,true); - } - } - - public Member( - Kind kind, - UnresolvedType declaringType, - int modifiers, - UnresolvedType returnType, - String name, - UnresolvedType[] parameterTypes) - { - super(); - this.kind = kind; - this.declaringType = declaringType; - this.modifiers = modifiers; - this.returnType = returnType; - this.name = name; - this.parameterTypes = parameterTypes; - if (kind == FIELD) { - this.signature = returnType.getErasureSignature(); - this.declaredSignature = returnType.getSignature(); - } else { - this.signature = typesToSignature(returnType, parameterTypes,true); - this.declaredSignature = typesToSignature(returnType,parameterTypes,false); - } - } - - public ResolvedMember resolve(World world) { - return world.resolve(this); - } - - // ---- utility methods - - /** returns an Object[] pair of UnresolvedType, UnresolvedType[] representing return type, - * argument types parsed from the JVM bytecode signature of a method. Yes, - * this should actually return a nice statically-typed pair object, but we - * don't have one of those. - * - *
-     *   UnresolvedType.signatureToTypes("()[Z")[0].equals(Type.forSignature("[Z"))
-     *   UnresolvedType.signatureToTypes("(JJ)I")[1]
-     *      .equals(UnresolvedType.forSignatures(new String[] {"J", "J"}))
-     * 
- * - * @param signature the JVM bytecode method signature string we want to break apart - * @return a pair of UnresolvedType, UnresolvedType[] representing the return types and parameter types. - */ - public static String typesToSignature(UnresolvedType returnType, UnresolvedType[] paramTypes, boolean useRawTypes) { - StringBuffer buf = new StringBuffer(); - buf.append("("); - for (int i = 0, len = paramTypes.length; i < len; i++) { - if (paramTypes[i].isParameterizedType() && useRawTypes) buf.append(paramTypes[i].getErasureSignature()); - else buf.append(paramTypes[i].getSignature()); - } - buf.append(")"); - if (returnType.isParameterizedType() && useRawTypes) buf.append(returnType.getErasureSignature()); - else buf.append(returnType.getSignature()); - return buf.toString(); - } - - /** - * Returns "(,...)" - unlike the other typesToSignature - * that also includes the return type, this one just deals with the parameter types. - */ - public static String typesToSignature(UnresolvedType[] paramTypes) { - StringBuffer buf = new StringBuffer(); - buf.append("("); - for(int i=0;i
-     *   UnresolvedType.signatureToTypes("()[Z")[0].equals(Type.forSignature("[Z"))
-     *   UnresolvedType.signatureToTypes("(JJ)I")[1]
-     *      .equals(UnresolvedType.forSignatures(new String[] {"J", "J"}))
-     * 
- * - * @param signature the JVM bytecode method signature string we want to break apart - * @return a pair of UnresolvedType, UnresolvedType[] representing the return types and parameter types. - */ - private static Object[] signatureToTypes(String sig,boolean keepParameterizationInfo) { - List l = new ArrayList(); - int i = 1; - while (true) { - char c = sig.charAt(i); - if (c == ')') break; // break out when the hit the ')' - int start = i; - while (c == '[') c = sig.charAt(++i); - if (c == 'L' || c == 'P') { - int nextSemicolon = sig.indexOf(';',start); - int firstAngly = sig.indexOf('<',start); - if (firstAngly == -1 || firstAngly>nextSemicolon) { - i = nextSemicolon + 1; - l.add(UnresolvedType.forSignature(sig.substring(start, i))); - } else { - // generics generics generics - // Have to skip to the *correct* ';' - boolean endOfSigReached = false; - int posn = firstAngly; - int genericDepth=0; - while (!endOfSigReached) { - switch (sig.charAt(posn)) { - case '<': genericDepth++;break; - case '>': genericDepth--;break; - case ';': if (genericDepth==0) endOfSigReached=true;break; - default: - } - posn++; - } - // posn now points to the correct nextSemicolon :) - i=posn; - String toProcess = null; - toProcess = sig.substring(start,i); - UnresolvedType tx = UnresolvedType.forSignature(toProcess); - l.add(tx); - } - } else if (c=='T') { // assumed 'reference' to a type variable, so just "Tname;" - int nextSemicolon = sig.indexOf(';',start); - String nextbit = sig.substring(start,nextSemicolon); - l.add(UnresolvedType.forSignature(nextbit)); - i=nextSemicolon+1; - } else { - i++; - l.add(UnresolvedType.forSignature(sig.substring(start, i))); - } - } - UnresolvedType[] paramTypes = (UnresolvedType[]) l.toArray(new UnresolvedType[l.size()]); - UnresolvedType returnType = UnresolvedType.forSignature(sig.substring(i+1, sig.length())); - return new Object[] { returnType, paramTypes }; - } - - // ---- factory methods - public static Member field(String declaring, int mods, String name, String signature) { - return field(declaring, mods, UnresolvedType.forSignature(signature), name); - } - public static Member field(UnresolvedType declaring, int mods, String name, UnresolvedType type) { - return new Member(FIELD, declaring, mods, type, name, UnresolvedType.NONE); - } - public static Member method(UnresolvedType declaring, int mods, String name, String signature) { - Object[] pair = signatureToTypes(signature,false); - return method(declaring, mods, (UnresolvedType) pair[0], name, (UnresolvedType[]) pair[1]); - } - public static Member pointcut(UnresolvedType declaring, String name, String signature) { - Object[] pair = signatureToTypes(signature,false); - return pointcut(declaring, 0, (UnresolvedType) pair[0], name, (UnresolvedType[]) pair[1]); - } - - - private static Member field(String declaring, int mods, UnresolvedType ty, String name) { - return new Member( - FIELD, - UnresolvedType.forName(declaring), - mods, - ty, - name, - UnresolvedType.NONE); - } - - public static Member method(UnresolvedType declTy, int mods, UnresolvedType rTy, String name, UnresolvedType[] paramTys) { - return new Member( - //??? this calls a method - name.equals("") ? CONSTRUCTOR : METHOD, - declTy, - mods, - rTy, - name, - paramTys); - } - private static Member pointcut(UnresolvedType declTy, int mods, UnresolvedType rTy, String name, UnresolvedType[] paramTys) { - return new Member( - POINTCUT, - declTy, - mods, - rTy, - name, - paramTys); - } - - public static ResolvedMember makeExceptionHandlerSignature(UnresolvedType inType, UnresolvedType catchType) { - return new ResolvedMember( - HANDLER, - inType, - Modifier.STATIC, - "", - "(" + catchType.getSignature() + ")V"); - } - - // ---- parsing methods - - /** Takes a string in this form: - * - *
-     * static? TypeName TypeName.Id
-     * 
- * Pretty much just for testing, and as such should perhaps be moved. - */ - - public static Member fieldFromString(String str) { - str = str.trim(); - final int len = str.length(); - int i = 0; - int mods = 0; - if (str.startsWith("static", i)) { - mods = Modifier.STATIC; - i += 6; - while (Character.isWhitespace(str.charAt(i))) i++; - } - int start = i; - while (! Character.isWhitespace(str.charAt(i))) i++; - UnresolvedType retTy = UnresolvedType.forName(str.substring(start, i)); - - start = i; - i = str.lastIndexOf('.'); - UnresolvedType declaringTy = UnresolvedType.forName(str.substring(start, i).trim()); - start = ++i; - String name = str.substring(start, len).trim(); - return new Member( - FIELD, - declaringTy, - mods, - retTy, - name, - UnresolvedType.NONE); - } - - /** Takes a string in this form: - * - *
-     * (static|interface|private)? TypeName TypeName . Id ( TypeName , ...)
-     * 
- * Pretty much just for testing, and as such should perhaps be moved. - */ - - public static Member methodFromString(String str) { - str = str.trim(); - // final int len = str.length(); - int i = 0; - - int mods = 0; - if (str.startsWith("static", i)) { - mods = Modifier.STATIC; - i += 6; - } else if (str.startsWith("interface", i)) { - mods = Modifier.INTERFACE; - i += 9; - } else if (str.startsWith("private", i)) { - mods = Modifier.PRIVATE; - i += 7; - } - while (Character.isWhitespace(str.charAt(i))) i++; - - int start = i; - while (! Character.isWhitespace(str.charAt(i))) i++; - UnresolvedType returnTy = UnresolvedType.forName(str.substring(start, i)); - - start = i; - i = str.indexOf('(', i); - i = str.lastIndexOf('.', i); - UnresolvedType declaringTy = UnresolvedType.forName(str.substring(start, i).trim()); - - start = ++i; - i = str.indexOf('(', i); - String name = str.substring(start, i).trim(); - start = ++i; - i = str.indexOf(')', i); - - String[] paramTypeNames = parseIds(str.substring(start, i).trim()); - - return method(declaringTy, mods, returnTy, name, UnresolvedType.forNames(paramTypeNames)); - } - - private static String[] parseIds(String str) { - if (str.length() == 0) return ZERO_STRINGS; - List l = new ArrayList(); - int start = 0; - while (true) { - int i = str.indexOf(',', start); - if (i == -1) { - l.add(str.substring(start).trim()); - break; - } - l.add(str.substring(start, i).trim()); - start = i+1; - } - return (String[]) l.toArray(new String[l.size()]); - } - - private static final String[] ZERO_STRINGS = new String[0]; - - // ---- things we know without resolution - - public boolean equals(Object other) { - if (! (other instanceof Member)) return false; - Member o = (Member) other; - - return (kind == o.kind - && name.equals(o.name) - && signature.equals(o.signature) - && declaringType.equals(o.declaringType)); - } - - public int compareTo(Object other) { - Member o = (Member) other; - - int i = getName().compareTo(o.getName()); - if (i != 0) return i; - return getSignature().compareTo(o.getSignature()); - } - - /** - * Equality is checked based on the underlying signature, so the hash code - * of a member is based on its kind, name, signature, and declaring type. The - * algorithm for this was taken from page 38 of effective java. - */ - private volatile int hashCode = 0; - public int hashCode() { - if (hashCode == 0) { - int result = 17; - result = 37*result + kind.hashCode(); - result = 37*result + name.hashCode(); - result = 37*result + signature.hashCode(); - result = 37*result + declaringType.hashCode(); - hashCode = result; - } - return hashCode; - } - - public String toString() { - StringBuffer buf = new StringBuffer(); - buf.append(returnType.getName()); - buf.append(' '); - buf.append(declaringType.getName()); - buf.append('.'); - buf.append(name); - if (kind != FIELD) { - buf.append("("); - if (parameterTypes.length != 0) { - buf.append(parameterTypes[0]); - for (int i=1, len = parameterTypes.length; i < len; i++) { - buf.append(", "); - buf.append(parameterTypes[i].getName()); - } - } - buf.append(")"); - } - return buf.toString(); - } - - public String toLongString() { - StringBuffer buf = new StringBuffer(); - buf.append(kind); - buf.append(' '); - if (modifiers != 0) { - buf.append(Modifier.toString(modifiers)); - buf.append(' '); - } - buf.append(toString()); - buf.append(" <"); - buf.append(signature); - buf.append(" >"); - return buf.toString(); - } - - public Kind getKind() { return kind; } - public UnresolvedType getDeclaringType() { return declaringType; } - public UnresolvedType getReturnType() { return returnType; } - public UnresolvedType getType() { return returnType; } - public String getName() { return name; } - public UnresolvedType[] getParameterTypes() { return parameterTypes; } - /** - * Return full signature, including return type, e.g. "()LFastCar;" for a signature without the return type, - * use getParameterSignature() - it is importnant to choose the right one in the face of covariance. - */ - public String getSignature() { return signature; } - - /** TODO ASC Should return the non-erased version of the signature... untested */ - public String getDeclaredSignature() { return declaredSignature;} - public int getArity() { return parameterTypes.length; } - - /** - * Return signature without return type, e.g. "()" for a signature *with* the return type, - * use getSignature() - it is important to choose the right one in the face of covariance. - */ - public String getParameterSignature() { - if (paramSignature != null) return paramSignature; - StringBuffer sb = new StringBuffer(); - sb.append("("); - for (int i = 0; i < parameterTypes.length; i++) { - UnresolvedType tx = parameterTypes[i]; - sb.append(tx.getSignature()); - } - sb.append(")"); - paramSignature = sb.toString(); - return paramSignature; - } - - public boolean isCompatibleWith(Member am) { - if (kind != METHOD || am.getKind() != METHOD) return true; - if (! name.equals(am.getName())) return true; - if (! equalTypes(getParameterTypes(), am.getParameterTypes())) return true; - return getReturnType().equals(am.getReturnType()); - } - - private static boolean equalTypes(UnresolvedType[] a, UnresolvedType[] b) { - int len = a.length; - if (len != b.length) return false; - for (int i = 0; i < len; i++) { - if (!a[i].equals(b[i])) return false; - } - return true; - } - - // ---- things we know only with resolution - - public int getModifiers(World world) { - return resolve(world).getModifiers(); - } - - public UnresolvedType[] getExceptions(World world) { - return resolve(world).getExceptions(); - } - - public final boolean isProtected(World world) { - return Modifier.isProtected(resolve(world).getModifiers()); - } - public final boolean isStatic(World world) { - return Modifier.isStatic(resolve(world).getModifiers()); - } - public final boolean isStrict(World world) { - return Modifier.isStrict(resolve(world).getModifiers()); - } - - public final boolean isStatic() { - return Modifier.isStatic(modifiers); - } - - public final boolean isInterface() { - return Modifier.isInterface(modifiers); // this is kinda weird - } - - public final boolean isPrivate() { - return Modifier.isPrivate(modifiers); - } - - /** - * Returns true iff the member is generic (NOT parameterized) - * For example, a method declared in a generic type - */ - public boolean canBeParameterized() { - return false; - } - - public final int getCallsiteModifiers() { - return modifiers & ~ Modifier.INTERFACE; - } - - public final String getExtractableName() { - if (name.equals("")) return "init$"; - else if (name.equals("")) return "clinit$"; - else return name; - } - - /** - * If you want a sensible answer, resolve the member and call - * hasAnnotation() on the ResolvedMember. - */ - public boolean hasAnnotation(UnresolvedType ofType) { - throw new UnsupportedOperationException("You should resolve this member and call hasAnnotation() on the result..."); - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.AnnotatedElement#getAnnotationTypes() - */ - public ResolvedType[] getAnnotationTypes() { - throw new UnsupportedOperationException("You should resolve this member and call hasAnnotation() on the result..."); - } - - public AnnotationX[] getAnnotations() { - throw new UnsupportedOperationException("You should resolve this member and call getAnnotations() on the result..."); - } - - // ---- fields 'n' stuff - - public static final Member[] NONE = new Member[0]; +public interface Member { public static class Kind extends TypeSafeEnum { public Kind(String name, int key) { super(name, key); } @@ -568,310 +38,108 @@ public class Member implements Comparable, AnnotatedElement { throw new BCException("weird kind " + key); } } - - public static final Kind METHOD = new Kind("METHOD", 1); - public static final Kind FIELD = new Kind("FIELD", 2); - public static final Kind CONSTRUCTOR = new Kind("CONSTRUCTOR", 3); - public static final Kind STATIC_INITIALIZATION = new Kind("STATIC_INITIALIZATION", 4); - public static final Kind POINTCUT = new Kind("POINTCUT", 5); - public static final Kind ADVICE = new Kind("ADVICE", 6); - public static final Kind HANDLER = new Kind("HANDLER", 7); - - - -// //ATAJ. Should probably be ajc$, used only for slow impl of Aspects.aspectOf() -// public static final Member ajClassField = new Member( -// FIELD, -// UnresolvedType.OBJECT,//any one -// Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL, -// "aj$class", -// UnresolvedType.JAVA_LANG_CLASS.getSignature() -// ); - - - - public Collection/*ResolvedType*/ getDeclaringTypes(World world) { - ResolvedType myType = getDeclaringType().resolve(world); - Collection ret = new HashSet(); - if (kind == CONSTRUCTOR) { - // this is wrong if the member doesn't exist, but that doesn't matter - ret.add(myType); - } else if (isStatic() || kind == FIELD) { - walkUpStatic(ret, myType); - } else { - walkUp(ret, myType); - } - - return ret; - } - - private boolean walkUp(Collection acc, ResolvedType curr) { - if (acc.contains(curr)) return true; - - boolean b = false; - for (Iterator i = curr.getDirectSupertypes(); i.hasNext(); ) { - b |= walkUp(acc, (ResolvedType)i.next()); - } - - if (!b && curr.isParameterizedType()) { - b = walkUp(acc,curr.getGenericType()); - } - - if (!b) { - b = curr.lookupMemberNoSupers(this) != null; - } - if (b) acc.add(curr); - return b; - } - - private boolean walkUpStatic(Collection acc, ResolvedType curr) { - if (curr.lookupMemberNoSupers(this) != null) { - acc.add(curr); - return true; - } else { - boolean b = false; - for (Iterator i = curr.getDirectSupertypes(); i.hasNext(); ) { - b |= walkUpStatic(acc, (ResolvedType)i.next()); - } - if (!b && curr.isParameterizedType()) { - b = walkUpStatic(acc,curr.getGenericType()); - } - if (b) acc.add(curr); - return b; - } - } - // ---- reflective thisJoinPoint stuff - public String getSignatureMakerName() { - if (getName().equals("")) return "makeInitializerSig"; - - Kind kind = getKind(); - if (kind == METHOD) { - return "makeMethodSig"; - } else if (kind == CONSTRUCTOR) { - return "makeConstructorSig"; - } else if (kind == FIELD) { - return "makeFieldSig"; - } else if (kind == HANDLER) { - return "makeCatchClauseSig"; - } else if (kind == STATIC_INITIALIZATION) { - return "makeInitializerSig"; - } else if (kind == ADVICE) { - return "makeAdviceSig"; - } else { - throw new RuntimeException("unimplemented"); - } - } - - - - - public String getSignatureType() { - Kind kind = getKind(); - if (getName().equals("")) return "org.aspectj.lang.reflect.InitializerSignature"; - - if (kind == METHOD) { - return "org.aspectj.lang.reflect.MethodSignature"; - } else if (kind == CONSTRUCTOR) { - return "org.aspectj.lang.reflect.ConstructorSignature"; - } else if (kind == FIELD) { - return "org.aspectj.lang.reflect.FieldSignature"; - } else if (kind == HANDLER) { - return "org.aspectj.lang.reflect.CatchClauseSignature"; - } else if (kind == STATIC_INITIALIZATION) { - return "org.aspectj.lang.reflect.InitializerSignature"; - } else if (kind == ADVICE) { - return "org.aspectj.lang.reflect.AdviceSignature"; - } else { - throw new RuntimeException("unimplemented"); - } - } + public static final Member[] NONE = new Member[0]; + public static final Kind METHOD = new Kind("METHOD", 1); + public static final Kind FIELD = new Kind("FIELD", 2); + public static final Kind CONSTRUCTOR = new Kind("CONSTRUCTOR", 3); + public static final Kind STATIC_INITIALIZATION = new Kind("STATIC_INITIALIZATION", 4); + public static final Kind POINTCUT = new Kind("POINTCUT", 5); + public static final Kind ADVICE = new Kind("ADVICE", 6); + public static final Kind HANDLER = new Kind("HANDLER", 7); - public String getSignatureString(World world) { - if (getName().equals("")) return getStaticInitializationSignatureString(world); - - Kind kind = getKind(); - if (kind == METHOD) { - return getMethodSignatureString(world); - } else if (kind == CONSTRUCTOR) { - return getConstructorSignatureString(world); - } else if (kind == FIELD) { - return getFieldSignatureString(world); - } else if (kind == HANDLER) { - return getHandlerSignatureString(world); - } else if (kind == STATIC_INITIALIZATION) { - return getStaticInitializationSignatureString(world); - } else if (kind == ADVICE) { - return getAdviceSignatureString(world); - } else { - throw new RuntimeException("unimplemented"); - } - } + public ResolvedMember resolve(World world); - private String getHandlerSignatureString(World world) { - StringBuffer buf = new StringBuffer(); - buf.append(makeString(0)); - buf.append('-'); - //buf.append(getName()); - buf.append('-'); - buf.append(makeString(getDeclaringType())); - buf.append('-'); - buf.append(makeString(getParameterTypes()[0])); - buf.append('-'); - String pName = ""; - String[] names = getParameterNames(world); - if (names != null) pName = names[0]; - buf.append(pName); - buf.append('-'); - return buf.toString(); - } - - private String getStaticInitializationSignatureString(World world) { - StringBuffer buf = new StringBuffer(); - buf.append(makeString(getModifiers(world))); - buf.append('-'); - //buf.append(getName()); - buf.append('-'); - buf.append(makeString(getDeclaringType())); - buf.append('-'); - return buf.toString(); - } - - - - protected String getAdviceSignatureString(World world) { - StringBuffer buf = new StringBuffer(); - buf.append(makeString(getModifiers(world))); - buf.append('-'); - buf.append(getName()); - buf.append('-'); - buf.append(makeString(getDeclaringType())); - buf.append('-'); - buf.append(makeString(getParameterTypes())); - buf.append('-'); - buf.append(makeString(getParameterNames(world))); - buf.append('-'); - buf.append(makeString(getExceptions(world))); - buf.append('-'); - buf.append(makeString(getReturnType())); - buf.append('-'); - return buf.toString(); - } - - - protected String getMethodSignatureString(World world) { - StringBuffer buf = new StringBuffer(); - buf.append(makeString(getModifiers(world))); - buf.append('-'); - buf.append(getName()); - buf.append('-'); - buf.append(makeString(getDeclaringType())); - buf.append('-'); - buf.append(makeString(getParameterTypes())); - buf.append('-'); - buf.append(makeString(getParameterNames(world))); - buf.append('-'); - buf.append(makeString(getExceptions(world))); - buf.append('-'); - buf.append(makeString(getReturnType())); - buf.append('-'); - return buf.toString(); - } - + public int compareTo(Object other); + public String toLongString(); - protected String getConstructorSignatureString(World world) { - StringBuffer buf = new StringBuffer(); - buf.append(makeString(getModifiers(world))); - buf.append('-'); - buf.append('-'); - buf.append(makeString(getDeclaringType())); - buf.append('-'); - buf.append(makeString(getParameterTypes())); - buf.append('-'); - buf.append(makeString(getParameterNames(world))); - buf.append('-'); - buf.append(makeString(getExceptions(world))); - buf.append('-'); - return buf.toString(); - } + public Kind getKind(); + + public UnresolvedType getDeclaringType(); + + public UnresolvedType getReturnType(); + + public UnresolvedType getType(); + + public String getName(); + + public UnresolvedType[] getParameterTypes(); + + /** + * Return full signature, including return type, e.g. "()LFastCar;" for a signature without the return type, + * use getParameterSignature() - it is importnant to choose the right one in the face of covariance. + */ + public String getSignature(); + /** + * All the signatures that a join point with this member as its signature has. + */ + public JoinPointSignature[] getJoinPointSignatures(World world); + + /** TODO ASC Should return the non-erased version of the signature... untested */ + public String getDeclaredSignature(); + + public int getArity(); + + /** + * Return signature without return type, e.g. "()" for a signature *with* the return type, + * use getSignature() - it is important to choose the right one in the face of covariance. + */ + public String getParameterSignature(); + + public boolean isCompatibleWith(Member am); + + public int getModifiers(World world); + public int getModifiers(); + public UnresolvedType[] getExceptions(World world); - protected String getFieldSignatureString(World world) { - StringBuffer buf = new StringBuffer(); - buf.append(makeString(getModifiers(world))); - buf.append('-'); - buf.append(getName()); - buf.append('-'); - buf.append(makeString(getDeclaringType())); - buf.append('-'); - buf.append(makeString(getReturnType())); - buf.append('-'); - return buf.toString(); - } + public boolean isProtected(World world); - protected String makeString(int i) { - return Integer.toString(i, 16); //??? expensive - } + public boolean isStatic(World world); + public boolean isStrict(World world); + public boolean isStatic(); + public boolean isInterface(); - protected String makeString(UnresolvedType t) { - // this is the inverse of the odd behavior for Class.forName w/ arrays - if (t.isArray()) { - // this behavior matches the string used by the eclipse compiler for Foo.class literals - return t.getSignature().replace('/', '.'); - } else { - return t.getName(); - } - } - + public boolean isPrivate(); + /** + * Returns true iff the member is generic (NOT parameterized) + * For example, a method declared in a generic type + */ + public boolean canBeParameterized(); - protected String makeString(UnresolvedType[] types) { - if (types == null) return ""; - StringBuffer buf = new StringBuffer(); - for (int i = 0, len=types.length; i < len; i++) { - buf.append(makeString(types[i])); - buf.append(':'); - } - return buf.toString(); - } - + public int getCallsiteModifiers(); + public String getExtractableName(); - protected String makeString(String[] names) { - if (names == null) return ""; - StringBuffer buf = new StringBuffer(); - for (int i = 0, len=names.length; i < len; i++) { - buf.append(names[i]); - buf.append(':'); - } - return buf.toString(); - } + /** + * If you want a sensible answer, resolve the member and call + * hasAnnotation() on the ResolvedMember. + */ + public boolean hasAnnotation(UnresolvedType ofType); - public String[] getParameterNames(World world) { - return resolve(world).getParameterNames(); - } - - + /* (non-Javadoc) + * @see org.aspectj.weaver.AnnotatedElement#getAnnotationTypes() + */ + public ResolvedType[] getAnnotationTypes(); - - - - // ---- - + public AnnotationX[] getAnnotations(); - + public Collection/*ResolvedType*/getDeclaringTypes(World world); + + // ---- reflective thisJoinPoint stuff + public String getSignatureMakerName(); + public String getSignatureType(); - - - + public String getSignatureString(World world); + public String[] getParameterNames(World world); -} - +} \ No newline at end of file diff --git a/weaver/src/org/aspectj/weaver/MemberImpl.java b/weaver/src/org/aspectj/weaver/MemberImpl.java new file mode 100644 index 000000000..cf2a16548 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/MemberImpl.java @@ -0,0 +1,922 @@ +/* ******************************************************************* + * 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.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; + + +public class MemberImpl implements Comparable, AnnotatedElement, Member { + + private final Kind kind; + protected UnresolvedType declaringType; + protected final int modifiers; // protected because ResolvedMember uses it + private final UnresolvedType returnType; + private final String name; + private final UnresolvedType[] parameterTypes; + private final String signature; + private final String declaredSignature; // TODO asc Is this redundant? Is it needed for generics? + private String paramSignature; + + /** + * All the signatures that a join point with this member as its signature has. + * The fact that this has to go on MemberImpl and not ResolvedMemberImpl says a lot about + * how broken the Member/ResolvedMember distinction currently is. + */ + private JoinPointSignature[] joinPointSignatures = null; + + public MemberImpl( + Kind kind, + UnresolvedType declaringType, + int modifiers, + String name, + String signature) + { + this.kind = kind; + this.declaringType = declaringType; + this.modifiers = modifiers; + this.name = name; + this.signature = signature; + this.declaredSignature = signature; + if (kind == FIELD) { + this.returnType = UnresolvedType.forSignature(signature); + this.parameterTypes = UnresolvedType.NONE; + } else { + Object[] returnAndParams = signatureToTypes(signature,false); + this.returnType = (UnresolvedType) returnAndParams[0]; + this.parameterTypes = (UnresolvedType[]) returnAndParams[1]; + signature = typesToSignature(returnType,parameterTypes,true); + } + } + + public MemberImpl( + Kind kind, + UnresolvedType declaringType, + int modifiers, + UnresolvedType returnType, + String name, + UnresolvedType[] parameterTypes) + { + super(); + this.kind = kind; + this.declaringType = declaringType; + this.modifiers = modifiers; + this.returnType = returnType; + this.name = name; + this.parameterTypes = parameterTypes; + if (kind == FIELD) { + this.signature = returnType.getErasureSignature(); + this.declaredSignature = returnType.getSignature(); + } else { + this.signature = typesToSignature(returnType, parameterTypes,true); + this.declaredSignature = typesToSignature(returnType,parameterTypes,false); + } + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#resolve(org.aspectj.weaver.World) + */ + public ResolvedMember resolve(World world) { + return world.resolve(this); + } + + // ---- utility methods + + /** returns an Object[] pair of UnresolvedType, UnresolvedType[] representing return type, + * argument types parsed from the JVM bytecode signature of a method. Yes, + * this should actually return a nice statically-typed pair object, but we + * don't have one of those. + * + *
+     *   UnresolvedType.signatureToTypes("()[Z")[0].equals(Type.forSignature("[Z"))
+     *   UnresolvedType.signatureToTypes("(JJ)I")[1]
+     *      .equals(UnresolvedType.forSignatures(new String[] {"J", "J"}))
+     * 
+ * + * @param signature the JVM bytecode method signature string we want to break apart + * @return a pair of UnresolvedType, UnresolvedType[] representing the return types and parameter types. + */ + public static String typesToSignature(UnresolvedType returnType, UnresolvedType[] paramTypes, boolean useRawTypes) { + StringBuffer buf = new StringBuffer(); + buf.append("("); + for (int i = 0, len = paramTypes.length; i < len; i++) { + if (paramTypes[i].isParameterizedType() && useRawTypes) buf.append(paramTypes[i].getErasureSignature()); + else buf.append(paramTypes[i].getSignature()); + } + buf.append(")"); + if (returnType.isParameterizedType() && useRawTypes) buf.append(returnType.getErasureSignature()); + else buf.append(returnType.getSignature()); + return buf.toString(); + } + + /** + * Returns "(,...)" - unlike the other typesToSignature + * that also includes the return type, this one just deals with the parameter types. + */ + public static String typesToSignature(UnresolvedType[] paramTypes) { + StringBuffer buf = new StringBuffer(); + buf.append("("); + for(int i=0;i
+     *   UnresolvedType.signatureToTypes("()[Z")[0].equals(Type.forSignature("[Z"))
+     *   UnresolvedType.signatureToTypes("(JJ)I")[1]
+     *      .equals(UnresolvedType.forSignatures(new String[] {"J", "J"}))
+     * 
+ * + * @param signature the JVM bytecode method signature string we want to break apart + * @return a pair of UnresolvedType, UnresolvedType[] representing the return types and parameter types. + */ + private static Object[] signatureToTypes(String sig,boolean keepParameterizationInfo) { + List l = new ArrayList(); + int i = 1; + while (true) { + char c = sig.charAt(i); + if (c == ')') break; // break out when the hit the ')' + int start = i; + while (c == '[') c = sig.charAt(++i); + if (c == 'L' || c == 'P') { + int nextSemicolon = sig.indexOf(';',start); + int firstAngly = sig.indexOf('<',start); + if (firstAngly == -1 || firstAngly>nextSemicolon) { + i = nextSemicolon + 1; + l.add(UnresolvedType.forSignature(sig.substring(start, i))); + } else { + // generics generics generics + // Have to skip to the *correct* ';' + boolean endOfSigReached = false; + int posn = firstAngly; + int genericDepth=0; + while (!endOfSigReached) { + switch (sig.charAt(posn)) { + case '<': genericDepth++;break; + case '>': genericDepth--;break; + case ';': if (genericDepth==0) endOfSigReached=true;break; + default: + } + posn++; + } + // posn now points to the correct nextSemicolon :) + i=posn; + String toProcess = null; + toProcess = sig.substring(start,i); + UnresolvedType tx = UnresolvedType.forSignature(toProcess); + l.add(tx); + } + } else if (c=='T') { // assumed 'reference' to a type variable, so just "Tname;" + int nextSemicolon = sig.indexOf(';',start); + String nextbit = sig.substring(start,nextSemicolon); + l.add(UnresolvedType.forSignature(nextbit)); + i=nextSemicolon+1; + } else { + i++; + l.add(UnresolvedType.forSignature(sig.substring(start, i))); + } + } + UnresolvedType[] paramTypes = (UnresolvedType[]) l.toArray(new UnresolvedType[l.size()]); + UnresolvedType returnType = UnresolvedType.forSignature(sig.substring(i+1, sig.length())); + return new Object[] { returnType, paramTypes }; + } + + // ---- factory methods + public static MemberImpl field(String declaring, int mods, String name, String signature) { + return field(declaring, mods, UnresolvedType.forSignature(signature), name); + } + public static Member field(UnresolvedType declaring, int mods, String name, UnresolvedType type) { + return new MemberImpl(FIELD, declaring, mods, type, name, UnresolvedType.NONE); + } + public static MemberImpl method(UnresolvedType declaring, int mods, String name, String signature) { + Object[] pair = signatureToTypes(signature,false); + return method(declaring, mods, (UnresolvedType) pair[0], name, (UnresolvedType[]) pair[1]); + } + public static Member pointcut(UnresolvedType declaring, String name, String signature) { + Object[] pair = signatureToTypes(signature,false); + return pointcut(declaring, 0, (UnresolvedType) pair[0], name, (UnresolvedType[]) pair[1]); + } + + + private static MemberImpl field(String declaring, int mods, UnresolvedType ty, String name) { + return new MemberImpl( + FIELD, + UnresolvedType.forName(declaring), + mods, + ty, + name, + UnresolvedType.NONE); + } + + public static MemberImpl method(UnresolvedType declTy, int mods, UnresolvedType rTy, String name, UnresolvedType[] paramTys) { + return new MemberImpl( + //??? this calls a method + name.equals("") ? CONSTRUCTOR : METHOD, + declTy, + mods, + rTy, + name, + paramTys); + } + private static Member pointcut(UnresolvedType declTy, int mods, UnresolvedType rTy, String name, UnresolvedType[] paramTys) { + return new MemberImpl( + POINTCUT, + declTy, + mods, + rTy, + name, + paramTys); + } + + public static ResolvedMemberImpl makeExceptionHandlerSignature(UnresolvedType inType, UnresolvedType catchType) { + return new ResolvedMemberImpl( + HANDLER, + inType, + Modifier.STATIC, + "", + "(" + catchType.getSignature() + ")V"); + } + + // ---- parsing methods + + /** Takes a string in this form: + * + *
+     * static? TypeName TypeName.Id
+     * 
+ * Pretty much just for testing, and as such should perhaps be moved. + */ + + public static MemberImpl fieldFromString(String str) { + str = str.trim(); + final int len = str.length(); + int i = 0; + int mods = 0; + if (str.startsWith("static", i)) { + mods = Modifier.STATIC; + i += 6; + while (Character.isWhitespace(str.charAt(i))) i++; + } + int start = i; + while (! Character.isWhitespace(str.charAt(i))) i++; + UnresolvedType retTy = UnresolvedType.forName(str.substring(start, i)); + + start = i; + i = str.lastIndexOf('.'); + UnresolvedType declaringTy = UnresolvedType.forName(str.substring(start, i).trim()); + start = ++i; + String name = str.substring(start, len).trim(); + return new MemberImpl( + FIELD, + declaringTy, + mods, + retTy, + name, + UnresolvedType.NONE); + } + + /** Takes a string in this form: + * + *
+     * (static|interface|private)? TypeName TypeName . Id ( TypeName , ...)
+     * 
+ * Pretty much just for testing, and as such should perhaps be moved. + */ + + public static Member methodFromString(String str) { + str = str.trim(); + // final int len = str.length(); + int i = 0; + + int mods = 0; + if (str.startsWith("static", i)) { + mods = Modifier.STATIC; + i += 6; + } else if (str.startsWith("interface", i)) { + mods = Modifier.INTERFACE; + i += 9; + } else if (str.startsWith("private", i)) { + mods = Modifier.PRIVATE; + i += 7; + } + while (Character.isWhitespace(str.charAt(i))) i++; + + int start = i; + while (! Character.isWhitespace(str.charAt(i))) i++; + UnresolvedType returnTy = UnresolvedType.forName(str.substring(start, i)); + + start = i; + i = str.indexOf('(', i); + i = str.lastIndexOf('.', i); + UnresolvedType declaringTy = UnresolvedType.forName(str.substring(start, i).trim()); + + start = ++i; + i = str.indexOf('(', i); + String name = str.substring(start, i).trim(); + start = ++i; + i = str.indexOf(')', i); + + String[] paramTypeNames = parseIds(str.substring(start, i).trim()); + + return method(declaringTy, mods, returnTy, name, UnresolvedType.forNames(paramTypeNames)); + } + + private static String[] parseIds(String str) { + if (str.length() == 0) return ZERO_STRINGS; + List l = new ArrayList(); + int start = 0; + while (true) { + int i = str.indexOf(',', start); + if (i == -1) { + l.add(str.substring(start).trim()); + break; + } + l.add(str.substring(start, i).trim()); + start = i+1; + } + return (String[]) l.toArray(new String[l.size()]); + } + + private static final String[] ZERO_STRINGS = new String[0]; + + // ---- things we know without resolution + + public boolean equals(Object other) { + if (! (other instanceof Member)) return false; + Member o = (Member) other; + + return (kind == o.getKind() + && name.equals(o.getName()) + && signature.equals(o.getSignature()) + && declaringType.equals(o.getDeclaringType())); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#compareTo(java.lang.Object) + */ + public int compareTo(Object other) { + Member o = (Member) other; + + int i = getName().compareTo(o.getName()); + if (i != 0) return i; + return getSignature().compareTo(o.getSignature()); + } + + /** + * Equality is checked based on the underlying signature, so the hash code + * of a member is based on its kind, name, signature, and declaring type. The + * algorithm for this was taken from page 38 of effective java. + */ + private volatile int hashCode = 0; + public int hashCode() { + if (hashCode == 0) { + int result = 17; + result = 37*result + kind.hashCode(); + result = 37*result + name.hashCode(); + result = 37*result + signature.hashCode(); + result = 37*result + declaringType.hashCode(); + hashCode = result; + } + return hashCode; + } + + public String toString() { + StringBuffer buf = new StringBuffer(); + buf.append(returnType.getName()); + buf.append(' '); + buf.append(declaringType.getName()); + buf.append('.'); + buf.append(name); + if (kind != FIELD) { + buf.append("("); + if (parameterTypes.length != 0) { + buf.append(parameterTypes[0]); + for (int i=1, len = parameterTypes.length; i < len; i++) { + buf.append(", "); + buf.append(parameterTypes[i].getName()); + } + } + buf.append(")"); + } + return buf.toString(); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#toLongString() + */ + public String toLongString() { + StringBuffer buf = new StringBuffer(); + buf.append(kind); + buf.append(' '); + if (modifiers != 0) { + buf.append(Modifier.toString(modifiers)); + buf.append(' '); + } + buf.append(toString()); + buf.append(" <"); + buf.append(signature); + buf.append(" >"); + return buf.toString(); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getKind() + */ + public Kind getKind() { return kind; } + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getDeclaringType() + */ + public UnresolvedType getDeclaringType() { return declaringType; } + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getReturnType() + */ + public UnresolvedType getReturnType() { return returnType; } + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getType() + */ + public UnresolvedType getType() { return returnType; } + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getName() + */ + public String getName() { return name; } + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getParameterTypes() + */ + public UnresolvedType[] getParameterTypes() { return parameterTypes; } + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getSignature() + */ + public String getSignature() { return signature; } + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getDeclaredSignature() + */ + public String getDeclaredSignature() { return declaredSignature;} + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getArity() + */ + public int getArity() { return parameterTypes.length; } + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getParameterSignature() + */ + public String getParameterSignature() { + if (paramSignature != null) return paramSignature; + StringBuffer sb = new StringBuffer(); + sb.append("("); + for (int i = 0; i < parameterTypes.length; i++) { + UnresolvedType tx = parameterTypes[i]; + sb.append(tx.getSignature()); + } + sb.append(")"); + paramSignature = sb.toString(); + return paramSignature; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#isCompatibleWith(org.aspectj.weaver.Member) + */ + public boolean isCompatibleWith(Member am) { + if (kind != METHOD || am.getKind() != METHOD) return true; + if (! name.equals(am.getName())) return true; + if (! equalTypes(getParameterTypes(), am.getParameterTypes())) return true; + return getReturnType().equals(am.getReturnType()); + } + + private static boolean equalTypes(UnresolvedType[] a, UnresolvedType[] b) { + int len = a.length; + if (len != b.length) return false; + for (int i = 0; i < len; i++) { + if (!a[i].equals(b[i])) return false; + } + return true; + } + + // ---- things we know only with resolution + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getModifiers(org.aspectj.weaver.World) + */ + public int getModifiers(World world) { + return resolve(world).getModifiers(); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getExceptions(org.aspectj.weaver.World) + */ + public UnresolvedType[] getExceptions(World world) { + return resolve(world).getExceptions(); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#isProtected(org.aspectj.weaver.World) + */ + public final boolean isProtected(World world) { + return Modifier.isProtected(resolve(world).getModifiers()); + } + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#isStatic(org.aspectj.weaver.World) + */ + public final boolean isStatic(World world) { + return Modifier.isStatic(resolve(world).getModifiers()); + } + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#isStrict(org.aspectj.weaver.World) + */ + public final boolean isStrict(World world) { + return Modifier.isStrict(resolve(world).getModifiers()); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#isStatic() + */ + public final boolean isStatic() { + return Modifier.isStatic(modifiers); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#isInterface() + */ + public final boolean isInterface() { + return Modifier.isInterface(modifiers); // this is kinda weird + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#isPrivate() + */ + public final boolean isPrivate() { + return Modifier.isPrivate(modifiers); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#canBeParameterized() + */ + public boolean canBeParameterized() { + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getCallsiteModifiers() + */ + public final int getCallsiteModifiers() { + return modifiers & ~ Modifier.INTERFACE; + } + + public int getModifiers() { + return modifiers; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getExtractableName() + */ + public final String getExtractableName() { + if (name.equals("")) return "init$"; + else if (name.equals("")) return "clinit$"; + else return name; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#hasAnnotation(org.aspectj.weaver.UnresolvedType) + */ + public boolean hasAnnotation(UnresolvedType ofType) { + throw new UnsupportedOperationException("You should resolve this member and call hasAnnotation() on the result..."); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.AnnotatedElement#getAnnotationTypes() + */ + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getAnnotationTypes() + */ + public ResolvedType[] getAnnotationTypes() { + throw new UnsupportedOperationException("You should resolve this member and call hasAnnotation() on the result..."); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getAnnotations() + */ + public AnnotationX[] getAnnotations() { + throw new UnsupportedOperationException("You should resolve this member and call getAnnotations() on the result..."); + } + + // ---- fields 'n' stuff + + + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getDeclaringTypes(org.aspectj.weaver.World) + */ + public Collection/*ResolvedType*/ getDeclaringTypes(World world) { + ResolvedType myType = getDeclaringType().resolve(world); + Collection ret = new HashSet(); + if (kind == CONSTRUCTOR) { + // this is wrong if the member doesn't exist, but that doesn't matter + ret.add(myType); + } else if (isStatic() || kind == FIELD) { + walkUpStatic(ret, myType); + } else { + walkUp(ret, myType); + } + + return ret; + } + + private boolean walkUp(Collection acc, ResolvedType curr) { + if (acc.contains(curr)) return true; + + boolean b = false; + for (Iterator i = curr.getDirectSupertypes(); i.hasNext(); ) { + b |= walkUp(acc, (ResolvedType)i.next()); + } + + if (!b && curr.isParameterizedType()) { + b = walkUp(acc,curr.getGenericType()); + } + + if (!b) { + b = curr.lookupMemberNoSupers(this) != null; + } + if (b) acc.add(curr); + return b; + } + + private boolean walkUpStatic(Collection acc, ResolvedType curr) { + if (curr.lookupMemberNoSupers(this) != null) { + acc.add(curr); + return true; + } else { + boolean b = false; + for (Iterator i = curr.getDirectSupertypes(); i.hasNext(); ) { + b |= walkUpStatic(acc, (ResolvedType)i.next()); + } + if (!b && curr.isParameterizedType()) { + b = walkUpStatic(acc,curr.getGenericType()); + } + if (b) acc.add(curr); + return b; + } + } + + // ---- reflective thisJoinPoint stuff + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getSignatureMakerName() + */ + public String getSignatureMakerName() { + if (getName().equals("")) return "makeInitializerSig"; + + Kind kind = getKind(); + if (kind == METHOD) { + return "makeMethodSig"; + } else if (kind == CONSTRUCTOR) { + return "makeConstructorSig"; + } else if (kind == FIELD) { + return "makeFieldSig"; + } else if (kind == HANDLER) { + return "makeCatchClauseSig"; + } else if (kind == STATIC_INITIALIZATION) { + return "makeInitializerSig"; + } else if (kind == ADVICE) { + return "makeAdviceSig"; + } else { + throw new RuntimeException("unimplemented"); + } + } + + + + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getSignatureType() + */ + public String getSignatureType() { + Kind kind = getKind(); + if (getName().equals("")) return "org.aspectj.lang.reflect.InitializerSignature"; + + if (kind == METHOD) { + return "org.aspectj.lang.reflect.MethodSignature"; + } else if (kind == CONSTRUCTOR) { + return "org.aspectj.lang.reflect.ConstructorSignature"; + } else if (kind == FIELD) { + return "org.aspectj.lang.reflect.FieldSignature"; + } else if (kind == HANDLER) { + return "org.aspectj.lang.reflect.CatchClauseSignature"; + } else if (kind == STATIC_INITIALIZATION) { + return "org.aspectj.lang.reflect.InitializerSignature"; + } else if (kind == ADVICE) { + return "org.aspectj.lang.reflect.AdviceSignature"; + } else { + throw new RuntimeException("unimplemented"); + } + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getSignatureString(org.aspectj.weaver.World) + */ + public String getSignatureString(World world) { + if (getName().equals("")) return getStaticInitializationSignatureString(world); + + Kind kind = getKind(); + if (kind == METHOD) { + return getMethodSignatureString(world); + } else if (kind == CONSTRUCTOR) { + return getConstructorSignatureString(world); + } else if (kind == FIELD) { + return getFieldSignatureString(world); + } else if (kind == HANDLER) { + return getHandlerSignatureString(world); + } else if (kind == STATIC_INITIALIZATION) { + return getStaticInitializationSignatureString(world); + } else if (kind == ADVICE) { + return getAdviceSignatureString(world); + } else { + throw new RuntimeException("unimplemented"); + } + } + + private String getHandlerSignatureString(World world) { + StringBuffer buf = new StringBuffer(); + buf.append(makeString(0)); + buf.append('-'); + //buf.append(getName()); + buf.append('-'); + buf.append(makeString(getDeclaringType())); + buf.append('-'); + buf.append(makeString(getParameterTypes()[0])); + buf.append('-'); + String pName = ""; + String[] names = getParameterNames(world); + if (names != null) pName = names[0]; + buf.append(pName); + buf.append('-'); + return buf.toString(); + } + + private String getStaticInitializationSignatureString(World world) { + StringBuffer buf = new StringBuffer(); + buf.append(makeString(getModifiers(world))); + buf.append('-'); + //buf.append(getName()); + buf.append('-'); + buf.append(makeString(getDeclaringType())); + buf.append('-'); + return buf.toString(); + } + + + + protected String getAdviceSignatureString(World world) { + StringBuffer buf = new StringBuffer(); + buf.append(makeString(getModifiers(world))); + buf.append('-'); + buf.append(getName()); + buf.append('-'); + buf.append(makeString(getDeclaringType())); + buf.append('-'); + buf.append(makeString(getParameterTypes())); + buf.append('-'); + buf.append(makeString(getParameterNames(world))); + buf.append('-'); + buf.append(makeString(getExceptions(world))); + buf.append('-'); + buf.append(makeString(getReturnType())); + buf.append('-'); + return buf.toString(); + } + + + protected String getMethodSignatureString(World world) { + StringBuffer buf = new StringBuffer(); + buf.append(makeString(getModifiers(world))); + buf.append('-'); + buf.append(getName()); + buf.append('-'); + buf.append(makeString(getDeclaringType())); + buf.append('-'); + buf.append(makeString(getParameterTypes())); + buf.append('-'); + buf.append(makeString(getParameterNames(world))); + buf.append('-'); + buf.append(makeString(getExceptions(world))); + buf.append('-'); + buf.append(makeString(getReturnType())); + buf.append('-'); + return buf.toString(); + } + + + + protected String getConstructorSignatureString(World world) { + StringBuffer buf = new StringBuffer(); + buf.append(makeString(getModifiers(world))); + buf.append('-'); + buf.append('-'); + buf.append(makeString(getDeclaringType())); + buf.append('-'); + buf.append(makeString(getParameterTypes())); + buf.append('-'); + buf.append(makeString(getParameterNames(world))); + buf.append('-'); + buf.append(makeString(getExceptions(world))); + buf.append('-'); + return buf.toString(); + } + + + + + protected String getFieldSignatureString(World world) { + StringBuffer buf = new StringBuffer(); + buf.append(makeString(getModifiers(world))); + buf.append('-'); + buf.append(getName()); + buf.append('-'); + buf.append(makeString(getDeclaringType())); + buf.append('-'); + buf.append(makeString(getReturnType())); + buf.append('-'); + return buf.toString(); + } + + protected String makeString(int i) { + return Integer.toString(i, 16); //??? expensive + } + + + + + protected String makeString(UnresolvedType t) { + // this is the inverse of the odd behavior for Class.forName w/ arrays + if (t.isArray()) { + // this behavior matches the string used by the eclipse compiler for Foo.class literals + return t.getSignature().replace('/', '.'); + } else { + return t.getName(); + } + } + + + + protected String makeString(UnresolvedType[] types) { + if (types == null) return ""; + StringBuffer buf = new StringBuffer(); + for (int i = 0, len=types.length; i < len; i++) { + buf.append(makeString(types[i])); + buf.append(':'); + } + return buf.toString(); + } + + + + protected String makeString(String[] names) { + if (names == null) return ""; + StringBuffer buf = new StringBuffer(); + for (int i = 0, len=names.length; i < len; i++) { + buf.append(names[i]); + buf.append(':'); + } + return buf.toString(); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.Member#getParameterNames(org.aspectj.weaver.World) + */ + public String[] getParameterNames(World world) { + return resolve(world).getParameterNames(); + } + + /** + * All the signatures that a join point with this member as its signature has. + */ + public JoinPointSignature[] getJoinPointSignatures(World inAWorld) { + if (joinPointSignatures == null) { + joinPointSignatures = ResolvedMemberImpl.getJoinPointSignatures(this, inAWorld); + } + return joinPointSignatures; + } + +} + diff --git a/weaver/src/org/aspectj/weaver/NewConstructorTypeMunger.java b/weaver/src/org/aspectj/weaver/NewConstructorTypeMunger.java index 08d60789e..e8808f333 100644 --- a/weaver/src/org/aspectj/weaver/NewConstructorTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/NewConstructorTypeMunger.java @@ -54,9 +54,9 @@ public class NewConstructorTypeMunger extends ResolvedTypeMunger { public static ResolvedTypeMunger readConstructor(VersionedDataInputStream s, ISourceContext context) throws IOException { ResolvedTypeMunger munger = new NewConstructorTypeMunger( - ResolvedMember.readResolvedMember(s, context), - ResolvedMember.readResolvedMember(s, context), - ResolvedMember.readResolvedMember(s, context), + ResolvedMemberImpl.readResolvedMember(s, context), + ResolvedMemberImpl.readResolvedMember(s, context), + ResolvedMemberImpl.readResolvedMember(s, context), readSuperMethodsCalled(s)); if (ResolvedTypeMunger.persistSourceLocation) munger.setSourceLocation(readSourceLocation(s)); return munger; diff --git a/weaver/src/org/aspectj/weaver/NewFieldTypeMunger.java b/weaver/src/org/aspectj/weaver/NewFieldTypeMunger.java index 1c82c21c0..a3938ff30 100644 --- a/weaver/src/org/aspectj/weaver/NewFieldTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/NewFieldTypeMunger.java @@ -38,7 +38,7 @@ public class NewFieldTypeMunger extends ResolvedTypeMunger { public static ResolvedTypeMunger readField(VersionedDataInputStream s, ISourceContext context) throws IOException { ResolvedTypeMunger munger = new NewFieldTypeMunger( - ResolvedMember.readResolvedMember(s, context), + ResolvedMemberImpl.readResolvedMember(s, context), readSuperMethodsCalled(s)); if (ResolvedTypeMunger.persistSourceLocation) munger.setSourceLocation(readSourceLocation(s)); return munger; diff --git a/weaver/src/org/aspectj/weaver/NewMethodTypeMunger.java b/weaver/src/org/aspectj/weaver/NewMethodTypeMunger.java index 31543895f..961cec9c1 100644 --- a/weaver/src/org/aspectj/weaver/NewMethodTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/NewMethodTypeMunger.java @@ -44,7 +44,7 @@ public class NewMethodTypeMunger extends ResolvedTypeMunger { public static ResolvedTypeMunger readMethod(VersionedDataInputStream s, ISourceContext context) throws IOException { ResolvedTypeMunger munger = new NewMethodTypeMunger( - ResolvedMember.readResolvedMember(s, context), + ResolvedMemberImpl.readResolvedMember(s, context), readSuperMethodsCalled(s)); if (ResolvedTypeMunger.persistSourceLocation) munger.setSourceLocation(readSourceLocation(s)); return munger; diff --git a/weaver/src/org/aspectj/weaver/ResolvedMember.java b/weaver/src/org/aspectj/weaver/ResolvedMember.java index 15b8252ad..6fd6c0a7c 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedMember.java +++ b/weaver/src/org/aspectj/weaver/ResolvedMember.java @@ -1,5 +1,6 @@ /* ******************************************************************* * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * 2005 Contributors * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Common Public License v1.0 @@ -7,418 +8,112 @@ * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: - * PARC initial implementation + * PARC initial implementation + * AMC extracted as interface * ******************************************************************/ - - package org.aspectj.weaver; import java.io.DataOutputStream; import java.io.IOException; -import java.lang.reflect.Modifier; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; import org.aspectj.bridge.ISourceLocation; -/** - * This is the declared member, i.e. it will always correspond to an - * actual method/... declaration - */ -public class ResolvedMember extends Member implements IHasPosition, AnnotatedElement, TypeVariableDeclaringElement { - - public String[] parameterNames = null; - protected UnresolvedType[] checkedExceptions = UnresolvedType.NONE; - /** - * if this member is a parameterized version of a member in a generic type, - * then this field holds a reference to the member we parameterize. - */ - protected ResolvedMember backingGenericMember = null; - private Set annotationTypes = null; - // Some members are 'created' to represent other things (for example ITDs). These - // members have their annotations stored elsewhere, and this flag indicates that is - // the case. It is up to the caller to work out where that is! - // Once determined the caller may choose to stash the annotations in this member... - private boolean isAnnotatedElsewhere = false; // this field is not serialized. - private boolean isAjSynthetic = true; - - // generic methods have type variables - private UnresolvedType[] typeVariables; - - // these three fields hold the source location of this member - protected int start, end; - protected ISourceContext sourceContext = null; - - //XXX deprecate this in favor of the constructor below - public ResolvedMember( - Kind kind, - UnresolvedType declaringType, - int modifiers, - UnresolvedType returnType, - String name, - UnresolvedType[] parameterTypes) - { - super(kind, declaringType, modifiers, returnType, name, parameterTypes); - } - - - - public ResolvedMember( - Kind kind, - UnresolvedType declaringType, - int modifiers, - UnresolvedType returnType, - String name, - UnresolvedType[] parameterTypes, - UnresolvedType[] checkedExceptions) - { - super(kind, declaringType, modifiers, returnType, name, parameterTypes); - this.checkedExceptions = checkedExceptions; - } - - public ResolvedMember( - Kind kind, - UnresolvedType declaringType, - int modifiers, - UnresolvedType returnType, - String name, - UnresolvedType[] parameterTypes, - UnresolvedType[] checkedExceptions, - ResolvedMember backingGenericMember) - { - this(kind, declaringType, modifiers, returnType, name, parameterTypes,checkedExceptions); - this.backingGenericMember = backingGenericMember; - this.isAjSynthetic = backingGenericMember.isAjSynthetic(); - } - - public ResolvedMember( - Kind kind, - UnresolvedType declaringType, - int modifiers, - String name, - String signature) - { - super(kind, declaringType, modifiers, name, signature); - } - - public static final ResolvedMember[] NONE = new ResolvedMember[0]; - - // ---- - - public final int getModifiers(World world) { - return modifiers; - } - public final int getModifiers() { - return modifiers; - } - - // ---- - - - public final UnresolvedType[] getExceptions(World world) { - return getExceptions(); - } - - public UnresolvedType[] getExceptions() { - return checkedExceptions; - } - - public ShadowMunger getAssociatedShadowMunger() { - return null; - } - - // ??? true or false? - public boolean isAjSynthetic() { - return isAjSynthetic; - } - - public boolean hasAnnotations() { - return (annotationTypes==null); - } - - public boolean hasAnnotation(UnresolvedType ofType) { - // The ctors don't allow annotations to be specified ... yet - but - // that doesn't mean it is an error to call this method. - // Normally the weaver will be working with subtypes of - // this type - BcelField/BcelMethod - if (annotationTypes==null) return false; - return annotationTypes.contains(ofType); - } - - public ResolvedType[] getAnnotationTypes() { - // The ctors don't allow annotations to be specified ... yet - but - // that doesn't mean it is an error to call this method. - // Normally the weaver will be working with subtypes of - // this type - BcelField/BcelMethod - if (annotationTypes == null) return null; - return (ResolvedType[])annotationTypes.toArray(new ResolvedType[]{}); - } - - public void setAnnotationTypes(UnresolvedType[] annotationtypes) { - if (annotationTypes == null) annotationTypes = new HashSet(); - for (int i = 0; i < annotationtypes.length; i++) { - UnresolvedType typeX = annotationtypes[i]; - annotationTypes.add(typeX); - } - } - - public void addAnnotation(AnnotationX annotation) { - // FIXME asc only allows for annotation types, not instances - should it? - if (annotationTypes == null) annotationTypes = new HashSet(); - annotationTypes.add(annotation.getSignature()); - } - - public boolean isBridgeMethod() { - return (modifiers & Constants.ACC_BRIDGE)!=0; - } - - public boolean isVarargsMethod() { - return (modifiers & Constants.ACC_VARARGS)!=0; - } - - public boolean isSynthetic() { - return false; - } - - public void write(DataOutputStream s) throws IOException { - getKind().write(s); - getDeclaringType().write(s); - s.writeInt(modifiers); - s.writeUTF(getName()); - s.writeUTF(getSignature()); - UnresolvedType.writeArray(getExceptions(), s); - - s.writeInt(getStart()); - s.writeInt(getEnd()); - - // Write out any type variables... - if (typeVariables==null) { - s.writeInt(0); - } else { - s.writeInt(typeVariables.length); - for (int i = 0; i < typeVariables.length; i++) { - typeVariables[i].write(s); - } - } - } - - public static void writeArray(ResolvedMember[] members, DataOutputStream s) throws IOException { - s.writeInt(members.length); - for (int i = 0, len = members.length; i < len; i++) { - members[i].write(s); - } - } - - - public static ResolvedMember readResolvedMember(VersionedDataInputStream s, ISourceContext sourceContext) throws IOException { - ResolvedMember m = new ResolvedMember(Kind.read(s), UnresolvedType.read(s), s.readInt(), s.readUTF(), s.readUTF()); - m.checkedExceptions = UnresolvedType.readArray(s); - - m.start = s.readInt(); - m.end = s.readInt(); - m.sourceContext = sourceContext; - - // Read in the type variables... - if (s.getMajorVersion()>=AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) { - int tvcount = s.readInt(); - if (tvcount!=0) { - m.typeVariables = new UnresolvedType[tvcount]; - for (int i=0;i will turn into List (for example), // but if !isParameterized List will turn into List. - public ResolvedMember parameterizedWith(UnresolvedType[] typeParameters,ResolvedType newDeclaringType, boolean isParameterized) { - if (!this.getDeclaringType().isGenericType()) { - throw new IllegalStateException("Can't ask to parameterize a member of a non-generic type"); - } - TypeVariable[] typeVariables = getDeclaringType().getTypeVariables(); - if (typeVariables.length != typeParameters.length) { - throw new IllegalStateException("Wrong number of type parameters supplied"); - } - Map typeMap = new HashMap(); - for (int i = 0; i < typeVariables.length; i++) { - typeMap.put(typeVariables[i].getName(), typeParameters[i]); - } - UnresolvedType parameterizedReturnType = parameterize(getGenericReturnType(),typeMap,isParameterized); - UnresolvedType[] parameterizedParameterTypes = new UnresolvedType[getGenericParameterTypes().length]; - for (int i = 0; i < parameterizedParameterTypes.length; i++) { - parameterizedParameterTypes[i] = - parameterize(getGenericParameterTypes()[i], typeMap,isParameterized); - } - return new ResolvedMember( - getKind(), - newDeclaringType, - getModifiers(), - parameterizedReturnType, - getName(), - parameterizedParameterTypes, - getExceptions(), - this - ); - } - - - public void setTypeVariables(UnresolvedType[] types) { - typeVariables = types; - } - - public UnresolvedType[] getTypeVariables() { - return typeVariables; - } - - private UnresolvedType parameterize(UnresolvedType aType, Map typeVariableMap, boolean inParameterizedType) { - if (aType instanceof TypeVariableReferenceType) { - String variableName = ((TypeVariableReferenceType)aType).getTypeVariable().getName(); - if (!typeVariableMap.containsKey(variableName)) { - return aType; // if the type variable comes from the method (and not the type) thats OK - } - return (UnresolvedType) typeVariableMap.get(variableName); - } else if (aType.isParameterizedType()) { - if (inParameterizedType) { - return aType.parameterize(typeVariableMap); - } else { - return aType.getRawType(); - } - } - return aType; - } - - + public ResolvedMemberImpl parameterizedWith( + UnresolvedType[] typeParameters, ResolvedType newDeclaringType, + boolean isParameterized); + + public void setTypeVariables(UnresolvedType[] types); + + public UnresolvedType[] getTypeVariables(); + /** * If this member is defined by a parameterized super-type, return the erasure * of that member. @@ -432,34 +127,13 @@ public class ResolvedMember extends Member implements IHasPosition, AnnotatedEle * variable. * A type is a supertype of itself. */ - public ResolvedMember getErasure() { - if (calculatedMyErasure) return myErasure; - calculatedMyErasure = true; - ResolvedType resolvedDeclaringType = (ResolvedType) getDeclaringType(); - // this next test is fast, and the result is cached. - if (!resolvedDeclaringType.hasParameterizedSuperType()) { - return null; - } else { - // we have one or more parameterized super types. - // this member may be defined by one of them... we need to find out. - Collection declaringTypes = this.getDeclaringTypes(resolvedDeclaringType.getWorld()); - for (Iterator iter = declaringTypes.iterator(); iter.hasNext();) { - ResolvedType aDeclaringType = (ResolvedType) iter.next(); - if (aDeclaringType.isParameterizedType()) { - // we've found the (a?) parameterized type that defines this member. - // now get the erasure of it - ResolvedMember matchingMember = aDeclaringType.lookupMemberNoSupers(this); - if (matchingMember != null && matchingMember.backingGenericMember != null) { - myErasure = matchingMember.backingGenericMember; - return myErasure; - } - } - } - } - return null; - } - - private ResolvedMember myErasure = null; - private boolean calculatedMyErasure = false; -} - + public ResolvedMember getErasure(); + + /** + * Returns true if this member matches the other. The matching takes into account + * name and parameter types only. When comparing parameter types, we allow any type + * variable to match any other type variable regardless of bounds. + */ + public boolean matches(ResolvedMember aCandidateMatch); + +} \ No newline at end of file diff --git a/weaver/src/org/aspectj/weaver/ResolvedPointcutDefinition.java b/weaver/src/org/aspectj/weaver/ResolvedPointcutDefinition.java index dab7a281a..382a95bcf 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedPointcutDefinition.java +++ b/weaver/src/org/aspectj/weaver/ResolvedPointcutDefinition.java @@ -19,7 +19,7 @@ import java.io.IOException; import org.aspectj.weaver.patterns.Pointcut; -public class ResolvedPointcutDefinition extends ResolvedMember { +public class ResolvedPointcutDefinition extends ResolvedMemberImpl { private Pointcut pointcut; public ResolvedPointcutDefinition( diff --git a/weaver/src/org/aspectj/weaver/ResolvedType.java b/weaver/src/org/aspectj/weaver/ResolvedType.java index e592f59f5..a8b942c94 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedType.java +++ b/weaver/src/org/aspectj/weaver/ResolvedType.java @@ -234,22 +234,32 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl * on the superinterfaces. The getMethods() call above doesn't quite work the same as it will (through the iterator) return methods * declared on *this* class twice, once at the start and once at the end - I couldn't debug that problem, so created this alternative. */ - public List getMethodsWithoutIterator() { + public List getMethodsWithoutIterator(boolean includeITDs) { List methods = new ArrayList(); Set knowninterfaces = new HashSet(); - addAndRecurse(knowninterfaces,methods,this); + addAndRecurse(knowninterfaces,methods,this,includeITDs); return methods; } - private void addAndRecurse(Set knowninterfaces,List collector, ResolvedType rtx) { + private void addAndRecurse(Set knowninterfaces,List collector, ResolvedType rtx, boolean includeITDs) { collector.addAll(Arrays.asList(rtx.getDeclaredMethods())); // Add the methods declared on this type - if (!rtx.equals(ResolvedType.OBJECT)) addAndRecurse(knowninterfaces,collector,rtx.getSuperclass()); // Recurse if we aren't at the top + // now add all the inter-typed members too + if (includeITDs && rtx.interTypeMungers != null) { + for (Iterator i = interTypeMungers.iterator(); i.hasNext();) { + ConcreteTypeMunger tm = (ConcreteTypeMunger) i.next(); + ResolvedMember rm = tm.getSignature(); + if (rm != null) { // new parent type munger can have null signature... + collector.add(tm.getSignature()); + } + } + } + if (!rtx.equals(ResolvedType.OBJECT)) addAndRecurse(knowninterfaces,collector,rtx.getSuperclass(),includeITDs); // Recurse if we aren't at the top ResolvedType[] interfaces = rtx.getDeclaredInterfaces(); // Go through the interfaces on the way back down for (int i = 0; i < interfaces.length; i++) { ResolvedType iface = interfaces[i]; if (!knowninterfaces.contains(iface)) { // Dont do interfaces more than once knowninterfaces.add(iface); - addAndRecurse(knowninterfaces,collector,iface); + addAndRecurse(knowninterfaces,collector,iface,includeITDs); } } } @@ -302,12 +312,39 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl private ResolvedMember lookupMember(Member m, ResolvedMember[] a) { for (int i = 0; i < a.length; i++) { ResolvedMember f = a[i]; - if (matches(f, m)) return f; + if (matches(f, m)) return f; } return null; } + /** + * Looks for the first member in the hierarchy matching aMember. This method + * differs from lookupMember(Member) in that it takes into account parameters + * which are type variables - which clearly an unresolved Member cannot do since + * it does not know anything about type variables. + */ + public ResolvedMember lookupResolvedMember(ResolvedMember aMember) { + Iterator toSearch = null; + ResolvedMember found = null; + if ((aMember.getKind() == Member.METHOD) || (aMember.getKind() == Member.CONSTRUCTOR)) { + toSearch = getMethodsWithoutIterator(true).iterator(); + } else { + if (aMember.getKind() != Member.FIELD) + throw new IllegalStateException("I didn't know you would look for members of kind " + aMember.getKind()); + toSearch = getFields(); + } + while(toSearch.hasNext()) { + ResolvedMemberImpl candidate = (ResolvedMemberImpl) toSearch.next(); + if (candidate.matches(aMember)) { + found = candidate; + break; + } + } + + return found; + } + public static boolean matches(Member m1, Member m2) { if (m1 == null) return m2 == null; if (m2 == null) return false; @@ -1459,6 +1496,14 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl return parameterizedSuperTypes.length > 0; } + public boolean hasGenericSuperType() { + ResolvedType[] superTypes = getDeclaredInterfaces(); + for (int i = 0; i < superTypes.length; i++) { + if (superTypes[i].isGenericType()) return true; + } + return false; + } + private ResolvedType[] parameterizedSuperTypes = null; /** * Similar to the above method, but accumulates the super types diff --git a/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java b/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java index cb1de23a4..c3bfaa34a 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java @@ -127,7 +127,7 @@ public abstract class ResolvedTypeMunger { Set ret = new HashSet(); int n = s.readInt(); for (int i=0; i < n; i++) { - ret.add(ResolvedMember.readResolvedMember(s, null)); + ret.add(ResolvedMemberImpl.readResolvedMember(s, null)); } return ret; } diff --git a/weaver/src/org/aspectj/weaver/WeaverMessages.java b/weaver/src/org/aspectj/weaver/WeaverMessages.java index 00d40632d..a186a3691 100644 --- a/weaver/src/org/aspectj/weaver/WeaverMessages.java +++ b/weaver/src/org/aspectj/weaver/WeaverMessages.java @@ -138,6 +138,7 @@ public class WeaverMessages { public static final String GET_AND_SET_DONT_SUPPORT_DEC_TYPE_PARAMETERS="noParameterizedTypesInGetAndSet"; public static final String NO_INIT_JPS_FOR_PARAMETERIZED_TYPES = "noInitJPsForParameterizedTypes"; public static final String NO_GENERIC_THROWABLES = "noGenericThrowables"; + public static final String WITHINCODE_DOESNT_SUPPORT_PARAMETERIZED_DECLARING_TYPES="noParameterizedDeclaringTypesWithinCode"; public static String format(String key) { return bundle.getString(key); diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelAccessForInlineMunger.java b/weaver/src/org/aspectj/weaver/bcel/BcelAccessForInlineMunger.java index df4a06cea..a94b73a5d 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelAccessForInlineMunger.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelAccessForInlineMunger.java @@ -151,7 +151,7 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger { ResolvedType callee = m_aspectGen.getWorld().resolve(UnresolvedType.forName(invoke.getClassName(cpg))); // look in the whole method list and not just declared for super calls and alike - List methods = callee.getMethodsWithoutIterator(); + List methods = callee.getMethodsWithoutIterator(false); for (Iterator iter = methods.iterator(); iter.hasNext();) { ResolvedMember resolvedMember = (ResolvedMember) iter.next(); if (invoke.getName(cpg).equals(resolvedMember.getName()) diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java index 53f8e38be..c10b2f16d 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java @@ -1435,7 +1435,7 @@ class BcelClassWeaver implements IClassWeaver { InstructionHandle prevHandle = ih.getPrev(); Instruction prevI = prevHandle.getInstruction(); if (Utility.isConstantPushInstruction(prevI)) { - Member field = BcelWorld.makeFieldSignature(clazz, (FieldInstruction) i); + Member field = BcelWorld.makeFieldJoinPointSignature(clazz, (FieldInstruction) i); ResolvedMember resolvedField = field.resolve(world); if (resolvedField == null) { // we can't find the field, so it's not a join point. @@ -1519,7 +1519,7 @@ class BcelClassWeaver implements IClassWeaver { BcelShadow enclosingShadow, List shadowAccumulator) { FieldInstruction fi = (FieldInstruction) ih.getInstruction(); - Member field = BcelWorld.makeFieldSignature(clazz, fi); + Member field = BcelWorld.makeFieldJoinPointSignature(clazz, fi); // synthetic fields are never join points if (field.getName().startsWith(NameMangler.PREFIX)) return; @@ -1546,7 +1546,7 @@ class BcelClassWeaver implements IClassWeaver { private void matchGetInstruction(LazyMethodGen mg, InstructionHandle ih, BcelShadow enclosingShadow, List shadowAccumulator) { FieldInstruction fi = (FieldInstruction) ih.getInstruction(); - Member field = BcelWorld.makeFieldSignature(clazz, fi); + Member field = BcelWorld.makeFieldJoinPointSignature(clazz, fi); // synthetic fields are never join points if (field.getName().startsWith(NameMangler.PREFIX)) return; @@ -1621,15 +1621,15 @@ class BcelClassWeaver implements IClassWeaver { { String methodName = invoke.getName(cpg); if (methodName.startsWith(NameMangler.PREFIX)) { - Member method = - world.makeMethodSignature(clazz, invoke); - ResolvedMember declaredSig = method.resolve(world); + Member jpSig = + world.makeJoinPointSignatureForMethodInvocation(clazz, invoke); + ResolvedMember declaredSig = jpSig.resolve(world); //System.err.println(method + ", declaredSig: " +declaredSig); if (declaredSig == null) return; if (declaredSig.getKind() == Member.FIELD) { Shadow.Kind kind; - if (method.getReturnType().equals(ResolvedType.VOID)) { + if (jpSig.getReturnType().equals(ResolvedType.VOID)) { kind = Shadow.FieldSet; } else { kind = Shadow.FieldGet; diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelField.java b/weaver/src/org/aspectj/weaver/bcel/BcelField.java index eff031abc..f8b9451d8 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelField.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelField.java @@ -13,6 +13,7 @@ package org.aspectj.weaver.bcel; +import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -25,17 +26,16 @@ import org.aspectj.apache.bcel.classfile.annotation.Annotation; import org.aspectj.weaver.AjAttribute; import org.aspectj.weaver.AnnotationX; import org.aspectj.weaver.BCException; -import org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedMemberImpl; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.World; -final class BcelField extends ResolvedMember { +final class BcelField extends ResolvedMemberImpl { private Field field; private boolean isAjSynthetic; private boolean isSynthetic = false; - private ResolvedType[] annotationTypes; private AnnotationX[] annotations; private World world; private BcelObjectType bcelObjectType; @@ -90,28 +90,30 @@ final class BcelField extends ResolvedMember { } public boolean hasAnnotation(UnresolvedType ofType) { - Annotation[] anns = field.getAnnotations(); - for (int i = 0; i < anns.length; i++) { - Annotation annotation = anns[i]; - if (annotation.getTypeName().equals(ofType.getName())) return true; + ensureAnnotationTypesRetrieved(); + for (Iterator iter = annotationTypes.iterator(); iter.hasNext();) { + ResolvedType aType = (ResolvedType) iter.next(); + if (aType.equals(ofType)) return true; } return false; } public ResolvedType[] getAnnotationTypes() { ensureAnnotationTypesRetrieved(); - return annotationTypes; + ResolvedType[] ret = new ResolvedType[annotationTypes.size()]; + annotationTypes.toArray(ret); + return ret; } private void ensureAnnotationTypesRetrieved() { if (annotationTypes == null) { Annotation annos[] = field.getAnnotations(); - annotationTypes = new ResolvedType[annos.length]; + annotationTypes = new HashSet(); annotations = new AnnotationX[annos.length]; for (int i = 0; i < annos.length; i++) { Annotation annotation = annos[i]; ResolvedType rtx = world.resolve(UnresolvedType.forName(annotation.getTypeName())); - annotationTypes[i] = rtx; + annotationTypes.add(rtx); annotations[i] = new AnnotationX(annotation,world); } } @@ -127,11 +129,7 @@ final class BcelField extends ResolvedMember { annotations = ret; // Add it to the set of annotation types - len = annotationTypes.length; - ResolvedType[] ret2 = new ResolvedType[len+1]; - System.arraycopy(annotationTypes,0,ret2,0,len); - ret2[len] =world.resolve(UnresolvedType.forName(annotation.getTypeName())); - annotationTypes = ret2; + annotationTypes.add(UnresolvedType.forName(annotation.getTypeName()).resolve(world)); // FIXME asc this call here suggests we are managing the annotations at // too many levels, here in BcelField we keep a set and in the lower 'field' // object we keep a set - we should think about reducing this to one diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java b/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java index 140de2ea0..e38b6fae8 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java @@ -14,6 +14,7 @@ package org.aspectj.weaver.bcel; import java.lang.reflect.Modifier; +import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -31,21 +32,21 @@ import org.aspectj.weaver.AjAttribute; import org.aspectj.weaver.AnnotationX; import org.aspectj.weaver.BCException; import org.aspectj.weaver.ISourceContext; -import org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedMemberImpl; import org.aspectj.weaver.ResolvedPointcutDefinition; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.ShadowMunger; import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.World; -final class BcelMethod extends ResolvedMember { +final class BcelMethod extends ResolvedMemberImpl { private Method method; private boolean isAjSynthetic; private ShadowMunger associatedShadowMunger; private ResolvedPointcutDefinition preResolvedPointcut; // used when ajc has pre-resolved the pointcut of some @Advice - private ResolvedType[] annotationTypes = null; +// private ResolvedType[] annotationTypes = null; private AnnotationX[] annotations = null; private AjAttribute.EffectiveSignatureAttribute effectiveSignature; @@ -185,9 +186,9 @@ final class BcelMethod extends ResolvedMember { public boolean hasAnnotation(UnresolvedType ofType) { ensureAnnotationTypesRetrieved(); - for (int i=0; i", "([Ljava/lang/Object;)V"); @@ -2546,7 +2547,7 @@ public class BcelShadow extends Shadow { closureInstantiation.append(Utility.createInvoke( getFactory(), getWorld(), - new Member( + new MemberImpl( Member.METHOD, UnresolvedType.forName("org.aspectj.runtime.internal.AroundClosure"), Modifier.PUBLIC, diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java index 790cefee0..8ea410091 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java @@ -47,9 +47,9 @@ import org.aspectj.weaver.NewFieldTypeMunger; import org.aspectj.weaver.NewMethodTypeMunger; import org.aspectj.weaver.NewParentTypeMunger; import org.aspectj.weaver.PerObjectInterfaceTypeMunger; +import org.aspectj.weaver.ResolvedMember; //import org.aspectj.weaver.PerTypeWithinTargetTypeMunger; import org.aspectj.weaver.PrivilegedAccessMunger; -import org.aspectj.weaver.ResolvedMember; import org.aspectj.weaver.ResolvedTypeMunger; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.UnresolvedType; @@ -178,7 +178,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { cont = enforceDecpRule1_abstractMethodsImplemented(weaver, munger.getSourceLocation(),newParentTarget, newParent); cont = enforceDecpRule2_cantExtendFinalClass(weaver,munger.getSourceLocation(),newParentTarget,newParent) && cont; - List methods = newParent.getMethodsWithoutIterator(); + List methods = newParent.getMethodsWithoutIterator(false); for (Iterator iter = methods.iterator(); iter.hasNext();) { ResolvedMember superMethod = (ResolvedMember) iter.next(); if (!superMethod.getName().equals("")) { @@ -209,12 +209,12 @@ public class BcelTypeMunger extends ConcreteTypeMunger { private boolean enforceDecpRule1_abstractMethodsImplemented(BcelClassWeaver weaver, ISourceLocation mungerLoc,LazyClassGen newParentTarget, ResolvedType newParent) { boolean ruleCheckingSucceeded = true; if (!(newParentTarget.isAbstract() || newParentTarget.isInterface())) { // Ignore abstract classes or interfaces - List methods = newParent.getMethodsWithoutIterator(); + List methods = newParent.getMethodsWithoutIterator(false); for (Iterator i = methods.iterator(); i.hasNext();) { ResolvedMember o = (ResolvedMember)i.next(); if (o.isAbstract() && !o.getName().startsWith("ajc$interField")) { // Ignore abstract methods of ajc$interField prefixed methods ResolvedMember discoveredImpl = null; - List newParentTargetMethods = newParentTarget.getType().getMethodsWithoutIterator(); + List newParentTargetMethods = newParentTarget.getType().getMethodsWithoutIterator(false); for (Iterator ii = newParentTargetMethods.iterator(); ii.hasNext() && discoveredImpl==null;) { ResolvedMember gen2 = (ResolvedMember) ii.next(); if (gen2.getName().equals(o.getName()) && diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java b/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java index 3cb228677..cc6454f20 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java @@ -44,9 +44,11 @@ import org.aspectj.weaver.AjAttribute; import org.aspectj.weaver.ConcreteTypeMunger; import org.aspectj.weaver.ICrossReferenceHandler; import org.aspectj.weaver.Member; +import org.aspectj.weaver.MemberImpl; import org.aspectj.weaver.ReferenceType; import org.aspectj.weaver.ReferenceTypeDelegate; import org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedMemberImpl; import org.aspectj.weaver.ResolvedTypeMunger; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.UnresolvedType; @@ -158,7 +160,7 @@ public class BcelWorld extends World implements Repository { start = ++i; i = str.indexOf("->", i); Pointcut pointcut = Pointcut.fromString(str.substring(start, i).trim()); - Member m = Member.methodFromString(str.substring(i+2, str.length()).trim()); + Member m = MemberImpl.methodFromString(str.substring(i+2, str.length()).trim()); // now, we resolve UnresolvedType[] types = m.getParameterTypes(); @@ -298,37 +300,36 @@ public class BcelWorld extends World implements Repository { typeMap.remove(ty.getSignature()); } - public static Member makeFieldSignature(LazyClassGen cg, FieldInstruction fi) { + public static Member makeFieldJoinPointSignature(LazyClassGen cg, FieldInstruction fi) { ConstantPoolGen cpg = cg.getConstantPoolGen(); - return - Member.field( - fi.getClassName(cpg), - (fi instanceof GETSTATIC || fi instanceof PUTSTATIC) - ? Modifier.STATIC - : 0, - fi.getName(cpg), - fi.getSignature(cpg)); + return + MemberImpl.field( + fi.getClassName(cpg), + (fi instanceof GETSTATIC || fi instanceof PUTSTATIC) + ? Modifier.STATIC: 0, + fi.getName(cpg), + fi.getSignature(cpg)); } - public static Member makeFieldSetSignature(LazyClassGen cg, FieldInstruction fi) { - ConstantPoolGen cpg = cg.getConstantPoolGen(); - return - Member.field( - fi.getClassName(cpg), - (fi instanceof GETSTATIC || fi instanceof PUTSTATIC) - ? Modifier.STATIC - : 0, - fi.getName(cpg), - "(" + fi.getSignature(cpg) + ")" +fi.getSignature(cpg)); - } - - public Member makeMethodSignature(LazyMethodGen mg) { - return makeMethodSignature(mg, null); +// public static Member makeFieldSetSignature(LazyClassGen cg, FieldInstruction fi) { +// ConstantPoolGen cpg = cg.getConstantPoolGen(); +// return +// MemberImpl.field( +// fi.getClassName(cpg), +// (fi instanceof GETSTATIC || fi instanceof PUTSTATIC) +// ? Modifier.STATIC +// : 0, +// fi.getName(cpg), +// "(" + fi.getSignature(cpg) + ")" +fi.getSignature(cpg)); +// } + + public Member makeJoinPointSignature(LazyMethodGen mg) { + return makeJoinPointSignatureFromMethod(mg, null); } - public Member makeMethodSignature(LazyMethodGen mg, Member.Kind kind) { - ResolvedMember ret = mg.getMemberView(); + public Member makeJoinPointSignatureFromMethod(LazyMethodGen mg, MemberImpl.Kind kind) { + Member ret = mg.getMemberView(); if (ret == null) { int mods = mg.getAccessFlags(); if (mg.getEnclosingClass().isInterface()) { @@ -343,7 +344,7 @@ public class BcelWorld extends World implements Repository { kind = Member.METHOD; } } - return new ResolvedMember(kind, + return new ResolvedMemberImpl(kind, UnresolvedType.forName(mg.getClassName()), mods, fromBcel(mg.getReturnType()), @@ -356,7 +357,7 @@ public class BcelWorld extends World implements Repository { } - public Member makeMethodSignature(LazyClassGen cg, InvokeInstruction ii) { + public Member makeJoinPointSignatureForMethodInvocation(LazyClassGen cg, InvokeInstruction ii) { ConstantPoolGen cpg = cg.getConstantPoolGen(); String declaring = ii.getClassName(cpg); String name = ii.getName(cpg); @@ -391,7 +392,7 @@ public class BcelWorld extends World implements Repository { } //FIXME if not found we ll end up again with the bug.. can this happen? - return Member.method(UnresolvedType.forName(declaring), modifier, name, signature); + return MemberImpl.method(UnresolvedType.forName(declaring), modifier, name, signature); } public static Member makeMungerMethodSignature(JavaClass javaClass, Method method) { @@ -399,7 +400,7 @@ public class BcelWorld extends World implements Repository { if (method.isStatic()) mods = Modifier.STATIC; else if (javaClass.isInterface()) mods = Modifier.INTERFACE; else if (method.isPrivate()) mods = Modifier.PRIVATE; - return Member.method( + return MemberImpl.method( UnresolvedType.forName(javaClass.getClassName()), mods, method.getName(), method.getSignature()); } diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java index 2bf207c97..7c63a0575 100644 --- a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java +++ b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java @@ -67,6 +67,7 @@ import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.WeaverMessages; import org.aspectj.weaver.WeaverStateInfo; import org.aspectj.weaver.World; +import org.aspectj.weaver.AjAttribute.WeaverVersionInfo; /** * Lazy lazy lazy. @@ -706,7 +707,7 @@ public final class LazyClassGen { LazyMethodGen gen = (LazyMethodGen) iter.next(); // we skip empty clinits if (isEmptyClinit(gen)) continue; - gen.print(out); + gen.print(out, (myType != null ? myType.getWeaverVersionAttribute() : WeaverVersionInfo.UNKNOWN)); if (iter.hasNext()) out.println(); } // out.println(" ATTRIBS: " + Arrays.asList(myGen.getAttributes())); diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java index 47af560ce..2c647f0d3 100644 --- a/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java +++ b/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java @@ -57,10 +57,11 @@ import org.aspectj.weaver.AjAttribute; import org.aspectj.weaver.AnnotationX; import org.aspectj.weaver.BCException; import org.aspectj.weaver.ISourceContext; -import org.aspectj.weaver.Member; +import org.aspectj.weaver.MemberImpl; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.WeaverMessages; +import org.aspectj.weaver.AjAttribute.WeaverVersionInfo; /** @@ -419,7 +420,8 @@ public final class LazyMethodGen { // ============================= public String toString() { - return toLongString(); + WeaverVersionInfo weaverVersion = enclosingClass.getBcelObjectType().getWeaverVersionAttribute(); + return toLongString(weaverVersion); } public String toShortString() { @@ -470,19 +472,19 @@ public final class LazyMethodGen { return buf.toString(); } - public String toLongString() { + public String toLongString(WeaverVersionInfo weaverVersion) { ByteArrayOutputStream s = new ByteArrayOutputStream(); - print(new PrintStream(s)); + print(new PrintStream(s),weaverVersion); return new String(s.toByteArray()); } - public void print() { - print(System.out); + public void print(WeaverVersionInfo weaverVersion) { + print(System.out,weaverVersion); } - public void print(PrintStream out) { + public void print(PrintStream out, WeaverVersionInfo weaverVersion) { out.print(" " + toShortString()); - printAspectAttributes(out); + printAspectAttributes(out,weaverVersion); InstructionList body = getBody(); if (body == null) { @@ -495,12 +497,12 @@ public final class LazyMethodGen { } - private void printAspectAttributes(PrintStream out) { + private void printAspectAttributes(PrintStream out, WeaverVersionInfo weaverVersion) { ISourceContext context = null; if (enclosingClass != null && enclosingClass.getType() != null) { context = enclosingClass.getType().getSourceContext(); } - List as = BcelAttributes.readAjAttributes(getClassName(),attributes, context,null,AjAttribute.WeaverVersionInfo.UNKNOWN); + List as = BcelAttributes.readAjAttributes(getClassName(),attributes, context,null,weaverVersion); if (! as.isEmpty()) { out.println(" " + as.get(0)); // XXX assuming exactly one attribute, munger... } @@ -1359,13 +1361,13 @@ public final class LazyMethodGen { public String getSignature() { if (memberView!=null) return memberView.getSignature(); - return Member.typesToSignature(BcelWorld.fromBcel(getReturnType()), + return MemberImpl.typesToSignature(BcelWorld.fromBcel(getReturnType()), BcelWorld.fromBcel(getArgumentTypes()),false); } public String getParameterSignature() { if (memberView!=null) return memberView.getParameterSignature(); - return Member.typesToSignature(BcelWorld.fromBcel(getArgumentTypes())); + return MemberImpl.typesToSignature(BcelWorld.fromBcel(getArgumentTypes())); } public BcelMethod getMemberView() { diff --git a/weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java b/weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java index 3f269e11a..c1edb4b68 100644 --- a/weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java @@ -31,6 +31,7 @@ import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.IntMap; import org.aspectj.weaver.Member; import org.aspectj.weaver.NameMangler; +import org.aspectj.weaver.ResolvedMemberImpl; import org.aspectj.weaver.ResolvedMember; import org.aspectj.weaver.ResolvedPointcutDefinition; import org.aspectj.weaver.ResolvedType; @@ -236,7 +237,7 @@ public class CflowPointcut extends Pointcut { } else { // Create a counter field in the aspect - localCflowField = new ResolvedMember(Member.FIELD,concreteAspect,Modifier.STATIC | Modifier.PUBLIC | Modifier.FINAL, + localCflowField = new ResolvedMemberImpl(Member.FIELD,concreteAspect,Modifier.STATIC | Modifier.PUBLIC | Modifier.FINAL, NameMangler.cflowCounter(xcut),UnresolvedType.forName(NameMangler.CFLOW_COUNTER_TYPE).getSignature()); // Create type munger to add field to the aspect @@ -275,7 +276,7 @@ public class CflowPointcut extends Pointcut { localCflowField = (ResolvedMember)field; } else { - localCflowField = new ResolvedMember( + localCflowField = new ResolvedMemberImpl( Member.FIELD, concreteAspect, Modifier.STATIC | Modifier.PUBLIC | Modifier.FINAL, NameMangler.cflowStack(xcut), UnresolvedType.forName(NameMangler.CFLOW_STACK_TYPE).getSignature()); diff --git a/weaver/src/org/aspectj/weaver/patterns/ConcreteCflowPointcut.java b/weaver/src/org/aspectj/weaver/patterns/ConcreteCflowPointcut.java index f74061285..88a6c5860 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ConcreteCflowPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/ConcreteCflowPointcut.java @@ -22,6 +22,7 @@ import java.util.Set; import org.aspectj.util.FuzzyBoolean; import org.aspectj.weaver.IntMap; import org.aspectj.weaver.Member; +import org.aspectj.weaver.MemberImpl; import org.aspectj.weaver.NameMangler; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.Shadow; @@ -134,10 +135,10 @@ public class ConcreteCflowPointcut extends Pointcut { } private static final Member cflowStackIsValidMethod = - Member.method(UnresolvedType.forName(NameMangler.CFLOW_STACK_TYPE), 0, "isValid", "()Z"); + MemberImpl.method(UnresolvedType.forName(NameMangler.CFLOW_STACK_TYPE), 0, "isValid", "()Z"); private static final Member cflowCounterIsValidMethod = - Member.method(UnresolvedType.forName(NameMangler.CFLOW_COUNTER_TYPE), 0, "isValid", "()Z"); + MemberImpl.method(UnresolvedType.forName(NameMangler.CFLOW_COUNTER_TYPE), 0, "isValid", "()Z"); public Pointcut concretize1(ResolvedType inAspect, IntMap bindings) { diff --git a/weaver/src/org/aspectj/weaver/patterns/IfPointcut.java b/weaver/src/org/aspectj/weaver/patterns/IfPointcut.java index 3fcf629a0..c0e5abbdf 100644 --- a/weaver/src/org/aspectj/weaver/patterns/IfPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/IfPointcut.java @@ -27,6 +27,7 @@ import org.aspectj.weaver.Advice; import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.IntMap; import org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedMemberImpl; import org.aspectj.weaver.ResolvedPointcutDefinition; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.Shadow; @@ -126,7 +127,7 @@ public class IfPointcut extends Pointcut { } public static Pointcut read(VersionedDataInputStream s, ISourceContext context) throws IOException { //FIXME Adrian, read may failt if testMethod happens to be null for @style if() from JDT stuff - IfPointcut ret = new IfPointcut(ResolvedMember.readResolvedMember(s, context), s.readByte()); + IfPointcut ret = new IfPointcut(ResolvedMemberImpl.readResolvedMember(s, context), s.readByte()); ret.readLocation(context, s); return ret; } diff --git a/weaver/src/org/aspectj/weaver/patterns/PerCflow.java b/weaver/src/org/aspectj/weaver/patterns/PerCflow.java index 06ebc4214..0c723baed 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerCflow.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerCflow.java @@ -28,7 +28,7 @@ import org.aspectj.weaver.CrosscuttingMembers; import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.Member; import org.aspectj.weaver.NameMangler; -import org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedMemberImpl; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.Shadow; import org.aspectj.weaver.UnresolvedType; @@ -88,7 +88,7 @@ public class PerCflow extends PerClause { ret.inAspect = inAspect; if (inAspect.isAbstract()) return ret; - Member cflowStackField = new ResolvedMember( + Member cflowStackField = new ResolvedMemberImpl( Member.FIELD, inAspect, Modifier.STATIC|Modifier.PUBLIC|Modifier.FINAL, UnresolvedType.forName(NameMangler.CFLOW_STACK_TYPE), NameMangler.PERCFLOW_FIELD_NAME, UnresolvedType.NONE); diff --git a/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java b/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java index aa13f6726..b1aad6e3b 100644 --- a/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java @@ -33,6 +33,7 @@ import org.aspectj.weaver.AjAttribute; import org.aspectj.weaver.AjcMemberMaker; import org.aspectj.weaver.Constants; import org.aspectj.weaver.ISourceContext; +import org.aspectj.weaver.JoinPointSignature; import org.aspectj.weaver.Member; import org.aspectj.weaver.NameMangler; import org.aspectj.weaver.NewFieldTypeMunger; @@ -120,14 +121,159 @@ public class SignaturePattern extends PatternNode { } } - public boolean matches(Member member, World world) { - return (matchesIgnoringAnnotations(member,world) && - matchesAnnotations(member,world)); + public boolean matches(Member joinPointSignature, World world) { + // fail (or succeed!) fast tests... + if (joinPointSignature == null) return false; + if (kind != joinPointSignature.getKind()) return false; + if (kind == Member.ADVICE) return true; + + // do the hard work then... + JoinPointSignature[] candidateMatches = joinPointSignature.getJoinPointSignatures(world); + for (int i = 0; i < candidateMatches.length; i++) { + if (matchesExactly(candidateMatches[i],world)) return true; + } + return false; + } + + // Does this pattern match this exact signature (no declaring type mucking about + // or chasing up the hierarchy) + private boolean matchesExactly(JoinPointSignature aMember, World inAWorld) { + // Java5 introduces bridge methods, we don't want to match on them at all... + if (aMember.isBridgeMethod()) { + return false; + } + + if (!modifiers.matches(aMember.getModifiers())) return false; + + boolean matchesIgnoringAnnotations = true; + if (kind == Member.STATIC_INITIALIZATION) { + matchesIgnoringAnnotations = matchesExactlyStaticInitialization(aMember, inAWorld); + } else if (kind == Member.FIELD) { + matchesIgnoringAnnotations = matchesExactlyField(aMember,inAWorld); + } else if (kind == Member.METHOD) { + matchesIgnoringAnnotations = matchesExactlyMethod(aMember,inAWorld); + } else if (kind == Member.CONSTRUCTOR) { + matchesIgnoringAnnotations = matchesExactlyConstructor(aMember, inAWorld); + } + if (!matchesIgnoringAnnotations) return false; + + return matchesAnnotations(aMember, inAWorld); + } + + /** + * Matches on declaring type + */ + private boolean matchesExactlyStaticInitialization(JoinPointSignature aMember,World world) { + return declaringType.matchesStatically(aMember.getDeclaringType().resolve(world)); + } + + /** + * Matches on name, declaring type, field type + */ + private boolean matchesExactlyField(JoinPointSignature aField, World world) { + if (!name.matches(aField.getName())) return false; + if (!declaringType.matchesStatically(aField.getDeclaringType().resolve(world))) return false; + if (!returnType.matchesStatically(aField.getReturnType().resolve(world))) { + // looking bad, but there might be parameterization to consider... + if (!returnType.matchesStatically(aField.getGenericReturnType().resolve(world))) { + // ok, it's bad. + return false; + } + } + // passed all the guards... + return true; } - public boolean matchesAnnotations(Member member,World world) { - ResolvedMember rMember = member.resolve(world); - if (rMember == null) { + /** + * Matches on name, declaring type, return type, parameter types, throws types + */ + private boolean matchesExactlyMethod(JoinPointSignature aMethod, World world) { + if (!name.matches(aMethod.getName())) return false; + if (!declaringType.matchesStatically(aMethod.getDeclaringType().resolve(world))) return false; + if (!returnType.matchesStatically(aMethod.getReturnType().resolve(world))) { + // looking bad, but there might be parameterization to consider... + if (!returnType.matchesStatically(aMethod.getGenericReturnType().resolve(world))) { + // ok, it's bad. + return false; + } + } + ResolvedType[] resolvedParameters = world.resolve(aMethod.getParameterTypes()); + if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC).alwaysTrue()) { + // It could still be a match based on the generic sig parameter types of a parameterized type + if (!parameterTypes.matches(world.resolve(aMethod.getGenericParameterTypes()),TypePattern.STATIC).alwaysTrue()) { + return false; + // It could STILL be a match based on the erasure of the parameter types?? + // to be determined via test cases... + } + } + + // check that varargs specifications match + if (!matchesVarArgs(aMethod,world)) return false; + + // Check the throws pattern + if (!throwsPattern.matches(aMethod.getExceptions(), world)) return false; + + // passed all the guards.. + return true; + } + + /** + * match on declaring type, parameter types, throws types + */ + private boolean matchesExactlyConstructor(JoinPointSignature aConstructor, World world) { + if (!declaringType.matchesStatically(aConstructor.getDeclaringType().resolve(world))) return false; + + ResolvedType[] resolvedParameters = world.resolve(aConstructor.getParameterTypes()); + if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC).alwaysTrue()) { + // It could still be a match based on the generic sig parameter types of a parameterized type + if (!parameterTypes.matches(world.resolve(aConstructor.getGenericParameterTypes()),TypePattern.STATIC).alwaysTrue()) { + return false; + // It could STILL be a match based on the erasure of the parameter types?? + // to be determined via test cases... + } + } + + // check that varargs specifications match + if (!matchesVarArgs(aConstructor,world)) return false; + + // Check the throws pattern + if (!throwsPattern.matches(aConstructor.getExceptions(), world)) return false; + + // passed all the guards.. + return true; + } + + /** + * We've matched against this method or constructor so far, but without considering + * varargs (which has been matched as a simple array thus far). Now we do the additional + * checks to see if the parties agree on whether the last parameter is varargs or a + * straight array. + */ + private boolean matchesVarArgs(JoinPointSignature aMethodOrConstructor, World inAWorld) { + if (parameterTypes.size() == 0) return true; + + TypePattern lastPattern = parameterTypes.get(parameterTypes.size()-1); + boolean canMatchVarArgsSignature = lastPattern.isStar() || + lastPattern.isVarArgs() || + (lastPattern == TypePattern.ELLIPSIS); + + if (aMethodOrConstructor.isVarargsMethod()) { + // we have at least one parameter in the pattern list, and the method has a varargs signature + if (!canMatchVarArgsSignature) { + // XXX - Ideally the shadow would be included in the msg but we don't know it... + inAWorld.getLint().cantMatchArrayTypeOnVarargs.signal(aMethodOrConstructor.toString(),getSourceLocation()); + return false; + } + } else { + // the method ends with an array type, check that we don't *require* a varargs + if (lastPattern.isVarArgs()) return false; + } + + return true; + } + + private boolean matchesAnnotations(ResolvedMember member,World world) { + if (member == null) { if (member.getName().startsWith(NameMangler.PREFIX)) { return false; } @@ -141,10 +287,10 @@ public class SignaturePattern extends PatternNode { // fake members represent ITD'd fields - for their annotations we should go and look up the // relevant member in the original aspect - if (rMember.isAnnotatedElsewhere() && member.getKind()==Member.FIELD) { + if (member.isAnnotatedElsewhere() && member.getKind()==Member.FIELD) { // FIXME asc duplicate of code in AnnotationPattern.matchInternal()? same fixmes apply here. - ResolvedMember [] mems = rMember.getDeclaringType().resolve(world).getDeclaredFields(); // FIXME asc should include supers with getInterTypeMungersIncludingSupers? - List mungers = rMember.getDeclaringType().resolve(world).getInterTypeMungers(); + ResolvedMember [] mems = member.getDeclaringType().resolve(world).getDeclaredFields(); // FIXME asc should include supers with getInterTypeMungersIncludingSupers? + List mungers = member.getDeclaringType().resolve(world).getInterTypeMungers(); for (Iterator iter = mungers.iterator(); iter.hasNext();) { BcelTypeMunger typeMunger = (BcelTypeMunger) iter.next(); if (typeMunger.getMunger() instanceof NewFieldTypeMunger) { @@ -152,13 +298,13 @@ public class SignaturePattern extends PatternNode { ResolvedMember ajcMethod = AjcMemberMaker.interFieldInitializer(fakerm,typeMunger.getAspectType()); ResolvedMember rmm = findMethod(typeMunger.getAspectType(),ajcMethod); if (fakerm.equals(member)) { - rMember = rmm; + member = rmm; } } } } - return annotationPattern.matches(rMember).alwaysTrue(); + return annotationPattern.matches(member).alwaysTrue(); } private ResolvedMember findMethod(ResolvedType aspectType, ResolvedMember ajcMethod) { @@ -168,137 +314,11 @@ public class SignaturePattern extends PatternNode { if (member.equals(ajcMethod)) return member; } return null; - } - - public boolean matchesIgnoringAnnotations(Member member, World world) { - //XXX performance gains would come from matching on name before resolving - // to fail fast. ASC 30th Nov 04 => Not necessarily, it didn't make it faster for me. - // Here is the code I used: - // String n1 = member.getName(); - // String n2 = this.getName().maybeGetSimpleName(); - // if (n2!=null && !n1.equals(n2)) return false; - - if (member == null) return false; - ResolvedMember sig = member.resolve(world); - - if (sig == null) { - //XXX - if (member.getName().startsWith(NameMangler.PREFIX)) { - return false; - } - world.getLint().unresolvableMember.signal(member.toString(), getSourceLocation()); - return false; - } - - // Java5 introduces bridge methods, we don't want to match on them at all... - if (sig.isBridgeMethod()) { - return false; - } - - // This check should only matter when used from WithincodePointcut as KindedPointcut - // has already effectively checked this with the shadows kind. - if (kind != member.getKind()) { - return false; - } - - if (kind == Member.ADVICE) return true; - - if (!modifiers.matches(sig.getModifiers())) return false; - - if (kind == Member.STATIC_INITIALIZATION) { - //System.err.println("match static init: " + sig.getDeclaringType() + " with " + this); - return declaringType.matchesStatically(sig.getDeclaringType().resolve(world)); - } else if (kind == Member.FIELD) { - - if (!returnType.matchesStatically(sig.getReturnType().resolve(world))) { - // looking bad, but there might be parameterization to consider... - if (!returnType.matchesStatically(sig.getGenericReturnType().resolve(world))) { - // ok, it's bad. - return false; - } - } - if (!name.matches(sig.getName())) return false; - boolean ret = declaringTypeMatch(member.getDeclaringType(), member, world); - //System.out.println(" ret: " + ret); - return ret; - } else if (kind == Member.METHOD) { - // Change all this in the face of covariance... - - // Check the name - if (!name.matches(sig.getName())) return false; - - // Check the parameters - // AMC parameterized types make this more complex. Suppose I have a - // type that implements a parameterized interface. It might declare a method - // foo(Double). If foo is defined in I and the type implements I, - // then the signature pattern I.foo(Object) (the erasure) *should* match. - // But [Object] does not match [Double] so we have some work to do... - ResolvedType[] resolvedParameters = world.resolve(sig.getParameterTypes()); - if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC).alwaysTrue()) { - // It could still be a match based on the erasure of a parameterized type - // method in our hierarchy - this is only allowed if the declaring type pattern - // is raw. - // We need to find out as cheaply as possible. - if (declaringType.getTypeParameters().size() > 0) return false; - ResolvedMember sigErasure = sig.getErasure(); - if (sigErasure != null) { - ResolvedType[] erasureParameters = world.resolve(sigErasure.getParameterTypes()); - if (!parameterTypes.matches(erasureParameters,TypePattern.STATIC).alwaysTrue()) { - // fail if we don't match the erasure either - return false; - } - } else { - // fail if there is no erasure as the params don't match - // try the true (generic) parameter types then - if (!parameterTypes.matches(world.resolve(sig.getGenericParameterTypes()),TypePattern.STATIC).alwaysTrue()) { - return false; - } - } - } - - // If we have matched on parameters, let's just check it isn't because the last parameter in the pattern - // is an array type and the method is declared with varargs - // XXX - Ideally the shadow would be included in the msg but we don't know it... - if (isNotMatchBecauseOfVarargsIssue(parameterTypes,sig.getModifiers())) { - world.getLint().cantMatchArrayTypeOnVarargs.signal(sig.toString(),getSourceLocation()); - return false; - } - - if (parameterTypes.size()>0 && (sig.isVarargsMethod()^parameterTypes.get(parameterTypes.size()-1).isVarArgs)) - return false; - - // Check the throws pattern - if (!throwsPattern.matches(sig.getExceptions(), world)) return false; - - return declaringTypeMatchAllowingForCovariance(member,world,returnType,sig.getReturnType().resolve(world)); - } else if (kind == Member.CONSTRUCTOR) { - if (!parameterTypes.matches(world.resolve(sig.getParameterTypes()), TypePattern.STATIC).alwaysTrue()) { - // try generic before giving up - if (!parameterTypes.matches(world.resolve(sig.getGenericParameterTypes()), TypePattern.STATIC).alwaysTrue()) { - return false; - } - } - - // If we have matched on parameters, let's just check it isn't because the last parameter in the pattern - // is an array type and the method is declared with varargs - // XXX - Ideally the shadow would be included in the msg but we don't know it... - if (isNotMatchBecauseOfVarargsIssue(parameterTypes,sig.getModifiers())) { - world.getLint().cantMatchArrayTypeOnVarargs.signal(sig.toString(),getSourceLocation()); - return false; - } - - if (!throwsPattern.matches(sig.getExceptions(), world)) return false; - return declaringType.matchesStatically(member.getDeclaringType().resolve(world)); - //return declaringTypeMatch(member.getDeclaringType(), member, world); - } - - return false; } - public boolean declaringTypeMatchAllowingForCovariance(Member member,World world,TypePattern returnTypePattern,ResolvedType sigReturn) { - UnresolvedType onTypeUnresolved = member.getDeclaringType(); + public boolean declaringTypeMatchAllowingForCovariance(Member member, UnresolvedType shadowDeclaringType, World world,TypePattern returnTypePattern,ResolvedType sigReturn) { - ResolvedType onType = onTypeUnresolved.resolve(world); + ResolvedType onType = shadowDeclaringType.resolve(world); // fastmatch if (declaringType.matchesStatically(onType) && returnTypePattern.matchesStatically(sigReturn)) @@ -366,7 +386,7 @@ public class SignaturePattern extends PatternNode { if (!parameterTypes.matches(params, TypePattern.STATIC).alwaysTrue()) { return false; } - if (isNotMatchBecauseOfVarargsIssue(parameterTypes,msig.getModifiers())) { return false; } + if (matchedArrayAgainstVarArgs(parameterTypes,msig.getModifiers())) { return false; } if (!throwsPattern.matches(exceptionTypes)) return false; return declaringTypeMatch(sig); // XXXAJ5 - Need to make this a covariant aware version for dynamic JP matching to work @@ -377,7 +397,7 @@ public class SignaturePattern extends PatternNode { if (!parameterTypes.matches(params, TypePattern.STATIC).alwaysTrue()) { return false; } - if (isNotMatchBecauseOfVarargsIssue(parameterTypes,csig.getModifiers())) { return false; } + if (matchedArrayAgainstVarArgs(parameterTypes,csig.getModifiers())) { return false; } if (!throwsPattern.matches(exceptionTypes)) return false; return declaringType.matchesStatically(sig.getDeclaringType()); @@ -417,7 +437,7 @@ public class SignaturePattern extends PatternNode { if (!parameterTypes.matches(params, TypePattern.STATIC).alwaysTrue()) { return false; } - if (isNotMatchBecauseOfVarargsIssue(parameterTypes,member.getModifiers())) { return false; } + if (matchedArrayAgainstVarArgs(parameterTypes,member.getModifiers())) { return false; } if (!throwsPattern.matches(exceptionTypes)) return false; return declaringTypeMatch(member.getDeclaringClass()); // XXXAJ5 - Need to make this a covariant aware version for dynamic JP matching to work } @@ -429,29 +449,13 @@ public class SignaturePattern extends PatternNode { if (!parameterTypes.matches(params, TypePattern.STATIC).alwaysTrue()) { return false; } - if (isNotMatchBecauseOfVarargsIssue(parameterTypes,member.getModifiers())) { return false; } + if (matchedArrayAgainstVarArgs(parameterTypes,member.getModifiers())) { return false; } if (!throwsPattern.matches(exceptionTypes)) return false; return declaringType.matchesStatically(declaringClass); } return false; } -// For methods, the above covariant aware version (declaringTypeMatchAllowingForCovariance) is used - this version is still here for fields - private boolean declaringTypeMatch(UnresolvedType onTypeUnresolved, Member member, World world) { - ResolvedType onType = onTypeUnresolved.resolve(world); - - // fastmatch - if (declaringType.matchesStatically(onType)) return true; - - Collection declaringTypes = member.getDeclaringTypes(world); - - for (Iterator i = declaringTypes.iterator(); i.hasNext(); ) { - ResolvedType type = (ResolvedType)i.next(); - if (declaringType.matchesStatically(type)) return true; - } - return false; - } - private boolean declaringTypeMatch(Signature sig) { Class onType = sig.getDeclaringType(); if (declaringType.matchesStatically(onType)) return true; @@ -645,7 +649,7 @@ public class SignaturePattern extends PatternNode { * return true if last argument in params is an Object[] but the modifiers say this method * was declared with varargs (Object...). We shouldn't be matching if this is the case. */ - private boolean isNotMatchBecauseOfVarargsIssue(TypePatternList params,int modifiers) { + private boolean matchedArrayAgainstVarArgs(TypePatternList params,int modifiers) { if (params.size()>0 && (modifiers & Constants.ACC_VARARGS)!=0) { // we have at least one parameter in the pattern list, and the method has a varargs signature TypePattern lastPattern = params.get(params.size()-1); diff --git a/weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java b/weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java index 37808a1ce..94e897610 100644 --- a/weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java @@ -19,6 +19,7 @@ import java.lang.reflect.Member; import java.util.HashSet; import java.util.Set; +import org.aspectj.bridge.MessageUtil; import org.aspectj.lang.JoinPoint; import org.aspectj.runtime.reflect.Factory; import org.aspectj.util.FuzzyBoolean; @@ -27,6 +28,7 @@ import org.aspectj.weaver.IntMap; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.Shadow; import org.aspectj.weaver.VersionedDataInputStream; +import org.aspectj.weaver.WeaverMessages; import org.aspectj.weaver.ast.Literal; import org.aspectj.weaver.ast.Test; @@ -108,6 +110,22 @@ public class WithincodePointcut extends Pointcut { public void resolveBindings(IScope scope, Bindings bindings) { signature = signature.resolveBindings(scope, bindings); + + // look for inappropriate use of parameterized types and tell user... + HasThisTypePatternTriedToSneakInSomeGenericOrParameterizedTypePatternMatchingStuffAnywhereVisitor + visitor = new HasThisTypePatternTriedToSneakInSomeGenericOrParameterizedTypePatternMatchingStuffAnywhereVisitor(); + signature.getDeclaringType().traverse(visitor, null); + if (visitor.wellHasItThen/*?*/()) { + scope.message(MessageUtil.error(WeaverMessages.format(WeaverMessages.WITHINCODE_DOESNT_SUPPORT_PARAMETERIZED_DECLARING_TYPES), + getSourceLocation())); + } + + visitor = new HasThisTypePatternTriedToSneakInSomeGenericOrParameterizedTypePatternMatchingStuffAnywhereVisitor(); + signature.getThrowsPattern().traverse(visitor, null); + if (visitor.wellHasItThen/*?*/()) { + scope.message(MessageUtil.error(WeaverMessages.format(WeaverMessages.NO_GENERIC_THROWABLES), + getSourceLocation())); + } } public void resolveBindingsFromRTTI() { diff --git a/weaver/src/org/aspectj/weaver/weaver-messages.properties b/weaver/src/org/aspectj/weaver/weaver-messages.properties index c2a8b29d0..411780e55 100644 --- a/weaver/src/org/aspectj/weaver/weaver-messages.properties +++ b/weaver/src/org/aspectj/weaver/weaver-messages.properties @@ -148,4 +148,5 @@ noParameterizedTypePatternInWithin=parameterized type pattern not supported by ' noParameterizedTypesInThisAndTarget=parameterized types not supported for this and target pointcuts (erasure limitation) noParameterizedTypesInGetAndSet=can't use parameterized type patterns for the declaring type of a get or set pointcut expression (use the raw type instead) noInitJPsForParameterizedTypes=no [pre]initialization join points for parameterized types, use raw type instead -noGenericThrowables=invalid throws pattern: a generic class may not be a direct or indirect subclass of Throwable \ No newline at end of file +noGenericThrowables=invalid throws pattern: a generic class may not be a direct or indirect subclass of Throwable +noParameterizedDeclaringTypesWithinCode=can't use parameterized type patterns for the declaring type of a withincode pointcut expression (use the raw type instead) \ No newline at end of file diff --git a/weaver/testsrc/fluffy/Base.java b/weaver/testsrc/fluffy/Base.java index 9aa148d68..4cdb1f772 100644 --- a/weaver/testsrc/fluffy/Base.java +++ b/weaver/testsrc/fluffy/Base.java @@ -4,6 +4,9 @@ public class Base { public static void onlyBase() {} public static void both() {} + + public void onlyBaseNonStatic() {} + public void bothNonStatic() {} public int onlyBase; public int both; diff --git a/weaver/testsrc/fluffy/Derived.java b/weaver/testsrc/fluffy/Derived.java index 6c38db40e..ad0842c18 100644 --- a/weaver/testsrc/fluffy/Derived.java +++ b/weaver/testsrc/fluffy/Derived.java @@ -7,6 +7,9 @@ public class Derived extends Base { public static void onlyDerived() throws IOException, CloneNotSupportedException {} public static void both() {} + public void onlyDerivedNonStatic() {} + public void bothNonStatic() {} + public int onlyDerived; public int both; diff --git a/weaver/testsrc/org/aspectj/weaver/MemberTestCase.java b/weaver/testsrc/org/aspectj/weaver/MemberTestCase.java index d0b8e7812..cc242c2e4 100644 --- a/weaver/testsrc/org/aspectj/weaver/MemberTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/MemberTestCase.java @@ -30,10 +30,10 @@ public class MemberTestCase extends TestCase { } public void testMethodConstruction() { - Member s = Member.methodFromString("void Foo.goo(int)"); - Member t = Member.method(UnresolvedType.forName("Foo"), 0, "goo", "(I)V"); - Member u = Member.methodFromString("void Foo1.goo(int)"); - Member v = Member.methodFromString("int Foo.goo(int)"); + Member s = MemberImpl.methodFromString("void Foo.goo(int)"); + Member t = MemberImpl.method(UnresolvedType.forName("Foo"), 0, "goo", "(I)V"); + Member u = MemberImpl.methodFromString("void Foo1.goo(int)"); + Member v = MemberImpl.methodFromString("int Foo.goo(int)"); TestUtil.assertCommutativeEquals(s, s, true); TestUtil.assertCommutativeEquals(t, t, true); @@ -46,10 +46,10 @@ public class MemberTestCase extends TestCase { TestUtil.assertCommutativeEquals(t, v, false); TestUtil.assertCommutativeEquals(u, v, false); - s = Member.fieldFromString("int Foo.goo"); - t = Member.field("Foo", 0, "goo", "I"); - u = Member.fieldFromString("int Foo.goo1"); - v = Member.fieldFromString("long Foo.goo"); + s = MemberImpl.fieldFromString("int Foo.goo"); + t = MemberImpl.field("Foo", 0, "goo", "I"); + u = MemberImpl.fieldFromString("int Foo.goo1"); + v = MemberImpl.fieldFromString("long Foo.goo"); TestUtil.assertCommutativeEquals(s, s, true); TestUtil.assertCommutativeEquals(t, t, true); @@ -65,7 +65,7 @@ public class MemberTestCase extends TestCase { public void testMethodContents() { - Member m = Member.methodFromString("void Foo.goo(int)"); + Member m = MemberImpl.methodFromString("void Foo.goo(int)"); kindTest(m, Member.METHOD); declaringTypeTest(m, "Foo"); nameTest(m, "goo"); @@ -76,7 +76,7 @@ public class MemberTestCase extends TestCase { isConstructorTest(m, false); isStaticTest(m, false); - m = Member.methodFromString("interface java.lang.Object java.util.Iterator.next()"); + m = MemberImpl.methodFromString("interface java.lang.Object java.util.Iterator.next()"); kindTest(m, Member.METHOD); declaringTypeTest(m, "java.util.Iterator"); nameTest(m, "next"); @@ -87,7 +87,7 @@ public class MemberTestCase extends TestCase { isConstructorTest(m, false); isStaticTest(m, false); - m = Member.methodFromString("void Foo.(int, java.lang.Object)"); + m = MemberImpl.methodFromString("void Foo.(int, java.lang.Object)"); kindTest(m, Member.CONSTRUCTOR); declaringTypeTest(m, "Foo"); nameTest(m, ""); @@ -98,7 +98,7 @@ public class MemberTestCase extends TestCase { isConstructorTest(m, true); isStaticTest(m, false); - m = Member.methodFromString("private double Foo.sqrt(double)"); + m = MemberImpl.methodFromString("private double Foo.sqrt(double)"); kindTest(m, Member.METHOD); declaringTypeTest(m, "Foo"); nameTest(m, "sqrt"); @@ -109,7 +109,7 @@ public class MemberTestCase extends TestCase { isConstructorTest(m, false); isStaticTest(m, false); - m = Member.methodFromString("static int java.lang.Math.max(int, int)"); + m = MemberImpl.methodFromString("static int java.lang.Math.max(int, int)"); kindTest(m, Member.METHOD); declaringTypeTest(m, "java.lang.Math"); nameTest(m, "max"); @@ -122,7 +122,7 @@ public class MemberTestCase extends TestCase { } public void testFieldContents() { - Member m = Member.fieldFromString("int Foo.goo"); + Member m = MemberImpl.fieldFromString("int Foo.goo"); kindTest(m, Member.FIELD); declaringTypeTest(m, "Foo"); nameTest(m, "goo"); @@ -133,7 +133,7 @@ public class MemberTestCase extends TestCase { isConstructorTest(m, false); isStaticTest(m, false); - m = Member.fieldFromString("static java.util.Iterator goo.Bar.i"); + m = MemberImpl.fieldFromString("static java.util.Iterator goo.Bar.i"); kindTest(m, Member.FIELD); declaringTypeTest(m, "goo.Bar"); nameTest(m, "i"); @@ -169,7 +169,7 @@ public class MemberTestCase extends TestCase { private void declaringTypeTest(Member m, String declaringName) { assertEquals(m + " declared in", UnresolvedType.forName(declaringName), m.getDeclaringType()); } - private void kindTest(Member m, Member.Kind kind) { + private void kindTest(Member m, MemberImpl.Kind kind) { assertEquals(m + " kind", kind, m.getKind()); } diff --git a/weaver/testsrc/org/aspectj/weaver/ResolvedMemberSignaturesTestCase15.java b/weaver/testsrc/org/aspectj/weaver/ResolvedMemberSignaturesTestCase15.java new file mode 100644 index 000000000..95ce63e3f --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/ResolvedMemberSignaturesTestCase15.java @@ -0,0 +1,286 @@ +/* ******************************************************************* + * Copyright (c) 2005 Contributors. + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.weaver; + +import java.lang.reflect.Modifier; + +import org.aspectj.weaver.bcel.BcelWorld; + +import junit.framework.TestCase; + +public class ResolvedMemberSignaturesTestCase15 extends TestCase { + + World world; + UnresolvedType baseType; + UnresolvedType derivedType; + + // STATIC METHODS + + public void testBaseOnlyStaticMethod() { + Member toFind = new MemberImpl(Member.METHOD,baseType, + (Modifier.PUBLIC | Modifier.STATIC), + UnresolvedType.forSignature("V"), + "onlyBase", + new UnresolvedType[0] + ); + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 member",1,foundMembers.length); + assertEquals("Lfluffy/Base;",foundMembers[0].getDeclaringType().getSignature()); + + toFind = new MemberImpl(Member.METHOD,derivedType, + (Modifier.PUBLIC | Modifier.STATIC), + UnresolvedType.forSignature("V"), + "onlyBase", + new UnresolvedType[0] + ); + foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + // this looks odd but we need both because of the way calls to inherited static methods + // are rendered in bytecode when written as obj.foo(); - the bytecode says it is a call + // to obj.getClass().foo() even if the static method is defined in a super type. + assertEquals("found 2 members",2,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + assertEquals("Lfluffy/Base;",foundMembers[1].getDeclaringType().getSignature()); + } + + public void testBothStaticMethod() { + Member toFind = new MemberImpl(Member.METHOD,baseType, + (Modifier.PUBLIC | Modifier.STATIC), + UnresolvedType.forSignature("V"), + "both", + new UnresolvedType[0] + ); + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 member",1,foundMembers.length); + assertEquals("Lfluffy/Base;",foundMembers[0].getDeclaringType().getSignature()); + + toFind = new MemberImpl(Member.METHOD,derivedType, + (Modifier.PUBLIC | Modifier.STATIC), + UnresolvedType.forSignature("V"), + "both", + new UnresolvedType[0] + ); + foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 members",1,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + } + + public void testDerivedStaticMethod() { + Member toFind = new MemberImpl(Member.METHOD,baseType, + (Modifier.PUBLIC | Modifier.STATIC), + UnresolvedType.forSignature("V"), + "onlyDerived", + new UnresolvedType[0] + ); + + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found nothing",0,foundMembers.length); + + toFind = new MemberImpl(Member.METHOD,derivedType, + (Modifier.PUBLIC | Modifier.STATIC), + UnresolvedType.forSignature("V"), + "onlyDerived", + new UnresolvedType[0] + ); + foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 members",1,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + } + + // NON-STATIC METHODS + + public void testBaseOnlyMethod() { + Member toFind = new MemberImpl(Member.METHOD,baseType, + Modifier.PUBLIC, + UnresolvedType.forSignature("V"), + "onlyBaseNonStatic", + new UnresolvedType[0] + ); + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 member",1,foundMembers.length); + assertEquals("Lfluffy/Base;",foundMembers[0].getDeclaringType().getSignature()); + + toFind = new MemberImpl(Member.METHOD,derivedType, + Modifier.PUBLIC, + UnresolvedType.forSignature("V"), + "onlyBaseNonStatic", + new UnresolvedType[0] + ); + foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 2 members",2,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + assertEquals("Lfluffy/Base;",foundMembers[1].getDeclaringType().getSignature()); + + } + + public void testBothMethod() { + Member toFind = new MemberImpl(Member.METHOD,baseType, + Modifier.PUBLIC, + UnresolvedType.forSignature("V"), + "bothNonStatic", + new UnresolvedType[0] + ); + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 member",1,foundMembers.length); + assertEquals("Lfluffy/Base;",foundMembers[0].getDeclaringType().getSignature()); + + toFind = new MemberImpl(Member.METHOD,derivedType, + Modifier.PUBLIC, + UnresolvedType.forSignature("V"), + "bothNonStatic", + new UnresolvedType[0] + ); + foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 2 members",2,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + assertEquals("Lfluffy/Base;",foundMembers[1].getDeclaringType().getSignature()); + } + + public void testDerivedMethod() { + Member toFind = new MemberImpl(Member.METHOD,baseType, + Modifier.PUBLIC, + UnresolvedType.forSignature("V"), + "onlyDerivedNonStatic", + new UnresolvedType[0] + ); + + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found nothing",0,foundMembers.length); + + toFind = new MemberImpl(Member.METHOD,derivedType, + Modifier.PUBLIC, + UnresolvedType.forSignature("V"), + "onlyDerivedNonStatic", + new UnresolvedType[0] + ); + foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 members",1,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + } + + public void testChangingThrowsClause() { + Member toFind = new MemberImpl(Member.METHOD,derivedType, + Modifier.PUBLIC, + UnresolvedType.forSignature("V"), + "m", + new UnresolvedType[0] + ); + + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 2 members",2,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + assertEquals("Lfluffy/Base;",foundMembers[1].getDeclaringType().getSignature()); + + assertEquals("throws CloneNotSupported",1,foundMembers[1].getExceptions().length); + assertEquals("doesn't throw anything",0,foundMembers[0].getExceptions().length); + } + + // CONSTRUCTORS + + public void testNoWalkUpMatchingConstructor() { + Member toFind = new MemberImpl(Member.CONSTRUCTOR,derivedType, + Modifier.PUBLIC, + UnresolvedType.forSignature("V"), + "", + new UnresolvedType[0] + ); + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 members",1,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + } + + public void testNoWalkUpNoMatchingConstructor() { + Member toFind = new MemberImpl(Member.CONSTRUCTOR,derivedType, + Modifier.PUBLIC, + UnresolvedType.forSignature("V"), + "", + new UnresolvedType[] {UnresolvedType.forSignature("I")} + ); + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("No matches",0,foundMembers.length); + } + + // FIELDS + + public void testBaseOnlyField() { + Member toFind = new MemberImpl(Member.FIELD,baseType, + Modifier.PUBLIC, + UnresolvedType.forSignature("I"), + "onlyBase", + new UnresolvedType[0] + ); + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 member",1,foundMembers.length); + assertEquals("Lfluffy/Base;",foundMembers[0].getDeclaringType().getSignature()); + + toFind = new MemberImpl(Member.FIELD,derivedType, + Modifier.PUBLIC, + UnresolvedType.forSignature("I"), + "onlyBase", + new UnresolvedType[0] + ); + foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 2 members",2,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + assertEquals("Lfluffy/Base;",foundMembers[1].getDeclaringType().getSignature()); + } + + public void testBothField() { + Member toFind = new MemberImpl(Member.FIELD,baseType, + Modifier.PUBLIC, + UnresolvedType.forSignature("I"), + "both", + new UnresolvedType[0] + ); + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 member",1,foundMembers.length); + assertEquals("Lfluffy/Base;",foundMembers[0].getDeclaringType().getSignature()); + + toFind = new MemberImpl(Member.FIELD,derivedType, + Modifier.PUBLIC, + UnresolvedType.forSignature("I"), + "both", + new UnresolvedType[0] + ); + foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 members",1,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + } + + public void testDerivedField() { + Member toFind = new MemberImpl(Member.FIELD,baseType, + Modifier.PUBLIC, + UnresolvedType.forSignature("I"), + "onlyDerived", + new UnresolvedType[0] + ); + + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found nothing",0,foundMembers.length); + + toFind = new MemberImpl(Member.FIELD,derivedType, + Modifier.PUBLIC, + UnresolvedType.forSignature("I"), + "onlyDerived", + new UnresolvedType[0] + ); + foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 members",1,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + } + + protected void setUp() throws Exception { + world = new BcelWorld(); + baseType = UnresolvedType.forSignature("Lfluffy/Base;"); + derivedType = UnresolvedType.forSignature("Lfluffy/Derived;"); + } + +} diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/ArgsWeaveTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/ArgsWeaveTestCase.java index c487d24d7..722e4a83c 100644 --- a/weaver/testsrc/org/aspectj/weaver/bcel/ArgsWeaveTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/bcel/ArgsWeaveTestCase.java @@ -23,7 +23,7 @@ import org.aspectj.apache.bcel.generic.InstructionHandle; import org.aspectj.apache.bcel.generic.InstructionList; import org.aspectj.apache.bcel.generic.Type; import org.aspectj.weaver.AdviceKind; -import org.aspectj.weaver.Member; +import org.aspectj.weaver.MemberImpl; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.Shadow; import org.aspectj.weaver.UnresolvedType; @@ -103,7 +103,7 @@ public class ArgsWeaveTestCase extends WeaveTestCase { ResolvedType rtx = world.resolve(UnresolvedType.forName("Aspect"),true); assertTrue("Cant find required type Aspect",rtx!=ResolvedType.MISSING); return new BcelAdvice(AdviceKind.stringToKind(kindx), makePointcutNoZeroArg(), - Member.method(UnresolvedType.forName("Aspect"), 0, "foo", "()V"), 0, -1, -1, null, + MemberImpl.method(UnresolvedType.forName("Aspect"), 0, "foo", "()V"), 0, -1, -1, null, rtx) { public void specializeOn(Shadow shadow) { super.specializeOn(shadow); diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/AroundWeaveTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/AroundWeaveTestCase.java index 023005e53..2e892277d 100644 --- a/weaver/testsrc/org/aspectj/weaver/bcel/AroundWeaveTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/bcel/AroundWeaveTestCase.java @@ -48,7 +48,7 @@ public class AroundWeaveTestCase extends WeaveTestCase { private BcelAdvice makeAroundMunger(final boolean matchOnlyPrintln) { BcelWorld world = super.world; final Member sig = - Member.method( + MemberImpl.method( UnresolvedType.forName("Aspect"), Modifier.STATIC, "ajc_around", diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/MegaZipTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/MegaZipTestCase.java index ac57a0ba7..fed1ab4cd 100644 --- a/weaver/testsrc/org/aspectj/weaver/bcel/MegaZipTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/bcel/MegaZipTestCase.java @@ -22,6 +22,7 @@ import java.util.List; import org.aspectj.weaver.AdviceKind; import org.aspectj.weaver.BcweaverTests; import org.aspectj.weaver.Member; +import org.aspectj.weaver.MemberImpl; import org.aspectj.weaver.Shadow; import org.aspectj.weaver.UnresolvedType; @@ -46,7 +47,7 @@ public class MegaZipTestCase extends WeaveTestCase { private BcelAdvice makeAroundMunger(final boolean matchOnlyPrintln) { // BcelWorld world = new BcelWorld(); final Member sig = - Member.method( + MemberImpl.method( UnresolvedType.forName("fluffy.Aspect"), Modifier.STATIC, "aroundFun", diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/PointcutResidueTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/PointcutResidueTestCase.java index 428ab5ed2..3c2701241 100644 --- a/weaver/testsrc/org/aspectj/weaver/bcel/PointcutResidueTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/bcel/PointcutResidueTestCase.java @@ -186,11 +186,11 @@ public class PointcutResidueTestCase extends WeaveTestCase { new BcelAdvice( AdviceKind.Before, rp, - Member.method( + MemberImpl.method( UnresolvedType.forName("Aspect"), Modifier.STATIC, "ajc_before_0", - Member.typesToSignature( + MemberImpl.typesToSignature( ResolvedType.VOID, UnresolvedType.forNames(formalTypes),false)), 0, -1, -1, null, null); diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/TjpWeaveTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/TjpWeaveTestCase.java index 4fe362973..a028f9a98 100644 --- a/weaver/testsrc/org/aspectj/weaver/bcel/TjpWeaveTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/bcel/TjpWeaveTestCase.java @@ -18,7 +18,7 @@ import java.util.Arrays; import org.aspectj.weaver.Advice; import org.aspectj.weaver.AdviceKind; -import org.aspectj.weaver.Member; +import org.aspectj.weaver.MemberImpl; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.UnresolvedType; @@ -36,7 +36,7 @@ public class TjpWeaveTestCase extends WeaveTestCase { BcelAdvice munger = new BcelAdvice( AdviceKind.stringToKind("before"), makePointcutAll(), - Member.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint$StaticPart)"), + MemberImpl.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint$StaticPart)"), Advice.ThisJoinPointStaticPart, -1, -1, null, null); weaveTest("HelloWorld", "StaticTjpBeforeHelloWorld", munger); @@ -47,7 +47,7 @@ public class TjpWeaveTestCase extends WeaveTestCase { BcelAdvice munger = new BcelAdvice( AdviceKind.stringToKind("before"), makePointcutAll(), - Member.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint$StaticPart)"), + MemberImpl.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint$StaticPart)"), Advice.ThisEnclosingJoinPointStaticPart, -1, -1, null, null); weaveTest("HelloWorld", "StaticEnclosingTjpBeforeHelloWorld", munger); @@ -58,7 +58,7 @@ public class TjpWeaveTestCase extends WeaveTestCase { BcelAdvice munger = new BcelAdvice( AdviceKind.stringToKind("before"), makePointcutAll(), - Member.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint)"), + MemberImpl.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint)"), Advice.ThisJoinPoint, -1, -1, null, null); weaveTest("HelloWorld", "TjpBeforeHelloWorld", munger); @@ -68,7 +68,7 @@ public class TjpWeaveTestCase extends WeaveTestCase { BcelAdvice munger = new BcelAdvice( AdviceKind.stringToKind("around"), makePointcutAll(), - Member.methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"), + MemberImpl.methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"), Advice.ThisJoinPoint | Advice.ExtraArgument, -1, -1, null, null); weaveTest("HelloWorld", "TjpAroundHelloWorld", munger); @@ -80,14 +80,14 @@ public class TjpWeaveTestCase extends WeaveTestCase { BcelAdvice munger1 = new BcelAdvice( AdviceKind.stringToKind("around"), makePointcutAll(), - Member.methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"), + MemberImpl.methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"), Advice.ThisJoinPoint | Advice.ExtraArgument, -1, -1, null, rtx); BcelAdvice munger2 = new BcelAdvice( AdviceKind.stringToKind("around"), makePointcutAll(), - Member.methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"), + MemberImpl.methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"), Advice.ThisJoinPoint | Advice.ExtraArgument, -1, -1, null, rtx); diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/WeaveOrderTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/WeaveOrderTestCase.java index 5696a1df5..5976acd03 100644 --- a/weaver/testsrc/org/aspectj/weaver/bcel/WeaveOrderTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/bcel/WeaveOrderTestCase.java @@ -138,7 +138,7 @@ public class WeaveOrderTestCase extends WeaveTestCase { UnresolvedType concreteAspect, int lexicalPosition) { Advice a1 = new BcelAdvice(kind, makeResolvedPointcut("this(*)"), - Member.method(declaringAspect, 0, "foo", "()V"), + MemberImpl.method(declaringAspect, 0, "foo", "()V"), 0, lexicalPosition, lexicalPosition, null, null); a1 = (Advice)a1.concretize(concreteAspect.resolve(world), world, null); return a1; diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/WorldTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/WorldTestCase.java index e3cd0e3fa..cb82a2f5f 100644 --- a/weaver/testsrc/org/aspectj/weaver/bcel/WorldTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/bcel/WorldTestCase.java @@ -38,7 +38,7 @@ public class WorldTestCase extends AbstractWorldTestCase { ResolvedType trace = world.resolve(UnresolvedType.forName("Trace"),true); assertTrue("Couldnt find type Trace",trace!=ResolvedType.MISSING); fieldsTest(trace, Member.NONE); - /*Member constr = */Member.methodFromString("void Trace.()"); + /*Member constr = */MemberImpl.methodFromString("void Trace.()"); //XXX need attribute fix - //methodsTest(trace, new Member[] { constr }); @@ -50,7 +50,7 @@ public class WorldTestCase extends AbstractWorldTestCase { pointcutsTest(trace, new Member[] { - Member.pointcut(trace, "traced", "(Ljava/lang/Object;)V"), + MemberImpl.pointcut(trace, "traced", "(Ljava/lang/Object;)V"), }); modifiersTest(trace.findPointcut("traced"), @@ -83,7 +83,7 @@ public class WorldTestCase extends AbstractWorldTestCase { pointcutsTest(trace, new Member[] { - Member.pointcut(trace, "traced", "(Ljava/lang/Object;)V"), + MemberImpl.pointcut(trace, "traced", "(Ljava/lang/Object;)V"), }); modifiersTest(myTrace.findPointcut("traced"), @@ -102,16 +102,16 @@ public class WorldTestCase extends AbstractWorldTestCase { fieldsTest(iter, ResolvedMember.NONE); methodsTest(iter, new Member[] { - Member.method(iter, 0, "hasNext", "()Z"), - Member.method(iter, 0, "remove", "()V"), - Member.method(iter, 0, "next", "()Ljava/lang/Object;"), + MemberImpl.method(iter, 0, "hasNext", "()Z"), + MemberImpl.method(iter, 0, "remove", "()V"), + MemberImpl.method(iter, 0, "next", "()Ljava/lang/Object;"), }); - ResolvedMember remove = iter.lookupMethod(Member.method(iter, 0, "remove", "()V")); + ResolvedMember remove = iter.lookupMethod(MemberImpl.method(iter, 0, "remove", "()V")); assertNotNull("iterator doesn't have remove" , remove); modifiersTest(remove, abstractPublic | Modifier.INTERFACE); exceptionsTest(remove, UnresolvedType.NONE); - ResolvedMember clone = iter.lookupMethod(Member.method(UnresolvedType.OBJECT, 0, "clone", "()Ljava/lang/Object;")); + ResolvedMember clone = iter.lookupMethod(MemberImpl.method(UnresolvedType.OBJECT, 0, "clone", "()Ljava/lang/Object;")); assertNotNull("iterator doesn't have clone" , clone); //AV: JRockit Object.clone() is not native.. corrupted test here: //modifiersTest(clone, Modifier.PROTECTED | Modifier.NATIVE); diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/SignaturePatternTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/SignaturePatternTestCase.java index 4a9188bbc..d784afc70 100644 --- a/weaver/testsrc/org/aspectj/weaver/patterns/SignaturePatternTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/patterns/SignaturePatternTestCase.java @@ -1,5 +1,6 @@ /* ******************************************************************* * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * 2005 Contributors * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Common Public License v1.0 @@ -32,13 +33,13 @@ public class SignaturePatternTestCase extends TestCase { BcelWorld world = new BcelWorld(); public void testThrowsMatch() throws IOException { - Member onlyDerivedOnDerived = Member.methodFromString("static void fluffy.Derived.onlyDerived()"); - Member mOnBase = Member.methodFromString("void fluffy.Base.m()"); - Member mOnDerived = Member.methodFromString("void fluffy.Derived.m()"); + Member onlyDerivedOnDerived = MemberImpl.methodFromString("static void fluffy.Derived.onlyDerived()"); + Member mOnBase = MemberImpl.methodFromString("void fluffy.Base.m()"); + Member mOnDerived = MemberImpl.methodFromString("void fluffy.Derived.m()"); checkMatch(makeMethodPat("* fluffy.Base.*(..) throws java.lang.CloneNotSupportedException"), - new Member[] { mOnBase }, - new Member[] { mOnDerived }); + new Member[] { mOnBase, mOnDerived }, + new Member[] { }); checkMatch(makeMethodPat("* fluffy.Derived.*(..) throws java.lang.CloneNotSupportedException"), new Member[] { }, @@ -52,7 +53,7 @@ public class SignaturePatternTestCase extends TestCase { checkMatch(makeMethodPat("* *(..)"), M, NONE); checkMatch(makeMethodPat("* *(..) throws !*"), NO_EXCEPTIONS, M); - checkMatch(makeMethodPat("* *(..) throws *"), M, NO_EXCEPTIONS); + checkMatch(makeMethodPat("* *(..) throws *"), BOTH, NONE); checkMatch(makeMethodPat("* *(..) throws *, !*"), NONE, BOTH); checkMatch(makeMethodPat("* *(..) throws (!*)"), NONE, BOTH); @@ -65,9 +66,9 @@ public class SignaturePatternTestCase extends TestCase { } public void testInstanceMethodMatch() throws IOException { - Member objectToString = Member.methodFromString("java.lang.String java.lang.Object.toString()"); - Member integerToString = Member.methodFromString("java.lang.String java.lang.Integer.toString()"); - Member integerIntValue = Member.methodFromString("int java.lang.Integer.intValue()"); + Member objectToString = MemberImpl.methodFromString("java.lang.String java.lang.Object.toString()"); + Member integerToString = MemberImpl.methodFromString("java.lang.String java.lang.Integer.toString()"); + Member integerIntValue = MemberImpl.methodFromString("int java.lang.Integer.intValue()"); //Member objectToString = Member.methodFromString("java.lang.String java.lang.Object.toString()"); checkMatch(makeMethodPat("* java.lang.Object.*(..)"), @@ -81,11 +82,11 @@ public class SignaturePatternTestCase extends TestCase { public void testStaticMethodMatch() throws IOException { - Member onlyBaseOnBase = Member.methodFromString("static void fluffy.Base.onlyBase()"); - Member onlyBaseOnDerived = Member.methodFromString("static void fluffy.Derived.onlyBase()"); - Member onlyDerivedOnDerived = Member.methodFromString("static void fluffy.Derived.onlyDerived()"); - Member bothOnBase = Member.methodFromString("static void fluffy.Base.both()"); - Member bothOnDerived = Member.methodFromString("static void fluffy.Derived.both()"); + Member onlyBaseOnBase = MemberImpl.methodFromString("static void fluffy.Base.onlyBase()"); + Member onlyBaseOnDerived = MemberImpl.methodFromString("static void fluffy.Derived.onlyBase()"); + Member onlyDerivedOnDerived = MemberImpl.methodFromString("static void fluffy.Derived.onlyDerived()"); + Member bothOnBase = MemberImpl.methodFromString("static void fluffy.Base.both()"); + Member bothOnDerived = MemberImpl.methodFromString("static void fluffy.Derived.both()"); checkMatch(makeMethodPat("* fluffy.Base.*(..)"), new Member[] { onlyBaseOnBase, onlyBaseOnDerived, bothOnBase }, @@ -97,11 +98,11 @@ public class SignaturePatternTestCase extends TestCase { } public void testFieldMatch() throws IOException { - Member onlyBaseOnBase = Member.fieldFromString("int fluffy.Base.onlyBase"); - Member onlyBaseOnDerived = Member.fieldFromString("int fluffy.Derived.onlyBase"); - Member onlyDerivedOnDerived = Member.fieldFromString("int fluffy.Derived.onlyDerived"); - Member bothOnBase = Member.fieldFromString("int fluffy.Base.both"); - Member bothOnDerived = Member.fieldFromString("int fluffy.Derived.both"); + Member onlyBaseOnBase = MemberImpl.fieldFromString("int fluffy.Base.onlyBase"); + Member onlyBaseOnDerived = MemberImpl.fieldFromString("int fluffy.Derived.onlyBase"); + Member onlyDerivedOnDerived = MemberImpl.fieldFromString("int fluffy.Derived.onlyDerived"); + Member bothOnBase = MemberImpl.fieldFromString("int fluffy.Base.both"); + Member bothOnDerived = MemberImpl.fieldFromString("int fluffy.Derived.both"); checkMatch(makeFieldPat("* fluffy.Base.*"), new Member[] { onlyBaseOnBase, onlyBaseOnDerived, bothOnBase }, @@ -113,9 +114,9 @@ public class SignaturePatternTestCase extends TestCase { } public void testConstructorMatch() throws IOException { - Member onBase = Member.methodFromString("void fluffy.Base.()"); - Member onDerived = Member.methodFromString("void fluffy.Derived.()"); - Member onBaseWithInt = Member.methodFromString("void fluffy.Base.(int)"); + Member onBase = MemberImpl.methodFromString("void fluffy.Base.()"); + Member onDerived = MemberImpl.methodFromString("void fluffy.Derived.()"); + Member onBaseWithInt = MemberImpl.methodFromString("void fluffy.Base.(int)"); checkMatch(makeMethodPat("fluffy.Base.new(..)"), diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/WithinTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/WithinTestCase.java index bfbe18bc0..b0a0fb259 100644 --- a/weaver/testsrc/org/aspectj/weaver/patterns/WithinTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/patterns/WithinTestCase.java @@ -34,7 +34,7 @@ public class WithinTestCase extends TestCase { public void testMatch() throws IOException { Shadow getOutFromArrayList = new TestShadow( Shadow.FieldGet, - Member.fieldFromString("java.io.PrintStream java.lang.System.out"), + MemberImpl.fieldFromString("java.io.PrintStream java.lang.System.out"), UnresolvedType.forName("java.util.ArrayList"), world); @@ -50,7 +50,7 @@ public class WithinTestCase extends TestCase { Shadow getOutFromEntry = new TestShadow( Shadow.FieldGet, - Member.fieldFromString("java.io.PrintStream java.lang.System.out"), + MemberImpl.fieldFromString("java.io.PrintStream java.lang.System.out"), UnresolvedType.forName("java.util.Map$Entry"), world); -- 2.39.5