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