mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 04:51:24 +07:00
graph inference for the first arg
This commit is contained in:
@@ -25,6 +25,7 @@ import com.intellij.psi.scope.util.PsiScopesUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ConcurrentHashMap;
|
||||
import com.intellij.util.containers.ConcurrentWeakHashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -39,7 +40,7 @@ import java.util.Map;
|
||||
public class ProcessCandidateParameterTypeInferencePolicy extends DefaultParameterTypeInferencePolicy {
|
||||
public static final ProcessCandidateParameterTypeInferencePolicy INSTANCE = new ProcessCandidateParameterTypeInferencePolicy();
|
||||
private static final Map<PsiExpression, Map<JavaResolveResult, PsiSubstitutor>> ourResults =
|
||||
new ConcurrentHashMap<PsiExpression, Map<JavaResolveResult, PsiSubstitutor>>();
|
||||
new ConcurrentWeakHashMap<PsiExpression, Map<JavaResolveResult, PsiSubstitutor>>();
|
||||
|
||||
@Override
|
||||
public Pair<PsiType, ConstraintType> inferTypeConstraintFromCallContext(PsiExpression innerMethodCall,
|
||||
@@ -60,7 +61,7 @@ public class ProcessCandidateParameterTypeInferencePolicy extends DefaultParamet
|
||||
final PsiSubstitutor substitutor;
|
||||
if (subst == PsiSubstitutor.UNKNOWN) {
|
||||
if (result instanceof MethodCandidateInfo) {
|
||||
List<PsiExpression> leftArgs = Arrays.asList(expressions).subList(0, i);
|
||||
List<PsiExpression> leftArgs = getExpressions(expressions, i);
|
||||
substitutor = ((MethodCandidateInfo)result).inferTypeArguments(this, leftArgs.toArray(new PsiExpression[leftArgs.size()]));
|
||||
}
|
||||
else {
|
||||
@@ -82,6 +83,10 @@ public class ProcessCandidateParameterTypeInferencePolicy extends DefaultParamet
|
||||
return null;
|
||||
}
|
||||
|
||||
protected List<PsiExpression> getExpressions(PsiExpression[] expressions, int i) {
|
||||
return Arrays.asList(expressions).subList(0, i);
|
||||
}
|
||||
|
||||
private static Pair<PsiType, ConstraintType> inferConstraint(PsiTypeParameter typeParameter,
|
||||
PsiExpression innerMethodCall,
|
||||
int parameterIdx,
|
||||
|
||||
@@ -39,6 +39,7 @@ import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -1060,7 +1061,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
|
||||
PsiClassType[] superTypes = typeParameter.getSuperTypes();
|
||||
if (superTypes.length == 0) return null;
|
||||
PsiType superType = TypeConversionUtil.erasure(superTypes[0]);
|
||||
PsiType superType = TypeConversionUtil.erasure(substitutor.substitute(superTypes[0]));
|
||||
if (superType == null) superType = PsiType.getJavaLangObject(manager, scope);
|
||||
if (superType == null) return null;
|
||||
return policy.getInferredTypeWithNoConstraint(manager, superType);
|
||||
@@ -1095,6 +1096,14 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
}
|
||||
|
||||
private static RecursionGuard ourGraphGuard = RecursionManager.createGuard("graphTypeArgInference");
|
||||
private static final ProcessCandidateParameterTypeInferencePolicy GRAPH_INFERENCE_POLICY = new ProcessCandidateParameterTypeInferencePolicy() {
|
||||
@Override
|
||||
protected List<PsiExpression> getExpressions(PsiExpression[] expressions, int i) {
|
||||
final List<PsiExpression> list = Arrays.asList(expressions);
|
||||
list.set(i, null);
|
||||
return list;
|
||||
}
|
||||
};
|
||||
private static Pair<PsiType, ConstraintType> graphInferenceFromCallContext(@NotNull final PsiExpression methodCall,
|
||||
@NotNull final PsiTypeParameter typeParameter,
|
||||
@NotNull final PsiCallExpression parentCall) {
|
||||
@@ -1127,8 +1136,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
|
||||
final PsiExpression methodCallCopy = (PsiExpression)currentCallInCopy.replace(nullPlaceholder);
|
||||
copy.putCopyableUserData(CALL_EXPRESSION_KEY, parentCall);
|
||||
return ProcessCandidateParameterTypeInferencePolicy.INSTANCE
|
||||
.inferTypeConstraintFromCallContext(methodCallCopy, copyArgumentList, copy, typeParameter);
|
||||
return GRAPH_INFERENCE_POLICY.inferTypeConstraintFromCallContext(methodCallCopy, copyArgumentList, copy, typeParameter);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import java.util.*;
|
||||
class Main {
|
||||
public static <T> T foo() {return null;}
|
||||
|
||||
public static <B extends A, A> void bar0(B b, A a) {}
|
||||
public static <B extends A, A> void bar(A a, B b) {}
|
||||
public static <B extends List<A>, A> void bar1(B b, A a) {}
|
||||
public static <B extends Integer, A> void bar2(B b, A a) {}
|
||||
public static <B extends C, A, C> void bar3(B b, A a) {}
|
||||
static {
|
||||
bar0(foo(), "");
|
||||
bar("", foo());
|
||||
|
||||
bar1(foo(), "");
|
||||
bar2(foo(), "");
|
||||
bar3(foo(), "");
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,10 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testInferenceForFirstArg() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testConditionalExpressionsInference() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user