mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Avoid inlining lambdas not from local scope
When lambda is defined in the outer scope a number of problems may appear during the analysis. First, it actually could be analyzed twice producing different warnings (in inlining context, and as standalone expression). Second, trap-handling assumes that all exited expressions should appear within the current codeFragment. This could be violated when lambda comes from the outer scope, resulting in incorrect jumps. Fixes IDEA-240328 Condition always false inspection is wrong if using switch expressions GitOrigin-RevId: 11794502d2e661044fa2105402955aa54e3c1245
This commit is contained in:
committed by
intellij-monorepo-bot
parent
507268f2bd
commit
985b752fad
@@ -26,6 +26,7 @@ import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -766,14 +767,18 @@ public class CFGBuilder {
|
||||
}
|
||||
PsiLocalVariable localFn = ExpressionUtils.resolveLocalVariable(stripped);
|
||||
if (localFn != null) {
|
||||
PsiLambdaExpression localLambda =
|
||||
ObjectUtils.tryCast(PsiUtil.skipParenthesizedExprDown(localFn.getInitializer()), PsiLambdaExpression.class);
|
||||
if (myAnalyzer.wasAdded(localLambda)) {
|
||||
PsiElement scope = PsiUtil.getVariableCodeBlock(localFn, null);
|
||||
List<PsiReferenceExpression> refs = VariableAccessUtils.getVariableReferences(localFn, scope);
|
||||
if (ContainerUtil.getOnlyItem(refs) == stripped) {
|
||||
myAnalyzer.removeLambda(localLambda);
|
||||
return tryInlineLambda(argCount, localLambda, resultNullability, pushArgs);
|
||||
PsiElement parent =
|
||||
PsiTreeUtil.getParentOfType(functionalExpression, PsiLambdaExpression.class, PsiClass.class, PsiMethod.class);
|
||||
if (PsiTreeUtil.isAncestor(parent, localFn, true)) {
|
||||
PsiLambdaExpression localLambda =
|
||||
ObjectUtils.tryCast(PsiUtil.skipParenthesizedExprDown(localFn.getInitializer()), PsiLambdaExpression.class);
|
||||
if (myAnalyzer.wasAdded(localLambda)) {
|
||||
PsiElement scope = PsiUtil.getVariableCodeBlock(localFn, null);
|
||||
List<PsiReferenceExpression> refs = VariableAccessUtils.getVariableReferences(localFn, scope);
|
||||
if (ContainerUtil.getOnlyItem(refs) == stripped) {
|
||||
myAnalyzer.removeLambda(localLambda);
|
||||
return tryInlineLambda(argCount, localLambda, resultNullability, pushArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
import java.util.function.Predicate;
|
||||
|
||||
class SwitchExpr {
|
||||
void test() {
|
||||
Predicate<String> predicate = value -> switch(value) {
|
||||
case "A" -> true;
|
||||
default -> false;
|
||||
};
|
||||
Predicate<String> otherPredicate = value -> value.length() == 1 && predicate.test(value);
|
||||
}
|
||||
}
|
||||
@@ -25,4 +25,5 @@ public class DataFlowInspection14Test extends DataFlowInspectionTestCase {
|
||||
myFixture.addClass("package java.lang.constant; public interface ConstantDesc {}");
|
||||
doTest();
|
||||
}
|
||||
public void testSwitchExpressionAndLambdaInlining() { doTest(); }
|
||||
}
|
||||
Reference in New Issue
Block a user