diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java index b86796f14f2c..63ccef201181 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java @@ -23,6 +23,8 @@ import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; +import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy; +import com.intellij.psi.impl.source.resolve.ParameterTypeInferencePolicy; import com.intellij.psi.impl.source.resolve.graphInference.constraints.*; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.search.GlobalSearchScope; @@ -87,6 +89,7 @@ public class InferenceSession { public final InferenceIncorporationPhase myIncorporationPhase = new InferenceIncorporationPhase(this); private final PsiElement myContext; + private ParameterTypeInferencePolicy myPolicy; private PsiSubstitutor myInferenceSubstitution = PsiSubstitutor.EMPTY; private PsiSubstitutor myRestoreNameSubstitution = PsiSubstitutor.EMPTY; @@ -104,6 +107,7 @@ public class InferenceSession { } myInferenceSessionContainer = initialState.getInferenceSessionContainer(); myErased = initialState.isErased(); + myPolicy = DefaultParameterTypeInferencePolicy.INSTANCE; } public InferenceSession(PsiTypeParameter[] typeParams, @@ -125,15 +129,25 @@ public class InferenceSession { addConstraint(new TypeCompatibilityConstraint(substituteWithInferenceVariables(leftTypes[i]), substituteWithInferenceVariables(rightType))); } } + myPolicy = DefaultParameterTypeInferencePolicy.INSTANCE; } - + public InferenceSession(PsiTypeParameter[] typeParams, PsiSubstitutor siteSubstitutor, PsiManager manager, PsiElement context) { + this(typeParams, siteSubstitutor, manager, context, DefaultParameterTypeInferencePolicy.INSTANCE); + } + + public InferenceSession(PsiTypeParameter[] typeParams, + PsiSubstitutor siteSubstitutor, + PsiManager manager, + PsiElement context, + ParameterTypeInferencePolicy policy) { myManager = manager; mySiteSubstitutor = siteSubstitutor; myContext = context; + myPolicy = policy; initBounds(typeParams); } @@ -1198,7 +1212,12 @@ public class InferenceSession { type = PsiType.getJavaLangRuntimeException(myManager, GlobalSearchScope.allScope(myManager.getProject())); } else { - type = myErased ? null : upperBound; + if (myErased) { + type = null; + } + else { + type = var.getBounds(InferenceBound.UPPER).size() == 1 ? myPolicy.getInferredTypeWithNoConstraint(myManager, upperBound).first : upperBound; + } } if (type instanceof PsiIntersectionType) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSessionContainer.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSessionContainer.java index 6bce73f04df3..446cf3d6a15c 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSessionContainer.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSessionContainer.java @@ -18,6 +18,7 @@ package com.intellij.psi.impl.source.resolve.graphInference; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Computable; import com.intellij.psi.*; +import com.intellij.psi.impl.source.resolve.ParameterTypeInferencePolicy; import com.intellij.psi.impl.source.resolve.graphInference.constraints.ExpressionCompatibilityConstraint; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.util.*; @@ -63,7 +64,8 @@ public class InferenceSessionContainer { @NotNull PsiParameter[] parameters, @NotNull PsiExpression[] arguments, @NotNull PsiSubstitutor partialSubstitutor, - @NotNull final PsiElement parent) { + @NotNull final PsiElement parent, + @NotNull final ParameterTypeInferencePolicy policy) { if (parent instanceof PsiCall) { final PsiExpressionList argumentList = ((PsiCall)parent).getArgumentList(); final MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(argumentList); @@ -82,14 +84,14 @@ public class InferenceSessionContainer { InferenceSession session; if (MethodCandidateInfo.isOverloadCheck() || !PsiDiamondType.ourDiamondGuard.currentStack().isEmpty() || LambdaUtil.isLambdaParameterCheck()) { - session = startTopLevelInference(topLevelCall); + session = startTopLevelInference(topLevelCall, policy); } else { session = CachedValuesManager.getCachedValue(topLevelCall, new CachedValueProvider() { @Nullable @Override public Result compute() { - return new Result(startTopLevelInference(topLevelCall), PsiModificationTracker.MODIFICATION_COUNT); + return new Result(startTopLevelInference(topLevelCall, policy), PsiModificationTracker.MODIFICATION_COUNT); } }); @@ -102,7 +104,7 @@ public class InferenceSessionContainer { if (childSession != null) { for (PsiTypeParameter parameter : typeParameters) { if (!childSession.getInferenceSubstitution().getSubstitutionMap().containsKey(parameter)) { - session = startTopLevelInference(topLevelCall); + session = startTopLevelInference(topLevelCall, policy); break; } } @@ -124,13 +126,13 @@ public class InferenceSessionContainer { } } else if (topLevelCall instanceof PsiMethodCallExpression) { - return new InferenceSession(typeParameters, partialSubstitutor, parent.getManager(), parent).prepareSubstitution(); + return new InferenceSession(typeParameters, partialSubstitutor, parent.getManager(), parent, policy).prepareSubstitution(); } } } } - final InferenceSession inferenceSession = new InferenceSession(typeParameters, partialSubstitutor, parent.getManager(), parent); + final InferenceSession inferenceSession = new InferenceSession(typeParameters, partialSubstitutor, parent.getManager(), parent, policy); inferenceSession.initExpressionConstraints(parameters, arguments, parent, null); return inferenceSession.infer(parameters, arguments, parent); } @@ -178,7 +180,7 @@ public class InferenceSessionContainer { } @Nullable - private static InferenceSession startTopLevelInference(final PsiCall topLevelCall) { + private static InferenceSession startTopLevelInference(final PsiCall topLevelCall, final ParameterTypeInferencePolicy policy) { final JavaResolveResult result = topLevelCall.resolveMethodGenerics(); if (result instanceof MethodCandidateInfo) { final PsiMethod method = ((MethodCandidateInfo)result).getElement(); @@ -190,7 +192,7 @@ public class InferenceSessionContainer { @Override public InferenceSession compute() { final InferenceSession topLevelSession = - new InferenceSession(method.getTypeParameters(), ((MethodCandidateInfo)result).getSiteSubstitutor(), topLevelCall.getManager(), topLevelCall); + new InferenceSession(method.getTypeParameters(), ((MethodCandidateInfo)result).getSiteSubstitutor(), topLevelCall.getManager(), topLevelCall, policy); topLevelSession.initExpressionConstraints(topLevelParameters, topLevelArguments, topLevelCall, method, ((MethodCandidateInfo)result).isVarargs()); topLevelSession.infer(topLevelParameters, topLevelArguments, topLevelCall, ((MethodCandidateInfo)result).createProperties()); return topLevelSession; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiGraphInferenceHelper.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiGraphInferenceHelper.java index 0d27f4719162..eab17977301b 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiGraphInferenceHelper.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiGraphInferenceHelper.java @@ -68,7 +68,7 @@ public class PsiGraphInferenceHelper implements PsiInferenceHelper { @NotNull LanguageLevel languageLevel) { if (typeParameters.length == 0) return partialSubstitutor; - return InferenceSessionContainer.infer(typeParameters, parameters, arguments, partialSubstitutor, parent); + return InferenceSessionContainer.infer(typeParameters, parameters, arguments, partialSubstitutor, parent, policy); } @NotNull diff --git a/java/java-tests/testData/codeInsight/completion/smartType/NoConstraintsWildcard-out.java b/java/java-tests/testData/codeInsight/completion/smartType/NoConstraintsWildcard-out.java new file mode 100644 index 000000000000..637094088ba9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/NoConstraintsWildcard-out.java @@ -0,0 +1,24 @@ + +class FooBar { + + { + addSourceRoot(JavaResourceRootType.RESOURCE); + } + + public static

void addSourceRoot(JpsModuleSourceRootType

rootType) { + + } + + interface JpsElement {} + + interface JpsModuleSourceRootType

{} + + static class JavaResourceRootProperties extends JpsElementBase{} + static class JpsElementBase> implements JpsElement {} + + static class JavaResourceRootType implements JpsModuleSourceRootType { + public static final JavaResourceRootType RESOURCE = new JavaResourceRootType(); + public static final JavaResourceRootType TEST_RESOURCE = new JavaResourceRootType(); + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/smartType/NoConstraintsWildcard.java b/java/java-tests/testData/codeInsight/completion/smartType/NoConstraintsWildcard.java new file mode 100644 index 000000000000..e4da82cb471b --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/NoConstraintsWildcard.java @@ -0,0 +1,24 @@ + +class FooBar { + + { + addSourceRoot(JavaResourceRootType.); + } + + public static

void addSourceRoot(JpsModuleSourceRootType

rootType) { + + } + + interface JpsElement {} + + interface JpsModuleSourceRootType

{} + + static class JavaResourceRootProperties extends JpsElementBase{} + static class JpsElementBase> implements JpsElement {} + + static class JavaResourceRootType implements JpsModuleSourceRootType { + public static final JavaResourceRootType RESOURCE = new JavaResourceRootType(); + public static final JavaResourceRootType TEST_RESOURCE = new JavaResourceRootType(); + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/smartType/NoConstraintsWildcard_out.java b/java/java-tests/testData/codeInsight/completion/smartType/NoConstraintsWildcard_out.java new file mode 100644 index 000000000000..e4da82cb471b --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/NoConstraintsWildcard_out.java @@ -0,0 +1,24 @@ + +class FooBar { + + { + addSourceRoot(JavaResourceRootType.); + } + + public static

void addSourceRoot(JpsModuleSourceRootType

rootType) { + + } + + interface JpsElement {} + + interface JpsModuleSourceRootType

{} + + static class JavaResourceRootProperties extends JpsElementBase{} + static class JpsElementBase> implements JpsElement {} + + static class JavaResourceRootType implements JpsModuleSourceRootType { + public static final JavaResourceRootType RESOURCE = new JavaResourceRootType(); + public static final JavaResourceRootType TEST_RESOURCE = new JavaResourceRootType(); + } + +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java index 1e1e4eca0a0f..bf243b5f9139 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java @@ -85,6 +85,10 @@ public class SmartType18CompletionTest extends LightFixtureCompletionTestCase { doTest(false); } + public void testNoConstraintsWildcard() throws Exception { + doTest(); + } + public void testInheritorConstructorRef() { myFixture.addClass("package intf; public interface Intf {}"); myFixture.addClass("package foo; public class ImplBar implements intf.Intf {}");