From 55ec6729b0b1eb376bab500ef44e7f97763daff7 Mon Sep 17 00:00:00 2001 From: Ilya Muradyan Date: Fri, 9 Jul 2021 01:50:51 +0300 Subject: [PATCH] [REPL] Fix completion after final expressions --- .../ReplCompletionAndErrorsAnalysisTest.kt | 8 +++++- .../test_util/testConfiguration.kt | 24 +++++++++++++---- .../compiler/impl/KJvmReplCompleter.kt | 26 ++++++++++--------- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/plugins/scripting/scripting-ide-services-test/test/org/jetbrains/kotlin/scripting/ide_services/ReplCompletionAndErrorsAnalysisTest.kt b/plugins/scripting/scripting-ide-services-test/test/org/jetbrains/kotlin/scripting/ide_services/ReplCompletionAndErrorsAnalysisTest.kt index 9f493c5f19d..630752a1931 100644 --- a/plugins/scripting/scripting-ide-services-test/test/org/jetbrains/kotlin/scripting/ide_services/ReplCompletionAndErrorsAnalysisTest.kt +++ b/plugins/scripting/scripting-ide-services-test/test/org/jetbrains/kotlin/scripting/ide_services/ReplCompletionAndErrorsAnalysisTest.kt @@ -229,7 +229,13 @@ class ReplCompletionAndErrorsAnalysisTest : TestCase() { code = "df.fil" cursor = 6 expect { - addCompletion("filter { ", "filter(Line_1_simplescript.AClass.() -> ...", "Line_1_simplescript.AClass", "method") + completions.check { actual -> + assertEquals( + SourceCodeCompletionVariant( + "filter { ", "filter(Line_1_simplescript.AClass.() -> ...", "Line_1_simplescript.AClass", "method" + ), actual.single { it.tail != "keyword" } + ) + } } } } diff --git a/plugins/scripting/scripting-ide-services-test/test/org/jetbrains/kotlin/scripting/ide_services/test_util/testConfiguration.kt b/plugins/scripting/scripting-ide-services-test/test/org/jetbrains/kotlin/scripting/ide_services/test_util/testConfiguration.kt index a272faa93af..d489c44d04c 100644 --- a/plugins/scripting/scripting-ide-services-test/test/org/jetbrains/kotlin/scripting/ide_services/test_util/testConfiguration.kt +++ b/plugins/scripting/scripting-ide-services-test/test/org/jetbrains/kotlin/scripting/ide_services/test_util/testConfiguration.kt @@ -108,7 +108,7 @@ fun test(setup: (TestConf).() -> Unit) { } enum class ComparisonType { - COMPARE_SIZE, INCLUDES, EQUALS, DONT_CHECK + COMPARE_SIZE, INCLUDES, EQUALS, CUSTOM, DONT_CHECK } data class CSVLoggingInfoItem( @@ -138,12 +138,15 @@ data class RunRequest( val loggingInfo: CSVLoggingInfo?, ) -interface ExpectedOptions { +typealias ListCheck = (List) -> Unit + +interface ExpectedOptions { val mode: ComparisonType val size: Int + val checkFunction: ListCheck? } -class ExpectedList(private val runProperty: KProperty0) : ExpectedOptions { +class ExpectedList(private val runProperty: KProperty0) : ExpectedOptions { val list = mutableListOf() override var mode = ComparisonType.DONT_CHECK @@ -161,6 +164,16 @@ class ExpectedList(private val runProperty: KProperty0) : ExpectedOptio runProperty.get() list.add(elem) } + + override var checkFunction: ListCheck? = null + private set + + fun check(checkFunction: ListCheck) { + if (mode == ComparisonType.DONT_CHECK) + mode = ComparisonType.CUSTOM + runProperty.get() + this.checkFunction = checkFunction + } } class ExpectedNullableVar(private val runProperty: KProperty0) { @@ -211,7 +224,7 @@ private suspend fun evaluateInRepl( loggingInfo?.complete?.writeValue(timeMillis) - res!!.toList().filter { it.tail != "keyword" } + res!!.toList() } else { emptyList() } @@ -247,7 +260,7 @@ private suspend fun evaluateInRepl( } } -private fun checkLists(index: Int, checkName: String, expected: List, actual: List, options: ExpectedOptions) { +private fun checkLists(index: Int, checkName: String, expected: List, actual: List, options: ExpectedOptions) { when (options.mode) { ComparisonType.EQUALS -> Assert.assertEquals( "#$index ($checkName): Expected $expected, got $actual", @@ -263,6 +276,7 @@ private fun checkLists(index: Int, checkName: String, expected: List, act options.size, actual.size ) + ComparisonType.CUSTOM -> options.checkFunction!!(actual) ComparisonType.DONT_CHECK -> { } } diff --git a/plugins/scripting/scripting-ide-services/src/org/jetbrains/kotlin/scripting/ide_services/compiler/impl/KJvmReplCompleter.kt b/plugins/scripting/scripting-ide-services/src/org/jetbrains/kotlin/scripting/ide_services/compiler/impl/KJvmReplCompleter.kt index 8812221b9ae..18979d8be66 100644 --- a/plugins/scripting/scripting-ide-services/src/org/jetbrains/kotlin/scripting/ide_services/compiler/impl/KJvmReplCompleter.kt +++ b/plugins/scripting/scripting-ide-services/src/org/jetbrains/kotlin/scripting/ide_services/compiler/impl/KJvmReplCompleter.kt @@ -121,7 +121,6 @@ private class KJvmReplCompleter( private val getDescriptorsSimple = ResultGetter { element, options -> val expression = element.thisOrParent() ?: return@ResultGetter null - val result = DescriptorsResult(targetElement = expression) val inDescriptor: DeclarationDescriptor = expression.getResolutionScope(bindingContext, resolutionFacade).ownerDescriptor val prefix = element.text.substring(0, cursor - element.startOffset) @@ -131,7 +130,7 @@ private class KJvmReplCompleter( if (parentChildren.size == 3 && parentChildren[1] is KtOperationReferenceExpression && parentChildren[1].text == INSERTED_STRING - ) return@ResultGetter result + ) return@ResultGetter DescriptorsResult(targetElement = expression, addKeywords = false) } val containingArgument = expression.thisOrParent() @@ -303,18 +302,20 @@ private class KJvmReplCompleter( } } - yieldAll( - keywordsCompletionVariants( - KtTokens.KEYWORDS, - prefix + if (result.addKeywords) { + yieldAll( + keywordsCompletionVariants( + KtTokens.KEYWORDS, + prefix + ) ) - ) - yieldAll( - keywordsCompletionVariants( - KtTokens.SOFT_KEYWORDS, - prefix + yieldAll( + keywordsCompletionVariants( + KtTokens.SOFT_KEYWORDS, + prefix + ) ) - ) + } } } } @@ -356,6 +357,7 @@ private class KJvmReplCompleter( var sortNeeded: Boolean = true, var targetElement: PsiElement, val containingCallParameters: MutableList = mutableListOf(), + val addKeywords: Boolean = true, ) private class DescriptorsOptions(