Quick Fixes: Pass original element to KotlinIntentionActionFactoryWithDelegate.createFix()

This commit is contained in:
Alexey Sedunov
2016-01-06 00:35:14 +03:00
parent 66ab1c484c
commit 8264cef004
5 changed files with 26 additions and 30 deletions
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.idea.quickfix
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
@@ -62,7 +63,7 @@ class ChangeFunctionLiteralSignatureFix private constructor(
}
companion object : KotlinSingleIntentionActionFactoryWithDelegate<KtFunctionLiteral, Companion.Data>() {
data class Data(val functionLiteral: KtFunctionLiteral, val descriptor: FunctionDescriptor, val parameterTypes: List<KotlinType>)
data class Data(val descriptor: FunctionDescriptor, val parameterTypes: List<KotlinType>)
override fun getElementOfInterest(diagnostic: Diagnostic): KtFunctionLiteral? {
val diagnosticWithParameters = Errors.EXPECTED_PARAMETERS_NUMBER_MISMATCH.cast(diagnostic)
@@ -72,10 +73,10 @@ class ChangeFunctionLiteralSignatureFix private constructor(
override fun extractFixData(element: KtFunctionLiteral, diagnostic: Diagnostic): Data? {
val descriptor = element.resolveToDescriptor() as? FunctionDescriptor ?: return null
val parameterTypes = Errors.EXPECTED_PARAMETERS_NUMBER_MISMATCH.cast(diagnostic).b
return Data(element, descriptor, parameterTypes)
return Data(descriptor, parameterTypes)
}
override fun createFix(data: Data)
= ChangeFunctionLiteralSignatureFix(data.functionLiteral, data.descriptor, data.parameterTypes)
override fun createFix(originalElement: KtFunctionLiteral, data: Data): IntentionAction?
= ChangeFunctionLiteralSignatureFix(originalElement, data.descriptor, data.parameterTypes)
}
}
@@ -76,44 +76,39 @@ abstract class ChangeFunctionSignatureFix(
}
}
companion object : KotlinSingleIntentionActionFactoryWithDelegate<KtCallElement, Companion.Data>() {
data class Data(val callElement: KtCallElement, val descriptor: CallableDescriptor)
companion object : KotlinSingleIntentionActionFactoryWithDelegate<KtCallElement, CallableDescriptor>() {
override fun getElementOfInterest(diagnostic: Diagnostic): KtCallElement? {
return diagnostic.psiElement.getNonStrictParentOfType<KtCallElement>()
}
override fun extractFixData(element: KtCallElement, diagnostic: Diagnostic): Data? {
val descriptor = DiagnosticFactory.cast(diagnostic, Errors.TOO_MANY_ARGUMENTS, Errors.NO_VALUE_FOR_PARAMETER).a
return Data(element, descriptor)
override fun extractFixData(element: KtCallElement, diagnostic: Diagnostic): CallableDescriptor? {
return DiagnosticFactory.cast(diagnostic, Errors.TOO_MANY_ARGUMENTS, Errors.NO_VALUE_FOR_PARAMETER).a
}
override fun createFix(data: Data) = createFix(data.callElement, data.descriptor)
private fun createFix(callElement: KtCallElement, descriptor: CallableDescriptor): ChangeFunctionSignatureFix? {
val functionDescriptor = descriptor as? FunctionDescriptor
?: (descriptor as? ValueParameterDescriptor)?.containingDeclaration as? FunctionDescriptor
?: return null
override fun createFix(originalElement: KtCallElement, data: CallableDescriptor): ChangeFunctionSignatureFix? {
val functionDescriptor = data as? FunctionDescriptor
?: (data as? ValueParameterDescriptor)?.containingDeclaration as? FunctionDescriptor
?: return null
if (functionDescriptor.kind == SYNTHESIZED) return null
if (descriptor is ValueParameterDescriptor) {
return RemoveParameterFix(callElement, functionDescriptor, descriptor)
if (data is ValueParameterDescriptor) {
return RemoveParameterFix(originalElement, functionDescriptor, data)
}
else {
val parameters = functionDescriptor.valueParameters
val arguments = callElement.valueArguments
val arguments = originalElement.valueArguments
if (arguments.size > parameters.size) {
val bindingContext = callElement.analyze()
val call = callElement.getCall(bindingContext) ?: return null
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 argumentType = argument.getArgumentExpression()?.let { bindingContext.getType(it) }
argumentType == null || !KotlinTypeChecker.DEFAULT.isSubtypeOf(argumentType, parameter.type)
}
return AddFunctionParametersFix(callElement, functionDescriptor, hasTypeMismatches)
return AddFunctionParametersFix(originalElement, functionDescriptor, hasTypeMismatches)
}
}
@@ -30,7 +30,7 @@ abstract class KotlinSingleIntentionActionFactoryWithDelegate<E : KtElement, D :
private val actionPriority: IntentionActionPriority = IntentionActionPriority.NORMAL
) : KotlinIntentionActionFactoryWithDelegate<E, D>() {
protected abstract fun createFix(data: D): IntentionAction?
protected abstract fun createFix(originalElement: E, data: D): IntentionAction?
override final fun createFixes(
originalElementPointer: SmartPsiElementPointer<E>,
@@ -38,8 +38,9 @@ abstract class KotlinSingleIntentionActionFactoryWithDelegate<E : KtElement, D :
quickFixDataFactory: () -> D?
): List<QuickFixWithDelegateFactory> {
fun createAction(): IntentionAction? {
val originalElement = originalElementPointer.element ?: return null
val data = quickFixDataFactory() ?: return null
return createFix(data)
return createFix(originalElement, data)
}
val delegateFactory = when (actionPriority) {
@@ -149,8 +149,7 @@ class MapPlatformClassToKotlinFix(
}
companion object : KotlinSingleIntentionActionFactoryWithDelegate<KtReferenceExpression, Companion.Data>() {
data class Data(val element: KtReferenceExpression,
val platformClass: ClassDescriptor,
data class Data(val platformClass: ClassDescriptor,
val possibleClasses: Collection<ClassDescriptor>)
override fun getElementOfInterest(diagnostic: Diagnostic): KtReferenceExpression?
@@ -160,11 +159,11 @@ class MapPlatformClassToKotlinFix(
val context = element.analyze(BodyResolveMode.PARTIAL)
val platformClass = resolveToClass(element, context) ?: return null
val possibleClasses = Errors.PLATFORM_CLASS_MAPPED_TO_KOTLIN.cast(diagnostic).a
return Data(element, platformClass, possibleClasses)
return Data(platformClass, possibleClasses)
}
override fun createFix(data: Data): IntentionAction? {
return MapPlatformClassToKotlinFix(data.element, data.platformClass, data.possibleClasses)
override fun createFix(originalElement: KtReferenceExpression, data: Data): IntentionAction? {
return MapPlatformClassToKotlinFix(originalElement, data.platformClass, data.possibleClasses)
}
private fun resolveToClass(referenceExpression: KtReferenceExpression, context: BindingContext): ClassDescriptor? {
@@ -30,7 +30,7 @@ data class CreateParameterData<E : KtElement>(
)
abstract class CreateParameterFromUsageFactory<E : KtElement>: KotlinSingleIntentionActionFactoryWithDelegate<E, CreateParameterData<E>>() {
override fun createFix(data: CreateParameterData<E>): IntentionAction? {
override fun createFix(originalElement: E, data: CreateParameterData<E>): IntentionAction? {
return CreateParameterFromUsageFix(
data.parameterInfo.callableDescriptor as FunctionDescriptor,
data.parameterInfo,