FIR IDE: Refactor variables insertion handlers
This commit is contained in:
+43
-68
@@ -55,10 +55,10 @@ internal class KotlinFirLookupElementFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed class FunctionImportStrategy {
|
private sealed class CallableImportStrategy {
|
||||||
object DoNothing : FunctionImportStrategy()
|
object DoNothing : CallableImportStrategy()
|
||||||
data class AddImport(val nameToImport: FqName) : FunctionImportStrategy()
|
data class AddImport(val nameToImport: FqName) : CallableImportStrategy()
|
||||||
data class InsertFqNameAndShorten(val fqName: FqName) : FunctionImportStrategy()
|
data class InsertFqNameAndShorten(val fqName: FqName) : CallableImportStrategy()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -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: FunctionImportStrategy,
|
val importingStrategy: CallableImportStrategy,
|
||||||
val inputValueArguments: Boolean,
|
val inputValueArguments: Boolean,
|
||||||
val insertEmptyLambda: Boolean,
|
val insertEmptyLambda: Boolean,
|
||||||
// for distinction between different overloads
|
// for distinction between different overloads
|
||||||
@@ -87,7 +87,10 @@ private data class FunctionLookupObject(
|
|||||||
/**
|
/**
|
||||||
* Simplest lookup object so two lookup elements for the same property will clash.
|
* Simplest lookup object so two lookup elements for the same property will clash.
|
||||||
*/
|
*/
|
||||||
private data class VariableLookupObject(override val shortName: Name, val callableIdIfNonLocal: FqName?) : KotlinLookupObject
|
private data class VariableLookupObject(
|
||||||
|
override val shortName: Name,
|
||||||
|
val importStrategy: CallableImportStrategy
|
||||||
|
) : KotlinLookupObject
|
||||||
|
|
||||||
private class ClassLookupElementFactory {
|
private class ClassLookupElementFactory {
|
||||||
fun createLookup(symbol: KtClassLikeSymbol): LookupElementBuilder {
|
fun createLookup(symbol: KtClassLikeSymbol): LookupElementBuilder {
|
||||||
@@ -104,12 +107,15 @@ private class TypeParameterLookupElementFactory {
|
|||||||
|
|
||||||
private class VariableLookupElementFactory {
|
private class VariableLookupElementFactory {
|
||||||
fun KtAnalysisSession.createLookup(symbol: KtVariableLikeSymbol): LookupElementBuilder {
|
fun KtAnalysisSession.createLookup(symbol: KtVariableLikeSymbol): LookupElementBuilder {
|
||||||
val lookupObject = VariableLookupObject(symbol.name, symbol.callableIdIfExists)
|
val lookupObject = VariableLookupObject(
|
||||||
|
symbol.name,
|
||||||
|
importStrategy = detectImportStrategy(symbol)
|
||||||
|
)
|
||||||
|
|
||||||
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(createInsertHandler(symbol))
|
.withInsertHandler(ShorteningVariableInsertionHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun LookupElementBuilder.markIfSyntheticJavaProperty(symbol: KtVariableLikeSymbol): LookupElementBuilder = when (symbol) {
|
private fun LookupElementBuilder.markIfSyntheticJavaProperty(symbol: KtVariableLikeSymbol): LookupElementBuilder = when (symbol) {
|
||||||
@@ -125,29 +131,13 @@ private class VariableLookupElementFactory {
|
|||||||
private fun buildSyntheticPropertyTailText(getterName: String, setterName: String?): String =
|
private fun buildSyntheticPropertyTailText(getterName: String, setterName: String?): String =
|
||||||
if (setterName != null) "$getterName()/$setterName()" else "$getterName()"
|
if (setterName != null) "$getterName()/$setterName()" else "$getterName()"
|
||||||
|
|
||||||
private fun createInsertHandler(symbol: KtVariableLikeSymbol): InsertHandler<LookupElement> {
|
private fun detectImportStrategy(symbol: KtVariableLikeSymbol): CallableImportStrategy {
|
||||||
val callableId = symbol.callableIdIfExists ?: return QuotedNamesAwareInsertionHandler()
|
if (symbol !is KtKotlinPropertySymbol) return CallableImportStrategy.DoNothing
|
||||||
|
if (symbol.dispatchType != null || symbol.receiverType != null) return CallableImportStrategy.DoNothing
|
||||||
|
|
||||||
return if (symbol.canBeCalledByFqName) {
|
return symbol.callableIdIfNonLocal?.let(CallableImportStrategy::InsertFqNameAndShorten)
|
||||||
ShorteningVariableInsertionHandler(callableId)
|
?: CallableImportStrategy.DoNothing
|
||||||
} else {
|
|
||||||
SimpleVariableInsertionHandler(symbol.importableFqName)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val KtVariableLikeSymbol.canBeCalledByFqName: Boolean
|
|
||||||
get() = when (this) {
|
|
||||||
is KtKotlinPropertySymbol -> dispatchType == null && receiverType == null
|
|
||||||
|
|
||||||
is KtEnumEntrySymbol -> true
|
|
||||||
|
|
||||||
is KtJavaFieldSymbol,
|
|
||||||
is KtSyntheticJavaPropertySymbol,
|
|
||||||
is KtLocalVariableSymbol,
|
|
||||||
is KtFunctionParameterSymbol,
|
|
||||||
is KtConstructorParameterSymbol,
|
|
||||||
is KtSetterParameterSymbol -> false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FunctionLookupElementFactory {
|
private class FunctionLookupElementFactory {
|
||||||
@@ -172,13 +162,13 @@ private class FunctionLookupElementFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun detectImportingStrategy(symbol: KtFunctionSymbol): FunctionImportStrategy {
|
private fun detectImportingStrategy(symbol: KtFunctionSymbol): CallableImportStrategy {
|
||||||
val functionFqName = symbol.callableIdIfNonLocal
|
val functionFqName = symbol.callableIdIfNonLocal
|
||||||
return when {
|
return when {
|
||||||
functionFqName == null -> FunctionImportStrategy.DoNothing
|
functionFqName == null -> CallableImportStrategy.DoNothing
|
||||||
symbol.dispatchType != null -> FunctionImportStrategy.DoNothing
|
symbol.dispatchType != null -> CallableImportStrategy.DoNothing
|
||||||
!symbol.isExtension -> FunctionImportStrategy.InsertFqNameAndShorten(functionFqName)
|
!symbol.isExtension -> CallableImportStrategy.InsertFqNameAndShorten(functionFqName)
|
||||||
else -> FunctionImportStrategy.AddImport(functionFqName)
|
else -> CallableImportStrategy.AddImport(functionFqName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,7 +289,7 @@ private object ShorteningFunctionInsertionHandler : AbstractFunctionInsertionHan
|
|||||||
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 FunctionImportStrategy.InsertFqNameAndShorten) {
|
if (importingStrategy is CallableImportStrategy.InsertFqNameAndShorten) {
|
||||||
context.document.replaceString(
|
context.document.replaceString(
|
||||||
context.startOffset,
|
context.startOffset,
|
||||||
context.tailOffset,
|
context.tailOffset,
|
||||||
@@ -315,42 +305,40 @@ private object ShorteningFunctionInsertionHandler : AbstractFunctionInsertionHan
|
|||||||
addArguments(context, element, lookupObject)
|
addArguments(context, element, lookupObject)
|
||||||
context.commitDocument()
|
context.commitDocument()
|
||||||
|
|
||||||
if (importingStrategy is FunctionImportStrategy.AddImport) {
|
if (importingStrategy is CallableImportStrategy.AddImport) {
|
||||||
addCallableImportIfRequired(targetFile, importingStrategy.nameToImport)
|
addCallableImportIfRequired(targetFile, importingStrategy.nameToImport)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ShorteningVariableInsertionHandler(private val name: FqName) : InsertHandler<LookupElement> {
|
private object ShorteningVariableInsertionHandler : 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
|
||||||
|
|
||||||
context.document.replaceString(
|
when (val importStrategy = lookupObject.importStrategy) {
|
||||||
context.startOffset,
|
is CallableImportStrategy.AddImport -> {
|
||||||
context.tailOffset,
|
addCallableImportIfRequired(targetFile, importStrategy.nameToImport)
|
||||||
name.withRootPrefixIfNeeded().render()
|
}
|
||||||
)
|
|
||||||
context.commitDocument()
|
|
||||||
|
|
||||||
shortenReferences(targetFile, TextRange(context.startOffset, context.tailOffset))
|
is CallableImportStrategy.InsertFqNameAndShorten -> {
|
||||||
}
|
context.document.replaceString(
|
||||||
}
|
context.startOffset,
|
||||||
|
context.tailOffset,
|
||||||
|
importStrategy.fqName.withRootPrefixIfNeeded().render()
|
||||||
|
)
|
||||||
|
|
||||||
private class SimpleVariableInsertionHandler(private val nameToImport: FqName?) :
|
context.commitDocument()
|
||||||
QuotedNamesAwareInsertionHandler() {
|
shortenReferences(targetFile, TextRange(context.startOffset, context.tailOffset))
|
||||||
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
}
|
||||||
super.handleInsert(context, item)
|
|
||||||
|
|
||||||
val targetFile = context.file as? KtFile ?: return
|
is CallableImportStrategy.DoNothing -> {}
|
||||||
|
|
||||||
if (nameToImport != null) {
|
|
||||||
addCallableImportIfRequired(targetFile, nameToImport)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private open class QuotedNamesAwareInsertionHandler() : InsertHandler<LookupElement> {
|
private open class QuotedNamesAwareInsertionHandler : InsertHandler<LookupElement> {
|
||||||
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
||||||
val lookupElement = item.`object` as KotlinLookupObject
|
val lookupElement = item.`object` as KotlinLookupObject
|
||||||
|
|
||||||
@@ -402,19 +390,6 @@ private val KtVariableLikeSymbol.callableIdIfExists: FqName?
|
|||||||
is KtSetterParameterSymbol -> null
|
is KtSetterParameterSymbol -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
private val KtVariableLikeSymbol.importableFqName: FqName?
|
|
||||||
get() = when (this) {
|
|
||||||
is KtKotlinPropertySymbol -> if (dispatchType == null) callableIdIfNonLocal else null
|
|
||||||
|
|
||||||
is KtEnumEntrySymbol,
|
|
||||||
is KtJavaFieldSymbol,
|
|
||||||
is KtSyntheticJavaPropertySymbol,
|
|
||||||
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