mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 13:31:28 +07:00
new inference: cache substitutor for outer call conflict resolution
This commit is contained in:
@@ -18,7 +18,6 @@ package com.intellij.psi;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.util.*;
|
||||
@@ -312,6 +311,14 @@ public class LambdaUtil {
|
||||
|
||||
if (gParent instanceof PsiCall) {
|
||||
final PsiCall contextCall = (PsiCall)gParent;
|
||||
final MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(contextCall.getArgumentList());
|
||||
if (properties != null && properties.isApplicabilityCheck()) { //todo simplification
|
||||
final PsiParameter[] parameters = properties.getMethod().getParameterList().getParameters();
|
||||
final int finalLambdaIdx = adjustLambdaIdx(lambdaIdx, properties.getMethod(), parameters);
|
||||
if (finalLambdaIdx < parameters.length) {
|
||||
return properties.getSubstitutor().substitute(getNormalizedType(parameters[finalLambdaIdx]));
|
||||
}
|
||||
}
|
||||
final JavaResolveResult resolveResult = contextCall.resolveMethodGenerics();
|
||||
final PsiElement resolve = resolveResult.getElement();
|
||||
if (resolve instanceof PsiMethod) {
|
||||
@@ -462,8 +469,8 @@ public class LambdaUtil {
|
||||
if (parent instanceof PsiExpressionList) {
|
||||
final PsiElement gParent = parent.getParent();
|
||||
if (gParent instanceof PsiCall) {
|
||||
final Pair<PsiMethod, PsiSubstitutor> pair = MethodCandidateInfo.getCurrentMethod(parent);
|
||||
myMethod = pair != null ? pair.first : null;
|
||||
final MethodCandidateInfo.CurrentCandidateProperties pair = MethodCandidateInfo.getCurrentMethod(parent);
|
||||
myMethod = pair != null ? pair.getMethod() : null;
|
||||
if (myMethod == null) {
|
||||
myMethod = ((PsiCall)gParent).resolveMethod();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.RecursionGuard;
|
||||
import com.intellij.openapi.util.RecursionManager;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
@@ -39,7 +38,7 @@ import java.util.Map;
|
||||
*/
|
||||
public class MethodCandidateInfo extends CandidateInfo{
|
||||
public static final RecursionGuard ourOverloadGuard = RecursionManager.createGuard("overload.guard");
|
||||
public static final ThreadLocal<Map<PsiElement, Pair<PsiMethod, PsiSubstitutor>>> CURRENT_CANDIDATE = new ThreadLocal<Map<PsiElement, Pair<PsiMethod, PsiSubstitutor>>>();
|
||||
public static final ThreadLocal<Map<PsiElement, CurrentCandidateProperties>> CURRENT_CANDIDATE = new ThreadLocal<Map<PsiElement, CurrentCandidateProperties>>();
|
||||
@ApplicabilityLevelConstant
|
||||
private int myApplicabilityLevel; // benign race
|
||||
private final PsiElement myArgumentList;
|
||||
@@ -102,27 +101,39 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
|
||||
@ApplicabilityLevelConstant
|
||||
public int getPertinentApplicabilityLevel() {
|
||||
if (myTypeArguments != null) {
|
||||
return getApplicabilityLevel();
|
||||
}
|
||||
|
||||
@ApplicabilityLevelConstant int level;
|
||||
Integer boxedLevel = ourOverloadGuard.doPreventingRecursion(myArgumentList, false, new Computable<Integer>() {
|
||||
@Override
|
||||
public Integer compute() {
|
||||
if (PsiUtil.isLanguageLevel8OrHigher(myArgumentList)) {
|
||||
final PsiType[] argumentTypes = getArgumentTypes();
|
||||
if (argumentTypes == null) {
|
||||
return ApplicabilityLevel.NOT_APPLICABLE;
|
||||
PsiSubstitutor substitutor = getSubstitutor(false);
|
||||
Map<PsiElement, CurrentCandidateProperties> map = CURRENT_CANDIDATE.get();
|
||||
if (map == null) {
|
||||
map = new ConcurrentWeakHashMap<PsiElement, CurrentCandidateProperties>();
|
||||
CURRENT_CANDIDATE.set(map);
|
||||
}
|
||||
final PsiMethod method = getElement();
|
||||
final CurrentCandidateProperties properties = new CurrentCandidateProperties(method, substitutor, false, true);
|
||||
final CurrentCandidateProperties alreadyThere = map.put(getMarkerList(), properties);
|
||||
try {
|
||||
properties.setSubstitutor(substitutor);
|
||||
PsiType[] argumentTypes = getArgumentTypes();
|
||||
if (argumentTypes == null) {
|
||||
return ApplicabilityLevel.NOT_APPLICABLE;
|
||||
}
|
||||
|
||||
return PsiUtil.getApplicabilityLevel(getElement(), getSubstitutor(false), argumentTypes, myLanguageLevel);
|
||||
return PsiUtil.getApplicabilityLevel(method, substitutor, argumentTypes, myLanguageLevel);
|
||||
}
|
||||
finally {
|
||||
if (alreadyThere == null) map.remove(getMarkerList());
|
||||
}
|
||||
}
|
||||
return getApplicabilityLevelInner();
|
||||
}
|
||||
|
||||
});
|
||||
level = boxedLevel != null ? boxedLevel : getApplicabilityLevel();
|
||||
assert boxedLevel != null;
|
||||
level = boxedLevel;
|
||||
if (level > ApplicabilityLevel.NOT_APPLICABLE && !isTypeArgumentsApplicable(false)) level = ApplicabilityLevel.NOT_APPLICABLE;
|
||||
return level;
|
||||
}
|
||||
@@ -158,7 +169,7 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
|
||||
final PsiSubstitutor inferredSubstitutor = inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE, includeReturnConstraint);
|
||||
|
||||
if (!stackStamp.mayCacheNow() || !includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
|
||||
if (!stackStamp.mayCacheNow() || !ourOverloadGuard.currentStack().isEmpty() || !includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
|
||||
return inferredSubstitutor;
|
||||
}
|
||||
|
||||
@@ -225,15 +236,15 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
public PsiSubstitutor inferTypeArguments(@NotNull ParameterTypeInferencePolicy policy,
|
||||
@NotNull PsiExpression[] arguments,
|
||||
boolean includeReturnConstraint) {
|
||||
Map<PsiElement, Pair<PsiMethod, PsiSubstitutor>> map = CURRENT_CANDIDATE.get();
|
||||
Map<PsiElement, CurrentCandidateProperties> map = CURRENT_CANDIDATE.get();
|
||||
if (map == null) {
|
||||
map = new ConcurrentWeakHashMap<PsiElement, Pair<PsiMethod, PsiSubstitutor>>();
|
||||
map = new ConcurrentWeakHashMap<PsiElement, CurrentCandidateProperties>();
|
||||
CURRENT_CANDIDATE.set(map);
|
||||
}
|
||||
final PsiMethod method = getElement();
|
||||
final Pair<PsiMethod, PsiSubstitutor> alreadyThere = includeReturnConstraint
|
||||
? map.put(getMarkerList(), Pair.create(method, super.getSubstitutor()))
|
||||
: null;
|
||||
final CurrentCandidateProperties alreadyThere = map.put(getMarkerList(),
|
||||
new CurrentCandidateProperties(method, super.getSubstitutor(), false, //todo
|
||||
!includeReturnConstraint));
|
||||
try {
|
||||
PsiTypeParameter[] typeParameters = method.getTypeParameters();
|
||||
|
||||
@@ -267,17 +278,17 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
}
|
||||
|
||||
|
||||
public static Pair<PsiMethod, PsiSubstitutor> getCurrentMethod(PsiElement context) {
|
||||
final Map<PsiElement,Pair<PsiMethod,PsiSubstitutor>> currentMethodCandidates = CURRENT_CANDIDATE.get();
|
||||
public static CurrentCandidateProperties getCurrentMethod(PsiElement context) {
|
||||
final Map<PsiElement, CurrentCandidateProperties> currentMethodCandidates = CURRENT_CANDIDATE.get();
|
||||
return currentMethodCandidates != null ? currentMethodCandidates.get(context) : null;
|
||||
}
|
||||
|
||||
public static void updateSubstitutor(PsiElement context, PsiSubstitutor newSubstitutor) {
|
||||
final Map<PsiElement,Pair<PsiMethod,PsiSubstitutor>> currentMethodCandidates = CURRENT_CANDIDATE.get();
|
||||
final Map<PsiElement, CurrentCandidateProperties> currentMethodCandidates = CURRENT_CANDIDATE.get();
|
||||
if (currentMethodCandidates != null) {
|
||||
final Pair<PsiMethod, PsiSubstitutor> pair = currentMethodCandidates.get(context);
|
||||
if (pair != null) {
|
||||
currentMethodCandidates.put(context, Pair.create(pair.first, newSubstitutor));
|
||||
final CurrentCandidateProperties properties = currentMethodCandidates.get(context);
|
||||
if (properties != null) {
|
||||
properties.setSubstitutor(newSubstitutor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -286,6 +297,48 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
return myArgumentTypes;
|
||||
}
|
||||
|
||||
public static class CurrentCandidateProperties {
|
||||
private final PsiMethod myMethod;
|
||||
private PsiSubstitutor mySubstitutor;
|
||||
private boolean myVarargs;
|
||||
private boolean myApplicabilityCheck;
|
||||
|
||||
public CurrentCandidateProperties(PsiMethod method, PsiSubstitutor substitutor, boolean varargs, boolean applicabilityCheck) {
|
||||
myMethod = method;
|
||||
mySubstitutor = substitutor;
|
||||
myVarargs = varargs;
|
||||
myApplicabilityCheck = applicabilityCheck;
|
||||
}
|
||||
|
||||
public PsiMethod getMethod() {
|
||||
return myMethod;
|
||||
}
|
||||
|
||||
public PsiSubstitutor getSubstitutor() {
|
||||
return mySubstitutor;
|
||||
}
|
||||
|
||||
public void setSubstitutor(PsiSubstitutor substitutor) {
|
||||
mySubstitutor = substitutor;
|
||||
}
|
||||
|
||||
public boolean isVarargs() {
|
||||
return myVarargs;
|
||||
}
|
||||
|
||||
public void setVarargs(boolean varargs) {
|
||||
myVarargs = varargs;
|
||||
}
|
||||
|
||||
public boolean isApplicabilityCheck() {
|
||||
return myApplicabilityCheck && !ourOverloadGuard.currentStack().isEmpty();
|
||||
}
|
||||
|
||||
public void setApplicabilityCheck(boolean applicabilityCheck) {
|
||||
myApplicabilityCheck = applicabilityCheck;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ApplicabilityLevel {
|
||||
public static final int NOT_APPLICABLE = 1;
|
||||
public static final int VARARGS = 2;
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.intellij.psi.impl.AnyPsiChangeListener;
|
||||
import com.intellij.psi.impl.PsiManagerImpl;
|
||||
import com.intellij.psi.impl.source.PsiClassReferenceType;
|
||||
import com.intellij.psi.impl.source.PsiImmediateClassType;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import com.intellij.util.Function;
|
||||
@@ -90,7 +91,7 @@ public class JavaResolveCache {
|
||||
final RecursionGuard.StackStamp dStackStamp = PsiDiamondType.ourDiamondGuard.markStack();
|
||||
final RecursionGuard.StackStamp gStackStamp = PsiResolveHelper.ourGraphGuard.markStack();
|
||||
type = f.fun(expr);
|
||||
if (!dStackStamp.mayCacheNow() || !gStackStamp.mayCacheNow()) {
|
||||
if (!dStackStamp.mayCacheNow() || !gStackStamp.mayCacheNow() || !MethodCandidateInfo.ourOverloadGuard.currentStack().isEmpty()) {
|
||||
return type;
|
||||
}
|
||||
if (type == null) type = TypeConversionUtil.NULL_TYPE;
|
||||
|
||||
@@ -91,9 +91,9 @@ public class InferenceSession {
|
||||
|
||||
public void initExpressionConstraints(PsiParameter[] parameters, PsiExpression[] args, PsiElement parent, PsiMethod method) {
|
||||
if (method == null) {
|
||||
final Pair<PsiMethod, PsiCallExpression> pair = getPair(parent);
|
||||
final MethodCandidateInfo.CurrentCandidateProperties pair = getCurrentProperties(parent);
|
||||
if (pair != null) {
|
||||
method = pair.first;
|
||||
method = pair.getMethod();
|
||||
}
|
||||
}
|
||||
if (parameters.length > 0) {
|
||||
@@ -106,12 +106,9 @@ public class InferenceSession {
|
||||
}
|
||||
}
|
||||
|
||||
private static Pair<PsiMethod, PsiCallExpression> getPair(PsiElement parent) {
|
||||
private static MethodCandidateInfo.CurrentCandidateProperties getCurrentProperties(PsiElement parent) {
|
||||
if (parent instanceof PsiCallExpression) {
|
||||
final Pair<PsiMethod, PsiSubstitutor> pair = MethodCandidateInfo.getCurrentMethod(((PsiCallExpression)parent).getArgumentList());
|
||||
if (pair != null) {
|
||||
return Pair.create(pair.first, (PsiCallExpression)parent);
|
||||
}
|
||||
return MethodCandidateInfo.getCurrentMethod(((PsiCallExpression)parent).getArgumentList());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -167,7 +164,7 @@ public class InferenceSession {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static PsiType getParameterType(PsiParameter[] parameters, PsiExpression[] args, int i, @Nullable PsiSubstitutor substitutor) {
|
||||
private PsiType getParameterType(PsiParameter[] parameters, PsiExpression[] args, int i, @Nullable PsiSubstitutor substitutor) {
|
||||
if (substitutor == null) return null;
|
||||
PsiType parameterType = substitutor.substitute(parameters[i < parameters.length ? i : parameters.length - 1].getType());
|
||||
if (parameterType instanceof PsiEllipsisType) {
|
||||
@@ -204,14 +201,14 @@ public class InferenceSession {
|
||||
private PsiSubstitutor tryToInfer(@Nullable PsiParameter[] parameters,
|
||||
@Nullable PsiExpression[] args,
|
||||
@Nullable PsiCallExpression parent,
|
||||
PsiMethod parentMethod) {
|
||||
@Nullable MethodCandidateInfo.CurrentCandidateProperties properties) {
|
||||
if (!repeatInferencePhases(true)) {
|
||||
//inferred result would be checked as candidate won't be applicable
|
||||
return resolveSubset(myInferenceVariables.values(), mySiteSubstitutor);
|
||||
}
|
||||
|
||||
if (parentMethod != null) {
|
||||
initReturnTypeConstraint(parentMethod, parent);
|
||||
if (properties != null && !properties.isApplicabilityCheck()) {
|
||||
initReturnTypeConstraint(properties.getMethod(), parent);
|
||||
if (!repeatInferencePhases(true)) {
|
||||
return prepareSubstitution();
|
||||
}
|
||||
@@ -219,7 +216,7 @@ public class InferenceSession {
|
||||
if (parameters != null && args != null) {
|
||||
final Set<ConstraintFormula> additionalConstraints = new HashSet<ConstraintFormula>();
|
||||
if (parameters.length > 0) {
|
||||
collectAdditionalConstraints(parameters, args, parentMethod, PsiSubstitutor.EMPTY, additionalConstraints);
|
||||
collectAdditionalConstraints(parameters, args, properties.getMethod(), PsiSubstitutor.EMPTY, additionalConstraints);
|
||||
}
|
||||
|
||||
if (!additionalConstraints.isEmpty() && !proceedWithAdditionalConstraints(additionalConstraints)) {
|
||||
@@ -231,11 +228,11 @@ public class InferenceSession {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void collectAdditionalConstraints(PsiParameter[] parameters,
|
||||
PsiExpression[] args,
|
||||
PsiMethod parentMethod,
|
||||
PsiSubstitutor siteSubstitutor,
|
||||
Set<ConstraintFormula> additionalConstraints) {
|
||||
private void collectAdditionalConstraints(PsiParameter[] parameters,
|
||||
PsiExpression[] args,
|
||||
PsiMethod parentMethod,
|
||||
PsiSubstitutor siteSubstitutor,
|
||||
Set<ConstraintFormula> additionalConstraints) {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i] != null) {
|
||||
PsiType parameterType = getParameterType(parameters, args, i, siteSubstitutor);
|
||||
@@ -269,13 +266,8 @@ public class InferenceSession {
|
||||
public PsiSubstitutor infer(@Nullable PsiParameter[] parameters,
|
||||
@Nullable PsiExpression[] args,
|
||||
@Nullable PsiElement parent) {
|
||||
final Pair<PsiMethod, PsiCallExpression> pair = getPair(parent);
|
||||
return infer(parameters, args, parent, pair != null ? pair.first : null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiSubstitutor infer(PsiParameter[] parameters, PsiExpression[] args, PsiElement parent, PsiMethod parentMethod) {
|
||||
final PsiSubstitutor subst = tryToInfer(parameters, args, parent instanceof PsiCallExpression ? ((PsiCallExpression)parent) : null, parentMethod);
|
||||
final MethodCandidateInfo.CurrentCandidateProperties properties = getCurrentProperties(parent);
|
||||
final PsiSubstitutor subst = tryToInfer(parameters, args, parent instanceof PsiCallExpression ? ((PsiCallExpression)parent) : null, properties);
|
||||
if (subst != null) {
|
||||
return subst;
|
||||
}
|
||||
@@ -483,7 +475,7 @@ public class InferenceSession {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static PsiType getTargetType(final PsiExpression context) {
|
||||
private PsiType getTargetType(final PsiExpression context) {
|
||||
final PsiElement parent = PsiUtil.skipParenthesizedExprUp(context.getParent());
|
||||
if (parent instanceof PsiExpressionList) {
|
||||
PsiElement gParent = parent.getParent();
|
||||
@@ -493,8 +485,22 @@ public class InferenceSession {
|
||||
if (gParent instanceof PsiCallExpression) {
|
||||
final PsiExpressionList argumentList = ((PsiCallExpression)gParent).getArgumentList();
|
||||
if (argumentList != null) {
|
||||
final MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(argumentList);
|
||||
if (properties != null && properties.isApplicabilityCheck()) {
|
||||
return getTypeByMethod(context, argumentList, properties.getMethod(), properties.getSubstitutor());
|
||||
}
|
||||
final JavaResolveResult result = ((PsiCallExpression)gParent).resolveMethodGenerics();
|
||||
return getTypeByMethod(context, argumentList, result, result.getElement());
|
||||
return getTypeByMethod(context, argumentList, result.getElement(),
|
||||
PsiResolveHelper.ourGraphGuard.doPreventingRecursion(argumentList.getParent(), false,
|
||||
new Computable<PsiSubstitutor>() {
|
||||
@Override
|
||||
public PsiSubstitutor compute() {
|
||||
return result
|
||||
.getSubstitutor();
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if (parent instanceof PsiConditionalExpression) {
|
||||
@@ -514,9 +520,9 @@ public class InferenceSession {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static PsiType getTypeByMethod(PsiExpression context,
|
||||
PsiExpressionList argumentList,
|
||||
final JavaResolveResult result, PsiElement parentMethod) {
|
||||
private PsiType getTypeByMethod(PsiExpression context,
|
||||
PsiExpressionList argumentList,
|
||||
PsiElement parentMethod, PsiSubstitutor substitutor) {
|
||||
if (parentMethod instanceof PsiMethod) {
|
||||
final PsiParameter[] parameters = ((PsiMethod)parentMethod).getParameterList().getParameters();
|
||||
if (parameters.length == 0) return null;
|
||||
@@ -528,13 +534,7 @@ public class InferenceSession {
|
||||
}
|
||||
final int i = ArrayUtilRt.find(args, arg);
|
||||
if (i < 0) return null;
|
||||
return getParameterType(parameters, args, i, PsiResolveHelper.ourGraphGuard.doPreventingRecursion(argumentList.getParent(), false,
|
||||
new Computable<PsiSubstitutor>() {
|
||||
@Override
|
||||
public PsiSubstitutor compute() {
|
||||
return result.getSubstitutor();
|
||||
}
|
||||
}));
|
||||
return getParameterType(parameters, args, i, substitutor);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.intellij.psi.impl.source.tree.java;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiManagerEx;
|
||||
@@ -51,7 +50,10 @@ import com.intellij.util.SmartList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase implements PsiMethodReferenceExpression {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiMethodReferenceExpressionImpl");
|
||||
@@ -456,7 +458,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiSubstitutor inferTypeArguments(@NotNull ParameterTypeInferencePolicy policy, boolean includeReturnConstraint) {
|
||||
return inferTypeArguments(false);
|
||||
return inferTypeArguments(false); //includeReturnConstraint == vararg todo
|
||||
}
|
||||
|
||||
public PsiSubstitutor inferTypeArguments(boolean varargs) {
|
||||
@@ -465,9 +467,9 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
final InferenceSession session = new InferenceSession(method.getTypeParameters(), substitutor, getManager(), reference);
|
||||
|
||||
//lift parameters from outer call
|
||||
final Pair<PsiMethod,PsiSubstitutor> methodSubstitutorPair = MethodCandidateInfo.getCurrentMethod(reference.getParent());
|
||||
final CurrentCandidateProperties methodSubstitutorPair = MethodCandidateInfo.getCurrentMethod(reference.getParent());
|
||||
if (methodSubstitutorPair != null) {
|
||||
session.initBounds(methodSubstitutorPair.first.getTypeParameters());
|
||||
session.initBounds(methodSubstitutorPair.getMethod().getTypeParameters());
|
||||
}
|
||||
|
||||
final PsiParameter[] functionalMethodParameters = interfaceMethod.getParameterList().getParameters();
|
||||
|
||||
@@ -7,8 +7,8 @@ public class Sample {
|
||||
<B> B bar(G<B> gb) {return null;}
|
||||
|
||||
void f(G1 g1) {
|
||||
<error descr="Incompatible types. Found: 'java.lang.Object', required: 'Sample.G<java.lang.String>'">G<String> l11 = bar(g1);</error>
|
||||
<error descr="Incompatible types. Found: 'java.lang.Object', required: 'java.lang.String'">String l1 = bar(g1);</error>
|
||||
<error descr="Incompatible types. Found: 'B', required: 'Sample.G<java.lang.String>'">G<String> l11 = bar(g1);</error>
|
||||
<error descr="Incompatible types. Found: 'B', required: 'java.lang.String'">String l1 = bar(g1);</error>
|
||||
Object o = bar(g1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,12 +13,12 @@ class SortedOp<T> implements StatefulOp<T, T> {
|
||||
}
|
||||
}
|
||||
|
||||
class Usage<T> {
|
||||
public <E, S extends BaseStream<E>> S pipeline(IntermediateOp<T, E> newOp) { return null; }
|
||||
public <R> R pipeline(TerminalOp<T, R> terminal) { return null;}
|
||||
class Usage<Ts> {
|
||||
public <E, S extends BaseStream<E>> S pipeline(IntermediateOp<Ts, E> newOp) { return null; }
|
||||
public <R> R pipeline(TerminalOp<Ts, R> terminal) { return null;}
|
||||
|
||||
|
||||
public Stream<T> sorted(Comparator<? super T> comparator) {
|
||||
public Stream<Ts> sorted(Comparator<? super Ts> comparator) {
|
||||
return pipeline(new SortedOp<>(comparator));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import java.util.*;
|
||||
|
||||
class Test {
|
||||
|
||||
|
||||
void m(Runnable p) { }
|
||||
void m(List<Runnable> p) { }
|
||||
|
||||
{
|
||||
m(foo());
|
||||
m<error descr="Cannot resolve method 'm(java.lang.Object)'">(bar())</error>;
|
||||
}
|
||||
|
||||
<T> List<T> foo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
<T> T bar() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -172,6 +172,10 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testOuterCallConflictResolution() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() throws Exception {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user