KT-11957 No "catch" and "finally" keywords in completion
#KT-11957 Fixed
This commit is contained in:
@@ -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 (<caret>)",
|
||||
*/
|
||||
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 {
|
||||
|
||||
+17
-16
@@ -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()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
fun t() {
|
||||
while (true) {
|
||||
try {
|
||||
|
||||
}
|
||||
f<caret>
|
||||
}
|
||||
}
|
||||
|
||||
// ELEMENT: finally
|
||||
@@ -0,0 +1,12 @@
|
||||
fun t() {
|
||||
while (true) {
|
||||
try {
|
||||
|
||||
}
|
||||
finally {
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ELEMENT: finally
|
||||
@@ -0,0 +1,13 @@
|
||||
fun foo() {
|
||||
try {
|
||||
|
||||
}
|
||||
<caret>
|
||||
}
|
||||
|
||||
// EXIST: catch
|
||||
// EXIST: finally
|
||||
// EXIST: false
|
||||
// EXIST: null
|
||||
// EXIST: true
|
||||
// NOTHING_ELSE
|
||||
@@ -0,0 +1,32 @@
|
||||
fun foo() {
|
||||
try {
|
||||
|
||||
}
|
||||
catch(e: Exception) {
|
||||
|
||||
}
|
||||
<caret>
|
||||
}
|
||||
|
||||
// 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
|
||||
@@ -0,0 +1,29 @@
|
||||
fun foo() {
|
||||
try {
|
||||
|
||||
}
|
||||
finally {
|
||||
|
||||
}
|
||||
<caret>
|
||||
}
|
||||
|
||||
// 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
|
||||
+18
@@ -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);
|
||||
}
|
||||
|
||||
+12
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user