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)",
|
WHILE_KEYWORD to "fun foo() { while(caret)",
|
||||||
FOR_KEYWORD to "fun foo() { for(caret)",
|
FOR_KEYWORD to "fun foo() { for(caret)",
|
||||||
TRY_KEYWORD to "fun foo() { try {\ncaret\n}",
|
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}",
|
DO_KEYWORD to "fun foo() { do {\ncaret\n}",
|
||||||
INIT_KEYWORD to "class C { init {\ncaret\n}",
|
INIT_KEYWORD to "class C { init {\ncaret\n}",
|
||||||
CONSTRUCTOR_KEYWORD to "class C { constructor(caret)"
|
CONSTRUCTOR_KEYWORD to "class C { constructor(caret)"
|
||||||
@@ -187,8 +186,15 @@ object KeywordCompletion {
|
|||||||
while (parent != null) {
|
while (parent != null) {
|
||||||
when (parent) {
|
when (parent) {
|
||||||
is KtBlockExpression -> {
|
is KtBlockExpression -> {
|
||||||
val prefixText = "fun foo() { "
|
var prefixText = "fun foo() { "
|
||||||
if (prevParent is KtExpression) {
|
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)
|
return buildFilterWithContext(prefixText, prevParent, position)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
+17
-16
@@ -100,10 +100,8 @@ fun createKeywordConstructLookupElement(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val indent = detectIndent(newFileText, keywordOffset)
|
val indent = detectIndent(newFileText, keywordOffset)
|
||||||
if (indent != null) {
|
tailBeforeCaret = tailBeforeCaret.unindent(indent)
|
||||||
tailBeforeCaret = tailBeforeCaret.unindent(indent)
|
tailAfterCaret = tailAfterCaret.unindent(indent)
|
||||||
tailAfterCaret = tailAfterCaret.unindent(indent)
|
|
||||||
}
|
|
||||||
|
|
||||||
var lookupElementBuilder = LookupElementBuilder.create(KeywordLookupObject(), keyword)
|
var lookupElementBuilder = LookupElementBuilder.create(KeywordLookupObject(), keyword)
|
||||||
.bold()
|
.bold()
|
||||||
@@ -111,12 +109,10 @@ fun createKeywordConstructLookupElement(
|
|||||||
if (insertionContext.completionChar == Lookup.NORMAL_SELECT_CHAR || insertionContext.completionChar == Lookup.REPLACE_SELECT_CHAR) {
|
if (insertionContext.completionChar == Lookup.NORMAL_SELECT_CHAR || insertionContext.completionChar == Lookup.REPLACE_SELECT_CHAR) {
|
||||||
val offset = insertionContext.tailOffset
|
val offset = insertionContext.tailOffset
|
||||||
val newIndent = detectIndent(insertionContext.document.charsSequence, offset - keyword.length)
|
val newIndent = detectIndent(insertionContext.document.charsSequence, offset - keyword.length)
|
||||||
var beforeCaret = tailBeforeCaret
|
|
||||||
var afterCaret = tailAfterCaret
|
val beforeCaret = tailBeforeCaret.indentLinesAfterFirst(newIndent)
|
||||||
if (newIndent != null) {
|
val afterCaret = tailAfterCaret.indentLinesAfterFirst(newIndent)
|
||||||
beforeCaret = beforeCaret.indentLinesAfterFirst(newIndent)
|
|
||||||
afterCaret = afterCaret.indentLinesAfterFirst(newIndent)
|
|
||||||
}
|
|
||||||
insertionContext.document.insertString(offset, beforeCaret + afterCaret)
|
insertionContext.document.insertString(offset, beforeCaret + afterCaret)
|
||||||
insertionContext.editor.moveCaret(offset + beforeCaret.length)
|
insertionContext.editor.moveCaret(offset + beforeCaret.length)
|
||||||
}
|
}
|
||||||
@@ -127,19 +123,24 @@ fun createKeywordConstructLookupElement(
|
|||||||
return lookupElementBuilder
|
return lookupElementBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun detectIndent(text: CharSequence, offset: Int): String? {
|
private fun detectIndent(text: CharSequence, offset: Int): String {
|
||||||
val reversedIndent = buildString {
|
val reversedIndent = buildString {
|
||||||
var index = offset - 1
|
var index = offset - 1
|
||||||
Loop@
|
|
||||||
while (index >= 0) {
|
while (index >= 0) {
|
||||||
val c = text[index]
|
val c = text[index]
|
||||||
when (c) {
|
if (c == '\n' || c == '\r') {
|
||||||
' ', '\t' -> append(c)
|
break
|
||||||
'\r', '\n' -> break@Loop
|
|
||||||
else -> return null
|
|
||||||
}
|
}
|
||||||
index--
|
index--
|
||||||
}
|
}
|
||||||
|
index++
|
||||||
|
|
||||||
|
while (index < offset) {
|
||||||
|
val c = text[index]
|
||||||
|
if (!c.isWhitespace()) break
|
||||||
|
append(c)
|
||||||
|
index++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return reversedIndent.reversed()
|
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);
|
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 {
|
public void testAllFilesPresentInKeywords() throws Exception {
|
||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/keywords"), Pattern.compile("^(.+)\\.kt$"), false);
|
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);
|
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")
|
@TestMetadata("CompanionObject.kt")
|
||||||
public void testCompanionObject() throws Exception {
|
public void testCompanionObject() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/keywords/CompanionObject.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/keywords/CompanionObject.kt");
|
||||||
@@ -71,6 +77,12 @@ public class KeywordCompletionHandlerTestGenerated extends AbstractKeywordComple
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("For.kt")
|
||||||
public void testFor() throws Exception {
|
public void testFor() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/keywords/For.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/keywords/For.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user