// of its parent. In this case it is parameterized but theres no < in the signature.
int startOfParams = signature.indexOf('<');
- int endOfParams = signature.lastIndexOf('>');
if (startOfParams==-1) {
// Should be an inner type of a parameterized type - could assert there is a '$' in the signature....
String signatureErasure = "L" + signature.substring(1);
UnresolvedType[] typeParams = new UnresolvedType[0];
return new UnresolvedType(signature,signatureErasure,typeParams);
} else {
- String signatureErasure = "L" + signature.substring(1,startOfParams) + ";";
- UnresolvedType[] typeParams = createTypeParams(signature.substring(startOfParams +1, endOfParams));
+ int endOfParams = locateMatchingEndBracket(signature,startOfParams);//signature.lastIndexOf('>');
+ StringBuffer erasureSig = new StringBuffer(signature);
+ while (startOfParams!=-1) {
+ erasureSig.delete(startOfParams,endOfParams+1);
+ startOfParams = erasureSig.indexOf("<");
+ if (startOfParams!=-1) endOfParams = locateMatchingEndBracket(erasureSig,startOfParams);
+ }
+
+ String signatureErasure = "L" + erasureSig.toString().substring(1);
+
+ // the type parameters of interest are only those that apply to the 'last type' in the signature
+ // if the signature is 'PMyInterface<String>$MyOtherType;' then there are none...
+ String lastType = null;
+ int nestedTypePosition = signature.indexOf("$");
+ if (nestedTypePosition!=-1) lastType = signature.substring(nestedTypePosition+1);
+ else lastType = new String(signature);
+ startOfParams = lastType.indexOf("<");
+ endOfParams = locateMatchingEndBracket(lastType,startOfParams);
+ UnresolvedType[] typeParams = UnresolvedType.NONE;
+ if (startOfParams!=-1) {
+ typeParams = createTypeParams(lastType.substring(startOfParams +1, endOfParams));
+ }
+
return new UnresolvedType(signature,signatureErasure,typeParams);
}
// can't replace above with convertSigToType - leads to stackoverflow
return new UnresolvedType(signature);
}
+ private static int locateMatchingEndBracket(String signature, int startOfParams) {
+ if (startOfParams==-1) return -1;
+ int count =1;
+ int idx = startOfParams;
+ while (count>0 && idx<signature.length()) {
+ idx++;
+ if (signature.charAt(idx)=='<') count++;
+ if (signature.charAt(idx)=='>') count--;
+ }
+ return idx;
+ }
+
+ private static int locateMatchingEndBracket(StringBuffer signature, int startOfParams) {
+ if (startOfParams==-1) return -1;
+ int count =1;
+ int idx = startOfParams;
+ while (count>0 && idx<signature.length()) {
+ idx++;
+ if (signature.charAt(idx)=='<') count++;
+ if (signature.charAt(idx)=='>') count--;
+ }
+ return idx;
+ }
+
private static UnresolvedType[] createTypeParams(String typeParameterSpecification) {
String remainingToProcess = typeParameterSpecification;
List types = new ArrayList();
this,
componentType);
} else {
- ret = resolveToReferenceType(ty);
+ ret = resolveToReferenceType(ty,allowMissing);
if (!allowMissing && ret.isMissing()) {
ret = handleRequiredMissingTypeDuringResolution(ty);
}
* Resolve to a ReferenceType - simple, raw, parameterized, or generic.
* Raw, parameterized, and generic versions of a type share a delegate.
*/
- private final ResolvedType resolveToReferenceType(UnresolvedType ty) {
+ private final ResolvedType resolveToReferenceType(UnresolvedType ty,boolean allowMissing) {
if (ty.isParameterizedType()) {
// ======= parameterized types ================
- ReferenceType genericType = (ReferenceType)resolveGenericTypeFor(ty,false);
+ ResolvedType rt = resolveGenericTypeFor(ty,allowMissing);
+ if (rt.isMissing()) return rt;
+ ReferenceType genericType = (ReferenceType)rt;
currentlyResolvingBaseType = genericType;
- ReferenceType parameterizedType =
+ ReferenceType parameterizedType =
TypeFactory.createParameterizedType(genericType, ty.typeParameters, this);
currentlyResolvingBaseType = null;
return parameterizedType;
String rawSignature = anUnresolvedType.getRawType().getSignature();
ResolvedType rawType = (ResolvedType) typeMap.get(rawSignature);
if (rawType==null) {
- rawType = resolve(UnresolvedType.forSignature(rawSignature),false);
+ rawType = resolve(UnresolvedType.forSignature(rawSignature),allowMissing);
typeMap.put(rawSignature,rawType);
}
+ if (rawType.isMissing()) return rawType;
// Does the raw type know its generic form? (It will if we created the
// raw type from a source type, it won't if its been created just through
}
private ResolvedType lookupTypeInWorld(World world, String typeName) {
- ResolvedType ret = world.resolve(UnresolvedType.forName(typeName),true);
+ UnresolvedType ut = UnresolvedType.forName(typeName);
+ ResolvedType ret = world.resolve(ut,true);
while (ret.isMissing()) {
int lastDot = typeName.lastIndexOf('.');
if (lastDot == -1) break;
}
private TypePattern resolveParameterizedType(IScope scope, UnresolvedType aType, boolean requireExactType) {
- if (!verifyTypeParameters(aType.resolve(scope.getWorld()),scope,requireExactType)) return TypePattern.NO; // messages already isued
+ ResolvedType rt = aType.resolve(scope.getWorld());
+ if (!verifyTypeParameters(rt,scope,requireExactType)) return TypePattern.NO; // messages already isued
// Only if the type is exact *and* the type parameters are exact should we create an
// ExactTypePattern for this WildTypePattern
if (typeParameters.areAllExactWithNoSubtypesAllowed()) {
for (int i = 0; i < typeParameterTypes.length; i++) {
typeParameterTypes[i] = ((ExactTypePattern)typePats[i]).getExactType();
}
- ResolvedType type = TypeFactory.createParameterizedType(aType.resolve(scope.getWorld()), typeParameterTypes, scope.getWorld());
+ // rt could be a parameterized type 156058
+ if (rt.isParameterizedType()) {
+ rt = rt.getGenericType();
+ }
+ ResolvedType type = TypeFactory.createParameterizedType(rt, typeParameterTypes, scope.getWorld());
if (isGeneric) type = type.getGenericType();
// UnresolvedType tx = UnresolvedType.forParameterizedTypes(aType,typeParameterTypes);
// UnresolvedType type = scope.getWorld().resolve(tx,true);