From 9c47fc6d4d67a9a3fd807a5edd01c4a8b58d9c5a Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 12 Feb 2019 12:58:41 +0300 Subject: [PATCH] Don't auto close simple long template entry if it's already finished (KT-11143) #KT-11143 Fixed --- .../ui/KotlinConfigurationCheckerComponent.kt | 8 ++++--- .../idea/editor/KotlinTypedHandler.java | 24 +++++++++++++------ .../kotlin/idea/editor/TypedHandlerTest.kt | 18 ++++++++++++++ 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/ui/KotlinConfigurationCheckerComponent.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/ui/KotlinConfigurationCheckerComponent.kt index 0cb1e3e64bb..4997005f30f 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/ui/KotlinConfigurationCheckerComponent.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/ui/KotlinConfigurationCheckerComponent.kt @@ -53,13 +53,15 @@ class KotlinConfigurationCheckerComponent(val project: Project) : ProjectCompone if (!project.isInitialized) return if (notificationPostponed && !isSyncing) { - ApplicationManager.getApplication().executeOnPooledThread { - DumbService.getInstance(project).waitForSmartMode() + DumbService.getInstance(project).runWhenSmart { if (!isSyncing) { notificationPostponed = false + + val excludeModules = collectModulesWithOutdatedRuntime(findOutdatedKotlinLibraries(project)) + showConfigureKotlinNotificationIfNeeded( project, - collectModulesWithOutdatedRuntime(findOutdatedKotlinLibraries(project)) + excludeModules ) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/editor/KotlinTypedHandler.java b/idea/src/org/jetbrains/kotlin/idea/editor/KotlinTypedHandler.java index 03a279be47c..18968d7483b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/editor/KotlinTypedHandler.java +++ b/idea/src/org/jetbrains/kotlin/idea/editor/KotlinTypedHandler.java @@ -260,17 +260,27 @@ public class KotlinTypedHandler extends TypedHandlerDelegate { if (previousElement instanceof LeafPsiElement && ((LeafPsiElement) previousElement).getElementType() == KtTokens.LONG_TEMPLATE_ENTRY_START ) { - if (previousDollarInStringOffset != null && previousDollarInStringOffset.intValue() == offset - 1) { + PsiElement currentElement = file.findElementAt(offset); + boolean isNextTokenIsIdentifier = currentElement instanceof LeafPsiElement && + ((LeafPsiElement) currentElement).getElementType() == KtTokens.IDENTIFIER; + + if (!isNextTokenIsIdentifier) { editor.getDocument().insertString(offset, "}"); return Result.STOP; } - PsiElement currentElement = file.findElementAt(offset); - boolean isNextTokenIsIdentifier = currentElement instanceof LeafPsiElement && - ((LeafPsiElement) currentElement).getElementType() != KtTokens.IDENTIFIER; - if (isNextTokenIsIdentifier) { - editor.getDocument().insertString(offset, "}"); - return Result.STOP; + PsiElement lastInLongTemplateEntry = previousElement.getParent().getLastChild(); + boolean isSimpleLongTemplateEntry = + lastInLongTemplateEntry instanceof LeafPsiElement && + ((LeafPsiElement) lastInLongTemplateEntry).getElementType() == KtTokens.LONG_TEMPLATE_ENTRY_END && + lastInLongTemplateEntry.getParent().getTextLength() == currentElement.getTextLength() + "${}".length(); + + if (!isSimpleLongTemplateEntry) { + boolean isAfterTypedDollar = previousDollarInStringOffset != null && previousDollarInStringOffset.intValue() == offset - 1; + if (isAfterTypedDollar) { + editor.getDocument().insertString(offset, "}"); + return Result.STOP; + } } } } diff --git a/idea/tests/org/jetbrains/kotlin/idea/editor/TypedHandlerTest.kt b/idea/tests/org/jetbrains/kotlin/idea/editor/TypedHandlerTest.kt index 8e1d0187693..1e09128931e 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/editor/TypedHandlerTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/editor/TypedHandlerTest.kt @@ -63,6 +63,24 @@ class TypedHandlerTest : LightCodeInsightTestCase() { """fun foo() { "$dollar{}something" }""" ) + fun testTypeStringTemplateWithUnmatchedBrace() = doTypeTest( + "$dollar{", + """val a = "bar}foo"""", + """val a = "$dollar{bar}foo"""" + ) + + fun testTypeStringTemplateWithUnmatchedBraceComplex() = doTypeTest( + "$dollar{", + """val a = "bar + more}foo"""", + """val a = "$dollar{}bar + more}foo"""" + ) + + fun testTypeStringTemplateStartInStringWithBraceLiterals() = doTypeTest( + "$dollar{", + """val test = "{ code other }"""", + """val test = "{ code $dollar{}other }"""" + ) + fun testTypeStringTemplateStartInEmptyString() = doTypeTest( '{', """fun foo() { "$" }""",