mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
pass parameter type inference policy to produce ? extends for cases when no constraints were found during inference (IDEA-156231)
This commit is contained in:
+21
-2
@@ -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) {
|
||||
|
||||
+10
-8
@@ -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<InferenceSession>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Result<InferenceSession> compute() {
|
||||
return new Result<InferenceSession>(startTopLevelInference(topLevelCall), PsiModificationTracker.MODIFICATION_COUNT);
|
||||
return new Result<InferenceSession>(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;
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
|
||||
class FooBar {
|
||||
|
||||
{
|
||||
addSourceRoot(JavaResourceRootType.RESOURCE);
|
||||
}
|
||||
|
||||
public static <P extends JpsElement> void addSourceRoot(JpsModuleSourceRootType<P> rootType) {
|
||||
|
||||
}
|
||||
|
||||
interface JpsElement {}
|
||||
|
||||
interface JpsModuleSourceRootType<P extends JpsElement> {}
|
||||
|
||||
static class JavaResourceRootProperties extends JpsElementBase<JavaResourceRootProperties>{}
|
||||
static class JpsElementBase<Self extends JpsElementBase<Self>> implements JpsElement {}
|
||||
|
||||
static class JavaResourceRootType implements JpsModuleSourceRootType<JavaResourceRootProperties> {
|
||||
public static final JavaResourceRootType RESOURCE = new JavaResourceRootType();
|
||||
public static final JavaResourceRootType TEST_RESOURCE = new JavaResourceRootType();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
class FooBar {
|
||||
|
||||
{
|
||||
addSourceRoot(JavaResourceRootType.<caret>);
|
||||
}
|
||||
|
||||
public static <P extends JpsElement> void addSourceRoot(JpsModuleSourceRootType<P> rootType) {
|
||||
|
||||
}
|
||||
|
||||
interface JpsElement {}
|
||||
|
||||
interface JpsModuleSourceRootType<P extends JpsElement> {}
|
||||
|
||||
static class JavaResourceRootProperties extends JpsElementBase<JavaResourceRootProperties>{}
|
||||
static class JpsElementBase<Self extends JpsElementBase<Self>> implements JpsElement {}
|
||||
|
||||
static class JavaResourceRootType implements JpsModuleSourceRootType<JavaResourceRootProperties> {
|
||||
public static final JavaResourceRootType RESOURCE = new JavaResourceRootType();
|
||||
public static final JavaResourceRootType TEST_RESOURCE = new JavaResourceRootType();
|
||||
}
|
||||
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
|
||||
class FooBar {
|
||||
|
||||
{
|
||||
addSourceRoot(JavaResourceRootType.<caret>);
|
||||
}
|
||||
|
||||
public static <P extends JpsElement> void addSourceRoot(JpsModuleSourceRootType<P> rootType) {
|
||||
|
||||
}
|
||||
|
||||
interface JpsElement {}
|
||||
|
||||
interface JpsModuleSourceRootType<P extends JpsElement> {}
|
||||
|
||||
static class JavaResourceRootProperties extends JpsElementBase<JavaResourceRootProperties>{}
|
||||
static class JpsElementBase<Self extends JpsElementBase<Self>> implements JpsElement {}
|
||||
|
||||
static class JavaResourceRootType implements JpsModuleSourceRootType<JavaResourceRootProperties> {
|
||||
public static final JavaResourceRootType RESOURCE = new JavaResourceRootType();
|
||||
public static final JavaResourceRootType TEST_RESOURCE = new JavaResourceRootType();
|
||||
}
|
||||
|
||||
}
|
||||
+4
@@ -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<T> {}");
|
||||
myFixture.addClass("package foo; public class ImplBar implements intf.Intf<String> {}");
|
||||
|
||||
Reference in New Issue
Block a user