Lines 326-364
Link Here
|
326 |
return true; |
326 |
return true; |
327 |
} |
327 |
} |
328 |
// [JLS 5.5] S has no subtype X != T, such that |X| == |T| |
328 |
// [JLS 5.5] S has no subtype X != T, such that |X| == |T| |
329 |
TypeBinding genericCastType = castType.erasure(); // jump to generic type |
329 |
// if I2<T,U> extends I1<T>, then cast from I1<T> to I2<T,U> is unchecked |
330 |
TypeBinding genericMatch = genericCastType.findSuperTypeOriginatingFrom(expressionType); |
330 |
ParameterizedTypeBinding paramCastType = (ParameterizedTypeBinding) castType; |
331 |
if (genericMatch == match) { |
331 |
ParameterizedTypeBinding paramMatch = (ParameterizedTypeBinding) match; |
|
|
332 |
// easy case if less parameters on match |
333 |
TypeBinding[] castArguments = paramCastType.arguments; |
334 |
int length = castArguments.length; |
335 |
if (length > paramMatch.arguments.length) { |
332 |
this.bits |= ASTNode.UnsafeCast; |
336 |
this.bits |= ASTNode.UnsafeCast; |
333 |
} else { |
337 |
} else if ((paramCastType.tagBits & (TagBits.HasDirectWildcard|TagBits.HasTypeVariable)) != 0) { |
334 |
// if I2<T,U> extends I1<T>, then cast from I1<T> to I2<T,U> is unchecked |
338 |
// verify alternate cast type, substituting different type arguments |
335 |
ParameterizedTypeBinding paramCastType = (ParameterizedTypeBinding) castType; |
339 |
nextAlternateArgument: for (int i = 0; i < length; i++) { |
336 |
ParameterizedTypeBinding paramMatch = (ParameterizedTypeBinding) match; |
340 |
switch (castArguments[i].kind()) { |
337 |
// easy case if less parameters on match |
341 |
case Binding.WILDCARD_TYPE : |
338 |
TypeBinding[] castArguments = paramCastType.arguments; |
342 |
case Binding.TYPE_PARAMETER : |
339 |
int length = castArguments.length; |
343 |
break; // check substituting with other |
340 |
if (length > paramMatch.arguments.length) { |
344 |
default: |
341 |
this.bits |= ASTNode.UnsafeCast; |
345 |
continue nextAlternateArgument; // no alternative possible |
342 |
} else if ((paramCastType.tagBits & (TagBits.HasDirectWildcard|TagBits.HasTypeVariable)) != 0) { |
346 |
} |
343 |
// verify alternate cast type, substituting different type arguments |
347 |
TypeBinding[] alternateArguments; |
|
|
348 |
// need to clone for each iteration to avoid env paramtype cache interference |
349 |
System.arraycopy(paramCastType.arguments, 0, alternateArguments = new TypeBinding[length], 0, length); |
350 |
alternateArguments[i] = scope.getJavaLangObject(); |
344 |
LookupEnvironment environment = scope.environment(); |
351 |
LookupEnvironment environment = scope.environment(); |
345 |
nextAlternateArgument: for (int i = 0; i < length; i++) { |
352 |
ParameterizedTypeBinding alternateCastType = environment.createParameterizedType((ReferenceBinding)castType.erasure(), alternateArguments, castType.enclosingType()); |
346 |
switch (castArguments[i].kind()) { |
353 |
if (alternateCastType.findSuperTypeOriginatingFrom(expressionType) == match) { |
347 |
case Binding.WILDCARD_TYPE : |
354 |
this.bits |= ASTNode.UnsafeCast; |
348 |
case Binding.TYPE_PARAMETER : |
355 |
break; |
349 |
break; // check substituting with other |
|
|
350 |
default: |
351 |
continue nextAlternateArgument; // no alternative possible |
352 |
} |
353 |
TypeBinding[] alternateArguments; |
354 |
// need to clone for each iteration to avoid env paramtype cache interference |
355 |
System.arraycopy(paramCastType.arguments, 0, alternateArguments = new TypeBinding[length], 0, length); |
356 |
alternateArguments[i] = scope.getJavaLangObject(); |
357 |
ParameterizedTypeBinding alternateCastType = environment.createParameterizedType((ReferenceBinding)genericCastType, alternateArguments, castType.enclosingType()); |
358 |
if (alternateCastType.findSuperTypeOriginatingFrom(expressionType) == match) { |
359 |
this.bits |= ASTNode.UnsafeCast; |
360 |
break; |
361 |
} |
362 |
} |
356 |
} |
363 |
} |
357 |
} |
364 |
} |
358 |
} |