diff options
author | acolyer <acolyer> | 2005-07-20 11:11:29 +0000 |
---|---|---|
committer | acolyer <acolyer> | 2005-07-20 11:11:29 +0000 |
commit | aaa349d1543fbad515ff4fce869799fac591118d (patch) | |
tree | 25c8c750ff64767dfca53f399f6dd5be43d05b6b /weaver | |
parent | 9fc901ce7a0af0fca72f266504a0a7bc637cb10a (diff) | |
download | aspectj-aaa349d1543fbad515ff4fce869799fac591118d.tar.gz aspectj-aaa349d1543fbad515ff4fce869799fac591118d.zip |
changes to construction and representation of parameterized types, and enforcement of the constraint that type mungers always operate on the generic type (never raw or parameterized)
Diffstat (limited to 'weaver')
24 files changed, 407 insertions, 285 deletions
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], |