From 51e044a8f54812aed1c9c80ad1e745f429283965 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 6 Sep 2012 14:58:28 +0400 Subject: [PATCH] smart completion in lambda body: decision to insert semicolon based on lambda context and body type (IDEA-91083) --- .../codeInsight/ExpectedTypesProvider.java | 22 +++++++++++++++---- ...olonInCodeBlocBodyInLocalVariable-out.java | 5 +++++ ...emicolonInCodeBlocBodyInLocalVariable.java | 5 +++++ ...nInExpressionBodyInExpressionList-out.java | 5 +++++ ...colonInExpressionBodyInExpressionList.java | 5 +++++ ...onInExpressionBodyInLocalVariable-out.java | 5 +++++ ...icolonInExpressionBodyInLocalVariable.java | 5 +++++ .../completion/SmartType18CompletionTest.java | 12 ++++++++++ 8 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/smartType/SemicolonInCodeBlocBodyInLocalVariable-out.java create mode 100644 java/java-tests/testData/codeInsight/completion/smartType/SemicolonInCodeBlocBodyInLocalVariable.java create mode 100644 java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInExpressionList-out.java create mode 100644 java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInExpressionList.java create mode 100644 java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInLocalVariable-out.java create mode 100644 java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInLocalVariable.java diff --git a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java index 2e40838d208f..e0aa9bbae79b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java @@ -336,33 +336,47 @@ public class ExpectedTypesProvider { final PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType(); final PsiMethod scopeMethod = LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType); if (scopeMethod != null) { - visitMethodReturnType(scopeMethod, LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType)); + visitMethodReturnType(scopeMethod, LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType), insertSemicolonAfter(lambdaExpression)); } } @Override public void visitReturnStatement(PsiReturnStatement statement) { final PsiMethod method; final PsiType type; + final boolean tailTypeSemicolon; final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(statement, PsiLambdaExpression.class); if (lambdaExpression != null) { final PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType(); method = LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType); type = LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType); + tailTypeSemicolon = insertSemicolonAfter(lambdaExpression); } else { method = PsiTreeUtil.getParentOfType(statement, PsiMethod.class); type = method != null ? method.getReturnType() : null; + tailTypeSemicolon = true; } if (method != null) { - visitMethodReturnType(method, type); + visitMethodReturnType(method, type, tailTypeSemicolon); } } - private void visitMethodReturnType(final PsiMethod scopeMethod, PsiType type) { + private static boolean insertSemicolonAfter(PsiLambdaExpression lambdaExpression) { + if (lambdaExpression.getBody() instanceof PsiCodeBlock) { + return true; + } + final PsiElement parent = lambdaExpression.getParent(); + if (parent instanceof PsiExpressionList || parent instanceof PsiExpression) { + return false; + } + return true; + } + + private void visitMethodReturnType(final PsiMethod scopeMethod, PsiType type, boolean tailTypeSemicolon) { if (type != null) { ExpectedTypeInfoImpl info = createInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, type, - TailType.SEMICOLON); + tailTypeSemicolon ? TailType.SEMICOLON : TailType.NONE); if (PropertyUtil.isSimplePropertyAccessor(scopeMethod)) { info.expectedName = new NullableComputable() { @Override diff --git a/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInCodeBlocBodyInLocalVariable-out.java b/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInCodeBlocBodyInLocalVariable-out.java new file mode 100644 index 000000000000..446d58f6023b --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInCodeBlocBodyInLocalVariable-out.java @@ -0,0 +1,5 @@ +class Test { + public void foo() { + Runnable r = () -> {notify();}; + } +} diff --git a/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInCodeBlocBodyInLocalVariable.java b/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInCodeBlocBodyInLocalVariable.java new file mode 100644 index 000000000000..fa6f209bf19b --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInCodeBlocBodyInLocalVariable.java @@ -0,0 +1,5 @@ +class Test { + public void foo() { + Runnable r = () -> {}; + } +} diff --git a/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInExpressionList-out.java b/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInExpressionList-out.java new file mode 100644 index 000000000000..8b17af9e685c --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInExpressionList-out.java @@ -0,0 +1,5 @@ +class Test { + public void foo() { + new Thread(() -> notify()); + } +} diff --git a/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInExpressionList.java b/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInExpressionList.java new file mode 100644 index 000000000000..7b403c035879 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInExpressionList.java @@ -0,0 +1,5 @@ +class Test { + public void foo() { + new Thread(() -> ); + } +} diff --git a/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInLocalVariable-out.java b/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInLocalVariable-out.java new file mode 100644 index 000000000000..f6950c0dfbd7 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInLocalVariable-out.java @@ -0,0 +1,5 @@ +class Test { + public void foo() { + Runnable r = () -> notify(); + } +} diff --git a/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInLocalVariable.java b/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInLocalVariable.java new file mode 100644 index 000000000000..e41c2a19a0d3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInLocalVariable.java @@ -0,0 +1,5 @@ +class Test { + public void foo() { + Runnable r = () -> + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java index 1edd597e381c..06beba331d5c 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java @@ -50,6 +50,18 @@ public class SmartType18CompletionTest extends LightFixtureCompletionTestCase { public void testExpectedReturnType1() { doTest(); } + + public void testSemicolonInExpressionBodyInLocalVariable() { + doTest(); + } + + public void testSemicolonInCodeBlocBodyInLocalVariable() { + doTest(); + } + + public void testSemicolonInExpressionBodyInExpressionList() { + doTest(); + } private void doTest() { configureByFile("/" + getTestName(false) + ".java");