FIR IDE: Refactor KotlinFirLookupElementFactory
This commit is contained in:
+14
-31
@@ -77,7 +77,7 @@ private data class ClassifierLookupObject(override val shortName: Name, val clas
|
|||||||
*/
|
*/
|
||||||
private data class FunctionLookupObject(
|
private data class FunctionLookupObject(
|
||||||
override val shortName: Name,
|
override val shortName: Name,
|
||||||
val importingStrategy: CallableImportStrategy,
|
val importStrategy: CallableImportStrategy,
|
||||||
val inputValueArguments: Boolean,
|
val inputValueArguments: Boolean,
|
||||||
val insertEmptyLambda: Boolean,
|
val insertEmptyLambda: Boolean,
|
||||||
// for distinction between different overloads
|
// for distinction between different overloads
|
||||||
@@ -115,7 +115,7 @@ private class VariableLookupElementFactory {
|
|||||||
return LookupElementBuilder.create(lookupObject, symbol.name.asString())
|
return LookupElementBuilder.create(lookupObject, symbol.name.asString())
|
||||||
.withTypeText(symbol.annotatedType.type.render())
|
.withTypeText(symbol.annotatedType.type.render())
|
||||||
.markIfSyntheticJavaProperty(symbol)
|
.markIfSyntheticJavaProperty(symbol)
|
||||||
.withInsertHandler(ShorteningVariableInsertionHandler)
|
.withInsertHandler(VariableInsertionHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun LookupElementBuilder.markIfSyntheticJavaProperty(symbol: KtVariableLikeSymbol): LookupElementBuilder = when (symbol) {
|
private fun LookupElementBuilder.markIfSyntheticJavaProperty(symbol: KtVariableLikeSymbol): LookupElementBuilder = when (symbol) {
|
||||||
@@ -144,7 +144,7 @@ private class FunctionLookupElementFactory {
|
|||||||
fun KtAnalysisSession.createLookup(symbol: KtFunctionSymbol): LookupElementBuilder? {
|
fun KtAnalysisSession.createLookup(symbol: KtFunctionSymbol): LookupElementBuilder? {
|
||||||
val lookupObject = FunctionLookupObject(
|
val lookupObject = FunctionLookupObject(
|
||||||
symbol.name,
|
symbol.name,
|
||||||
importingStrategy = detectImportingStrategy(symbol),
|
importStrategy = detectImportStrategy(symbol),
|
||||||
inputValueArguments = symbol.valueParameters.isNotEmpty(),
|
inputValueArguments = symbol.valueParameters.isNotEmpty(),
|
||||||
insertEmptyLambda = insertLambdaBraces(symbol),
|
insertEmptyLambda = insertLambdaBraces(symbol),
|
||||||
renderedFunctionParameters = with(ShortNamesRenderer) { renderFunctionParameters(symbol) }
|
renderedFunctionParameters = with(ShortNamesRenderer) { renderFunctionParameters(symbol) }
|
||||||
@@ -154,7 +154,7 @@ private class FunctionLookupElementFactory {
|
|||||||
LookupElementBuilder.create(lookupObject, symbol.name.asString())
|
LookupElementBuilder.create(lookupObject, symbol.name.asString())
|
||||||
.withTailText(getTailText(symbol), true)
|
.withTailText(getTailText(symbol), true)
|
||||||
.withTypeText(symbol.annotatedType.type.render())
|
.withTypeText(symbol.annotatedType.type.render())
|
||||||
.withInsertHandler(ShorteningFunctionInsertionHandler)
|
.withInsertHandler(FunctionInsertionHandler)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
if (e is ControlFlowException) throw e
|
if (e is ControlFlowException) throw e
|
||||||
LOG.error(e)
|
LOG.error(e)
|
||||||
@@ -162,7 +162,7 @@ private class FunctionLookupElementFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun detectImportingStrategy(symbol: KtFunctionSymbol): CallableImportStrategy {
|
private fun detectImportStrategy(symbol: KtFunctionSymbol): CallableImportStrategy {
|
||||||
val functionFqName = symbol.callableIdIfNonLocal
|
val functionFqName = symbol.callableIdIfNonLocal
|
||||||
return when {
|
return when {
|
||||||
functionFqName == null -> CallableImportStrategy.DoNothing
|
functionFqName == null -> CallableImportStrategy.DoNothing
|
||||||
@@ -205,8 +205,8 @@ private object ClassifierInsertionHandler : InsertHandler<LookupElement> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private abstract class AbstractFunctionInsertionHandler : QuotedNamesAwareInsertionHandler() {
|
private object FunctionInsertionHandler : QuotedNamesAwareInsertionHandler() {
|
||||||
protected fun addArguments(context: InsertionContext, offsetElement: PsiElement, lookupObject: FunctionLookupObject) {
|
private fun addArguments(context: InsertionContext, offsetElement: PsiElement, lookupObject: FunctionLookupObject) {
|
||||||
val completionChar = context.completionChar
|
val completionChar = context.completionChar
|
||||||
if (completionChar == '(') { //TODO: more correct behavior related to braces type
|
if (completionChar == '(') { //TODO: more correct behavior related to braces type
|
||||||
context.setAddCompletionChar(false)
|
context.setAddCompletionChar(false)
|
||||||
@@ -275,25 +275,22 @@ private abstract class AbstractFunctionInsertionHandler : QuotedNamesAwareInsert
|
|||||||
if (completionChar == '(') return true
|
if (completionChar == '(') return true
|
||||||
return lookupObject.inputValueArguments || lookupObject.insertEmptyLambda
|
return lookupObject.inputValueArguments || lookupObject.insertEmptyLambda
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private object ShorteningFunctionInsertionHandler : AbstractFunctionInsertionHandler() {
|
|
||||||
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
||||||
val targetFile = context.file as? KtFile ?: return
|
val targetFile = context.file as? KtFile ?: return
|
||||||
val lookupObject = item.`object` as FunctionLookupObject
|
val lookupObject = item.`object` as FunctionLookupObject
|
||||||
|
|
||||||
val importingStrategy = lookupObject.importingStrategy
|
|
||||||
|
|
||||||
super.handleInsert(context, item)
|
super.handleInsert(context, item)
|
||||||
|
|
||||||
val startOffset = context.startOffset
|
val startOffset = context.startOffset
|
||||||
val element = context.file.findElementAt(startOffset) ?: return
|
val element = context.file.findElementAt(startOffset) ?: return
|
||||||
|
|
||||||
if (importingStrategy is CallableImportStrategy.InsertFqNameAndShorten) {
|
val importStrategy = lookupObject.importStrategy
|
||||||
|
if (importStrategy is CallableImportStrategy.InsertFqNameAndShorten) {
|
||||||
context.document.replaceString(
|
context.document.replaceString(
|
||||||
context.startOffset,
|
context.startOffset,
|
||||||
context.tailOffset,
|
context.tailOffset,
|
||||||
importingStrategy.fqName.withRootPrefixIfNeeded().render()
|
importStrategy.fqName.withRootPrefixIfNeeded().render()
|
||||||
)
|
)
|
||||||
context.commitDocument()
|
context.commitDocument()
|
||||||
|
|
||||||
@@ -305,14 +302,14 @@ private object ShorteningFunctionInsertionHandler : AbstractFunctionInsertionHan
|
|||||||
addArguments(context, element, lookupObject)
|
addArguments(context, element, lookupObject)
|
||||||
context.commitDocument()
|
context.commitDocument()
|
||||||
|
|
||||||
if (importingStrategy is CallableImportStrategy.AddImport) {
|
if (importStrategy is CallableImportStrategy.AddImport) {
|
||||||
addCallableImportIfRequired(targetFile, importingStrategy.nameToImport)
|
addCallableImportIfRequired(targetFile, importStrategy.nameToImport)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private object ShorteningVariableInsertionHandler : InsertHandler<LookupElement> {
|
private object VariableInsertionHandler : InsertHandler<LookupElement> {
|
||||||
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
||||||
val targetFile = context.file as? KtFile ?: return
|
val targetFile = context.file as? KtFile ?: return
|
||||||
val lookupObject = item.`object` as VariableLookupObject
|
val lookupObject = item.`object` as VariableLookupObject
|
||||||
@@ -369,27 +366,13 @@ private fun alreadyHasImport(file: KtFile, nameToImport: FqName): Boolean {
|
|||||||
return scopes
|
return scopes
|
||||||
.getCallableSymbols { it == nameToImport.shortName() }
|
.getCallableSymbols { it == nameToImport.shortName() }
|
||||||
.any {
|
.any {
|
||||||
it is KtVariableLikeSymbol && it.callableIdIfExists == nameToImport ||
|
it is KtKotlinPropertySymbol && it.callableIdIfNonLocal == nameToImport ||
|
||||||
it is KtFunctionSymbol && it.callableIdIfNonLocal == nameToImport
|
it is KtFunctionSymbol && it.callableIdIfNonLocal == nameToImport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val KtVariableLikeSymbol.callableIdIfExists: FqName?
|
|
||||||
get() = when (this) {
|
|
||||||
is KtJavaFieldSymbol -> callableIdIfNonLocal
|
|
||||||
is KtKotlinPropertySymbol -> callableIdIfNonLocal
|
|
||||||
is KtSyntheticJavaPropertySymbol -> callableIdIfNonLocal
|
|
||||||
|
|
||||||
// Compiler will complain if there would be a new type in the hierarchy
|
|
||||||
is KtEnumEntrySymbol,
|
|
||||||
is KtLocalVariableSymbol,
|
|
||||||
is KtFunctionParameterSymbol,
|
|
||||||
is KtConstructorParameterSymbol,
|
|
||||||
is KtSetterParameterSymbol -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
private object ShortNamesRenderer {
|
private object ShortNamesRenderer {
|
||||||
fun KtAnalysisSession.renderFunctionParameters(function: KtFunctionSymbol): String =
|
fun KtAnalysisSession.renderFunctionParameters(function: KtFunctionSymbol): String =
|
||||||
function.valueParameters.joinToString(", ", "(", ")") { renderFunctionParameter(it) }
|
function.valueParameters.joinToString(", ", "(", ")") { renderFunctionParameter(it) }
|
||||||
|
|||||||
Reference in New Issue
Block a user