mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
lambda: preserve partial substitutor data during substitute
This commit is contained in:
@@ -82,7 +82,16 @@ public class LambdaUtil {
|
||||
|
||||
final PsiClass methodContainingClass = method.getContainingClass();
|
||||
LOG.assertTrue(methodContainingClass != null);
|
||||
return TypeConversionUtil.getSuperClassSubstitutor(methodContainingClass, derivedClass, resolveResult.getSubstitutor());
|
||||
PsiSubstitutor initialSubst = resolveResult.getSubstitutor();
|
||||
final PsiSubstitutor superClassSubstitutor =
|
||||
TypeConversionUtil.getSuperClassSubstitutor(methodContainingClass, derivedClass, PsiSubstitutor.EMPTY);
|
||||
for (PsiTypeParameter param : superClassSubstitutor.getSubstitutionMap().keySet()) {
|
||||
final PsiType substitute = superClassSubstitutor.substitute(param);
|
||||
if (substitute != null) {
|
||||
initialSubst = initialSubst.put(param, initialSubst.substitute(substitute));
|
||||
}
|
||||
}
|
||||
return initialSubst;
|
||||
}
|
||||
|
||||
public static boolean isValidLambdaContext(PsiElement context) {
|
||||
|
||||
@@ -310,7 +310,7 @@ public class PsiSubstitutorImpl implements PsiSubstitutor {
|
||||
}
|
||||
if (alreadyFound) continue;*/
|
||||
final PsiType substituted = substituteInternal(original);
|
||||
if (substituted == null) return false;
|
||||
//if (substituted == null) return false;
|
||||
substMap.put(param, substituted);
|
||||
}
|
||||
}
|
||||
|
||||
+12
-13
@@ -709,19 +709,16 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
final Pair<PsiType, ConstraintType> constraintFromFormalParams = inferConstraintFromLambdaFormalParams(typeParam, subst, method, lambdaExpression);
|
||||
if (constraintFromFormalParams != null) return constraintFromFormalParams;
|
||||
|
||||
final PsiParameter[] methodParameters = method.getParameterList().getParameters();
|
||||
if (methodParamsDependOn(typeParam, lambdaExpression, functionalInterfaceType, methodParameters, subst)) {
|
||||
if (lowerBound != PsiType.NULL) {
|
||||
return null;
|
||||
}
|
||||
return getFailedInferenceConstraint(typeParam);
|
||||
}
|
||||
|
||||
final Set<PsiParameterList> lists = LambdaUtil.ourParams.get();
|
||||
if (lists != null && lists.contains(lambdaExpression.getParameterList())){
|
||||
return null;
|
||||
}
|
||||
|
||||
final PsiParameter[] methodParameters = method.getParameterList().getParameters();
|
||||
if (methodParamsDependOn(typeParam, lambdaExpression, functionalInterfaceType, methodParameters, subst)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final PsiType returnType = subst.substitute(method.getReturnType());
|
||||
if (returnType != null && returnType != PsiType.VOID) {
|
||||
Pair<PsiType, ConstraintType> constraint = null;
|
||||
@@ -985,8 +982,11 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
constraint = policy.inferTypeConstraintFromCallContext(methodCall, (PsiExpressionList)parent, (PsiCallExpression)pParent, typeParameter);
|
||||
if (constraint == null && PsiUtil.isLanguageLevel8OrHigher(methodCall)) {
|
||||
constraint = graphInferenceFromCallContext(methodCall, typeParameter, (PsiCallExpression)pParent);
|
||||
if (constraint != null && constraint.getFirst().equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
|
||||
constraint = null;
|
||||
if (constraint != null) {
|
||||
final PsiType constraintFirst = constraint.getFirst();
|
||||
if (constraintFirst == null || constraintFirst.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
|
||||
constraint = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1057,10 +1057,9 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
}
|
||||
}
|
||||
|
||||
final PsiSubstitutor finalSubstitutor = substitutor.put(typeParameter, null);
|
||||
PsiClassType[] superTypes = typeParameter.getSuperTypes();
|
||||
if (superTypes.length == 0) return null;
|
||||
PsiType superType = finalSubstitutor.substitute(superTypes[0]);
|
||||
PsiType superType = TypeConversionUtil.erasure(superTypes[0]);
|
||||
if (superType == null) superType = PsiType.getJavaLangObject(manager, scope);
|
||||
if (superType == null) return null;
|
||||
return policy.getInferredTypeWithNoConstraint(manager, superType);
|
||||
@@ -1094,7 +1093,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static RecursionGuard ourGraphGuard = RecursionManager.createGuard("typeArgInference");
|
||||
private static RecursionGuard ourGraphGuard = RecursionManager.createGuard("graphTypeArgInference");
|
||||
private static Pair<PsiType, ConstraintType> graphInferenceFromCallContext(@NotNull final PsiExpression methodCall,
|
||||
@NotNull final PsiTypeParameter typeParameter,
|
||||
@NotNull final PsiCallExpression parentCall) {
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ class InferenceFromArgs {
|
||||
bar(b, (k, v) -> {Integer i = k; return v;});
|
||||
|
||||
bazz(<error descr="Cyclic inference">(k, v) -> v</error>);
|
||||
bazz((k, v) -> {<error descr="Incompatible types. Found: '<lambda parameter>', required: 'int'">int i = k;</error> return v;});
|
||||
bazz((k, v) -> {<error descr="Incompatible types. Found: 'java.lang.Object', required: 'int'">int i = k;</error> return v;});
|
||||
}
|
||||
|
||||
public static <T> SameArgsI<T> max() {
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ class ReturnTypeCompatibility {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
<error descr="Cannot resolve method 'call(<lambda expression>)'">call</error>(i-> {return i;});
|
||||
call<error descr="Ambiguous method call: both 'ReturnTypeCompatibility.call(I1)' and 'ReturnTypeCompatibility.call(I2)' match">(i-> {return i;})</error>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -29,8 +29,8 @@ class TypeArgsConsistency1 {
|
||||
{
|
||||
I<Integer> i1 = (i, j) -> i + j;
|
||||
foo((i, j) -> i + j);
|
||||
I<Integer> i2 =bar(<error descr="Cyclic inference">(i, j) -> i</error>) ;
|
||||
I<Integer> i3 = bar(<error descr="Cyclic inference">(i, j) -> "" + i + j</error>);
|
||||
I<Integer> i2 =bar((i, j) -> i) ;
|
||||
I<Integer> i3 = bar(<error descr="Incompatible return type String in lambda expression">(i, j) -> "" + i + j</error>);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ class TypeArgsConsistency2 {
|
||||
static <T> I2<T> bar2(I2<T> i) {return i;}
|
||||
|
||||
public static void main(String[] args) {
|
||||
I<Integer> i1 = bar(<error descr="Cyclic inference">x -> x</error>);
|
||||
I1<Integer> i2 = bar1(<error descr="Cyclic inference">x -> 1</error>);
|
||||
I<Integer> i1 = bar(x -> x);
|
||||
I1<Integer> i2 = bar1(x -> 1);
|
||||
I2<String> aI2 = bar2(x -> "");
|
||||
<error descr="Incompatible types. Found: 'TypeArgsConsistency2.I2<java.lang.String>', required: 'TypeArgsConsistency2.I2<java.lang.Integer>'">I2<Integer> aI28 = bar2( x-> "");</error>
|
||||
I2<Integer> i3 = bar2(x -> x);
|
||||
|
||||
Reference in New Issue
Block a user