From: acolyer Date: Mon, 11 Jul 2005 09:35:36 +0000 (+0000) Subject: handle recursive type variables such as Enum X-Git-Tag: PRE_ANDY~51 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=c1e14262374890bf4259eda4024d4e9d5948049e;p=aspectj.git handle recursive type variables such as Enum --- diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXConverter.java b/weaver/src/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXConverter.java index af089568e..da573ff0e 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXConverter.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXConverter.java @@ -11,11 +11,16 @@ * ******************************************************************/ package org.aspectj.weaver.bcel; +import java.util.HashMap; +import java.util.Map; + import org.aspectj.apache.bcel.classfile.Signature; import org.aspectj.apache.bcel.classfile.Signature.SimpleClassTypeSignature; import org.aspectj.weaver.BoundedReferenceType; import org.aspectj.weaver.GenericsWildcardTypeX; +import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.ReferenceType; +import org.aspectj.weaver.ResolvedMember; import org.aspectj.weaver.ResolvedTypeX; import org.aspectj.weaver.TypeVariable; import org.aspectj.weaver.TypeVariableReferenceType; @@ -33,6 +38,18 @@ public class BcelGenericSignatureToTypeXConverter { Signature.ClassTypeSignature aClassTypeSignature, Signature.FormalTypeParameter[] typeParams, World world) { + Map typeMap = new HashMap(); + ResolvedTypeX ret = classTypeSignature2TypeX(aClassTypeSignature,typeParams,world,typeMap); + fixUpCircularDependencies(ret, typeMap); + return ret; + } + + + private static ResolvedTypeX classTypeSignature2TypeX( + Signature.ClassTypeSignature aClassTypeSignature, + Signature.FormalTypeParameter[] typeParams, + World world, + Map inProgressTypeVariableResolutions) { // class type sig consists of an outer type, and zero or more nested types // the fully qualified name is outer-type.nested-type1.nested-type2.... // each type in the hierarchy may have type arguments @@ -57,7 +74,7 @@ public class BcelGenericSignatureToTypeXConverter { // type arguments may be array types, class types, or typevariable types TypeX[] typeArgumentTypes = new TypeX[innerType.typeArguments.length]; for (int i = 0; i < typeArgumentTypes.length; i++) { - typeArgumentTypes[i] = typeArgument2TypeX(innerType.typeArguments[i],typeParams,world); + typeArgumentTypes[i] = typeArgument2TypeX(innerType.typeArguments[i],typeParams,world,inProgressTypeVariableResolutions); } return world.resolve(TypeX.forParameterizedTypes(TypeX.forSignature(sig.toString()), typeArgumentTypes)); } else { @@ -70,8 +87,19 @@ public class BcelGenericSignatureToTypeXConverter { Signature.FieldTypeSignature aFieldTypeSignature, Signature.FormalTypeParameter[] typeParams, World world) { + Map typeMap = new HashMap(); + ResolvedTypeX ret = fieldTypeSignature2TypeX(aFieldTypeSignature,typeParams,world,typeMap); + fixUpCircularDependencies(ret, typeMap); + return ret; + } + + private static ResolvedTypeX fieldTypeSignature2TypeX( + Signature.FieldTypeSignature aFieldTypeSignature, + Signature.FormalTypeParameter[] typeParams, + World world, + Map inProgressTypeVariableResolutions) { if (aFieldTypeSignature.isClassTypeSignature()) { - return classTypeSignature2TypeX((Signature.ClassTypeSignature)aFieldTypeSignature,typeParams,world); + return classTypeSignature2TypeX((Signature.ClassTypeSignature)aFieldTypeSignature,typeParams,world,inProgressTypeVariableResolutions); } else if (aFieldTypeSignature.isArrayTypeSignature()) { int dims = 0; Signature.TypeSignature ats = aFieldTypeSignature; @@ -79,22 +107,32 @@ public class BcelGenericSignatureToTypeXConverter { dims++; ats = ((Signature.ArrayTypeSignature)ats).typeSig; } - return world.resolve(TypeX.makeArray(typeSignature2TypeX(ats,typeParams,world), dims)); + return world.resolve(TypeX.makeArray(typeSignature2TypeX(ats,typeParams,world,inProgressTypeVariableResolutions), dims)); } else if (aFieldTypeSignature.isTypeVariableSignature()) { - return typeVariableSignature2TypeX((Signature.TypeVariableSignature)aFieldTypeSignature,typeParams,world); + ResolvedTypeX rtx = typeVariableSignature2TypeX((Signature.TypeVariableSignature)aFieldTypeSignature,typeParams,world,inProgressTypeVariableResolutions); + return rtx; } else { throw new IllegalStateException("Cant understand field type signature: " + aFieldTypeSignature); } } - + public static TypeVariable formalTypeParameter2TypeVariable( Signature.FormalTypeParameter aFormalTypeParameter, Signature.FormalTypeParameter[] typeParams, World world) { - TypeX upperBound = fieldTypeSignature2TypeX(aFormalTypeParameter.classBound,typeParams,world); + Map typeMap = new HashMap(); + return formalTypeParameter2TypeVariable(aFormalTypeParameter,typeParams,world,typeMap); + } + + private static TypeVariable formalTypeParameter2TypeVariable( + Signature.FormalTypeParameter aFormalTypeParameter, + Signature.FormalTypeParameter[] typeParams, + World world, + Map inProgressTypeVariableResolutions) { + TypeX upperBound = fieldTypeSignature2TypeX(aFormalTypeParameter.classBound,typeParams,world,inProgressTypeVariableResolutions); TypeX[] ifBounds = new TypeX[aFormalTypeParameter.interfaceBounds.length]; for (int i = 0; i < ifBounds.length; i++) { - ifBounds[i] = fieldTypeSignature2TypeX(aFormalTypeParameter.interfaceBounds[i], typeParams,world); + ifBounds[i] = fieldTypeSignature2TypeX(aFormalTypeParameter.interfaceBounds[i], typeParams,world,inProgressTypeVariableResolutions); } return new TypeVariable(aFormalTypeParameter.identifier,upperBound,ifBounds); } @@ -102,36 +140,50 @@ public class BcelGenericSignatureToTypeXConverter { private static ResolvedTypeX typeArgument2TypeX( Signature.TypeArgument aTypeArgument, Signature.FormalTypeParameter[] typeParams, - World world) { + World world, + Map inProgressTypeVariableResolutions) { if (aTypeArgument.isWildcard) return GenericsWildcardTypeX.GENERIC_WILDCARD.resolve(world); if (aTypeArgument.isMinus) { - TypeX bound = fieldTypeSignature2TypeX(aTypeArgument.signature, typeParams,world); + TypeX bound = fieldTypeSignature2TypeX(aTypeArgument.signature, typeParams,world,inProgressTypeVariableResolutions); ReferenceType rBound = (ReferenceType) world.resolve(bound); return new BoundedReferenceType(rBound,false,world); } else if (aTypeArgument.isPlus) { - TypeX bound = fieldTypeSignature2TypeX(aTypeArgument.signature, typeParams,world); + TypeX bound = fieldTypeSignature2TypeX(aTypeArgument.signature, typeParams,world,inProgressTypeVariableResolutions); ReferenceType rBound = (ReferenceType) world.resolve(bound); return new BoundedReferenceType(rBound,true,world); } else { - return fieldTypeSignature2TypeX(aTypeArgument.signature,typeParams,world); + return fieldTypeSignature2TypeX(aTypeArgument.signature,typeParams,world,inProgressTypeVariableResolutions); } } + public static ResolvedTypeX typeSignature2TypeX( Signature.TypeSignature aTypeSig, Signature.FormalTypeParameter[] typeParams, World world) { + Map typeMap = new HashMap(); + ResolvedTypeX ret = typeSignature2TypeX(aTypeSig,typeParams,world,typeMap); + fixUpCircularDependencies(ret, typeMap); + return ret; + } + + private static ResolvedTypeX typeSignature2TypeX( + Signature.TypeSignature aTypeSig, + Signature.FormalTypeParameter[] typeParams, + World world, + Map inProgressTypeVariableResolutions) { if (aTypeSig.isBaseType()) { return world.resolve(TypeX.forSignature(((Signature.BaseTypeSignature)aTypeSig).toString())); } else { - return fieldTypeSignature2TypeX((Signature.FieldTypeSignature)aTypeSig,typeParams,world); + return fieldTypeSignature2TypeX((Signature.FieldTypeSignature)aTypeSig,typeParams,world,inProgressTypeVariableResolutions); } } private static ResolvedTypeX typeVariableSignature2TypeX( Signature.TypeVariableSignature aTypeVarSig, Signature.FormalTypeParameter[] typeParams, - World world) { + World world, + Map inProgressTypeVariableResolutions) { Signature.FormalTypeParameter typeVarBounds = null; for (int i = 0; i < typeParams.length; i++) { if (typeParams[i].identifier.equals(aTypeVarSig.typeVariableName)) { @@ -142,10 +194,41 @@ public class BcelGenericSignatureToTypeXConverter { if (typeVarBounds == null) { throw new IllegalStateException("Undeclared type variable in signature: " + aTypeVarSig.typeVariableName); } - return new TypeVariableReferenceType( - formalTypeParameter2TypeVariable(typeVarBounds,typeParams,world), + if (inProgressTypeVariableResolutions.containsKey(typeVarBounds)) { + return (ResolvedTypeX) inProgressTypeVariableResolutions.get(typeVarBounds); + } + inProgressTypeVariableResolutions.put(typeVarBounds,new FTPHolder(typeVarBounds,world)); + ResolvedTypeX ret = new TypeVariableReferenceType( + formalTypeParameter2TypeVariable(typeVarBounds,typeParams,world,inProgressTypeVariableResolutions), world); + inProgressTypeVariableResolutions.put(typeVarBounds,ret); + return ret; } + private static void fixUpCircularDependencies(ResolvedTypeX aTypeX, Map typeVariableResolutions) { + if (! (aTypeX instanceof ReferenceType)) return; + + ReferenceType rt = (ReferenceType) aTypeX; + TypeVariable[] typeVars = rt.getTypeVariables(); + for (int i = 0; i < typeVars.length; i++) { + if (typeVars[i].getUpperBound() instanceof FTPHolder) { + Signature.FormalTypeParameter key = ((FTPHolder) typeVars[i].getUpperBound()).ftpToBeSubstituted; + typeVars[i].setUpperBound((TypeX)typeVariableResolutions.get(key)); + } + } + } + private static class FTPHolder extends ReferenceType { + public Signature.FormalTypeParameter ftpToBeSubstituted; + public FTPHolder(Signature.FormalTypeParameter ftp, World world) { + super("Ljava/lang/Object;",world); + this.ftpToBeSubstituted = ftp; + } + public String toString() { + return "placeholder for TypeVariable of " + ftpToBeSubstituted.toString(); + } + public ResolvedTypeX resolve(World world) { + return this; + } + } }