diff options
30 files changed, 440 insertions, 297 deletions
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 3ea8c54a0..7b33c9ab1 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 @@ -169,9 +169,12 @@ public class InterTypeFieldDeclaration extends InterTypeDeclaration { } //System.err.println("type: " + binding.returnType + ", " + returnType); - - ResolvedMember sig = - new ResolvedMember(Member.FIELD, world.fromBinding(onTypeBinding), + ResolvedType declaringType = world.fromBinding(onTypeBinding).resolve(world.getWorld()); + if (declaringType.isRawType() || declaringType.isParameterizedType()) { + declaringType = declaringType.getGenericType(); + } + ResolvedMember sig = + new ResolvedMember(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/lookup/AjLookupEnvironment.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java index 340a532da..5999b17b9 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java @@ -367,6 +367,8 @@ public class AjLookupEnvironment extends LookupEnvironment { private void weaveInterTypeDeclarations(SourceTypeBinding sourceType, Collection typeMungers, Collection declareParents, Collection declareAnnotationOnTypes, boolean skipInners) { ResolvedType onType = factory.fromEclipse(sourceType); + // AMC we shouldn't need this when generic sigs are fixed?? + if (onType.isRawType()) onType = onType.getGenericType(); WeaverStateInfo info = onType.getWeaverState(); if (info != null && !info.isOldStyle()) { 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 8e85b0653..36d84aced 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 @@ -34,6 +34,7 @@ import org.aspectj.weaver.ReferenceType; import org.aspectj.weaver.ResolvedMember; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.Shadow; +import org.aspectj.weaver.TypeFactory; import org.aspectj.weaver.TypeVariable; import org.aspectj.weaver.TypeVariableReferenceType; import org.aspectj.weaver.UnresolvedType; @@ -212,7 +213,11 @@ public class EclipseFactory { } } } - return UnresolvedType.forParameterizedTypes(UnresolvedType.forName(getName(binding)), arguments); + ResolvedType baseType = UnresolvedType.forName(getName(binding)).resolve(getWorld()); + return TypeFactory.createParameterizedType( + baseType, + arguments, + getWorld()); } // Convert the source type binding for a generic type into a generic UnresolvedType @@ -232,9 +237,9 @@ public class EclipseFactory { //TODO asc generics - temporary guard.... if (!(binding instanceof SourceTypeBinding)) throw new RuntimeException("Cant get the generic sig for "+binding.debugName()); - return ResolvedType.forGenericType(getName(binding),tVars, + return UnresolvedType.forGenericType(getName(binding),tVars, CharOperation.charToString(((SourceTypeBinding)binding).genericSignature())); - } + } return UnresolvedType.forName(getName(binding)); } @@ -254,6 +259,7 @@ public class EclipseFactory { superinterfaces[i] = fromBinding(aTypeVariableBinding.superInterfaces[i]); } TypeVariable tv = new TypeVariable(name,superclassType,superinterfaces); + tv.resolve(world); ret.setTypeVariable(tv); typeVariableBindingsInProgress.remove(aTypeVariableBinding); return ret; @@ -343,9 +349,12 @@ public class EclipseFactory { public ResolvedMember makeResolvedMember(MethodBinding binding, TypeBinding declaringType) { //System.err.println("member for: " + binding + ", " + new String(binding.declaringClass.sourceName)); + // 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( binding.isConstructor() ? Member.CONSTRUCTOR : Member.METHOD, - world.resolve(fromBinding(declaringType)), + realDeclaringType, binding.modifiers, world.resolve(fromBinding(binding.returnType)), new String(binding.selector), @@ -359,9 +368,12 @@ public class EclipseFactory { } public ResolvedMember makeResolvedMember(FieldBinding binding, TypeBinding receiverType) { + // 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( Member.FIELD, - world.resolve(fromBinding(receiverType)), + realDeclaringType, binding.modifiers, world.resolve(fromBinding(binding.type)), new String(binding.name), @@ -521,6 +533,7 @@ public class EclipseFactory { ReferenceType complexName = new ReferenceType(complexTx,world);//getWorld().lookupOrCreateName(complexTx); name.setGenericType(complexName); complexName.setDelegate(t); + complexName.setSourceContext(t.getResolvedTypeX().getSourceContext()); } name.setDelegate(t); diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java index b8eb60b83..240d2c478 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java @@ -458,8 +458,7 @@ public class EclipseSourceType extends AbstractReferenceTypeDelegate { } public boolean isGeneric() { - char[] sig = binding.genericSignature(); - return (sig==null?false:sig[0]=='<'); + return binding.isGenericType(); } public TypeVariable[] getTypeVariables() { diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseTypeMunger.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseTypeMunger.java index 98672327d..b17d21a3a 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseTypeMunger.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseTypeMunger.java @@ -53,6 +53,8 @@ public class EclipseTypeMunger extends ConcreteTypeMunger { munger.setSourceLocation(sourceLocation); } targetTypeX = munger.getSignature().getDeclaringType().resolve(world.getWorld()); + // AMC, needed until generic and raw have distinct sigs... + if (targetTypeX.isParameterizedType() || targetTypeX.isRawType()) targetTypeX = targetTypeX.getGenericType(); //targetBinding = (ReferenceBinding)world.makeTypeBinding(targetTypeX); } @@ -71,7 +73,9 @@ public class EclipseTypeMunger extends ConcreteTypeMunger { * i.e. adds Method|FieldBindings, plays with inheritance, ... */ public boolean munge(SourceTypeBinding sourceType) { - if (!world.fromEclipse(sourceType).equals(targetTypeX)) return false; //??? move this test elsewhere + ResolvedType rt = world.fromEclipse(sourceType); + if (rt.isRawType() || rt.isParameterizedType()) rt = rt.getGenericType(); + if (!rt.equals(targetTypeX)) return false; //??? move this test elsewhere //System.out.println("munging: " + sourceType); // System.out.println("match: " + world.fromEclipse(sourceType) + // " with " + targetTypeX); diff --git a/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java b/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java index 90d2cf4fb..6f8877814 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java +++ b/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java @@ -178,7 +178,7 @@ public class GenericsTests extends XMLBasedAjcTestCase { public void testPR96220_GenericDecp() { runTest("generic decp - simple"); - verifyClassSignature("Basic","Ljava/lang/Object;LJ<Ljava/lang/Double;>;LI<Ljava/lang/Double;>;"); + verifyClassSignature("Basic","Ljava/lang/Object;PJ<Ljava/lang/Double;>;PI<Ljava/lang/Double;>;"); } // Both the existing type decl and the one adding via decp are parameterized diff --git a/weaver/src/org/aspectj/weaver/AjcMemberMaker.java b/weaver/src/org/aspectj/weaver/AjcMemberMaker.java index 798864ff1..dc5db0a71 100644 --- a/weaver/src/org/aspectj/weaver/AjcMemberMaker.java +++ b/weaver/src/org/aspectj/weaver/AjcMemberMaker.java @@ -694,9 +694,12 @@ public class AjcMemberMaker { } } public static Member interfaceConstructor(ResolvedType resolvedTypeX) { + // 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( Member.CONSTRUCTOR, - resolvedTypeX, + declaringType, Modifier.PUBLIC, "<init>", "()V"); diff --git a/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java b/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java index 25785e059..1d257c065 100644 --- a/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java +++ b/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java @@ -150,7 +150,13 @@ public class CrosscuttingMembers { public void exposeType(UnresolvedType typeToExpose) { if (typeToExpose == ResolvedType.MISSING) return; - + if (typeToExpose.isParameterizedType() || typeToExpose.isRawType()) { + if (typeToExpose instanceof ResolvedType) { + typeToExpose = ((ResolvedType)typeToExpose).getGenericType(); + } else { + typeToExpose = UnresolvedType.forSignature(typeToExpose.getRawTypeSignature()); + } + } ResolvedMember member = new ResolvedMember( Member.STATIC_INITIALIZATION, typeToExpose, 0, ResolvedType.VOID, "", UnresolvedType.NONE); addTypeMunger(world.concreteTypeMunger( diff --git a/weaver/src/org/aspectj/weaver/Member.java b/weaver/src/org/aspectj/weaver/Member.java index 52be008e0..c29355f34 100644 --- a/weaver/src/org/aspectj/weaver/Member.java +++ b/weaver/src/org/aspectj/weaver/Member.java @@ -27,7 +27,7 @@ import org.aspectj.util.TypeSafeEnum; public class Member implements Comparable, AnnotatedElement { private final Kind kind; - private final UnresolvedType declaringType; + protected UnresolvedType declaringType; protected final int modifiers; // protected because ResolvedMember uses it private final UnresolvedType returnType; private final String name; @@ -154,7 +154,7 @@ public class Member implements Comparable, AnnotatedElement { if (c == ')') break; // break out when the hit the ')' int start = i; while (c == '[') c = sig.charAt(++i); - if (c == 'L') { + if (c == 'L' || c == 'P') { int nextSemicolon = sig.indexOf(';',start); int firstAngly = sig.indexOf('<',start); if (firstAngly == -1 || firstAngly>nextSemicolon) { @@ -389,9 +389,9 @@ public class Member implements Comparable, AnnotatedElement { public String toString() { StringBuffer buf = new StringBuffer(); - buf.append(returnType); + buf.append(returnType.getName()); buf.append(' '); - buf.append(declaringType); + buf.append(declaringType.getName()); buf.append('.'); buf.append(name); if (kind != FIELD) { @@ -400,7 +400,7 @@ public class Member implements Comparable, AnnotatedElement { buf.append(parameterTypes[0]); for (int i=1, len = parameterTypes.length; i < len; i++) { buf.append(", "); - buf.append(parameterTypes[i]); + buf.append(parameterTypes[i].getName()); } } buf.append(")"); diff --git a/weaver/src/org/aspectj/weaver/NewFieldTypeMunger.java b/weaver/src/org/aspectj/weaver/NewFieldTypeMunger.java index 400d16019..85321083b 100644 --- a/weaver/src/org/aspectj/weaver/NewFieldTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/NewFieldTypeMunger.java @@ -47,6 +47,7 @@ public class NewFieldTypeMunger extends ResolvedTypeMunger { public ResolvedMember getMatchingSyntheticMember(Member member, ResolvedType aspectType) { //??? might give a field where a method is expected ResolvedType onType = aspectType.getWorld().resolve(getSignature().getDeclaringType()); + if (onType.isRawType()) onType = onType.getGenericType(); ResolvedMember ret = AjcMemberMaker.interFieldGetDispatcher(getSignature(), aspectType); if (ResolvedType.matches(ret, member)) return getSignature(); diff --git a/weaver/src/org/aspectj/weaver/ReferenceType.java b/weaver/src/org/aspectj/weaver/ReferenceType.java index eecee9f85..f62d4f1ed 100644 --- a/weaver/src/org/aspectj/weaver/ReferenceType.java +++ b/weaver/src/org/aspectj/weaver/ReferenceType.java @@ -57,6 +57,23 @@ public class ReferenceType extends ResolvedType { public ReferenceType(String signature, World world) { super(signature, world); } + + /** + * Constructor used when creating a parameterized type. + */ + public ReferenceType( + ResolvedType theGenericType, + ResolvedType[] theParameters, + World aWorld) { + super(makeParameterizedSignature(theGenericType,theParameters), + theGenericType.signatureErasure, + aWorld); + ReferenceType genericReferenceType = (ReferenceType) theGenericType; + this.typeParameters = theParameters; + this.genericType = genericReferenceType; + this.typeKind = PARAMETERIZED; + this.delegate = genericReferenceType.getDelegate(); + } /** * Create a reference type for a generic type @@ -72,7 +89,7 @@ public class ReferenceType extends ResolvedType { } public final boolean isGenericType() { - return delegate.isGeneric(); + return !isParameterizedType() && !isRawType() && delegate.isGeneric(); } public AnnotationX[] getAnnotations() { @@ -164,11 +181,11 @@ public class ReferenceType extends ResolvedType { public ResolvedMember[] getDeclaredFields() { if (parameterizedFields != null) return parameterizedFields; - if (isParameterizedType()) { + if (isParameterizedType() || isRawType()) { ResolvedMember[] delegateFields = delegate.getDeclaredFields(); parameterizedFields = new ResolvedMember[delegateFields.length]; for (int i = 0; i < delegateFields.length; i++) { - parameterizedFields[i] = delegateFields[i].parameterizedWith(getTypeParameters()); + parameterizedFields[i] = delegateFields[i].parameterizedWith(getTypesForMemberParameterization(),this); } return parameterizedFields; } else { @@ -183,11 +200,11 @@ public class ReferenceType extends ResolvedType { */ public ResolvedType[] getDeclaredInterfaces() { if (parameterizedInterfaces != null) return parameterizedInterfaces; - if (isParameterizedType()) { + if (isParameterizedType() || isRawType()) { ResolvedType[] delegateInterfaces = delegate.getDeclaredInterfaces(); parameterizedInterfaces = new ResolvedType[delegateInterfaces.length]; for (int i = 0; i < delegateInterfaces.length; i++) { - parameterizedInterfaces[i] = delegateInterfaces[i].parameterizedWith(getTypeParameters()); + parameterizedInterfaces[i] = delegateInterfaces[i].parameterizedWith(getTypesForMemberParameterization()); } return parameterizedInterfaces; } else { @@ -197,11 +214,12 @@ public class ReferenceType extends ResolvedType { public ResolvedMember[] getDeclaredMethods() { if (parameterizedMethods != null) return parameterizedMethods; - if (isParameterizedType()) { + if (isParameterizedType() || isRawType()) { ResolvedMember[] delegateMethods = delegate.getDeclaredMethods(); + UnresolvedType[] parameters = getTypesForMemberParameterization(); parameterizedMethods = new ResolvedMember[delegateMethods.length]; for (int i = 0; i < delegateMethods.length; i++) { - parameterizedMethods[i] = delegateMethods[i].parameterizedWith(getTypeParameters()); + parameterizedMethods[i] = delegateMethods[i].parameterizedWith(parameters,this); } return parameterizedMethods; } else { @@ -211,17 +229,32 @@ public class ReferenceType extends ResolvedType { public ResolvedMember[] getDeclaredPointcuts() { if (parameterizedPointcuts != null) return parameterizedPointcuts; - if (isParameterizedType()) { + if (isParameterizedType() || isRawType()) { ResolvedMember[] delegatePointcuts = delegate.getDeclaredPointcuts(); parameterizedPointcuts = new ResolvedMember[delegatePointcuts.length]; for (int i = 0; i < delegatePointcuts.length; i++) { - parameterizedPointcuts[i] = delegatePointcuts[i].parameterizedWith(getTypeParameters()); + parameterizedPointcuts[i] = delegatePointcuts[i].parameterizedWith(getTypesForMemberParameterization(),this); } return parameterizedPointcuts; } else { return delegate.getDeclaredPointcuts(); } } + + private UnresolvedType[] getTypesForMemberParameterization() { + UnresolvedType[] parameters = null; + if (isParameterizedType()) { + parameters = getTypeParameters(); + } else if (isRawType()){ + // raw type, use upper bounds of type variables on generic type + TypeVariable[] tvs = getGenericType().getTypeVariables(); + parameters = new UnresolvedType[tvs.length]; + for (int i = 0; i < tvs.length; i++) { + parameters[i] = tvs[i].getUpperBound(); + } + } + return parameters; + } public TypeVariable[] getTypeVariables() { return delegate.getTypeVariables(); @@ -293,7 +326,7 @@ public class ReferenceType extends ResolvedType { // makes sense if someone is specifying that it has a generic form if ( typeKind == UnresolvedType.SIMPLE ) { typeKind = UnresolvedType.RAW; - rawTypeSignature = signature; + signatureErasure = signature; } } @@ -301,4 +334,25 @@ public class ReferenceType extends ResolvedType { return genericType; } + /** + * a parameterized signature starts with a "P" in place of the "L", + * see the comment on signatures in UnresolvedType. + * @param aGenericType + * @param someParameters + * @return + */ + private static String makeParameterizedSignature(ResolvedType aGenericType, ResolvedType[] someParameters) { + String rawSignature = aGenericType.getRawTypeSignature(); + String prefix = PARAMETERIZED_TYPE_IDENTIFIER + rawSignature.substring(1,rawSignature.length()-1); + + StringBuffer ret = new StringBuffer(); + ret.append(prefix); + ret.append("<"); + for (int i = 0; i < someParameters.length; i++) { + ret.append(someParameters[i].getSignature()); + } + ret.append(">;"); + return ret.toString(); + } + }
\ No newline at end of file diff --git a/weaver/src/org/aspectj/weaver/ResolvedMember.java b/weaver/src/org/aspectj/weaver/ResolvedMember.java index a06084ef2..c34ef714c 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedMember.java +++ b/weaver/src/org/aspectj/weaver/ResolvedMember.java @@ -45,6 +45,7 @@ public class ResolvedMember extends Member implements IHasPosition, AnnotatedEle // 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; // these three fields hold the source location of this member @@ -90,6 +91,7 @@ public class ResolvedMember extends Member implements IHasPosition, AnnotatedEle { this(kind, declaringType, modifiers, returnType, name, parameterTypes,checkedExceptions); this.backingGenericMember = backingGenericMember; + this.isAjSynthetic = backingGenericMember.isAjSynthetic(); } public ResolvedMember( @@ -130,7 +132,7 @@ public class ResolvedMember extends Member implements IHasPosition, AnnotatedEle // ??? true or false? public boolean isAjSynthetic() { - return true; + return isAjSynthetic; } public boolean hasAnnotations() { @@ -232,6 +234,8 @@ public class ResolvedMember extends Member implements IHasPosition, AnnotatedEle } annotationTypes = r; } + declaringType = declaringType.resolve(world); + if (declaringType.isRawType()) declaringType = ((ReferenceType)declaringType).getGenericType(); return this; } @@ -333,7 +337,7 @@ public class ResolvedMember extends Member implements IHasPosition, AnnotatedEle // return a resolved member in which all type variables in the signature of this // member have been replaced with the given bindings. - public ResolvedMember parameterizedWith(UnresolvedType[] typeParameters) { + public ResolvedMember parameterizedWith(UnresolvedType[] typeParameters,ResolvedType newDeclaringType) { if (!this.getDeclaringType().isGenericType()) { throw new IllegalStateException("Can't ask to parameterize a member of a non-generic type"); } @@ -353,7 +357,7 @@ public class ResolvedMember extends Member implements IHasPosition, AnnotatedEle } return new ResolvedMember( getKind(), - getDeclaringType(), + newDeclaringType, getModifiers(), parameterizedReturnType, getName(), diff --git a/weaver/src/org/aspectj/weaver/ResolvedType.java b/weaver/src/org/aspectj/weaver/ResolvedType.java index 6ee333fd1..60600da5c 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedType.java +++ b/weaver/src/org/aspectj/weaver/ResolvedType.java @@ -33,28 +33,19 @@ import org.aspectj.weaver.patterns.PerClause; public abstract class ResolvedType extends UnresolvedType implements AnnotatedElement { private static final ResolvedType[] EMPTY_RESOLVED_TYPE_ARRAY = new ResolvedType[0]; + public static final String PARAMETERIZED_TYPE_IDENTIFIER = "P"; protected World world; - - // Factory methods - - public static UnresolvedType forGenericType(String name,TypeVariable[] tvbs,String genericSig) { - // TODO asc generics needs a declared sig - UnresolvedType ret = UnresolvedType.forName(name); - ret.typeKind=GENERIC; - ret.typeVariables = tvbs; - ret.rawTypeSignature = ret.signature; - ret.genericSignature = genericSig; - return ret; // this cast will fail at runtime, temp refactoring issue - } - - - - + protected ResolvedType(String signature, World world) { super(signature); this.world = world; } + + protected ResolvedType(String signature, String signatureErasure, World world) { + super(signature,signatureErasure); + this.world = world; + } // ---- things that don't require a world @@ -135,9 +126,7 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl public ResolvedType getResolvedComponentType() { return null; } - public ResolvedType resolve(World world) { - return this; - } + public World getWorld() { return world; } @@ -1307,6 +1296,7 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } public void clearInterTypeMungers() { + if (isRawType()) getGenericType().clearInterTypeMungers(); interTypeMungers = new ArrayList(); } diff --git a/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java b/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java index c11a82023..1b13ff564 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java @@ -48,6 +48,11 @@ public abstract class ResolvedTypeMunger { public ResolvedTypeMunger(Kind kind, ResolvedMember signature) { this.kind = kind; this.signature = signature; + UnresolvedType declaringType = signature != null ? signature.getDeclaringType() : null; + if (declaringType != null) { + if (declaringType.isRawType()) throw new IllegalStateException("Use generic type, not raw type"); + if (declaringType.isParameterizedType()) throw new IllegalStateException("Use generic type, not parameterized type"); + } } public void setSourceLocation(ISourceLocation isl) { @@ -62,6 +67,7 @@ public abstract class ResolvedTypeMunger { // fromType is guaranteed to be a non-abstract aspect public ConcreteTypeMunger concretize(World world, ResolvedType aspectType) { + ConcreteTypeMunger munger = world.concreteTypeMunger(this, aspectType); return munger; } @@ -69,6 +75,7 @@ public abstract class ResolvedTypeMunger { public boolean matches(ResolvedType matchType, ResolvedType aspectType) { ResolvedType onType = matchType.getWorld().resolve(signature.getDeclaringType()); + if (onType.isRawType()) onType = onType.getGenericType(); //System.err.println("matching: " + this + " to " + matchType + " onType = " + onType); if (matchType.equals(onType)) { if (!onType.isExposedToWeaver()) { diff --git a/weaver/src/org/aspectj/weaver/TypeFactory.java b/weaver/src/org/aspectj/weaver/TypeFactory.java new file mode 100644 index 000000000..8967f98a5 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/TypeFactory.java @@ -0,0 +1,97 @@ +/* ******************************************************************* + * 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.util.ArrayList; +import java.util.List; + +/** + * @author colyer + * + */ +public class TypeFactory { + + /** + * Create a parameterized version of a generic type. + * @param aGenericType + * @param someTypeParameters note, in the case of an inner type of a parameterized type, + * this parameter may legitimately be null + * @param inAWorld + * @return + */ + public static ReferenceType createParameterizedType( + ResolvedType aBaseType, + UnresolvedType[] someTypeParameters, + World inAWorld + ) { + ResolvedType baseType = aBaseType; + if (!aBaseType.isGenericType()) { + // try and find the generic type... + if (someTypeParameters != null) { + if (!aBaseType.isRawType()) throw new IllegalStateException("Expecting raw type"); + baseType = baseType.getGenericType(); + if (baseType == null) throw new IllegalStateException("Raw type does not have generic type set"); + } // else if someTypeParameters is null, then the base type is allowed to be non-generic, it's an inner + } + ResolvedType[] resolvedParameters = inAWorld.resolve(someTypeParameters); + ReferenceType pType = new ReferenceType(baseType,resolvedParameters,inAWorld); + pType.setSourceContext(aBaseType.getSourceContext()); + return (ReferenceType) pType.resolve(inAWorld); + } + + /** + * Used by UnresolvedType.read, creates a type from a full signature. + * @param signature + * @return + */ + public static UnresolvedType createTypeFromSignature(String signature) { + if (signature.equals(ResolvedType.MISSING_NAME)) return ResolvedType.MISSING; + + if (signature.startsWith(ResolvedType.PARAMETERIZED_TYPE_IDENTIFIER)) { + // parameterized type, calculate signature erasure and type parameters + int startOfParams = signature.indexOf('<'); + int endOfParams = signature.lastIndexOf('>'); + String signatureErasure = "L" + signature.substring(1,startOfParams) + ";"; + UnresolvedType[] typeParams = createTypeParams(signature.substring(startOfParams +1, endOfParams)); + return new UnresolvedType(signature,signatureErasure,typeParams); + } else { + return new UnresolvedType(signature); + } + } + + private static UnresolvedType[] createTypeParams(String typeParameterSpecification) { + String remainingToProcess = typeParameterSpecification; + List types = new ArrayList(); + while(!remainingToProcess.equals("")) { + int endOfSig = 0; + int anglies = 0; + boolean sigFound = false; + for (endOfSig = 0; (endOfSig < remainingToProcess.length()) && !sigFound; endOfSig++) { + char thisChar = remainingToProcess.charAt(endOfSig); + switch(thisChar) { + case '<' : anglies++; break; + case '>' : anglies--; break; + case ';' : + if (anglies == 0) { + sigFound = true; + break; + } + } + } + types.add(createTypeFromSignature(remainingToProcess.substring(0,endOfSig))); + remainingToProcess = remainingToProcess.substring(endOfSig); + } + UnresolvedType[] typeParams = new UnresolvedType[types.size()]; + types.toArray(typeParams); + return typeParams; + } +} diff --git a/weaver/src/org/aspectj/weaver/UnresolvedType.java b/weaver/src/org/aspectj/weaver/UnresolvedType.java index 8f503e858..06fcf1874 100644 --- a/weaver/src/org/aspectj/weaver/UnresolvedType.java +++ b/weaver/src/org/aspectj/weaver/UnresolvedType.java @@ -117,7 +117,7 @@ public class UnresolvedType { public static final UnresolvedType AT_TARGET = forSignature("Ljava/lang/annotation/Target;"); // this doesn't belong here and will get moved to ResolvedType later in the refactoring - public static final String MISSING_NAME = "<missing>"; + public static final String MISSING_NAME = "@missing@"; // constants indicating the base kind of the type @@ -132,6 +132,18 @@ public class UnresolvedType { public final static int TYPE_VARIABLE = 5; // a type variable public final static int WILDCARD = 6; // a generic wildcard type + public String getKind() { + switch (typeKind) { + case PRIMITIVE: return "PRIMITIVE"; + case SIMPLE: return "SIMPLE"; + case RAW: return "RAW"; + case GENERIC: return "GENERIC"; + case PARAMETERIZED: return "PARAMETERIZED"; + case TYPE_VARIABLE: return "TYPE_VARIABLE"; + case WILDCARD: return "WILDCARD"; + default: return null; + } + } protected int typeKind = SIMPLE; // what kind of type am I? /** @@ -144,7 +156,7 @@ public class UnresolvedType { * with all supertype, superinterface, type variable, and parameter information * removed. */ - protected String signatureErasure; + protected String signatureErasure; /** * Iff isParameterized(), then these are the type parameters @@ -225,13 +237,7 @@ public class UnresolvedType { // ----------------------------- // old stuff... - - /** - * For parameterized types, this is the signature of the raw type (e.g. Ljava/util/List; ) - * For non-parameterized types, it is null. - */ - protected String rawTypeSignature; - + // For a generic type, this is the 'declared' signature // e.g. for Enum: <E:Ljava/lang/Enum<TE;>;>Ljava/lang/Object;Ljava/lang/Comparable<TE;>;Ljava/io/Serializable; // note: it doesnt include the name of the type! @@ -242,82 +248,24 @@ public class UnresolvedType { */ protected UnresolvedType(String signature) { super(); + // if (signature.indexOf('<') != -1) throw new IllegalStateException("Shouldn't be calling simple signature based type constructor with generic info in signature"); this.signature = signature; - // avoid treating '<missing>' as a parameterized type ... - if (signature.charAt(0)!='<' && signature.indexOf("<")!=-1 && !signature.startsWith("<missing>")) { - // anglies alert - parameterized type - processSignature(signature); - } + this.signatureErasure = signature; } - - /** - * Called when processing a parameterized type, sets the raw type for this typeX and calls a subroutine - * to handle sorting out the type parameters for the type. - */ - private void processSignature(String sig) { - // determine the raw type - //TODO asc generics tidy this bit up? - boolean skip=false; - if (sig.charAt(0)=='+') {/*isExtends=true;*/skip=true;} - if (sig.charAt(0)=='-') {/*isSuper=true;*/skip=true;} - int parameterTypesStart = signature.indexOf("<"); - int parameterTypesEnd = signature.lastIndexOf(">"); - StringBuffer rawTypeSb = new StringBuffer(); - String p = signature.substring(0,parameterTypesStart); - if (skip) p = p.substring(1); - rawTypeSb.append(p).append(";"); - rawTypeSignature = rawTypeSb.toString(); - typeParameters = processParameterization(signature,parameterTypesStart+1,parameterTypesEnd-1); - typeKind = PARAMETERIZED; - } - - /** - * For a parameterized signature, e.g. <Ljava/lang/String;Ljava/util/List<Ljava/lang/String;>;>" - * this routine will return an appropriate array of TypeXs representing the top level type parameters. - * Where type parameters are themselves parameterized, we recurse. - */ - public UnresolvedType[] processParameterization(String paramSig,int startpos,int endpos) { - boolean debug = false; - if (debug) { - StringBuffer sb = new StringBuffer(); - sb.append(paramSig).append("\n"); - for(int i=0;i<paramSig.length();i++) { - if (i==startpos || i==endpos) sb.append("^"); - else if (i<startpos || i>endpos) sb.append(" "); - else sb.append("-"); - } - sb.append("\n"); - System.err.println(sb.toString()); - } - int posn = startpos; - List parameterTypes = new ArrayList(); - while (posn<endpos && paramSig.charAt(posn)!='>') { - int nextAngly = paramSig.indexOf("<",posn); - int nextSemi = paramSig.indexOf(";",posn); - if (nextAngly==-1 || nextSemi<nextAngly) { // the next type is not parameterized - // simple type - parameterTypes.add(UnresolvedType.forSignature(paramSig.substring(posn,nextSemi+1))); - posn=nextSemi+1; // jump to the next type - } else if (nextAngly!=-1 && nextSemi>nextAngly) { // parameterized type, e.g. Ljava/util/Set<Ljava/util/String;> - int count=1; - int pos=nextAngly+1; - for (;count>0;pos++){ - switch (paramSig.charAt(pos)) { - case '<':count++;break; - case '>':count--;break; - default: - } - } - String sub = paramSig.substring(posn,pos+1); - parameterTypes.add(UnresolvedType.forSignature(sub)); - posn=pos+1; - } else { - throw new BCException("What the hell do i do with this? ["+paramSig.substring(posn)+"]"); - } - } - return (UnresolvedType[])parameterTypes.toArray(new UnresolvedType[]{}); - } - + + protected UnresolvedType(String signature, String signatureErasure) { + this.signature = signature; + this.signatureErasure = signatureErasure; + } + + // called from TypeFactory + public UnresolvedType(String signature, String signatureErasure, UnresolvedType[] typeParams) { + this.signature = signature; + this.signatureErasure = signatureErasure; + this.typeParameters = typeParams; + if (typeParams != null) this.typeKind = PARAMETERIZED; + } + // ---- Things we can do without a world /** @@ -373,9 +321,19 @@ public class UnresolvedType { return ret; } - - public static UnresolvedType forGenericTypeSignature(String nameSig,String declaredGenericSig) { - UnresolvedType ret = UnresolvedType.forSignature(nameSig); + public static UnresolvedType forGenericType(String name,TypeVariable[] tvbs,String genericSig) { + // TODO asc generics needs a declared sig + String sig = nameToSignature(name); + UnresolvedType ret = UnresolvedType.forSignature(sig); + ret.typeKind=GENERIC; + ret.typeVariables = tvbs; + ret.signatureErasure = sig; + ret.genericSignature = genericSig; + return ret; + } + + public static UnresolvedType forGenericTypeSignature(String sig,String declaredGenericSig) { + UnresolvedType ret = UnresolvedType.forSignature(sig); ret.typeKind=GENERIC; ClassSignature csig = new GenericSignatureParser().parseAsClassSignature(declaredGenericSig); @@ -387,46 +345,12 @@ public class UnresolvedType { Signature.ClassTypeSignature cts = (Signature.ClassTypeSignature)parameter.classBound; ret.typeVariables[i]=new TypeVariable(ftps[i].identifier,UnresolvedType.forSignature(cts.outerType.identifier+";")); } - ret.rawTypeSignature = ret.signature; - ret.signature = ret.rawTypeSignature; + ret.signatureErasure = sig; + ret.signature = ret.signatureErasure; ret.genericSignature=declaredGenericSig; return ret; } - /** - * Makes a parameterized type with the given name - * and parameterized type names. - */ - public static UnresolvedType forParameterizedTypeNames(String name, String[] paramTypeNames) { - UnresolvedType[] paramTypes = null; - if (paramTypeNames!=null) { - paramTypes = new UnresolvedType[paramTypeNames.length]; - for (int i = 0; i < paramTypeNames.length; i++) { - paramTypes[i] = UnresolvedType.forName(paramTypeNames[i]); - } - } - return UnresolvedType.forParameterizedTypes(UnresolvedType.forName(name), paramTypes); - } - - public static UnresolvedType forParameterizedTypes(UnresolvedType rawType, UnresolvedType[] paramTypes) { - UnresolvedType ret = rawType; - ret.typeKind=PARAMETERIZED; - ret.typeParameters = paramTypes; - ret.rawTypeSignature = ret.signature; - // sig for e.g. List<String> is Ljava/util/List<Ljava/lang/String;>; - if (ret.typeParameters!=null) { - StringBuffer sigAddition = new StringBuffer(); - sigAddition.append("<"); - for (int i = 0; i < ret.typeParameters.length; i++) { - sigAddition.append(ret.typeParameters[i].signature); - } - sigAddition.append(">"); - sigAddition.append(";"); - ret.signature = ret.signature.substring(0,ret.signature.length()-1) + sigAddition.toString(); - } - return ret; - } - public static UnresolvedType forRawTypeNames(String name) { UnresolvedType ret = UnresolvedType.forName(name); ret.typeKind = RAW; @@ -488,11 +412,12 @@ public class UnresolvedType { case 'F': return ResolvedType.FLOAT; case 'I': return ResolvedType.INT; case 'J': return ResolvedType.LONG; - case 'L': return new UnresolvedType(signature); + case 'L': return TypeFactory.createTypeFromSignature(signature); + case 'P': return TypeFactory.createTypeFromSignature(signature); case 'S': return ResolvedType.SHORT; case 'V': return ResolvedType.VOID; case 'Z': return ResolvedType.BOOLEAN; - case '[': return new UnresolvedType(signature); + case '[': return TypeFactory.createTypeFromSignature(signature); case '+': return new UnresolvedType(signature); case '-' : return new UnresolvedType(signature); case '?' : return GenericsWildcardTypeX.GENERIC_WILDCARD; @@ -538,7 +463,7 @@ public class UnresolvedType { } public String getRawName() { - return signatureToName((rawTypeSignature==null?signature:rawTypeSignature)); + return signatureToName((signatureErasure==null?signature:signatureErasure)); } public String getBaseName() { @@ -595,8 +520,8 @@ public class UnresolvedType { * For parameterized types, return the signature for the raw type */ public String getRawTypeSignature() { - if (rawTypeSignature==null) return signature; - return rawTypeSignature; + if (signatureErasure==null) return signature; + return signatureErasure; } public UnresolvedType getRawType() { @@ -642,7 +567,7 @@ public class UnresolvedType { * Returns a java language string representation of this type. */ public String toString() { - return getName(); + return getName(); // + " - " + getKind(); } // ---- requires worlds @@ -669,59 +594,36 @@ public class UnresolvedType { case 'J': return "long"; case 'L': String name = signature.substring(1, signature.length() - 1).replace('/', '.'); - if (name.indexOf("<") == -1) return name; + return name; + case 'P': // it's one of our parameterized type sigs + StringBuffer nameBuff = new StringBuffer(); // signature for parameterized types is e.g. // List<String> -> Ljava/util/List<Ljava/lang/String;>; // Map<String,List<Integer>> -> Ljava/util/Map<java/lang/String;Ljava/util/List<Ljava/lang/Integer;>;>; - StringBuffer nameBuff = new StringBuffer(); - boolean justSeenLeftArrowChar = false; - boolean justSeenTypeParameter = false; - boolean justSeenSemiColon= false; int paramNestLevel = 0; - for (int i = 0 ; i < name.length(); i++) { - char c = name.charAt(i); + for (int i = 1 ; i < signature.length(); i++) { + char c = signature.charAt(i); switch (c) { - case '<' : - justSeenLeftArrowChar = true; + case '/' : nameBuff.append('.'); break; + case '<' : + nameBuff.append("<"); paramNestLevel++; - nameBuff.append(c); - break; - case ';' : - justSeenSemiColon = true; - break; - case '>' : - paramNestLevel--; - nameBuff.append(c); - break; - case 'L' : - if (justSeenLeftArrowChar) { - justSeenLeftArrowChar = false; - break; - } - if (justSeenSemiColon) { - nameBuff.append(","); - } else { - nameBuff.append("L"); + StringBuffer innerBuff = new StringBuffer(); + while(paramNestLevel > 0) { + c = signature.charAt(++i); + if (c == '<') paramNestLevel++; + if (c == '>') paramNestLevel--; + if (paramNestLevel > 0) innerBuff.append(c); + if (c == ';' && paramNestLevel == 1) { + nameBuff.append(signatureToName(innerBuff.toString())); + if (signature.charAt(i+1) != '>') nameBuff.append(','); + innerBuff = new StringBuffer(); + } } + nameBuff.append(">"); break; - case 'T': - if (justSeenLeftArrowChar) { - justSeenLeftArrowChar = false; - justSeenTypeParameter = true; - break; - } - if (justSeenSemiColon) { - nameBuff.append(","); - } else { - nameBuff.append("T"); - } - justSeenTypeParameter = true; - // type parameter - break; + case ';' : break; default: - justSeenSemiColon = false; - justSeenTypeParameter = false; - justSeenLeftArrowChar = false; nameBuff.append(c); } } @@ -764,14 +666,34 @@ public class UnresolvedType { return "L" + name.replace('.', '/') + ";"; } else { StringBuffer nameBuff = new StringBuffer(); - nameBuff.append("L"); + int nestLevel = 0; + nameBuff.append("P"); for (int i = 0; i < name.length(); i++) { char c = name.charAt(i); switch (c) { case '.' : nameBuff.append('/'); break; - case '<' : nameBuff.append("<L"); break; - case '>' : nameBuff.append(";>"); break; - case ',' : nameBuff.append(";L"); break; + case '<' : + nameBuff.append("<"); + nestLevel++; + StringBuffer innerBuff = new StringBuffer(); + while(nestLevel > 0) { + c = name.charAt(++i); + if (c == '<') nestLevel++; + if (c == '>') nestLevel--; + if (c == ',' && nestLevel == 1) { + nameBuff.append(nameToSignature(innerBuff.toString())); + innerBuff = new StringBuffer(); + } else { + if (nestLevel > 0) innerBuff.append(c); + } + } + nameBuff.append(nameToSignature(innerBuff.toString())); + nameBuff.append('>'); + break; + case '>' : + throw new IllegalStateException("Should by matched by <"); + case ',' : + throw new IllegalStateException("Should only happen inside <...>"); default: nameBuff.append(c); } } @@ -861,32 +783,6 @@ public class UnresolvedType { } - - - public static UnresolvedType[] getInterfacesFromSignature(String sig) { - // there is a declared signature - use it to work out the interfaces, rather than the stuff in the class file... - ClassSignature cSig = new GenericSignatureParser().parseAsClassSignature(sig); - Signature.ClassTypeSignature[] declaredInterfaces = cSig.superInterfaceSignatures; - UnresolvedType[] retVal = new UnresolvedType[declaredInterfaces.length]; - for (int i = 0; i < declaredInterfaces.length; i++) { - Signature.ClassTypeSignature signature = declaredInterfaces[i]; - retVal[i] = convertFromClassSignatureToTypeX(signature); - } - return retVal; - } - - private static UnresolvedType convertFromClassSignatureToTypeX(Signature.ClassTypeSignature signature) { - return new UnresolvedType(signature.classSignature); - } - public String getKind() { - switch (typeKind) { - case 0: return "SIMPLE"; - case 1: return "RAW"; - case 2: return "GENERIC"; - case 3: return "PARAMETERIZED"; - default: return null; - } - } } diff --git a/weaver/src/org/aspectj/weaver/UnresolvedTypeVariableReferenceType.java b/weaver/src/org/aspectj/weaver/UnresolvedTypeVariableReferenceType.java index 8101680c9..32dd637fe 100644 --- a/weaver/src/org/aspectj/weaver/UnresolvedTypeVariableReferenceType.java +++ b/weaver/src/org/aspectj/weaver/UnresolvedTypeVariableReferenceType.java @@ -37,6 +37,7 @@ public class UnresolvedTypeVariableReferenceType extends UnresolvedType { } public ResolvedType resolve(World world) { + if (typeVariable == null) return ResolvedType.MISSING; typeVariable.resolve(world); return new TypeVariableReferenceType(typeVariable,world); } diff --git a/weaver/src/org/aspectj/weaver/World.java b/weaver/src/org/aspectj/weaver/World.java index d6905da18..602e16b64 100644 --- a/weaver/src/org/aspectj/weaver/World.java +++ b/weaver/src/org/aspectj/weaver/World.java @@ -80,6 +80,7 @@ public abstract class World implements Dump.INode { } public ResolvedType[] resolve(UnresolvedType[] types) { + if (types == null) return new ResolvedType[0]; int len = types.length; ResolvedType[] ret = new ResolvedType[len]; for (int i=0; i<len; i++) { @@ -113,7 +114,12 @@ public abstract class World implements Dump.INode { // if we already have an rtx, don't re-resolve it public ResolvedType resolve(ResolvedType ty) { - return ty; + ResolvedType resolved = typeMap.get(ty.getSignature()); + if (resolved == null) { + typeMap.put(ty.getSignature(), ty); + resolved = ty; + } + return resolved; } public ResolvedType getCoreType(UnresolvedType tx) { @@ -158,6 +164,7 @@ public abstract class World implements Dump.INode { public ResolvedType resolve(UnresolvedType ty, boolean allowMissing) { if (ty instanceof ResolvedType) { ResolvedType rty = (ResolvedType) ty; + rty = resolve(rty); rty.world = this; return rty; } @@ -212,9 +219,8 @@ public abstract class World implements Dump.INode { protected final ResolvedType resolveObjectType(UnresolvedType ty) { if (ty.isParameterizedType()) { ReferenceType genericType = (ReferenceType)resolveTheGenericType(ty,false); - ReferenceType parameterizedType = new ReferenceType(ty.getSignature(),this); - parameterizedType.setGenericType(genericType); - parameterizedType.setDelegate(genericType.getDelegate()); // move into setgenerictype + ReferenceType parameterizedType = + TypeFactory.createParameterizedType(genericType, ty.typeParameters, this); return parameterizedType; } else if (ty.isGenericType()) { ReferenceType genericType = (ReferenceType)resolveTheGenericType(ty,false); @@ -564,6 +570,10 @@ public abstract class World implements Dump.INode { return ret; } + public ReferenceType lookupBySignature(String signature) { + return (ReferenceType) typeMap.get(signature); + } + // public void clearUnexposed() { // List toRemove = new ArrayList(); diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java index dd927f9e9..b33f84e35 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java @@ -230,6 +230,8 @@ class BcelClassWeaver implements IClassWeaver { public void addInitializer(ConcreteTypeMunger cm) { NewFieldTypeMunger m = (NewFieldTypeMunger) cm.getMunger(); ResolvedType onType = m.getSignature().getDeclaringType().resolve(world); + if (onType.isRawType()) onType = onType.getGenericType(); + if (m.getSignature().isStatic()) { addedClassInitializers.add(cm); } else { diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXConverter.java b/weaver/src/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXConverter.java index 12602ccbe..0c937e848 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXConverter.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXConverter.java @@ -22,6 +22,7 @@ import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.ReferenceType; import org.aspectj.weaver.ResolvedMember; import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.TypeFactory; import org.aspectj.weaver.TypeVariable; import org.aspectj.weaver.TypeVariableReferenceType; import org.aspectj.weaver.UnresolvedType; @@ -72,11 +73,21 @@ public class BcelGenericSignatureToTypeXConverter { if (innerType.typeArguments.length > 0) { // we have to create a parameterized type // type arguments may be array types, class types, or typevariable types - UnresolvedType[] typeArgumentTypes = new UnresolvedType[innerType.typeArguments.length]; + ResolvedType[] typeArgumentTypes = new ResolvedType[innerType.typeArguments.length]; for (int i = 0; i < typeArgumentTypes.length; i++) { typeArgumentTypes[i] = typeArgument2TypeX(innerType.typeArguments[i],typeParams,world,inProgressTypeVariableResolutions); } - return world.resolve(UnresolvedType.forParameterizedTypes(UnresolvedType.forSignature(sig.toString()), typeArgumentTypes)); + ResolvedType theBaseType = UnresolvedType.forSignature(sig.toString()).resolve(world); + return + TypeFactory.createParameterizedType( + theBaseType, + typeArgumentTypes, + world); + + +// world.resolve(UnresolvedType.forParameterizedTypes( +// UnresolvedType.forSignature(sig.toString()).resolve(world), +// typeArgumentTypes)); } else { // we have a non-parameterized type return world.resolve(UnresolvedType.forSignature(sig.toString())); diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java b/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java index 5389ac8ea..575480e94 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java @@ -181,6 +181,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { } public ResolvedMember[] getDeclaredMethods() { + unpackGenericSignature(); if (methods == null) { Method[] ms = javaClass.getMethods(); ResolvedMember[] ret = new ResolvedMember[ms.length]; @@ -193,6 +194,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { } public ResolvedMember[] getDeclaredFields() { + unpackGenericSignature(); if (fields == null) { Field[] fs = javaClass.getFields(); ResolvedMember[] ret = new ResolvedMember[fs.length]; @@ -529,6 +531,10 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { getResolvedTypeX().getWorld()); } } + if (isGeneric()) { + // update resolved typex to point at generic type not raw type. + this.resolvedTypeX = (ReferenceType) this.resolvedTypeX.getGenericType(); + } } private void ensureGenericInfoProcessed() { getDeclaredGenericSignature();} diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java index 83c71a150..f0521dd69 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java @@ -180,7 +180,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { List methods = newParent.getMethodsWithoutIterator(); for (Iterator iter = methods.iterator(); iter.hasNext();) { - BcelMethod superMethod = (BcelMethod) iter.next(); + ResolvedMember superMethod = (ResolvedMember) iter.next(); if (!superMethod.getName().equals("<init>")) { LazyMethodGen subMethod = findMatchingMethod(newParentTarget, superMethod); if (subMethod!=null) { @@ -211,7 +211,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { if (!(newParentTarget.isAbstract() || newParentTarget.isInterface())) { // Ignore abstract classes or interfaces List methods = newParent.getMethodsWithoutIterator(); for (Iterator i = methods.iterator(); i.hasNext();) { - BcelMethod o = (BcelMethod)i.next(); + 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(); @@ -270,7 +270,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { /** * Rule 3. Can't narrow visibility of methods when overriding */ - private boolean enforceDecpRule3_visibilityChanges(BcelClassWeaver weaver, ResolvedType newParent, BcelMethod superMethod, LazyMethodGen subMethod) { + private boolean enforceDecpRule3_visibilityChanges(BcelClassWeaver weaver, ResolvedType newParent, ResolvedMember superMethod, LazyMethodGen subMethod) { boolean cont = true; if (superMethod.isPublic()) { if (subMethod.isProtected() || subMethod.isDefault() || subMethod.isPrivate()) { @@ -300,7 +300,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { /** * Rule 4. Can't have incompatible return types */ - private boolean enforceDecpRule4_compatibleReturnTypes(BcelClassWeaver weaver, BcelMethod superMethod, LazyMethodGen subMethod) { + private boolean enforceDecpRule4_compatibleReturnTypes(BcelClassWeaver weaver, ResolvedMember superMethod, LazyMethodGen subMethod) { boolean cont = true; String superReturnTypeSig = superMethod.getReturnType().getSignature(); String subReturnTypeSig = subMethod.getReturnType().getSignature(); @@ -323,7 +323,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { * Rule5. Method overrides can't change the staticality (word?) - you can't override and make an instance * method static or override and make a static method an instance method. */ - private boolean enforceDecpRule5_cantChangeFromStaticToNonstatic(BcelClassWeaver weaver,ISourceLocation mungerLoc,BcelMethod superMethod, LazyMethodGen subMethod ) { + private boolean enforceDecpRule5_cantChangeFromStaticToNonstatic(BcelClassWeaver weaver,ISourceLocation mungerLoc,ResolvedMember superMethod, LazyMethodGen subMethod ) { if (superMethod.isStatic() && !subMethod.isStatic()) { error(weaver,"This instance method "+subMethod.getName()+subMethod.getParameterSignature()+ " cannot override the static method from "+superMethod.getDeclaringType().getName(), @@ -344,7 +344,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { } - private LazyMethodGen findMatchingMethod(LazyClassGen newParentTarget, BcelMethod m) { + private LazyMethodGen findMatchingMethod(LazyClassGen newParentTarget, ResolvedMember m) { LazyMethodGen found = null; // Search the type for methods overriding super methods (methods that come from the new parent) // Don't use the return value in the comparison as overriding doesnt @@ -456,6 +456,8 @@ public class BcelTypeMunger extends ConcreteTypeMunger { ResolvedMember member = munger.getMember(); ResolvedType onType = weaver.getWorld().resolve(member.getDeclaringType(),munger.getSourceLocation()); + if (onType.isRawType()) onType = onType.getGenericType(); + //System.out.println("munging: " + gen + " with " + member); if (onType.equals(gen.getType())) { if (member.getKind() == Member.FIELD) { @@ -713,6 +715,8 @@ public class BcelTypeMunger extends ConcreteTypeMunger { LazyClassGen gen = weaver.getLazyClassGen(); ResolvedType onType = weaver.getWorld().resolve(signature.getDeclaringType(),munger.getSourceLocation()); + if (onType.isRawType()) onType = onType.getGenericType(); + boolean onInterface = onType.isInterface(); if (onType.isAnnotation()) { @@ -898,14 +902,15 @@ public class BcelTypeMunger extends ConcreteTypeMunger { final InstructionFactory fact = currentClass.getFactory(); ResolvedMember newConstructorMember = newConstructorTypeMunger.getSyntheticConstructor(); - UnresolvedType onType = newConstructorMember.getDeclaringType(); + ResolvedType onType = newConstructorMember.getDeclaringType().resolve(weaver.getWorld()); + if (onType.isRawType()) onType = onType.getGenericType(); - if (onType.resolve(weaver.getWorld()).isAnnotation()) { + if (onType.isAnnotation()) { signalError(WeaverMessages.ITDC_ON_ANNOTATION_NOT_ALLOWED,weaver,onType); return false; } - if (onType.resolve(weaver.getWorld()).isEnum()) { + if (onType.isEnum()) { signalError(WeaverMessages.ITDC_ON_ENUM_NOT_ALLOWED,weaver,onType); return false; } @@ -1044,6 +1049,8 @@ public class BcelTypeMunger extends ConcreteTypeMunger { ResolvedType onType = weaver.getWorld().resolve(field.getDeclaringType(),munger.getSourceLocation()); + if (onType.isRawType()) onType = onType.getGenericType(); + boolean onInterface = onType.isInterface(); if (onType.isAnnotation()) { diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java index 7cc653128..009af6499 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java @@ -1154,7 +1154,8 @@ public class BcelWeaver implements IWeaver { * FIXME asc confirm that algorithm is optimal ?? */ public void weaveParentTypeMungers(ResolvedType onType) { - onType.clearInterTypeMungers(); + if (onType.isRawType()) onType = onType.getGenericType(); + onType.clearInterTypeMungers(); List decpToRepeat = new ArrayList(); @@ -1312,6 +1313,7 @@ public class BcelWeaver implements IWeaver { } public void weaveNormalTypeMungers(ResolvedType onType) { + if (onType.isRawType() || onType.isParameterizedType()) onType = onType.getGenericType(); for (Iterator i = typeMungerList.iterator(); i.hasNext(); ) { ConcreteTypeMunger m = (ConcreteTypeMunger)i.next(); if (m.matches(onType)) { diff --git a/weaver/src/org/aspectj/weaver/patterns/DeclareSoft.java b/weaver/src/org/aspectj/weaver/patterns/DeclareSoft.java index ae6052b64..f5bb96786 100644 --- a/weaver/src/org/aspectj/weaver/patterns/DeclareSoft.java +++ b/weaver/src/org/aspectj/weaver/patterns/DeclareSoft.java @@ -100,7 +100,7 @@ public class DeclareSoft extends Declare { // ENH 42743 suggests that we don't soften runtime exceptions. if (scope.getWorld().getCoreType(UnresolvedType.RUNTIME_EXCEPTION).isAssignableFrom(excType)) { scope.getWorld().getLint().runtimeExceptionNotSoftened.signal( - new String[]{exception.toString()}, + new String[]{excType.getName()}, exception.getSourceLocation(),null); pointcut = Pointcut.makeMatchesNothing(Pointcut.RESOLVED); return; diff --git a/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java index bb8f0615b..ee9198b5a 100644 --- a/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java @@ -27,6 +27,7 @@ import org.aspectj.weaver.AjAttribute; import org.aspectj.weaver.BCException; import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.TypeFactory; import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.VersionedDataInputStream; import org.aspectj.weaver.WeaverMessages; @@ -509,11 +510,11 @@ public class WildTypePattern extends TypePattern { if (type == ResolvedType.MISSING) { return resolveBindingsForMissingType(resolvedTypeInTheWorld, originalName, scope, bindings, allowBinding, requireExactType); } else { - return resolveBindingsForExactRawType(scope,type,fullyQualifiedName); + return resolveBindingsForExactType(scope,type,fullyQualifiedName); } } - private TypePattern resolveBindingsForExactRawType(IScope scope, UnresolvedType rawType, String fullyQualifiedName) { + private TypePattern resolveBindingsForExactType(IScope scope, UnresolvedType aType, String fullyQualifiedName) { TypePattern ret = null; if (typeParameters.size()>0) { // Only if the type is exact *and* the type parameters are exact should we create an @@ -524,8 +525,9 @@ public class WildTypePattern extends TypePattern { for (int i = 0; i < typeParameterTypes.length; i++) { typeParameterTypes[i] = ((ExactTypePattern)typePats[i]).getExactType(); } - UnresolvedType tx = UnresolvedType.forParameterizedTypes(rawType,typeParameterTypes); - UnresolvedType type = scope.getWorld().resolve(tx,true); + UnresolvedType type = TypeFactory.createParameterizedType(aType.resolve(scope.getWorld()), typeParameterTypes, scope.getWorld()); +// UnresolvedType tx = UnresolvedType.forParameterizedTypes(aType,typeParameterTypes); +// UnresolvedType type = scope.getWorld().resolve(tx,true); if (dim != 0) type = UnresolvedType.makeArray(type, dim); ret = new ExactTypePattern(type,includeSubtypes,isVarArgs); } else { @@ -537,8 +539,8 @@ public class WildTypePattern extends TypePattern { return this; } } else { - if (dim != 0) rawType = UnresolvedType.makeArray(rawType, dim); - ret = new ExactTypePattern(rawType,includeSubtypes,isVarArgs); + if (dim != 0) aType = UnresolvedType.makeArray(aType, dim); + ret = new ExactTypePattern(aType,includeSubtypes,isVarArgs); } ret.setAnnotationTypePattern(annotationPattern); ret.copyLocationFrom(this); diff --git a/weaver/testsrc/org/aspectj/weaver/MemberTestCase15.java b/weaver/testsrc/org/aspectj/weaver/MemberTestCase15.java index 4610b6e3c..a3c60d709 100644 --- a/weaver/testsrc/org/aspectj/weaver/MemberTestCase15.java +++ b/weaver/testsrc/org/aspectj/weaver/MemberTestCase15.java @@ -40,7 +40,9 @@ public class MemberTestCase15 extends TestCase { public void testCanBeParameterizedGenericMethod() { BcelWorld world = new BcelWorld(); - ResolvedType javaLangClass = world.resolve(UnresolvedType.forName("java/lang/Class")); + ResolvedType javaLangClass = world.resolve(UnresolvedType.forName("java.lang.Class")); + javaLangClass = javaLangClass.getGenericType(); + if (javaLangClass == null) return; // for < 1.5 ResolvedMember[] methods = javaLangClass.getDeclaredMethods(); ResolvedMember asSubclass = null; for (int i = 0; i < methods.length; i++) { @@ -57,7 +59,9 @@ public class MemberTestCase15 extends TestCase { public void testCanBeParameterizedMethodInGenericType() { BcelWorld world = new BcelWorld(); - ResolvedType javaUtilList = world.resolve(UnresolvedType.forName("java/util/List")); + ResolvedType javaUtilList = world.resolve(UnresolvedType.forName("java.util.List")); + javaUtilList = javaUtilList.getGenericType(); + if (javaUtilList == null) return; // for < 1.5 ResolvedMember[] methods = javaUtilList.getDeclaredMethods(); ResolvedMember add = null; for (int i = 0; i < methods.length; i++) { diff --git a/weaver/testsrc/org/aspectj/weaver/ParameterizedReferenceTypeTestCase.java b/weaver/testsrc/org/aspectj/weaver/ParameterizedReferenceTypeTestCase.java index bf4ae07ad..71a640caa 100644 --- a/weaver/testsrc/org/aspectj/weaver/ParameterizedReferenceTypeTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/ParameterizedReferenceTypeTestCase.java @@ -62,7 +62,6 @@ public class ParameterizedReferenceTypeTestCase extends TestCase { super.setUp(); world = new BcelWorld(); listOfString = (ReferenceType) - world.resolve(UnresolvedType.forParameterizedTypeNames("java/util/List", - new String[] {"java/lang/String"})); + TypeFactory.createTypeFromSignature("Ljava/util/List<Ljava/lang/String;>;").resolve(world); } } diff --git a/weaver/testsrc/org/aspectj/weaver/ReferenceTypeTestCase.java b/weaver/testsrc/org/aspectj/weaver/ReferenceTypeTestCase.java index 21930aa35..1e0e435c7 100644 --- a/weaver/testsrc/org/aspectj/weaver/ReferenceTypeTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/ReferenceTypeTestCase.java @@ -19,22 +19,36 @@ import junit.framework.TestCase; // XXX - couldn't find any unit test cases for the rest of the ReferenceType class public class ReferenceTypeTestCase extends TestCase { - public void testIsGenericTrue() { + public void testIsRawTrue() { BcelWorld world = new BcelWorld(); - UnresolvedType javaLangClass = UnresolvedType.forName("java/lang/Class"); + UnresolvedType javaLangClass = UnresolvedType.forName("java.lang.Class"); ResolvedType rtx = world.resolve(javaLangClass); assertTrue("Resolves to reference type",(rtx instanceof ReferenceType)); ReferenceType rt = (ReferenceType) rtx; - assertTrue("java.lang.Class is generic",rt.isGenericType()); + assertTrue("java.lang.Class is raw",rt.isRawType()); } - public void testIsGenericFalse() { + public void testIsRawFalse() { BcelWorld world = new BcelWorld(); - UnresolvedType javaLangObject = UnresolvedType.forName("java/lang/Object"); + UnresolvedType javaLangObject = UnresolvedType.forName("java.lang.Object"); ResolvedType rtx = world.resolve(javaLangObject); assertTrue("Resolves to reference type",(rtx instanceof ReferenceType)); ReferenceType rt = (ReferenceType) rtx; - assertFalse("java.lang.Object is not generic",rt.isGenericType()); + assertFalse("java.lang.Object is not raw",rt.isRawType()); + } + + public void testIsGenericTrue() { + BcelWorld world = new BcelWorld(); + UnresolvedType javaLangClass = UnresolvedType.forName("java.lang.Class"); + ResolvedType rtx = world.resolve(javaLangClass); + assertTrue("java.lang.Class has underpinning generic type",rtx.getGenericType().isGenericType()); + } + + public void testIsGenericFalse() { + BcelWorld world = new BcelWorld(); + UnresolvedType javaLangObject = UnresolvedType.forName("java.lang.Object"); + ResolvedType rtx = world.resolve(javaLangObject); + assertFalse(rtx.isGenericType()); } } diff --git a/weaver/testsrc/org/aspectj/weaver/TypeXTestCase.java b/weaver/testsrc/org/aspectj/weaver/TypeXTestCase.java index 793a071bf..432e441cb 100644 --- a/weaver/testsrc/org/aspectj/weaver/TypeXTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/TypeXTestCase.java @@ -16,6 +16,7 @@ package org.aspectj.weaver; import junit.framework.TestCase; import org.aspectj.testing.util.TestUtil; +import org.aspectj.weaver.bcel.BcelWorld; /** * This is a test case for all the portions of UnresolvedType that don't require a world. @@ -65,16 +66,16 @@ public class TypeXTestCase extends TestCase { public void testNameAndSigWithParameters() { UnresolvedType t = UnresolvedType.forName("java.util.List<java.lang.String>"); assertEquals(t.getName(),"java.util.List<java.lang.String>"); - assertEquals(t.getSignature(),"Ljava/util/List<Ljava/lang/String;>;"); - t = new UnresolvedType("Ljava/util/List<Ljava/lang/String;>;"); + assertEquals(t.getSignature(),"Pjava/util/List<Ljava/lang/String;>;"); + t = UnresolvedType.forSignature("Pjava/util/List<Ljava/lang/String;>;"); assertEquals(t.getName(),"java.util.List<java.lang.String>"); - assertEquals(t.getSignature(),"Ljava/util/List<Ljava/lang/String;>;"); + assertEquals(t.getSignature(),"Pjava/util/List<Ljava/lang/String;>;"); t = UnresolvedType.forName("java.util.Map<java.util.String,java.util.List<java.lang.Integer>>"); assertEquals(t.getName(),"java.util.Map<java.util.String,java.util.List<java.lang.Integer>>"); - assertEquals(t.getSignature(),"Ljava/util/Map<Ljava/util/String;Ljava/util/List<Ljava/lang/Integer;>;>;"); - t = new UnresolvedType("Ljava/util/Map<Ljava/util/String;Ljava/util/List<Ljava/lang/Integer;>;>;"); + assertEquals(t.getSignature(),"Pjava/util/Map<Ljava/util/String;Pjava/util/List<Ljava/lang/Integer;>;>;"); + t = UnresolvedType.forSignature("Pjava/util/Map<Ljava/util/String;Pjava/util/List<Ljava/lang/Integer;>;>;"); assertEquals(t.getName(),"java.util.Map<java.util.String,java.util.List<java.lang.Integer>>"); - assertEquals(t.getSignature(),"Ljava/util/Map<Ljava/util/String;Ljava/util/List<Ljava/lang/Integer;>;>;"); + assertEquals(t.getSignature(),"Pjava/util/Map<Ljava/util/String;Pjava/util/List<Ljava/lang/Integer;>;>;"); } /** @@ -91,13 +92,13 @@ public class TypeXTestCase extends TestCase { public void testTypexGenericSignatureProcessing() { UnresolvedType tx = null; - tx = new UnresolvedType("Ljava/util/Set<Ljava/lang/String;>;"); + tx = UnresolvedType.forSignature("Pjava/util/Set<Ljava/lang/String;>;"); checkTX(tx,true,1); - tx = new UnresolvedType("Ljava/util/Set<Ljava/util/List<Ljava/lang/String;>;>;"); + tx = UnresolvedType.forSignature("Pjava/util/Set<Pjava/util/List<Ljava/lang/String;>;>;"); checkTX(tx,true,1); - tx = new UnresolvedType("Ljava/util/Map<Ljava/util/List<Ljava/lang/String;>;Ljava/lang/String;>;"); + tx = UnresolvedType.forSignature("Pjava/util/Map<Pjava/util/List<Ljava/lang/String;>;Ljava/lang/String;>;"); checkTX(tx,true,2); checkTX(tx.getTypeParameters()[0],true,1); checkTX(tx.getTypeParameters()[1],false,0); @@ -105,8 +106,13 @@ public class TypeXTestCase extends TestCase { } public void testTypeXForParameterizedTypes() { + World world = new BcelWorld(); UnresolvedType stringType = UnresolvedType.forName("java/lang/String"); - UnresolvedType listOfStringType = UnresolvedType.forParameterizedTypes(UnresolvedType.forName("java/util/List"), new UnresolvedType[] {stringType}); + ResolvedType listOfStringType = + TypeFactory.createParameterizedType( + UnresolvedType.forName("java/util/List").resolve(world), + new UnresolvedType[] {stringType}, + world); assertEquals("1 type param",1,listOfStringType.typeParameters.length); assertEquals(stringType,listOfStringType.typeParameters[0]); assertTrue(listOfStringType.isParameterizedType()); diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXTestCase.java index d42e769d2..f36b86023 100644 --- a/weaver/testsrc/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXTestCase.java @@ -45,7 +45,7 @@ public class BcelGenericSignatureToTypeXTestCase extends TestCase { cSig.formalTypeParameters, world ); - assertEquals("Ljava/lang/Comparable<Ljava/lang/Enum<Ljava/lang/Object;>;>;",comparable.getSignature()); + assertEquals("Pjava/lang/Comparable<Pjava/lang/Enum<Ljava/lang/Object;>;>;",comparable.getSignature()); UnresolvedType serializable = BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX( cSig.superInterfaceSignatures[1], |