diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/KtPsiUtil.java b/compiler/frontend/src/org/jetbrains/kotlin/psi/KtPsiUtil.java index c138b6fe6de..58bb237434c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/KtPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/KtPsiUtil.java @@ -860,4 +860,14 @@ public class KtPsiUtil { } return deparenthesizedExpression; } + + public static boolean isStatementContainer(@Nullable PsiElement container) { + return container instanceof KtBlockExpression || + container instanceof KtContainerNodeForControlStructureBody || + container instanceof KtWhenEntry; + } + + public static boolean isStatement(@NotNull PsiElement element) { + return isStatementContainer(element.getParent()); + } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java index 5193df13d51..3a662cfa8ca 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java @@ -1681,13 +1681,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { parent = parent.getParent(); } - return isParentForBlockLevelExpression(parent); - } - - private static boolean isParentForBlockLevelExpression(@Nullable PsiElement parent) { - return parent instanceof KtBlockExpression || - parent instanceof KtContainerNodeForControlStructureBody || - parent instanceof KtWhenEntry; + return KtPsiUtil.isStatementContainer(parent); } @Override diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/postfix/KtPostfixTemplateProvider.kt b/idea/src/org/jetbrains/kotlin/idea/codeInsight/postfix/KtPostfixTemplateProvider.kt index e95e9d9e7d5..cecfb95a80c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInsight/postfix/KtPostfixTemplateProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/postfix/KtPostfixTemplateProvider.kt @@ -34,7 +34,6 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForReceiverOrThis import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsStatement import org.jetbrains.kotlin.resolve.calls.callUtil.getType import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.types.KotlinType @@ -145,8 +144,11 @@ private class KtExpressionPostfixTemplateSelector( val bindingContext by lazy { element.analyze(BodyResolveMode.PARTIAL) } if (statementsOnly) { - val elementToCheck = element.getQualifiedExpressionForReceiverOrThis() - if (elementToCheck.parent !is KtBlockExpression && !elementToCheck.isUsedAsStatement(bindingContext)) return false + // We use getQualifiedExpressionForReceiverOrThis because when postfix completion is run on some statement like: + // foo().try + // `element` points to `foo()` call, while we need to select the whole statement with `try` selector + // to check if it's in a statement position + if (!KtPsiUtil.isStatement(element.getQualifiedExpressionForReceiverOrThis())) return false } if (checkCanBeUsedAsValue && !element.canBeUsedAsValue()) return false diff --git a/idea/testData/codeInsight/postfix/tryInLocalClass.kt b/idea/testData/codeInsight/postfix/tryInLocalClass.kt new file mode 100644 index 00000000000..cac1bf6fe53 --- /dev/null +++ b/idea/testData/codeInsight/postfix/tryInLocalClass.kt @@ -0,0 +1,6 @@ +fun foo() { + class A { + // it's not a statement, while it has a block expression as an ancestor + val w = 1.try + } +} diff --git a/idea/testData/codeInsight/postfix/tryInLocalClass.kt.after b/idea/testData/codeInsight/postfix/tryInLocalClass.kt.after new file mode 100644 index 00000000000..693fe192dd0 --- /dev/null +++ b/idea/testData/codeInsight/postfix/tryInLocalClass.kt.after @@ -0,0 +1,6 @@ +fun foo() { + class A { + // it's not a statement, while it has a block expression as an ancestor + val w = 1.try + } +} diff --git a/idea/testData/codeInsight/postfix/tryOnImportStatement.kt b/idea/testData/codeInsight/postfix/tryOnImportStatement.kt new file mode 100644 index 00000000000..82c95dacb48 --- /dev/null +++ b/idea/testData/codeInsight/postfix/tryOnImportStatement.kt @@ -0,0 +1 @@ +import qwe.try diff --git a/idea/testData/codeInsight/postfix/tryOnImportStatement.kt.after b/idea/testData/codeInsight/postfix/tryOnImportStatement.kt.after new file mode 100644 index 00000000000..0055da4bb94 --- /dev/null +++ b/idea/testData/codeInsight/postfix/tryOnImportStatement.kt.after @@ -0,0 +1 @@ +import qwe.try diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/postfix/PostfixTemplateProviderTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/postfix/PostfixTemplateProviderTestGenerated.java index 6240d791536..8c15c8a0fca 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/postfix/PostfixTemplateProviderTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/postfix/PostfixTemplateProviderTestGenerated.java @@ -180,12 +180,24 @@ public class PostfixTemplateProviderTestGenerated extends AbstractPostfixTemplat doTest(fileName); } + @TestMetadata("tryInLocalClass.kt") + public void testTryInLocalClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/tryInLocalClass.kt"); + doTest(fileName); + } + @TestMetadata("tryOnFor.kt") public void testTryOnFor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/tryOnFor.kt"); doTest(fileName); } + @TestMetadata("tryOnImportStatement.kt") + public void testTryOnImportStatement() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/tryOnImportStatement.kt"); + doTest(fileName); + } + @TestMetadata("tryOnStatement.kt") public void testTryOnStatement() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/tryOnStatement.kt");