Minor: refactoring ChangeFunctionSignature quickfix
This commit is contained in:
@@ -38,9 +38,10 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import java.util.*
|
||||
|
||||
class AddFunctionParametersFix(
|
||||
callElement: KtCallElement,
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
private val hasTypeMismatches: Boolean) : ChangeFunctionSignatureFix(callElement, functionDescriptor) {
|
||||
callElement: KtCallElement,
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
private val hasTypeMismatches: Boolean
|
||||
) : ChangeFunctionSignatureFix(callElement, functionDescriptor) {
|
||||
private val callElement: KtCallElement?
|
||||
get() = element as? KtCallElement
|
||||
|
||||
@@ -59,8 +60,7 @@ class AddFunctionParametersFix(
|
||||
val callableDescription = if (isConstructor()) {
|
||||
val className = functionDescriptor.containingDeclaration.name.asString()
|
||||
"constructor '$className'"
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
val functionName = functionDescriptor.name.asString()
|
||||
"function '$functionName'"
|
||||
}
|
||||
@@ -88,9 +88,9 @@ class AddFunctionParametersFix(
|
||||
private fun addParameterConfiguration(): KotlinChangeSignatureConfiguration {
|
||||
return object : KotlinChangeSignatureConfiguration {
|
||||
override fun configure(originalDescriptor: KotlinMethodDescriptor): KotlinMethodDescriptor {
|
||||
return originalDescriptor.modify {
|
||||
val callElement = callElement ?: return@modify
|
||||
val call = callElement.getCall(callElement.analyze()) ?: return@modify
|
||||
return originalDescriptor.modify(fun(descriptor: KotlinMutableMethodDescriptor) {
|
||||
val callElement = callElement ?: return
|
||||
val call = callElement.getCall(callElement.analyze()) ?: return
|
||||
val parameters = functionDescriptor.valueParameters
|
||||
val arguments = callElement.valueArguments
|
||||
val validator = CollectingNameValidator()
|
||||
@@ -109,15 +109,14 @@ class AddFunctionParametersFix(
|
||||
val parameterType = parameters[i].type
|
||||
|
||||
if (argumentType != null && !KotlinTypeChecker.DEFAULT.isSubtypeOf(argumentType, parameterType)) {
|
||||
it.parameters[i].currentTypeInfo = KotlinTypeInfo(false, argumentType)
|
||||
descriptor.parameters[i].currentTypeInfo = KotlinTypeInfo(false, argumentType)
|
||||
typesToShorten.add(argumentType)
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
val parameterInfo = getNewParameterInfo(
|
||||
originalDescriptor.baseDescriptor as FunctionDescriptor,
|
||||
argument,
|
||||
validator
|
||||
originalDescriptor.baseDescriptor as FunctionDescriptor,
|
||||
argument,
|
||||
validator
|
||||
)
|
||||
parameterInfo.originalTypeInfo.type?.let { typesToShorten.add(it) }
|
||||
|
||||
@@ -125,10 +124,10 @@ class AddFunctionParametersFix(
|
||||
parameterInfo.defaultValueForCall = expression
|
||||
}
|
||||
|
||||
it.addParameter(parameterInfo)
|
||||
descriptor.addParameter(parameterInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun performSilently(affectedFunctions: Collection<PsiElement>): Boolean {
|
||||
@@ -139,15 +138,15 @@ class AddFunctionParametersFix(
|
||||
}
|
||||
|
||||
private fun getNewParameterInfo(
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
argument: ValueArgument,
|
||||
validator: (String) -> Boolean
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
argument: ValueArgument,
|
||||
validator: (String) -> Boolean
|
||||
): KotlinParameterInfo {
|
||||
val name = getNewArgumentName(argument, validator)
|
||||
val expression = argument.getArgumentExpression()
|
||||
val type = expression?.let { getDataFlowAwareTypes(it).firstOrNull() } ?: functionDescriptor.builtIns.nullableAnyType
|
||||
return KotlinParameterInfo(functionDescriptor, -1, name, KotlinTypeInfo(false, null))
|
||||
.apply { currentTypeInfo = KotlinTypeInfo(false, type) }
|
||||
.apply { currentTypeInfo = KotlinTypeInfo(false, type) }
|
||||
}
|
||||
|
||||
private fun hasOtherUsages(function: PsiElement): Boolean {
|
||||
|
||||
@@ -32,9 +32,9 @@ import org.jetbrains.kotlin.psi.KtFunctionLiteral
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class ChangeFunctionLiteralSignatureFix private constructor(
|
||||
functionLiteral: KtFunctionLiteral,
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
private val parameterTypes: List<KotlinType>
|
||||
functionLiteral: KtFunctionLiteral,
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
private val parameterTypes: List<KotlinType>
|
||||
) : ChangeFunctionSignatureFix(functionLiteral, functionDescriptor) {
|
||||
|
||||
override fun getText() = "Change the signature of lambda expression"
|
||||
@@ -42,25 +42,26 @@ class ChangeFunctionLiteralSignatureFix private constructor(
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
runChangeSignature(
|
||||
project,
|
||||
functionDescriptor,
|
||||
object : KotlinChangeSignatureConfiguration {
|
||||
override fun configure(originalDescriptor: KotlinMethodDescriptor): KotlinMethodDescriptor {
|
||||
return originalDescriptor.modify { descriptor ->
|
||||
val validator = CollectingNameValidator()
|
||||
descriptor.clearNonReceiverParameters()
|
||||
for (type in parameterTypes) {
|
||||
val name = KotlinNameSuggester.suggestNamesByType(type, validator, "param")[0]
|
||||
descriptor.addParameter(KotlinParameterInfo(functionDescriptor, -1, name, KotlinTypeInfo(false, type)))
|
||||
}
|
||||
project,
|
||||
functionDescriptor,
|
||||
object : KotlinChangeSignatureConfiguration {
|
||||
override fun configure(originalDescriptor: KotlinMethodDescriptor): KotlinMethodDescriptor {
|
||||
return originalDescriptor.modify { descriptor ->
|
||||
val validator = CollectingNameValidator()
|
||||
descriptor.clearNonReceiverParameters()
|
||||
for (type in parameterTypes) {
|
||||
val name = KotlinNameSuggester.suggestNamesByType(type, validator, "param")[0]
|
||||
descriptor.addParameter(KotlinParameterInfo(functionDescriptor, -1, name, KotlinTypeInfo(false, type)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun performSilently(affectedFunctions: Collection<PsiElement>) = false
|
||||
override fun forcePerformForSelectedFunctionOnly() = false
|
||||
},
|
||||
element,
|
||||
text)
|
||||
override fun performSilently(affectedFunctions: Collection<PsiElement>) = false
|
||||
override fun forcePerformForSelectedFunctionOnly() = false
|
||||
},
|
||||
element,
|
||||
text
|
||||
)
|
||||
}
|
||||
|
||||
companion object : KotlinSingleIntentionActionFactoryWithDelegate<KtFunctionLiteral, Companion.Data>() {
|
||||
@@ -77,7 +78,7 @@ class ChangeFunctionLiteralSignatureFix private constructor(
|
||||
return Data(descriptor, parameterTypes)
|
||||
}
|
||||
|
||||
override fun createFix(originalElement: KtFunctionLiteral, data: Data): IntentionAction?
|
||||
= ChangeFunctionLiteralSignatureFix(originalElement, data.descriptor, data.parameterTypes)
|
||||
override fun createFix(originalElement: KtFunctionLiteral, data: Data): IntentionAction? =
|
||||
ChangeFunctionLiteralSignatureFix(originalElement, data.descriptor, data.parameterTypes)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +44,8 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
|
||||
abstract class ChangeFunctionSignatureFix(
|
||||
element: PsiElement,
|
||||
protected val functionDescriptor: FunctionDescriptor
|
||||
element: PsiElement,
|
||||
protected val functionDescriptor: FunctionDescriptor
|
||||
) : KotlinQuickFixAction<PsiElement>(element) {
|
||||
override fun getFamilyName() = FAMILY_NAME
|
||||
|
||||
@@ -71,9 +71,7 @@ abstract class ChangeFunctionSignatureFix(
|
||||
}
|
||||
|
||||
companion object : KotlinSingleIntentionActionFactoryWithDelegate<KtCallElement, CallableDescriptor>() {
|
||||
override fun getElementOfInterest(diagnostic: Diagnostic): KtCallElement? {
|
||||
return diagnostic.psiElement.getNonStrictParentOfType<KtCallElement>()
|
||||
}
|
||||
override fun getElementOfInterest(diagnostic: Diagnostic): KtCallElement? = diagnostic.psiElement.getNonStrictParentOfType()
|
||||
|
||||
override fun extractFixData(element: KtCallElement, diagnostic: Diagnostic): CallableDescriptor? {
|
||||
return DiagnosticFactory.cast(diagnostic, Errors.TOO_MANY_ARGUMENTS, Errors.NO_VALUE_FOR_PARAMETER).a
|
||||
@@ -81,15 +79,14 @@ abstract class ChangeFunctionSignatureFix(
|
||||
|
||||
override fun createFix(originalElement: KtCallElement, data: CallableDescriptor): ChangeFunctionSignatureFix? {
|
||||
val functionDescriptor = data as? FunctionDescriptor
|
||||
?: (data as? ValueParameterDescriptor)?.containingDeclaration as? FunctionDescriptor
|
||||
?: return null
|
||||
?: (data as? ValueParameterDescriptor)?.containingDeclaration as? FunctionDescriptor
|
||||
?: return null
|
||||
|
||||
if (functionDescriptor.kind == SYNTHESIZED) return null
|
||||
|
||||
if (data is ValueParameterDescriptor) {
|
||||
return RemoveParameterFix(originalElement, functionDescriptor, data)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
val parameters = functionDescriptor.valueParameters
|
||||
val arguments = originalElement.valueArguments
|
||||
|
||||
@@ -97,8 +94,7 @@ abstract class ChangeFunctionSignatureFix(
|
||||
val bindingContext = originalElement.analyze()
|
||||
val call = originalElement.getCall(bindingContext) ?: return null
|
||||
val argumentToParameter = call.mapArgumentsToParameters(functionDescriptor)
|
||||
val hasTypeMismatches = argumentToParameter.any {
|
||||
val (argument, parameter) = it
|
||||
val hasTypeMismatches = argumentToParameter.any { (argument, parameter) ->
|
||||
val argumentType = argument.getArgumentExpression()?.let { bindingContext.getType(it) }
|
||||
argumentType == null || !KotlinTypeChecker.DEFAULT.isSubtypeOf(argumentType, parameter.type)
|
||||
}
|
||||
@@ -110,9 +106,9 @@ abstract class ChangeFunctionSignatureFix(
|
||||
}
|
||||
|
||||
private class RemoveParameterFix(
|
||||
element: PsiElement,
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
private val parameterToRemove: ValueParameterDescriptor
|
||||
element: PsiElement,
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
private val parameterToRemove: ValueParameterDescriptor
|
||||
) : ChangeFunctionSignatureFix(element, functionDescriptor) {
|
||||
|
||||
override fun getText() = "Remove parameter '${parameterToRemove.name.asString()}'"
|
||||
@@ -122,26 +118,27 @@ abstract class ChangeFunctionSignatureFix(
|
||||
}
|
||||
}
|
||||
|
||||
val FAMILY_NAME = "Change signature of function/constructor"
|
||||
const val FAMILY_NAME = "Change signature of function/constructor"
|
||||
|
||||
fun runRemoveParameter(parameterDescriptor: ValueParameterDescriptor, context: PsiElement) {
|
||||
val functionDescriptor = parameterDescriptor.containingDeclaration as FunctionDescriptor
|
||||
runChangeSignature(
|
||||
context.project,
|
||||
functionDescriptor,
|
||||
object : KotlinChangeSignatureConfiguration {
|
||||
override fun configure(originalDescriptor: KotlinMethodDescriptor): KotlinMethodDescriptor {
|
||||
return originalDescriptor.modify { descriptor ->
|
||||
val index = if (descriptor.receiver != null) parameterDescriptor.index + 1 else parameterDescriptor.index
|
||||
descriptor.removeParameter(index)
|
||||
}
|
||||
context.project,
|
||||
functionDescriptor,
|
||||
object : KotlinChangeSignatureConfiguration {
|
||||
override fun configure(originalDescriptor: KotlinMethodDescriptor): KotlinMethodDescriptor {
|
||||
return originalDescriptor.modify { descriptor ->
|
||||
val index = if (descriptor.receiver != null) parameterDescriptor.index + 1 else parameterDescriptor.index
|
||||
descriptor.removeParameter(index)
|
||||
}
|
||||
}
|
||||
|
||||
override fun performSilently(affectedFunctions: Collection<PsiElement>) = true
|
||||
override fun forcePerformForSelectedFunctionOnly() = false
|
||||
},
|
||||
context,
|
||||
"Remove parameter '${parameterDescriptor.name.asString()}'")
|
||||
override fun performSilently(affectedFunctions: Collection<PsiElement>) = true
|
||||
override fun forcePerformForSelectedFunctionOnly() = false
|
||||
},
|
||||
context,
|
||||
"Remove parameter '${parameterDescriptor.name.asString()}'"
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user