mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-06 11:50:54 +07:00
inference: stop tree up traversal when lambda expression is currently checked
EA-76546 - assert: InferenceSessionContainer.treeWalkUp IDEA-150168; IDEA-150166
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
package com.intellij.codeInsight;
|
||||
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.RecursionGuard;
|
||||
import com.intellij.openapi.util.RecursionManager;
|
||||
@@ -457,7 +456,7 @@ public class ExceptionUtil {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final PsiSubstitutor substitutor = getSubstitutor(result, methodCall);
|
||||
final PsiSubstitutor substitutor = result.getSubstitutor();
|
||||
if (!isArrayClone(method, methodCall) && methodCall instanceof PsiMethodCallExpression) {
|
||||
final PsiFile containingFile = (containingMethod == null ? methodCall : containingMethod).getContainingFile();
|
||||
final MethodResolverProcessor processor = new MethodResolverProcessor((PsiMethodCallExpression)methodCall, containingFile);
|
||||
@@ -471,7 +470,7 @@ public class ExceptionUtil {
|
||||
if (element instanceof PsiMethod &&
|
||||
MethodSignatureUtil.areSignaturesEqual(method, (PsiMethod)element) &&
|
||||
!MethodSignatureUtil.isSuperMethod((PsiMethod)element, method)) {
|
||||
return Pair.create((PsiMethod)element, getSubstitutor(info, methodCall));
|
||||
return Pair.create((PsiMethod)element, info.getSubstitutor());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -497,25 +496,6 @@ public class ExceptionUtil {
|
||||
return getUnhandledExceptions(method, methodCall, topElement, substitutor);
|
||||
}
|
||||
|
||||
private static PsiSubstitutor getSubstitutor(final JavaResolveResult result, PsiCallExpression methodCall) {
|
||||
final PsiLambdaExpression expression = PsiTreeUtil.getParentOfType(methodCall, PsiLambdaExpression.class);
|
||||
final PsiSubstitutor substitutor;
|
||||
if (expression != null) {
|
||||
final PsiElement parent = methodCall.getParent();
|
||||
final boolean callInReturnStatement = parent == expression ||
|
||||
parent instanceof PsiReturnStatement && PsiTreeUtil.getParentOfType(parent, PsiLambdaExpression.class, true, PsiMethod.class) == expression;
|
||||
substitutor = callInReturnStatement ? ourThrowsGuard.doPreventingRecursion(expression, false, new Computable<PsiSubstitutor>() {
|
||||
@Override
|
||||
public PsiSubstitutor compute() {
|
||||
return result.getSubstitutor();
|
||||
}
|
||||
}) : result.getSubstitutor();
|
||||
} else {
|
||||
substitutor = result.getSubstitutor();
|
||||
}
|
||||
return substitutor == null ? ((MethodCandidateInfo)result).getSiteSubstitutor() : substitutor;
|
||||
}
|
||||
|
||||
public static void retainExceptions(List<PsiClassType> ex, List<PsiClassType> thrownEx) {
|
||||
final List<PsiClassType> replacement = new ArrayList<PsiClassType>();
|
||||
for (Iterator<PsiClassType> iterator = ex.iterator(); iterator.hasNext(); ) {
|
||||
|
||||
@@ -198,18 +198,32 @@ public class InferenceSessionContainer {
|
||||
if (parent instanceof PsiCall) {
|
||||
break;
|
||||
}
|
||||
if (parent instanceof PsiCodeBlock && PsiTreeUtil.getParentOfType(parent, PsiLambdaExpression.class) == null) {
|
||||
break;
|
||||
}
|
||||
if (parent instanceof PsiLambdaExpression) {
|
||||
boolean inReturnExpressions = false;
|
||||
for (PsiExpression expression : LambdaUtil.getReturnExpressions((PsiLambdaExpression)parent)) {
|
||||
inReturnExpressions |= PsiTreeUtil.isAncestor(expression, context, false);
|
||||
}
|
||||
if (!inReturnExpressions) {
|
||||
|
||||
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(parent, PsiLambdaExpression.class);
|
||||
if (parent instanceof PsiCodeBlock) {
|
||||
if (lambdaExpression == null) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
boolean inReturnExpressions = false;
|
||||
for (PsiExpression expression : LambdaUtil.getReturnExpressions(lambdaExpression)) {
|
||||
inReturnExpressions |= PsiTreeUtil.isAncestor(expression, context, false);
|
||||
}
|
||||
|
||||
if (!inReturnExpressions) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (LambdaUtil.getFunctionalTypeMap().containsKey(lambdaExpression)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parent instanceof PsiLambdaExpression && LambdaUtil.getFunctionalTypeMap().containsKey(parent)) {
|
||||
break;
|
||||
}
|
||||
|
||||
final PsiCall psiCall = PsiTreeUtil.getParentOfType(parent, PsiCall.class);
|
||||
if (psiCall == null) {
|
||||
break;
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.intellij.psi.impl.source.resolve.graphInference.constraints;
|
||||
|
||||
import com.intellij.codeInsight.ExceptionUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
|
||||
@@ -118,12 +117,7 @@ public class CheckedExceptionCompatibilityConstraint extends InputOutputConstrai
|
||||
final List<PsiType> thrownTypes = new ArrayList<PsiType>();
|
||||
final PsiElement body = myExpression instanceof PsiLambdaExpression ? ((PsiLambdaExpression)myExpression).getBody() : myExpression;
|
||||
if (body != null) {
|
||||
final List<PsiClassType> exceptions = ExceptionUtil.ourThrowsGuard.doPreventingRecursion(myExpression, false, new Computable<List<PsiClassType>>() {
|
||||
@Override
|
||||
public List<PsiClassType> compute() {
|
||||
return ExceptionUtil.getUnhandledExceptions(new PsiElement[] {body});
|
||||
}
|
||||
});
|
||||
final List<PsiClassType> exceptions = ExceptionUtil.getUnhandledExceptions(new PsiElement[] {body});
|
||||
if (exceptions != null) {
|
||||
thrownTypes.addAll(ContainerUtil.filter(exceptions, new Condition<PsiClassType>() {
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import java.util.Optional;
|
||||
|
||||
class Test {
|
||||
public static void main(String[] args) {
|
||||
Optional<Either<IllegalArgumentException, String>> eith =
|
||||
Optional.of(new Either<IllegalArgumentException, String>());
|
||||
|
||||
eith.map(either -> {
|
||||
String foo = Test.foo(either);
|
||||
return foo;
|
||||
}).orElse("Hello");
|
||||
|
||||
eith.map(either -> {
|
||||
return Test.foo(either);
|
||||
}).orElse("Hello");
|
||||
|
||||
eith.map(either -> Test.foo(either)).orElse("Hello");
|
||||
}
|
||||
|
||||
private static <X extends Exception, A> A foo(Either<X, A> either) throws X { return null; }
|
||||
}
|
||||
|
||||
class Either<L, R> { }
|
||||
@@ -264,6 +264,10 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testCodeBlockLambdaWithIsValueCompatibleChecks() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user