[REPL] Fix completion after final expressions

This commit is contained in:
Ilya Muradyan
2021-07-09 01:50:51 +03:00
committed by teamcityserver
parent a915eddf22
commit 55ec6729b0
3 changed files with 40 additions and 18 deletions
@@ -229,7 +229,13 @@ class ReplCompletionAndErrorsAnalysisTest : TestCase() {
code = "df.fil" code = "df.fil"
cursor = 6 cursor = 6
expect { 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" }
)
}
} }
} }
} }
@@ -108,7 +108,7 @@ fun test(setup: (TestConf).() -> Unit) {
} }
enum class ComparisonType { enum class ComparisonType {
COMPARE_SIZE, INCLUDES, EQUALS, DONT_CHECK COMPARE_SIZE, INCLUDES, EQUALS, CUSTOM, DONT_CHECK
} }
data class CSVLoggingInfoItem( data class CSVLoggingInfoItem(
@@ -138,12 +138,15 @@ data class RunRequest(
val loggingInfo: CSVLoggingInfo?, val loggingInfo: CSVLoggingInfo?,
) )
interface ExpectedOptions { typealias ListCheck<T> = (List<T>) -> Unit
interface ExpectedOptions<T> {
val mode: ComparisonType val mode: ComparisonType
val size: Int val size: Int
val checkFunction: ListCheck<T>?
} }
class ExpectedList<T>(private val runProperty: KProperty0<Unit>) : ExpectedOptions { class ExpectedList<T>(private val runProperty: KProperty0<Unit>) : ExpectedOptions<T> {
val list = mutableListOf<T>() val list = mutableListOf<T>()
override var mode = ComparisonType.DONT_CHECK override var mode = ComparisonType.DONT_CHECK
@@ -161,6 +164,16 @@ class ExpectedList<T>(private val runProperty: KProperty0<Unit>) : ExpectedOptio
runProperty.get() runProperty.get()
list.add(elem) list.add(elem)
} }
override var checkFunction: ListCheck<T>? = null
private set
fun check(checkFunction: ListCheck<T>) {
if (mode == ComparisonType.DONT_CHECK)
mode = ComparisonType.CUSTOM
runProperty.get()
this.checkFunction = checkFunction
}
} }
class ExpectedNullableVar<T>(private val runProperty: KProperty0<Unit>) { class ExpectedNullableVar<T>(private val runProperty: KProperty0<Unit>) {
@@ -211,7 +224,7 @@ private suspend fun evaluateInRepl(
loggingInfo?.complete?.writeValue(timeMillis) loggingInfo?.complete?.writeValue(timeMillis)
res!!.toList().filter { it.tail != "keyword" } res!!.toList()
} else { } else {
emptyList() emptyList()
} }
@@ -247,7 +260,7 @@ private suspend fun evaluateInRepl(
} }
} }
private fun <T> checkLists(index: Int, checkName: String, expected: List<T>, actual: List<T>, options: ExpectedOptions) { private fun <T> checkLists(index: Int, checkName: String, expected: List<T>, actual: List<T>, options: ExpectedOptions<T>) {
when (options.mode) { when (options.mode) {
ComparisonType.EQUALS -> Assert.assertEquals( ComparisonType.EQUALS -> Assert.assertEquals(
"#$index ($checkName): Expected $expected, got $actual", "#$index ($checkName): Expected $expected, got $actual",
@@ -263,6 +276,7 @@ private fun <T> checkLists(index: Int, checkName: String, expected: List<T>, act
options.size, options.size,
actual.size actual.size
) )
ComparisonType.CUSTOM -> options.checkFunction!!(actual)
ComparisonType.DONT_CHECK -> { ComparisonType.DONT_CHECK -> {
} }
} }
@@ -121,7 +121,6 @@ private class KJvmReplCompleter(
private val getDescriptorsSimple = ResultGetter { element, options -> private val getDescriptorsSimple = ResultGetter { element, options ->
val expression = element.thisOrParent<KtSimpleNameExpression>() ?: return@ResultGetter null val expression = element.thisOrParent<KtSimpleNameExpression>() ?: return@ResultGetter null
val result = DescriptorsResult(targetElement = expression)
val inDescriptor: DeclarationDescriptor = expression.getResolutionScope(bindingContext, resolutionFacade).ownerDescriptor val inDescriptor: DeclarationDescriptor = expression.getResolutionScope(bindingContext, resolutionFacade).ownerDescriptor
val prefix = element.text.substring(0, cursor - element.startOffset) val prefix = element.text.substring(0, cursor - element.startOffset)
@@ -131,7 +130,7 @@ private class KJvmReplCompleter(
if (parentChildren.size == 3 && if (parentChildren.size == 3 &&
parentChildren[1] is KtOperationReferenceExpression && parentChildren[1] is KtOperationReferenceExpression &&
parentChildren[1].text == INSERTED_STRING parentChildren[1].text == INSERTED_STRING
) return@ResultGetter result ) return@ResultGetter DescriptorsResult(targetElement = expression, addKeywords = false)
} }
val containingArgument = expression.thisOrParent<KtValueArgument>() val containingArgument = expression.thisOrParent<KtValueArgument>()
@@ -303,18 +302,20 @@ private class KJvmReplCompleter(
} }
} }
yieldAll( if (result.addKeywords) {
keywordsCompletionVariants( yieldAll(
KtTokens.KEYWORDS, keywordsCompletionVariants(
prefix KtTokens.KEYWORDS,
prefix
)
) )
) yieldAll(
yieldAll( keywordsCompletionVariants(
keywordsCompletionVariants( KtTokens.SOFT_KEYWORDS,
KtTokens.SOFT_KEYWORDS, prefix
prefix )
) )
) }
} }
} }
} }
@@ -356,6 +357,7 @@ private class KJvmReplCompleter(
var sortNeeded: Boolean = true, var sortNeeded: Boolean = true,
var targetElement: PsiElement, var targetElement: PsiElement,
val containingCallParameters: MutableList<ValueParameterDescriptor> = mutableListOf(), val containingCallParameters: MutableList<ValueParameterDescriptor> = mutableListOf(),
val addKeywords: Boolean = true,
) )
private class DescriptorsOptions( private class DescriptorsOptions(