mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
type compatibility constrain: boxing is not completeness-preserving: move treatment to return constraint
This commit is contained in:
+34
-4
@@ -300,8 +300,9 @@ public class InferenceSession {
|
||||
private void initReturnTypeConstraint(PsiMethod method, final PsiCallExpression context) {
|
||||
if (PsiPolyExpressionUtil.isMethodCallPolyExpression(context, method) ||
|
||||
context instanceof PsiNewExpression && PsiDiamondType.ourDiamondGuard.currentStack().contains(context)) {
|
||||
final PsiType returnType = method.getReturnType();
|
||||
PsiType returnType = method.getReturnType();
|
||||
if (!PsiType.VOID.equals(returnType) && returnType != null) {
|
||||
returnType = PsiImplUtil.normalizeWildcardTypeByPosition(returnType, context);
|
||||
PsiType targetType = PsiTypesUtil.getExpectedTypeByParent(context);
|
||||
if (targetType == null) {
|
||||
targetType = PsiResolveHelper.ourGraphGuard.doPreventingRecursion(context, true, new Computable<PsiType>() {
|
||||
@@ -312,15 +313,44 @@ public class InferenceSession {
|
||||
});
|
||||
}
|
||||
if (targetType != null) {
|
||||
if (targetType instanceof PsiClassType && ((PsiClassType)targetType).isRaw()) {
|
||||
setErased();
|
||||
final InferenceVariable inferenceVariable = shouldResolveAndInstantiate(returnType, targetType);
|
||||
if (inferenceVariable != null) {
|
||||
resolveBounds(Collections.singletonList(inferenceVariable), mySiteSubstitutor, true);
|
||||
myConstraints.add(new TypeCompatibilityConstraint(inferenceVariable.getInstantiation(), returnType));
|
||||
}
|
||||
else {
|
||||
if (targetType instanceof PsiClassType && ((PsiClassType)targetType).isRaw()) {
|
||||
setErased();
|
||||
}
|
||||
myConstraints.add(new TypeCompatibilityConstraint(myErased ? TypeConversionUtil.erasure(targetType) : GenericsUtil.eliminateWildcards(targetType, false), returnType));
|
||||
}
|
||||
myConstraints.add(new TypeCompatibilityConstraint(myErased ? TypeConversionUtil.erasure(targetType) : GenericsUtil.eliminateWildcards(targetType, false), PsiImplUtil.normalizeWildcardTypeByPosition(returnType, context)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private InferenceVariable shouldResolveAndInstantiate(PsiType returnType, PsiType targetType) {
|
||||
final InferenceVariable inferenceVariable = getInferenceVariable(returnType);
|
||||
if (inferenceVariable != null) {
|
||||
if (targetType instanceof PsiPrimitiveType && hasPrimitiveWrapperBound(inferenceVariable)) {
|
||||
return inferenceVariable;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean hasPrimitiveWrapperBound(InferenceVariable inferenceVariable) {
|
||||
for (InferenceBound inferenceBound : InferenceBound.values()) {
|
||||
final List<PsiType> bounds = inferenceVariable.getBounds(inferenceBound);
|
||||
for (PsiType bound : bounds) {
|
||||
if (PsiPrimitiveType.getUnboxedType(bound) != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private PsiType getTargetType(final PsiExpression context) {
|
||||
final PsiElement parent = PsiUtil.skipParenthesizedExprUp(context.getParent());
|
||||
if (parent instanceof PsiExpressionList) {
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ public class TypeCompatibilityConstraint implements ConstraintFormula {
|
||||
if (myT instanceof PsiPrimitiveType) {
|
||||
final PsiClassType boxedType = ((PsiPrimitiveType)myT).getBoxedType(session.getManager(), session.getScope());
|
||||
if (boxedType != null) {
|
||||
constraints.add(new TypeCompatibilityConstraint(boxedType, myS));
|
||||
constraints.add(new TypeEqualityConstraint(boxedType, myS));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
public class Sample {
|
||||
static <T> T foo(T t) { return null; }
|
||||
|
||||
static {
|
||||
long l11 = foo(1 );
|
||||
}
|
||||
}
|
||||
+4
@@ -30,6 +30,10 @@ public class ConstraintsInferenceMiscTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
public void testPrimitiveTypesCompatibility() throws Exception {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
private void doTest(final boolean checkWarnings) {
|
||||
doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user