Code improvements
This commit is contained in:
@@ -56,22 +56,10 @@ abstract class ChangeFunctionSignatureFix(
|
||||
override fun startInWriteAction() = false
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
if (!super.isAvailable(project, editor, file)) {
|
||||
return false
|
||||
}
|
||||
if (!super.isAvailable(project, editor, file)) return false
|
||||
|
||||
val declarations = DescriptorToSourceUtilsIde.getAllDeclarations(project, functionDescriptor)
|
||||
if (declarations.isEmpty()) {
|
||||
return false
|
||||
}
|
||||
|
||||
for (declaration in declarations) {
|
||||
if (!declaration.isValid || !QuickFixUtil.canModifyElement(declaration)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
return declarations.all { it.isValid && QuickFixUtil.canModifyElement(it) }
|
||||
}
|
||||
|
||||
protected fun getNewArgumentName(argument: ValueArgument, validator: Function1<String, Boolean>): String {
|
||||
@@ -80,10 +68,12 @@ abstract class ChangeFunctionSignatureFix(
|
||||
|
||||
if (argumentName != null) {
|
||||
return KotlinNameSuggester.suggestNameByName(argumentName.asName.asString(), validator)
|
||||
} else if (expression != null) {
|
||||
}
|
||||
else if (expression != null) {
|
||||
val bindingContext = expression.analyze(BodyResolveMode.PARTIAL)
|
||||
return KotlinNameSuggester.suggestNamesByExpressionAndType(expression, bindingContext, validator, "param").iterator().next()
|
||||
} else {
|
||||
return KotlinNameSuggester.suggestNamesByExpressionAndType(expression, bindingContext, validator, "param").first()
|
||||
}
|
||||
else {
|
||||
return KotlinNameSuggester.suggestNameByName("param", validator)
|
||||
}
|
||||
}
|
||||
@@ -91,119 +81,75 @@ abstract class ChangeFunctionSignatureFix(
|
||||
protected fun getNewParameterInfo(
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
argument: ValueArgument,
|
||||
validator: Function1<String, Boolean>): JetParameterInfo {
|
||||
validator: Function1<String, Boolean>
|
||||
): JetParameterInfo {
|
||||
val name = getNewArgumentName(argument, validator)
|
||||
val expression = argument.getArgumentExpression()
|
||||
val type = expression?.let { it.analyze().getType(it) } ?: functionDescriptor.builtIns.nullableAnyType
|
||||
val parameterInfo = JetParameterInfo(functionDescriptor, -1, name, type, null, null, JetValVar.None, null)
|
||||
parameterInfo.currentTypeText = IdeDescriptorRenderers.SOURCE_CODE.renderType(type)
|
||||
|
||||
return parameterInfo
|
||||
return JetParameterInfo(functionDescriptor, -1, name, type, null, null, JetValVar.None, null)
|
||||
.apply { currentTypeText = IdeDescriptorRenderers.SOURCE_CODE.renderType(type) }
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun createFactory(): JetSingleIntentionActionFactory {
|
||||
return object : JetSingleIntentionActionFactory() {
|
||||
public override fun createAction(diagnostic: Diagnostic): ChangeFunctionSignatureFix? {
|
||||
val callElement = PsiTreeUtil.getParentOfType(diagnostic.psiElement, JetCallElement::class.java)
|
||||
//noinspection unchecked
|
||||
val descriptor = DiagnosticFactory.cast(diagnostic, Errors.TOO_MANY_ARGUMENTS, Errors.NO_VALUE_FOR_PARAMETER).a
|
||||
|
||||
if (callElement != null) {
|
||||
return createFix(callElement, callElement, descriptor)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
}
|
||||
object Factory : JetSingleIntentionActionFactory() {
|
||||
override fun createAction(diagnostic: Diagnostic): ChangeFunctionSignatureFix? {
|
||||
val callElement = PsiTreeUtil.getParentOfType(diagnostic.psiElement, JetCallElement::class.java) ?: return null
|
||||
val descriptor = DiagnosticFactory.cast(diagnostic, Errors.TOO_MANY_ARGUMENTS, Errors.NO_VALUE_FOR_PARAMETER).a
|
||||
return createFix(callElement, callElement, descriptor)
|
||||
}
|
||||
}
|
||||
|
||||
fun createFactoryForParametersNumberMismatch(): JetSingleIntentionActionFactory {
|
||||
return object : JetSingleIntentionActionFactory() {
|
||||
public override fun createAction(diagnostic: Diagnostic): ChangeFunctionSignatureFix? {
|
||||
val diagnosticWithParameters = EXPECTED_PARAMETERS_NUMBER_MISMATCH.cast(diagnostic)
|
||||
val functionLiteral = diagnosticWithParameters.psiElement
|
||||
val descriptor = functionLiteral.resolveToDescriptor()
|
||||
|
||||
if (descriptor is FunctionDescriptor && functionLiteral is JetFunctionLiteral) {
|
||||
return ChangeFunctionLiteralSignatureFix(functionLiteral, descriptor,
|
||||
diagnosticWithParameters.b)
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
object FactoryForParametersNumberMismatch: JetSingleIntentionActionFactory() {
|
||||
override fun createAction(diagnostic: Diagnostic): ChangeFunctionSignatureFix? {
|
||||
val diagnosticWithParameters = EXPECTED_PARAMETERS_NUMBER_MISMATCH.cast(diagnostic)
|
||||
val functionLiteral = diagnosticWithParameters.psiElement as? JetFunctionLiteral ?: return null
|
||||
val descriptor = functionLiteral.resolveToDescriptor() as? FunctionDescriptor ?: return null
|
||||
return ChangeFunctionLiteralSignatureFix(functionLiteral, descriptor, diagnosticWithParameters.b)
|
||||
}
|
||||
}
|
||||
|
||||
fun createFactoryForUnusedParameter(): JetSingleIntentionActionFactory {
|
||||
return object : JetSingleIntentionActionFactory() {
|
||||
public override fun createAction(diagnostic: Diagnostic): ChangeFunctionSignatureFix? {
|
||||
@SuppressWarnings("unchecked")
|
||||
val descriptor = UNUSED_PARAMETER.cast(diagnostic).a
|
||||
|
||||
if (descriptor is ValueParameterDescriptor) {
|
||||
return createFix(null, diagnostic.psiElement, descriptor as CallableDescriptor)
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createFix(callElement: JetCallElement?, context: PsiElement, descriptor: CallableDescriptor): ChangeFunctionSignatureFix? {
|
||||
var functionDescriptor: FunctionDescriptor? = null
|
||||
|
||||
if (descriptor is FunctionDescriptor) {
|
||||
functionDescriptor = descriptor
|
||||
} else if (descriptor is ValueParameterDescriptor) {
|
||||
val containingDescriptor = descriptor.containingDeclaration
|
||||
|
||||
if (containingDescriptor is FunctionDescriptor) {
|
||||
functionDescriptor = containingDescriptor
|
||||
}
|
||||
}
|
||||
|
||||
if (functionDescriptor == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (functionDescriptor.kind == SYNTHESIZED) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (descriptor is ValueParameterDescriptor) {
|
||||
return RemoveFunctionParametersFix(context, functionDescriptor, descriptor)
|
||||
} else {
|
||||
val parameters = functionDescriptor.valueParameters
|
||||
val arguments = callElement!!.valueArguments
|
||||
|
||||
if (arguments.size() > parameters.size()) {
|
||||
val bindingContext = callElement.analyze()
|
||||
val hasTypeMismatches = hasTypeMismatches(parameters, arguments, bindingContext)
|
||||
return AddFunctionParametersFix(callElement, functionDescriptor, hasTypeMismatches)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun hasTypeMismatches(
|
||||
parameters: List<ValueParameterDescriptor>,
|
||||
arguments: List<ValueArgument>,
|
||||
bindingContext: BindingContext): Boolean {
|
||||
for (i in parameters.indices) {
|
||||
assert(i < arguments.size()) // number of parameters must not be greater than the number of arguments (it's called only for TOO_MANY_ARGUMENTS error)
|
||||
val argumentExpression = arguments.get(i).getArgumentExpression()
|
||||
val argumentType = if (argumentExpression != null) bindingContext.getType(argumentExpression) else null
|
||||
val parameterType = parameters.get(i).type
|
||||
|
||||
if (argumentType == null || !JetTypeChecker.DEFAULT.isSubtypeOf(argumentType, parameterType)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
object FactoryForUnusedParameter : JetSingleIntentionActionFactory() {
|
||||
override fun createAction(diagnostic: Diagnostic): ChangeFunctionSignatureFix? {
|
||||
val descriptor = UNUSED_PARAMETER.cast(diagnostic).a as? ValueParameterDescriptor ?: return null
|
||||
return createFix(null, diagnostic.psiElement, descriptor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createFix(callElement: JetCallElement?, context: PsiElement, descriptor: CallableDescriptor): ChangeFunctionSignatureFix? {
|
||||
val functionDescriptor = when (descriptor) {
|
||||
is FunctionDescriptor -> descriptor as FunctionDescriptor
|
||||
else -> if (descriptor is ValueParameterDescriptor) descriptor.containingDeclaration as? FunctionDescriptor
|
||||
else null
|
||||
} ?: return null
|
||||
|
||||
if (functionDescriptor.kind == SYNTHESIZED) return null
|
||||
|
||||
if (descriptor is ValueParameterDescriptor) {
|
||||
return RemoveFunctionParametersFix(context, functionDescriptor, descriptor)
|
||||
}
|
||||
else {
|
||||
val parameters = functionDescriptor.valueParameters
|
||||
val arguments = callElement!!.valueArguments
|
||||
|
||||
if (arguments.size > parameters.size) {
|
||||
val hasTypeMismatches = hasTypeMismatches(parameters, arguments, callElement.analyze())
|
||||
return AddFunctionParametersFix(callElement, functionDescriptor, hasTypeMismatches)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun hasTypeMismatches(
|
||||
parameters: List<ValueParameterDescriptor>,
|
||||
arguments: List<ValueArgument>,
|
||||
bindingContext: BindingContext
|
||||
): Boolean {
|
||||
assert(parameters.size <= arguments.size) // number of parameters must not be greater than the number of arguments (it's called only for TOO_MANY_ARGUMENTS error)
|
||||
for ((parameter, argument) in parameters.zip(arguments)) {
|
||||
val argumentType = argument.getArgumentExpression()?.let { bindingContext.getType(it) }
|
||||
if (argumentType == null || !JetTypeChecker.DEFAULT.isSubtypeOf(argumentType, parameter.type)) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -222,10 +222,10 @@ public class QuickFixRegistrar : QuickFixContributor {
|
||||
COMPARE_TO_TYPE_MISMATCH.registerFactory(ChangeFunctionReturnTypeFix.createFactoryForCompareToTypeMismatch())
|
||||
IMPLICIT_NOTHING_RETURN_TYPE.registerFactory(ChangeFunctionReturnTypeFix.createFactoryForChangingReturnTypeToNothing())
|
||||
|
||||
TOO_MANY_ARGUMENTS.registerFactory(ChangeFunctionSignatureFix.createFactory())
|
||||
NO_VALUE_FOR_PARAMETER.registerFactory(ChangeFunctionSignatureFix.createFactory())
|
||||
UNUSED_PARAMETER.registerFactory(ChangeFunctionSignatureFix.createFactoryForUnusedParameter())
|
||||
EXPECTED_PARAMETERS_NUMBER_MISMATCH.registerFactory(ChangeFunctionSignatureFix.createFactoryForParametersNumberMismatch())
|
||||
TOO_MANY_ARGUMENTS.registerFactory(ChangeFunctionSignatureFix.Factory)
|
||||
NO_VALUE_FOR_PARAMETER.registerFactory(ChangeFunctionSignatureFix.Factory)
|
||||
UNUSED_PARAMETER.registerFactory(ChangeFunctionSignatureFix.FactoryForUnusedParameter)
|
||||
EXPECTED_PARAMETERS_NUMBER_MISMATCH.registerFactory(ChangeFunctionSignatureFix.FactoryForParametersNumberMismatch)
|
||||
|
||||
EXPECTED_PARAMETER_TYPE_MISMATCH.registerFactory(ChangeTypeFix.createFactoryForExpectedParameterTypeMismatch())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user