From 022075995bcb45d9320d78615761fe3d84d6b659 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Mon, 18 Apr 2016 22:42:10 +0300 Subject: [PATCH] KT-11957 No "catch" and "finally" keywords in completion #KT-11957 Fixed --- .../idea/completion/KeywordCompletion.kt | 14 +++++--- .../idea/completion/handlers/handlerUtils.kt | 33 ++++++++++--------- .../keywords/{Catch.kt.todo => Catch.kt} | 0 .../testData/handlers/keywords/Finally.kt | 10 ++++++ .../handlers/keywords/Finally.kt.after | 12 +++++++ .../testData/keywords/AfterTry.kt | 13 ++++++++ .../testData/keywords/AfterTryCatch.kt | 32 ++++++++++++++++++ .../testData/keywords/AfterTryFinally.kt | 29 ++++++++++++++++ .../test/KeywordCompletionTestGenerated.java | 18 ++++++++++ ...KeywordCompletionHandlerTestGenerated.java | 12 +++++++ 10 files changed, 153 insertions(+), 20 deletions(-) rename idea/idea-completion/testData/handlers/keywords/{Catch.kt.todo => Catch.kt} (100%) create mode 100644 idea/idea-completion/testData/handlers/keywords/Finally.kt create mode 100644 idea/idea-completion/testData/handlers/keywords/Finally.kt.after create mode 100644 idea/idea-completion/testData/keywords/AfterTry.kt create mode 100644 idea/idea-completion/testData/keywords/AfterTryCatch.kt create mode 100644 idea/idea-completion/testData/keywords/AfterTryFinally.kt diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/KeywordCompletion.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/KeywordCompletion.kt index 3ef396e2349..f2ba185b772 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/KeywordCompletion.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/KeywordCompletion.kt @@ -64,9 +64,8 @@ object KeywordCompletion { WHILE_KEYWORD to "fun foo() { while(caret)", FOR_KEYWORD to "fun foo() { for(caret)", TRY_KEYWORD to "fun foo() { try {\ncaret\n}", -/* TODO! - CATCH_KEYWORD to "fun foo() { try {} catch ()", -*/ + CATCH_KEYWORD to "fun foo() { try {} catch (caret)", + FINALLY_KEYWORD to "fun foo() { try {\n}\nfinally{\ncaret\n}", DO_KEYWORD to "fun foo() { do {\ncaret\n}", INIT_KEYWORD to "class C { init {\ncaret\n}", CONSTRUCTOR_KEYWORD to "class C { constructor(caret)" @@ -187,8 +186,15 @@ object KeywordCompletion { while (parent != null) { when (parent) { is KtBlockExpression -> { - val prefixText = "fun foo() { " + var prefixText = "fun foo() { " if (prevParent is KtExpression) { + val tryExpression = prevParent.prevSiblingOfSameType() as? KtTryExpression + if (tryExpression != null && tryExpression.finallyBlock == null) { + prefixText += when { + tryExpression.catchClauses.isEmpty() -> "try {}\n" + else -> "try {} catch (e: E) {}\n" + } + } return buildFilterWithContext(prefixText, prevParent, position) } else { diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/handlers/handlerUtils.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/handlers/handlerUtils.kt index 60fd9cce225..28b58cf603f 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/handlers/handlerUtils.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/handlers/handlerUtils.kt @@ -100,10 +100,8 @@ fun createKeywordConstructLookupElement( } val indent = detectIndent(newFileText, keywordOffset) - if (indent != null) { - tailBeforeCaret = tailBeforeCaret.unindent(indent) - tailAfterCaret = tailAfterCaret.unindent(indent) - } + tailBeforeCaret = tailBeforeCaret.unindent(indent) + tailAfterCaret = tailAfterCaret.unindent(indent) var lookupElementBuilder = LookupElementBuilder.create(KeywordLookupObject(), keyword) .bold() @@ -111,12 +109,10 @@ fun createKeywordConstructLookupElement( if (insertionContext.completionChar == Lookup.NORMAL_SELECT_CHAR || insertionContext.completionChar == Lookup.REPLACE_SELECT_CHAR) { val offset = insertionContext.tailOffset val newIndent = detectIndent(insertionContext.document.charsSequence, offset - keyword.length) - var beforeCaret = tailBeforeCaret - var afterCaret = tailAfterCaret - if (newIndent != null) { - beforeCaret = beforeCaret.indentLinesAfterFirst(newIndent) - afterCaret = afterCaret.indentLinesAfterFirst(newIndent) - } + + val beforeCaret = tailBeforeCaret.indentLinesAfterFirst(newIndent) + val afterCaret = tailAfterCaret.indentLinesAfterFirst(newIndent) + insertionContext.document.insertString(offset, beforeCaret + afterCaret) insertionContext.editor.moveCaret(offset + beforeCaret.length) } @@ -127,19 +123,24 @@ fun createKeywordConstructLookupElement( return lookupElementBuilder } -private fun detectIndent(text: CharSequence, offset: Int): String? { +private fun detectIndent(text: CharSequence, offset: Int): String { val reversedIndent = buildString { var index = offset - 1 - Loop@ while (index >= 0) { val c = text[index] - when (c) { - ' ', '\t' -> append(c) - '\r', '\n' -> break@Loop - else -> return null + if (c == '\n' || c == '\r') { + break } index-- } + index++ + + while (index < offset) { + val c = text[index] + if (!c.isWhitespace()) break + append(c) + index++ + } } return reversedIndent.reversed() } diff --git a/idea/idea-completion/testData/handlers/keywords/Catch.kt.todo b/idea/idea-completion/testData/handlers/keywords/Catch.kt similarity index 100% rename from idea/idea-completion/testData/handlers/keywords/Catch.kt.todo rename to idea/idea-completion/testData/handlers/keywords/Catch.kt diff --git a/idea/idea-completion/testData/handlers/keywords/Finally.kt b/idea/idea-completion/testData/handlers/keywords/Finally.kt new file mode 100644 index 00000000000..3178f3c853e --- /dev/null +++ b/idea/idea-completion/testData/handlers/keywords/Finally.kt @@ -0,0 +1,10 @@ +fun t() { + while (true) { + try { + + } + f + } +} + +// ELEMENT: finally \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/keywords/Finally.kt.after b/idea/idea-completion/testData/handlers/keywords/Finally.kt.after new file mode 100644 index 00000000000..57a698f936c --- /dev/null +++ b/idea/idea-completion/testData/handlers/keywords/Finally.kt.after @@ -0,0 +1,12 @@ +fun t() { + while (true) { + try { + + } + finally { + + } + } +} + +// ELEMENT: finally \ No newline at end of file diff --git a/idea/idea-completion/testData/keywords/AfterTry.kt b/idea/idea-completion/testData/keywords/AfterTry.kt new file mode 100644 index 00000000000..931b6898347 --- /dev/null +++ b/idea/idea-completion/testData/keywords/AfterTry.kt @@ -0,0 +1,13 @@ +fun foo() { + try { + + } + +} + +// EXIST: catch +// EXIST: finally +// EXIST: false +// EXIST: null +// EXIST: true +// NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/AfterTryCatch.kt b/idea/idea-completion/testData/keywords/AfterTryCatch.kt new file mode 100644 index 00000000000..ee4f1dd9e71 --- /dev/null +++ b/idea/idea-completion/testData/keywords/AfterTryCatch.kt @@ -0,0 +1,32 @@ +fun foo() { + try { + + } + catch(e: Exception) { + + } + +} + +// EXIST: catch +// EXIST: finally +// EXIST: class +// EXIST: do +// EXIST: false +// EXIST: for +// EXIST: fun +// EXIST: if +// EXIST: null +// EXIST: object +// EXIST: return +// EXIST: super +// EXIST: throw +// EXIST: interface +// EXIST: true +// EXIST: try +// EXIST: val +// EXIST: var +// EXIST: when +// EXIST: while +// EXIST: as +// NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/AfterTryFinally.kt b/idea/idea-completion/testData/keywords/AfterTryFinally.kt new file mode 100644 index 00000000000..f84949fa6e1 --- /dev/null +++ b/idea/idea-completion/testData/keywords/AfterTryFinally.kt @@ -0,0 +1,29 @@ +fun foo() { + try { + + } + finally { + + } + +} + +// EXIST: class +// EXIST: do +// EXIST: false +// EXIST: for +// EXIST: fun +// EXIST: if +// EXIST: null +// EXIST: object +// EXIST: return +// EXIST: super +// EXIST: throw +// EXIST: interface +// EXIST: true +// EXIST: try +// EXIST: val +// EXIST: var +// EXIST: when +// EXIST: while +// NOTHING_ELSE diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/KeywordCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/KeywordCompletionTestGenerated.java index ecffe865320..66a288e23ed 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/KeywordCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/KeywordCompletionTestGenerated.java @@ -67,6 +67,24 @@ public class KeywordCompletionTestGenerated extends AbstractKeywordCompletionTes doTest(fileName); } + @TestMetadata("AfterTry.kt") + public void testAfterTry() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/AfterTry.kt"); + doTest(fileName); + } + + @TestMetadata("AfterTryCatch.kt") + public void testAfterTryCatch() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/AfterTryCatch.kt"); + doTest(fileName); + } + + @TestMetadata("AfterTryFinally.kt") + public void testAfterTryFinally() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/AfterTryFinally.kt"); + doTest(fileName); + } + public void testAllFilesPresentInKeywords() throws Exception { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/keywords"), Pattern.compile("^(.+)\\.kt$"), false); } diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/KeywordCompletionHandlerTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/KeywordCompletionHandlerTestGenerated.java index 044d6a8d09e..6ae454ada44 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/KeywordCompletionHandlerTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/KeywordCompletionHandlerTestGenerated.java @@ -47,6 +47,12 @@ public class KeywordCompletionHandlerTestGenerated extends AbstractKeywordComple doTest(fileName); } + @TestMetadata("Catch.kt") + public void testCatch() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/keywords/Catch.kt"); + doTest(fileName); + } + @TestMetadata("CompanionObject.kt") public void testCompanionObject() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/keywords/CompanionObject.kt"); @@ -71,6 +77,12 @@ public class KeywordCompletionHandlerTestGenerated extends AbstractKeywordComple doTest(fileName); } + @TestMetadata("Finally.kt") + public void testFinally() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/keywords/Finally.kt"); + doTest(fileName); + } + @TestMetadata("For.kt") public void testFor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/keywords/For.kt");