@@ -30,6 +30,7 @@ import org.aspectj.weaver.ResolvedMemberImpl; | |||
import org.aspectj.weaver.ResolvedType; | |||
import org.aspectj.weaver.UnresolvedType; | |||
import org.aspectj.weaver.World; | |||
import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter.GenericSignatureFormatException; | |||
final class BcelField extends ResolvedMemberImpl { | |||
@@ -155,7 +156,16 @@ final class BcelField extends ResolvedMemberImpl { | |||
Signature.FieldTypeSignature fts = new GenericSignatureParser().parseAsFieldSignature(gSig); | |||
Signature.ClassSignature genericTypeSig = bcelObjectType.getGenericClassTypeSignature(); | |||
Signature.FormalTypeParameter[] typeVars = ((genericTypeSig == null) ? new Signature.FormalTypeParameter[0] : genericTypeSig.formalTypeParameters); | |||
genericFieldType = BcelGenericSignatureToTypeXConverter.fieldTypeSignature2TypeX(fts, typeVars, world); | |||
try { | |||
genericFieldType = | |||
BcelGenericSignatureToTypeXConverter.fieldTypeSignature2TypeX(fts, typeVars, world); | |||
} catch (GenericSignatureFormatException e) { | |||
// development bug, fail fast with good info | |||
throw new IllegalStateException( | |||
"While determing the generic field type of " + this.toString() | |||
+ " with generic signature " + gSig + " the following error was detected: " | |||
+ e.getMessage()); | |||
} | |||
} else { | |||
genericFieldType = getReturnType(); | |||
} |
@@ -35,7 +35,9 @@ public class BcelGenericSignatureToTypeXConverter { | |||
public static ResolvedType classTypeSignature2TypeX( | |||
Signature.ClassTypeSignature aClassTypeSignature, | |||
Signature.FormalTypeParameter[] typeParams, | |||
World world) { | |||
World world) | |||
throws GenericSignatureFormatException | |||
{ | |||
Map typeMap = new HashMap(); | |||
ResolvedType ret = classTypeSignature2TypeX(aClassTypeSignature,typeParams,world,typeMap); | |||
fixUpCircularDependencies(ret, typeMap); | |||
@@ -47,7 +49,9 @@ public class BcelGenericSignatureToTypeXConverter { | |||
Signature.ClassTypeSignature aClassTypeSignature, | |||
Signature.FormalTypeParameter[] typeParams, | |||
World world, | |||
Map inProgressTypeVariableResolutions) { | |||
Map inProgressTypeVariableResolutions) | |||
throws GenericSignatureFormatException | |||
{ | |||
// 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 | |||
@@ -94,7 +98,9 @@ public class BcelGenericSignatureToTypeXConverter { | |||
public static ResolvedType fieldTypeSignature2TypeX( | |||
Signature.FieldTypeSignature aFieldTypeSignature, | |||
Signature.FormalTypeParameter[] typeParams, | |||
World world) { | |||
World world) | |||
throws GenericSignatureFormatException | |||
{ | |||
Map typeMap = new HashMap(); | |||
ResolvedType ret = fieldTypeSignature2TypeX(aFieldTypeSignature,typeParams,world,typeMap); | |||
fixUpCircularDependencies(ret, typeMap); | |||
@@ -105,7 +111,9 @@ public class BcelGenericSignatureToTypeXConverter { | |||
Signature.FieldTypeSignature aFieldTypeSignature, | |||
Signature.FormalTypeParameter[] typeParams, | |||
World world, | |||
Map inProgressTypeVariableResolutions) { | |||
Map inProgressTypeVariableResolutions) | |||
throws GenericSignatureFormatException | |||
{ | |||
if (aFieldTypeSignature.isClassTypeSignature()) { | |||
return classTypeSignature2TypeX((Signature.ClassTypeSignature)aFieldTypeSignature,typeParams,world,inProgressTypeVariableResolutions); | |||
} else if (aFieldTypeSignature.isArrayTypeSignature()) { | |||
@@ -120,14 +128,16 @@ public class BcelGenericSignatureToTypeXConverter { | |||
ResolvedType rtx = typeVariableSignature2TypeX((Signature.TypeVariableSignature)aFieldTypeSignature,typeParams,world,inProgressTypeVariableResolutions); | |||
return rtx; | |||
} else { | |||
throw new IllegalStateException("Cant understand field type signature: " + aFieldTypeSignature); | |||
throw new GenericSignatureFormatException("Cant understand field type signature: " + aFieldTypeSignature); | |||
} | |||
} | |||
public static TypeVariable formalTypeParameter2TypeVariable( | |||
Signature.FormalTypeParameter aFormalTypeParameter, | |||
Signature.FormalTypeParameter[] typeParams, | |||
World world) { | |||
World world) | |||
throws GenericSignatureFormatException | |||
{ | |||
Map typeMap = new HashMap(); | |||
return formalTypeParameter2TypeVariable(aFormalTypeParameter,typeParams,world,typeMap); | |||
} | |||
@@ -136,7 +146,9 @@ public class BcelGenericSignatureToTypeXConverter { | |||
Signature.FormalTypeParameter aFormalTypeParameter, | |||
Signature.FormalTypeParameter[] typeParams, | |||
World world, | |||
Map inProgressTypeVariableResolutions) { | |||
Map inProgressTypeVariableResolutions) | |||
throws GenericSignatureFormatException | |||
{ | |||
UnresolvedType upperBound = fieldTypeSignature2TypeX(aFormalTypeParameter.classBound,typeParams,world,inProgressTypeVariableResolutions); | |||
UnresolvedType[] ifBounds = new UnresolvedType[aFormalTypeParameter.interfaceBounds.length]; | |||
for (int i = 0; i < ifBounds.length; i++) { | |||
@@ -149,7 +161,9 @@ public class BcelGenericSignatureToTypeXConverter { | |||
Signature.TypeArgument aTypeArgument, | |||
Signature.FormalTypeParameter[] typeParams, | |||
World world, | |||
Map inProgressTypeVariableResolutions) { | |||
Map inProgressTypeVariableResolutions) | |||
throws GenericSignatureFormatException | |||
{ | |||
if (aTypeArgument.isWildcard) return UnresolvedType.SOMETHING.resolve(world); | |||
if (aTypeArgument.isMinus) { | |||
UnresolvedType bound = fieldTypeSignature2TypeX(aTypeArgument.signature, typeParams,world,inProgressTypeVariableResolutions); | |||
@@ -168,7 +182,9 @@ public class BcelGenericSignatureToTypeXConverter { | |||
public static ResolvedType typeSignature2TypeX( | |||
Signature.TypeSignature aTypeSig, | |||
Signature.FormalTypeParameter[] typeParams, | |||
World world) { | |||
World world) | |||
throws GenericSignatureFormatException | |||
{ | |||
Map typeMap = new HashMap(); | |||
ResolvedType ret = typeSignature2TypeX(aTypeSig,typeParams,world,typeMap); | |||
fixUpCircularDependencies(ret, typeMap); | |||
@@ -179,7 +195,9 @@ public class BcelGenericSignatureToTypeXConverter { | |||
Signature.TypeSignature aTypeSig, | |||
Signature.FormalTypeParameter[] typeParams, | |||
World world, | |||
Map inProgressTypeVariableResolutions) { | |||
Map inProgressTypeVariableResolutions) | |||
throws GenericSignatureFormatException | |||
{ | |||
if (aTypeSig.isBaseType()) { | |||
return world.resolve(UnresolvedType.forSignature(((Signature.BaseTypeSignature)aTypeSig).toString())); | |||
} else { | |||
@@ -191,7 +209,9 @@ public class BcelGenericSignatureToTypeXConverter { | |||
Signature.TypeVariableSignature aTypeVarSig, | |||
Signature.FormalTypeParameter[] typeParams, | |||
World world, | |||
Map inProgressTypeVariableResolutions) { | |||
Map inProgressTypeVariableResolutions) | |||
throws GenericSignatureFormatException | |||
{ | |||
Signature.FormalTypeParameter typeVarBounds = null; | |||
for (int i = 0; i < typeParams.length; i++) { | |||
if (typeParams[i].identifier.equals(aTypeVarSig.typeVariableName)) { | |||
@@ -200,7 +220,7 @@ public class BcelGenericSignatureToTypeXConverter { | |||
} | |||
} | |||
if (typeVarBounds == null) { | |||
throw new IllegalStateException("Undeclared type variable in signature: " + aTypeVarSig.typeVariableName); | |||
throw new GenericSignatureFormatException("Undeclared type variable in signature: " + aTypeVarSig.typeVariableName); | |||
} | |||
if (inProgressTypeVariableResolutions.containsKey(typeVarBounds)) { | |||
return (ResolvedType) inProgressTypeVariableResolutions.get(typeVarBounds); | |||
@@ -239,4 +259,10 @@ public class BcelGenericSignatureToTypeXConverter { | |||
return this; | |||
} | |||
} | |||
public static class GenericSignatureFormatException extends Exception { | |||
public GenericSignatureFormatException(String explanation) { | |||
super(explanation); | |||
} | |||
} | |||
} |
@@ -38,6 +38,7 @@ import org.aspectj.weaver.ResolvedType; | |||
import org.aspectj.weaver.ShadowMunger; | |||
import org.aspectj.weaver.UnresolvedType; | |||
import org.aspectj.weaver.World; | |||
import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter.GenericSignatureFormatException; | |||
final class BcelMethod extends ResolvedMemberImpl { | |||
@@ -279,15 +280,31 @@ final class BcelMethod extends ResolvedMemberImpl { | |||
System.arraycopy(mSig.formalTypeParameters,0,formals,0,mSig.formalTypeParameters.length); | |||
System.arraycopy(parentFormals,0,formals,mSig.formalTypeParameters.length,parentFormals.length); | |||
Signature.TypeSignature returnTypeSignature = mSig.returnType; | |||
genericReturnType = BcelGenericSignatureToTypeXConverter.typeSignature2TypeX( | |||
returnTypeSignature, formals, | |||
world); | |||
try { | |||
genericReturnType = BcelGenericSignatureToTypeXConverter.typeSignature2TypeX( | |||
returnTypeSignature, formals, | |||
world); | |||
} catch (GenericSignatureFormatException e) { | |||
// development bug, fail fast with good info | |||
throw new IllegalStateException( | |||
"While determing the generic return type of " + this.toString() | |||
+ " with generic signature " + gSig + " the following error was detected: " | |||
+ e.getMessage()); | |||
} | |||
Signature.TypeSignature[] paramTypeSigs = mSig.parameters; | |||
genericParameterTypes = new UnresolvedType[paramTypeSigs.length]; | |||
for (int i = 0; i < paramTypeSigs.length; i++) { | |||
genericParameterTypes[i] = | |||
BcelGenericSignatureToTypeXConverter.typeSignature2TypeX( | |||
paramTypeSigs[i],formals,world); | |||
try { | |||
genericParameterTypes[i] = | |||
BcelGenericSignatureToTypeXConverter.typeSignature2TypeX( | |||
paramTypeSigs[i],formals,world); | |||
} catch (GenericSignatureFormatException e) { | |||
// development bug, fail fast with good info | |||
throw new IllegalStateException( | |||
"While determing the generic parameter types of " + this.toString() | |||
+ " with generic signature " + gSig + " the following error was detected: " | |||
+ e.getMessage()); | |||
} | |||
if (paramTypeSigs[i] instanceof TypeVariableSignature) { | |||
canBeParameterized = true; | |||
} |
@@ -43,6 +43,7 @@ import org.aspectj.weaver.ResolvedType; | |||
import org.aspectj.weaver.TypeVariable; | |||
import org.aspectj.weaver.UnresolvedType; | |||
import org.aspectj.weaver.WeaverStateInfo; | |||
import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter.GenericSignatureFormatException; | |||
import org.aspectj.weaver.patterns.PerClause; | |||
@@ -137,10 +138,18 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { | |||
typeVars = new TypeVariable[classSig.formalTypeParameters.length]; | |||
for (int i = 0; i < typeVars.length; i++) { | |||
Signature.FormalTypeParameter ftp = classSig.formalTypeParameters[i]; | |||
typeVars[i] = BcelGenericSignatureToTypeXConverter.formalTypeParameter2TypeVariable( | |||
ftp, | |||
classSig.formalTypeParameters, | |||
getResolvedTypeX().getWorld()); | |||
try { | |||
typeVars[i] = BcelGenericSignatureToTypeXConverter.formalTypeParameter2TypeVariable( | |||
ftp, | |||
classSig.formalTypeParameters, | |||
getResolvedTypeX().getWorld()); | |||
} catch (GenericSignatureFormatException e) { | |||
// this is a development bug, so fail fast with good info | |||
throw new IllegalStateException( | |||
"While getting the type variables for type " + this.toString() | |||
+ " with generic signature " + classSig + | |||
" the following error condition was detected: " + e.getMessage()); | |||
} | |||
} | |||
} | |||
return typeVars; | |||
@@ -525,16 +534,32 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { | |||
} | |||
} | |||
Signature.ClassTypeSignature superSig = cSig.superclassSignature; | |||
this.superClass = | |||
BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX( | |||
superSig, formalsForResolution, getResolvedTypeX().getWorld()); | |||
try { | |||
this.superClass = | |||
BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX( | |||
superSig, formalsForResolution, getResolvedTypeX().getWorld()); | |||
} catch (GenericSignatureFormatException e) { | |||
// development bug, fail fast with good info | |||
throw new IllegalStateException( | |||
"While determing the generic superclass of " + this.javaClass.getClassName() | |||
+ " with generic signature " + this.javaClass.getGenericSignature() + " the following error was detected: " | |||
+ e.getMessage()); | |||
} | |||
this.interfaces = new ResolvedType[cSig.superInterfaceSignatures.length]; | |||
for (int i = 0; i < cSig.superInterfaceSignatures.length; i++) { | |||
this.interfaces[i] = | |||
BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX( | |||
cSig.superInterfaceSignatures[i], | |||
formalsForResolution, | |||
getResolvedTypeX().getWorld()); | |||
try { | |||
this.interfaces[i] = | |||
BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX( | |||
cSig.superInterfaceSignatures[i], | |||
formalsForResolution, | |||
getResolvedTypeX().getWorld()); | |||
} catch (GenericSignatureFormatException e) { | |||
// development bug, fail fast with good info | |||
throw new IllegalStateException( | |||
"While determing the generic superinterfaces of " + this.javaClass.getClassName() | |||
+ " with generic signature " + this.javaClass.getGenericSignature() + " the following error was detected: " | |||
+ e.getMessage()); | |||
} | |||
} | |||
} | |||
if (isGeneric()) { | |||
@@ -568,18 +593,29 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { | |||
} | |||
private Signature.FormalTypeParameter[] getFormalTypeParametersFromOuterClass() { | |||
List typeParameters = new ArrayList(); | |||
ReferenceType outer = getOuterClass(); | |||
ReferenceTypeDelegate outerDelegate = outer.getDelegate(); | |||
if (!(outerDelegate instanceof BcelObjectType)) { | |||
throw new IllegalStateException("How come we're in BcelObjectType resolving an inner type of something that is NOT a BcelObjectType??"); | |||
} | |||
BcelObjectType outerObjectType = (BcelObjectType) outerDelegate; | |||
if (outerObjectType.isNestedClass()) { | |||
Signature.FormalTypeParameter[] parentParams = outerObjectType.getFormalTypeParametersFromOuterClass(); | |||
for (int i = 0; i < parentParams.length; i++) { | |||
typeParameters.add(parentParams[i]); | |||
} | |||
} | |||
Signature.ClassSignature outerSig = outerObjectType.getGenericClassTypeSignature(); | |||
if (outerSig != null) { | |||
return outerSig.formalTypeParameters; | |||
} else { | |||
return new Signature.FormalTypeParameter[0]; | |||
} | |||
for (int i = 0; i < outerSig.formalTypeParameters .length; i++) { | |||
typeParameters.add(outerSig.formalTypeParameters[i]); | |||
} | |||
} | |||
Signature.FormalTypeParameter[] ret = new Signature.FormalTypeParameter[typeParameters.size()]; | |||
typeParameters.toArray(ret); | |||
return ret; | |||
} | |||
private void ensureGenericInfoProcessed() { getDeclaredGenericSignature();} |
@@ -25,7 +25,7 @@ import org.aspectj.weaver.UnresolvedType; | |||
*/ | |||
public class BcelGenericSignatureToTypeXTestCase extends TestCase { | |||
public void testEnumFromHell() { | |||
public void testEnumFromHell() throws Exception { | |||
BcelWorld world = new BcelWorld(); | |||
JavaClass javaLangEnum = Repository.lookupClass("java/lang/Enum"); | |||
Signature.ClassSignature cSig = javaLangEnum.getGenericClassTypeSignature(); | |||
@@ -53,7 +53,7 @@ public class BcelGenericSignatureToTypeXTestCase extends TestCase { | |||
assertEquals("Ljava/io/Serializable;",serializable.getSignature()); | |||
} | |||
public void testColonColon() { | |||
public void testColonColon() throws Exception { | |||
BcelWorld world = new BcelWorld(); | |||
Signature.ClassSignature cSig = new GenericSignatureParser().parseAsClassSignature("<T::Ljava/io/Serializable;>Ljava/lang/Object;Ljava/lang/Comparable<TT;>;"); | |||
UnresolvedType resolved = BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX( |