From 7de5f6862956e6468b5e12a4e4c2f9f77012811b Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Mon, 9 Apr 2012 11:43:46 +0400 Subject: [PATCH] KT-1238 Completion of 'break' keyword: why does it add space char at the end? KT-1237 Auto-completion of "return" keyword should not insert space after it when in a method returning Unit #KT-1237 fixed #KT-1238 fixed --- .../jetbrains/jet/lang/psi/JetPsiUtil.java | 8 ++++ .../handlers/JetKeywordInsertHandler.java | 40 ++++++++++++++++--- .../completion/handlers/keywords/Break.kt | 3 ++ .../handlers/keywords/Break_after.kt | 3 ++ .../handlers/keywords/ReturnInEmptyType.kt | 3 ++ .../keywords/ReturnInEmptyType_after.kt | 3 ++ .../handlers/keywords/ReturnInProperty.kt | 6 +++ .../keywords/ReturnInProperty_after.kt | 6 +++ .../handlers/keywords/ReturnInTypeFunction.kt | 5 +++ .../keywords/ReturnInTypeFunction_after.kt | 5 +++ .../handlers/keywords/ReturnInUnit.kt | 5 +++ .../handlers/keywords/ReturnInUnit_after.kt | 5 +++ .../handlers/KeywordsHandlerTest.java | 28 ++++++++++++- 13 files changed, 113 insertions(+), 7 deletions(-) create mode 100644 idea/testData/completion/handlers/keywords/Break.kt create mode 100644 idea/testData/completion/handlers/keywords/Break_after.kt create mode 100644 idea/testData/completion/handlers/keywords/ReturnInEmptyType.kt create mode 100644 idea/testData/completion/handlers/keywords/ReturnInEmptyType_after.kt create mode 100644 idea/testData/completion/handlers/keywords/ReturnInProperty.kt create mode 100644 idea/testData/completion/handlers/keywords/ReturnInProperty_after.kt create mode 100644 idea/testData/completion/handlers/keywords/ReturnInTypeFunction.kt create mode 100644 idea/testData/completion/handlers/keywords/ReturnInTypeFunction_after.kt create mode 100644 idea/testData/completion/handlers/keywords/ReturnInUnit.kt create mode 100644 idea/testData/completion/handlers/keywords/ReturnInUnit_after.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index 97c7fe21711..4758735c7da 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -299,4 +299,12 @@ public class JetPsiUtil { } return null; } + + public static boolean isVoidType(@Nullable JetTypeReference typeReference) { + if (typeReference == null) { + return false; + } + + return "Unit".equals(typeReference.getText()); + } } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetKeywordInsertHandler.java b/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetKeywordInsertHandler.java index b7f50952e4e..1742545a632 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetKeywordInsertHandler.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetKeywordInsertHandler.java @@ -21,6 +21,11 @@ import com.intellij.codeInsight.TailType; import com.intellij.codeInsight.completion.InsertHandler; import com.intellij.codeInsight.completion.InsertionContext; import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; +import org.jetbrains.jet.lang.psi.JetFunction; +import org.jetbrains.jet.lang.psi.JetPsiUtil; +import org.jetbrains.jet.lexer.JetTokens; import java.util.Set; @@ -29,17 +34,40 @@ import java.util.Set; */ public class JetKeywordInsertHandler implements InsertHandler { - private final static Set NO_SPACE_AFTER = Sets.newHashSet("this", "super", "This", "true", "false", "null"); + private final static Set NO_SPACE_AFTER = Sets.newHashSet( + JetTokens.THIS_KEYWORD.toString(), + JetTokens.SUPER_KEYWORD.toString(), + JetTokens.CAPITALIZED_THIS_KEYWORD.toString(), + JetTokens.THIS_KEYWORD.toString(), + JetTokens.FALSE_KEYWORD.toString(), + JetTokens.NULL_KEYWORD.toString(), + JetTokens.BREAK_KEYWORD.toString(), + JetTokens.CONTINUE_KEYWORD.toString()); @Override public void handleInsert(InsertionContext context, LookupElement item) { String keyword = item.getLookupString(); - // Add space after keyword - if (!NO_SPACE_AFTER.contains(keyword)) { - context.setAddCompletionChar(false); - final TailType tailType = TailType.SPACE; - tailType.processTail(context.getEditor(), context.getTailOffset()); + if (NO_SPACE_AFTER.contains(keyword)) { + return; } + + if (keyword.equals(JetTokens.RETURN_KEYWORD.toString())) { + PsiElement element = context.getFile().findElementAt(context.getStartOffset()); + if (element != null) { + JetFunction jetFunction = PsiTreeUtil.getParentOfType(element, JetFunction.class); + if (jetFunction != null) { + if (!jetFunction.hasDeclaredReturnType() || JetPsiUtil.isVoidType(jetFunction.getReturnTypeRef())) { + // No space for void function + return; + } + } + } + } + + // Add space after keyword + context.setAddCompletionChar(false); + final TailType tailType = TailType.SPACE; + tailType.processTail(context.getEditor(), context.getTailOffset()); } } diff --git a/idea/testData/completion/handlers/keywords/Break.kt b/idea/testData/completion/handlers/keywords/Break.kt new file mode 100644 index 00000000000..0c592e98d5e --- /dev/null +++ b/idea/testData/completion/handlers/keywords/Break.kt @@ -0,0 +1,3 @@ +fun t() { + brea +} \ No newline at end of file diff --git a/idea/testData/completion/handlers/keywords/Break_after.kt b/idea/testData/completion/handlers/keywords/Break_after.kt new file mode 100644 index 00000000000..2a0482cbb7e --- /dev/null +++ b/idea/testData/completion/handlers/keywords/Break_after.kt @@ -0,0 +1,3 @@ +fun t() { + break +} \ No newline at end of file diff --git a/idea/testData/completion/handlers/keywords/ReturnInEmptyType.kt b/idea/testData/completion/handlers/keywords/ReturnInEmptyType.kt new file mode 100644 index 00000000000..caf3aaaddc2 --- /dev/null +++ b/idea/testData/completion/handlers/keywords/ReturnInEmptyType.kt @@ -0,0 +1,3 @@ +fun test(a: Int) { + retur +} \ No newline at end of file diff --git a/idea/testData/completion/handlers/keywords/ReturnInEmptyType_after.kt b/idea/testData/completion/handlers/keywords/ReturnInEmptyType_after.kt new file mode 100644 index 00000000000..2c31061fbf9 --- /dev/null +++ b/idea/testData/completion/handlers/keywords/ReturnInEmptyType_after.kt @@ -0,0 +1,3 @@ +fun test(a: Int) { + return +} \ No newline at end of file diff --git a/idea/testData/completion/handlers/keywords/ReturnInProperty.kt b/idea/testData/completion/handlers/keywords/ReturnInProperty.kt new file mode 100644 index 00000000000..be4a18be817 --- /dev/null +++ b/idea/testData/completion/handlers/keywords/ReturnInProperty.kt @@ -0,0 +1,6 @@ +class Test { + val test : String + get() { + retur + } +} \ No newline at end of file diff --git a/idea/testData/completion/handlers/keywords/ReturnInProperty_after.kt b/idea/testData/completion/handlers/keywords/ReturnInProperty_after.kt new file mode 100644 index 00000000000..a3f11d43a2f --- /dev/null +++ b/idea/testData/completion/handlers/keywords/ReturnInProperty_after.kt @@ -0,0 +1,6 @@ +class Test { + val test : String + get() { + return + } +} \ No newline at end of file diff --git a/idea/testData/completion/handlers/keywords/ReturnInTypeFunction.kt b/idea/testData/completion/handlers/keywords/ReturnInTypeFunction.kt new file mode 100644 index 00000000000..d060ce9b037 --- /dev/null +++ b/idea/testData/completion/handlers/keywords/ReturnInTypeFunction.kt @@ -0,0 +1,5 @@ +class Test { + fun someMethod() : Int { + retur + } +} \ No newline at end of file diff --git a/idea/testData/completion/handlers/keywords/ReturnInTypeFunction_after.kt b/idea/testData/completion/handlers/keywords/ReturnInTypeFunction_after.kt new file mode 100644 index 00000000000..e05c5eb5fe9 --- /dev/null +++ b/idea/testData/completion/handlers/keywords/ReturnInTypeFunction_after.kt @@ -0,0 +1,5 @@ +class Test { + fun someMethod() : Int { + return + } +} \ No newline at end of file diff --git a/idea/testData/completion/handlers/keywords/ReturnInUnit.kt b/idea/testData/completion/handlers/keywords/ReturnInUnit.kt new file mode 100644 index 00000000000..87c304b1538 --- /dev/null +++ b/idea/testData/completion/handlers/keywords/ReturnInUnit.kt @@ -0,0 +1,5 @@ +object OtherTest { + fun test() : Unit { + retur + } +} \ No newline at end of file diff --git a/idea/testData/completion/handlers/keywords/ReturnInUnit_after.kt b/idea/testData/completion/handlers/keywords/ReturnInUnit_after.kt new file mode 100644 index 00000000000..044a851ecb6 --- /dev/null +++ b/idea/testData/completion/handlers/keywords/ReturnInUnit_after.kt @@ -0,0 +1,5 @@ +object OtherTest { + fun test() : Unit { + return + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/completion/handlers/KeywordsHandlerTest.java b/idea/tests/org/jetbrains/jet/completion/handlers/KeywordsHandlerTest.java index 77d8fe832e9..2454950cd81 100644 --- a/idea/tests/org/jetbrains/jet/completion/handlers/KeywordsHandlerTest.java +++ b/idea/tests/org/jetbrains/jet/completion/handlers/KeywordsHandlerTest.java @@ -39,9 +39,35 @@ public class KeywordsHandlerTest extends LightCompletionTestCase { checkResultByText("fun test() { null }"); } + public void testBreak() { + doFileTest(); + } + + public void testReturnInEmptyType() { + doFileTest(); + } + + public void testReturnInProperty() { + doFileTest(); + } + + public void testReturnInTypeFunction() { + doFileTest(); + } + + public void testReturnInUnit() { + doFileTest(); + } + + protected void doFileTest() { + configureByFile(getTestName(false) + ".kt"); + complete(); + checkResultByFile(getTestName(false) + "_after.kt"); + } + @Override protected String getTestDataPath() { - return new File(PluginTestCaseBase.getTestDataPathBase(), "/completion/handlers/").getPath() + + return new File(PluginTestCaseBase.getTestDataPathBase(), "/completion/handlers/keywords").getPath() + File.separator; } }