From ab22b9b3ac8eae947204c8b705fdfae8c13b1960 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 18 Jan 2017 19:09:20 +0100 Subject: [PATCH] IDEA-166582 No completion inside lambda when instance of contains lambda --- .../dataFlow/DataFlowRunner.java | 3 +-- .../codeInspection/dataFlow/DfaPsiUtil.java | 26 +++++++------------ ...stanceofedQualifierInExpressionLambda.java | 8 ++++++ ...ofedQualifierInExpressionLambda_after.java | 8 ++++++ .../completion/NormalCompletionDfaTest.groovy | 2 ++ 5 files changed, 28 insertions(+), 19 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/normal/CastInstanceofedQualifierInExpressionLambda.java create mode 100644 java/java-tests/testData/codeInsight/completion/normal/CastInstanceofedQualifierInExpressionLambda_after.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java index 133d64c08eba..567161a3e08b 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java @@ -75,8 +75,7 @@ public class DataFlowRunner { private Collection createInitialStates(@NotNull PsiElement psiBlock, @NotNull InstructionVisitor visitor) { PsiElement container = PsiTreeUtil.getParentOfType(psiBlock, PsiClass.class, PsiLambdaExpression.class); if (container != null && (!(container instanceof PsiClass) || PsiUtil.isLocalOrAnonymousClass((PsiClass)container))) { - final PsiElement parent = container.getParent(); - final PsiCodeBlock block = DfaPsiUtil.getTopmostBlockInSameClass(parent); + PsiElement block = DfaPsiUtil.getTopmostBlockInSameClass(container.getParent()); if (block != null) { final RunnerResult result = analyzeMethod(block, visitor); if (result == RunnerResult.OK) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java index b5876ba15922..04aefe4a52c8 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java @@ -336,29 +336,21 @@ public class DfaPsiUtil { } @Nullable - public static PsiCodeBlock getTopmostBlockInSameClass(@NotNull PsiElement position) { - PsiCodeBlock block = PsiTreeUtil.getParentOfType(position, PsiCodeBlock.class, false, PsiMember.class, PsiFile.class, PsiLambdaExpression.class); - if (block == null) { - return null; - } - - PsiCodeBlock lastBlock = block; - while (true) { - block = PsiTreeUtil.getParentOfType(block, PsiCodeBlock.class, true, PsiMember.class, PsiFile.class, PsiLambdaExpression.class); - if (block == null) { - return lastBlock; - } - lastBlock = block; - } + public static PsiElement getTopmostBlockInSameClass(@NotNull PsiElement position) { + return JBIterable. + generate(position, PsiElement::getParent). + takeWhile(e -> !(e instanceof PsiMember || e instanceof PsiFile || e instanceof PsiLambdaExpression)). + filter(e -> e instanceof PsiCodeBlock || e instanceof PsiExpression && e.getParent() instanceof PsiLambdaExpression). + last(); } @NotNull public static Collection getVariableAssignmentsInFile(@NotNull PsiVariable psiVariable, final boolean literalsOnly, final PsiElement place) { - final Ref modificationRef = Ref.create(Boolean.FALSE); - final PsiCodeBlock codeBlock = place == null? null : getTopmostBlockInSameClass(place); - final int placeOffset = codeBlock != null? place.getTextRange().getStartOffset() : 0; + Ref modificationRef = Ref.create(Boolean.FALSE); + PsiElement codeBlock = place == null? null : getTopmostBlockInSameClass(place); + int placeOffset = codeBlock != null? place.getTextRange().getStartOffset() : 0; PsiFile containingFile = psiVariable.getContainingFile(); LocalSearchScope scope = new LocalSearchScope(new PsiElement[]{containingFile}, null, true); Collection references = ReferencesSearch.search(psiVariable, scope).findAll(); diff --git a/java/java-tests/testData/codeInsight/completion/normal/CastInstanceofedQualifierInExpressionLambda.java b/java/java-tests/testData/codeInsight/completion/normal/CastInstanceofedQualifierInExpressionLambda.java new file mode 100644 index 000000000000..b4fe0be70f05 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/CastInstanceofedQualifierInExpressionLambda.java @@ -0,0 +1,8 @@ +public class Test { + public void f(Object o ) { + if (o instanceof String) { + Runnable r = () -> o.leng; + } + } + +} diff --git a/java/java-tests/testData/codeInsight/completion/normal/CastInstanceofedQualifierInExpressionLambda_after.java b/java/java-tests/testData/codeInsight/completion/normal/CastInstanceofedQualifierInExpressionLambda_after.java new file mode 100644 index 000000000000..3c51694a58b9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/CastInstanceofedQualifierInExpressionLambda_after.java @@ -0,0 +1,8 @@ +public class Test { + public void f(Object o ) { + if (o instanceof String) { + Runnable r = () -> ((String) o).length(); + } + } + +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionDfaTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionDfaTest.groovy index 5b94b2dcd043..b1d4451dacb0 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionDfaTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionDfaTest.groovy @@ -72,4 +72,6 @@ public class FooImpl extends Foo { void testCastInstanceofedQualifierInLambda2() { doTest() } + void testCastInstanceofedQualifierInExpressionLambda() { doTest() } + }