FIR Completion: Add insertion handling for functions with lambdas

- The support is not complete
This commit is contained in:
Roman Golyshev
2020-08-10 18:20:13 +03:00
parent b3a674abee
commit 6e2887e083
@@ -68,13 +68,26 @@ private class VariableLookupElementFactory {
private class FunctionLookupElementFactory { private class FunctionLookupElementFactory {
fun createLookup(symbol: KtFunctionSymbol): LookupElementBuilder { fun createLookup(symbol: KtFunctionSymbol): LookupElementBuilder {
return LookupElementBuilder.create(UniqueLookupObject(), symbol.name.asString()) return LookupElementBuilder.create(UniqueLookupObject(), symbol.name.asString())
.appendTailText(ShortNamesRenderer.renderFunctionParameters(symbol), true) .withTailText(getTailText(symbol), true)
.withTypeText(ShortNamesRenderer.renderType(symbol.type)) .withTypeText(ShortNamesRenderer.renderType(symbol.type))
.withInsertHandler(createInsertHandler(symbol)) .withInsertHandler(createInsertHandler(symbol))
} }
private fun getTailText(symbol: KtFunctionSymbol): String {
return if (insertLambdaBraces(symbol)) " {...}" else ShortNamesRenderer.renderFunctionParameters(symbol)
}
private fun insertLambdaBraces(symbol: KtFunctionSymbol): Boolean {
val singleParam = symbol.valueParameters.singleOrNull()
return singleParam != null && !singleParam.hasDefaultValue && singleParam.type.isBuiltInFunctionalType
}
private fun createInsertHandler(symbol: KtFunctionSymbol): InsertHandler<LookupElement> { private fun createInsertHandler(symbol: KtFunctionSymbol): InsertHandler<LookupElement> {
return FunctionInsertionHandler(symbol.name, inputValueArguments = symbol.valueParameters.isNotEmpty()) return FunctionInsertionHandler(
symbol.name,
inputValueArguments = symbol.valueParameters.isNotEmpty(),
insertEmptyLambda = insertLambdaBraces(symbol)
)
} }
} }
@@ -83,7 +96,8 @@ private class FunctionLookupElementFactory {
*/ */
private class FunctionInsertionHandler( private class FunctionInsertionHandler(
name: Name, name: Name,
private val inputValueArguments: Boolean private val inputValueArguments: Boolean,
private val insertEmptyLambda: Boolean
) : QuotedNamesAwareInsertionHandler(name) { ) : QuotedNamesAwareInsertionHandler(name) {
override fun handleInsert(context: InsertionContext, item: LookupElement) { override fun handleInsert(context: InsertionContext, item: LookupElement) {
super.handleInsert(context, item) super.handleInsert(context, item)
@@ -109,8 +123,7 @@ private class FunctionInsertionHandler(
val isSmartEnterCompletion = completionChar == Lookup.COMPLETE_STATEMENT_SELECT_CHAR val isSmartEnterCompletion = completionChar == Lookup.COMPLETE_STATEMENT_SELECT_CHAR
val isReplaceCompletion = completionChar == Lookup.REPLACE_SELECT_CHAR val isReplaceCompletion = completionChar == Lookup.REPLACE_SELECT_CHAR
val openingBracket = '(' val (openingBracket, closingBracket) = if (insertEmptyLambda) '{' to '}' else '(' to ')'
val closingBracket = ')'
if (isReplaceCompletion) { if (isReplaceCompletion) {
val offset1 = chars.skipSpaces(offset) val offset1 = chars.skipSpaces(offset)
@@ -132,10 +145,18 @@ private class FunctionInsertionHandler(
var closeBracketOffset = openingBracketOffset?.let { chars.indexOfSkippingSpace(closingBracket, it + 1) } var closeBracketOffset = openingBracketOffset?.let { chars.indexOfSkippingSpace(closingBracket, it + 1) }
if (openingBracketOffset == null) { if (openingBracketOffset == null) {
if (isSmartEnterCompletion) { if (insertEmptyLambda) {
document.insertString(offset, "(") if (completionChar == ' ' || completionChar == '{') {
context.setAddCompletionChar(false)
}
document.insertString(offset, " {}")
} else { } else {
document.insertString(offset, "()") if (isSmartEnterCompletion) {
document.insertString(offset, "(")
} else {
document.insertString(offset, "()")
}
} }
context.commitDocument() context.commitDocument()
@@ -154,7 +175,7 @@ private class FunctionInsertionHandler(
private fun shouldPlaceCaretInBrackets(completionChar: Char): Boolean { private fun shouldPlaceCaretInBrackets(completionChar: Char): Boolean {
if (completionChar == ',' || completionChar == '.' || completionChar == '=') return false if (completionChar == ',' || completionChar == '.' || completionChar == '=') return false
if (completionChar == '(') return true if (completionChar == '(') return true
return inputValueArguments return inputValueArguments || insertEmptyLambda
} }
} }