FIR IDE: Implement applicatorByQuickFix() to re-use quick fix actions
from idea-frontend-independent.
This commit is contained in:
committed by
Ilya Kirillov
parent
1b649fa4cb
commit
3ebdfa3850
@@ -10,6 +10,7 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.PrivateForInline
|
||||
import org.jetbrains.kotlin.idea.frontend.api.ForbidKtResolve
|
||||
import org.jetbrains.kotlin.idea.quickfix.KotlinPsiOnlyQuickFixAction
|
||||
import kotlin.experimental.ExperimentalTypeInference
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@@ -194,3 +195,19 @@ fun <PSI : PsiElement, INPUT : HLApplicatorInput> applicator(
|
||||
init: HLApplicatorBuilder<PSI, INPUT>.() -> Unit,
|
||||
): HLApplicator<PSI, INPUT> =
|
||||
HLApplicatorBuilder<PSI, INPUT>().apply(init).build()
|
||||
|
||||
/**
|
||||
* Builds a new applicator that uses a [KotlinPsiOnlyQuickFixAction] to apply the fix to the PSI
|
||||
*
|
||||
* @see HLApplicator
|
||||
*/
|
||||
fun <PSI : PsiElement, INPUT : HLApplicatorInput, QUICK_FIX : KotlinPsiOnlyQuickFixAction<PSI>> applicatorByQuickFix(
|
||||
getFamilyName: () -> String,
|
||||
isApplicableByPsi: (PSI) -> Boolean = { true },
|
||||
quickFixByInput: (PSI, INPUT) -> QUICK_FIX,
|
||||
): HLApplicator<PSI, INPUT> = HLApplicatorImpl(
|
||||
applyTo = { psi, input, project, editor -> quickFixByInput(psi, input).invoke(project ?: psi.project, editor, psi.containingFile) },
|
||||
isApplicableByPsi = isApplicableByPsi,
|
||||
getActionName = { psi, input -> quickFixByInput(psi, input).text },
|
||||
getFamilyName = getFamilyName
|
||||
)
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.fir.api.fixes
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.idea.fir.api.applicator.HLApplicator
|
||||
import org.jetbrains.kotlin.idea.fir.api.applicator.HLApplicatorInput
|
||||
|
||||
class HLApplicatorWithTargetAndInput<PSI : PsiElement, INPUT : HLApplicatorInput>(
|
||||
val applicator: HLApplicator<PSI, INPUT>,
|
||||
private val targetAndInput: HLApplicatorTargetWithInput<PSI, INPUT>,
|
||||
) {
|
||||
operator fun component1() = applicator
|
||||
operator fun component2() = targetAndInput.target
|
||||
operator fun component3() = targetAndInput.input
|
||||
}
|
||||
+28
-10
@@ -12,17 +12,22 @@ import org.jetbrains.kotlin.idea.fir.api.applicator.HLApplicatorInput
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.idea.frontend.api.diagnostics.KtDiagnosticWithPsi
|
||||
|
||||
sealed class HLDiagnosticFixFactory<DIAGNOSTIC_PSI : PsiElement, in DIAGNOSTIC : KtDiagnosticWithPsi<DIAGNOSTIC_PSI>, TARGET_PSI : PsiElement, INPUT : HLApplicatorInput>(
|
||||
val applicator: HLApplicator<TARGET_PSI, INPUT>
|
||||
) {
|
||||
abstract fun KtAnalysisSession.createTargets(diagnostic: DIAGNOSTIC): List<HLApplicatorTargetWithInput<TARGET_PSI, INPUT>>
|
||||
sealed class HLDiagnosticFixFactory<DIAGNOSTIC_PSI : PsiElement, in DIAGNOSTIC : KtDiagnosticWithPsi<DIAGNOSTIC_PSI>, TARGET_PSI : PsiElement, INPUT : HLApplicatorInput> {
|
||||
abstract fun KtAnalysisSession.createTargets(diagnostic: DIAGNOSTIC): List<HLApplicatorWithTargetAndInput<TARGET_PSI, INPUT>>
|
||||
}
|
||||
|
||||
private class HLDiagnosticFixFactoryImpl<DIAGNOSTIC_PSI : PsiElement, DIAGNOSTIC : KtDiagnosticWithPsi<DIAGNOSTIC_PSI>, TARGET_PSI : PsiElement, INPUT : HLApplicatorInput>(
|
||||
applicator: HLApplicator<TARGET_PSI, INPUT>,
|
||||
private class HLDiagnosticFixFactoryWithFixedApplicator<DIAGNOSTIC_PSI : PsiElement, DIAGNOSTIC : KtDiagnosticWithPsi<DIAGNOSTIC_PSI>, TARGET_PSI : PsiElement, INPUT : HLApplicatorInput>(
|
||||
private val applicator: HLApplicator<TARGET_PSI, INPUT>,
|
||||
private val createQuickFixes: KtAnalysisSession.(DIAGNOSTIC) -> List<HLApplicatorTargetWithInput<TARGET_PSI, INPUT>>
|
||||
) : HLDiagnosticFixFactory<DIAGNOSTIC_PSI, DIAGNOSTIC, TARGET_PSI, INPUT>(applicator) {
|
||||
override fun KtAnalysisSession.createTargets(diagnostic: DIAGNOSTIC): List<HLApplicatorTargetWithInput<TARGET_PSI, INPUT>> =
|
||||
) : HLDiagnosticFixFactory<DIAGNOSTIC_PSI, DIAGNOSTIC, TARGET_PSI, INPUT>() {
|
||||
override fun KtAnalysisSession.createTargets(diagnostic: DIAGNOSTIC): List<HLApplicatorWithTargetAndInput<TARGET_PSI, INPUT>> =
|
||||
createQuickFixes.invoke(this, diagnostic).map { targetAndInput -> HLApplicatorWithTargetAndInput(applicator, targetAndInput) }
|
||||
}
|
||||
|
||||
private class HLDiagnosticFixFactoryWithVariableApplicator<DIAGNOSTIC_PSI : PsiElement, DIAGNOSTIC : KtDiagnosticWithPsi<DIAGNOSTIC_PSI>, TARGET_PSI : PsiElement, INPUT : HLApplicatorInput>(
|
||||
private val createQuickFixes: KtAnalysisSession.(DIAGNOSTIC) -> List<HLApplicatorWithTargetAndInput<TARGET_PSI, INPUT>>
|
||||
) : HLDiagnosticFixFactory<DIAGNOSTIC_PSI, DIAGNOSTIC, TARGET_PSI, INPUT>() {
|
||||
override fun KtAnalysisSession.createTargets(diagnostic: DIAGNOSTIC): List<HLApplicatorWithTargetAndInput<TARGET_PSI, INPUT>> =
|
||||
createQuickFixes.invoke(this, diagnostic)
|
||||
}
|
||||
|
||||
@@ -30,11 +35,24 @@ internal fun <DIAGNOSTIC : KtDiagnosticWithPsi<PsiElement>> KtAnalysisSession.cr
|
||||
diagnostic: DIAGNOSTIC,
|
||||
factory: HLDiagnosticFixFactory<PsiElement, DIAGNOSTIC, PsiElement, HLApplicatorInput>
|
||||
): List<IntentionAction> = with(factory) {
|
||||
createTargets(diagnostic).map { (target, input) -> HLQuickFix(target, input, factory.applicator) }
|
||||
createTargets(diagnostic).map { (applicator, target, input) -> HLQuickFix(target, input, applicator) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a [HLDiagnosticFixFactory] that creates targets and inputs ([HLApplicatorTargetWithInput]) from a diagnostic.
|
||||
* The targets and inputs are consumed by the given applicator to apply fixes.
|
||||
*/
|
||||
fun <DIAGNOSTIC_PSI : PsiElement, DIAGNOSTIC : KtDiagnosticWithPsi<DIAGNOSTIC_PSI>, TARGET_PSI : PsiElement, INPUT : HLApplicatorInput> diagnosticFixFactory(
|
||||
applicator: HLApplicator<TARGET_PSI, INPUT>,
|
||||
createQuickFixes: KtAnalysisSession.(DIAGNOSTIC) -> List<HLApplicatorTargetWithInput<TARGET_PSI, INPUT>>
|
||||
): HLDiagnosticFixFactory<DIAGNOSTIC_PSI, DIAGNOSTIC, TARGET_PSI, INPUT> =
|
||||
HLDiagnosticFixFactoryImpl(applicator, createQuickFixes)
|
||||
HLDiagnosticFixFactoryWithFixedApplicator(applicator, createQuickFixes)
|
||||
|
||||
/**
|
||||
* Returns a [HLDiagnosticFixFactory] that creates applicators, targets, and inputs ([HLApplicatorWithTargetAndInput]) from a diagnostic.
|
||||
* The targets and inputs are consumed by the corresponding applicator to apply fixes.
|
||||
*/
|
||||
fun <DIAGNOSTIC_PSI : PsiElement, DIAGNOSTIC : KtDiagnosticWithPsi<DIAGNOSTIC_PSI>, TARGET_PSI : PsiElement, INPUT : HLApplicatorInput> diagnosticFixFactory(
|
||||
createQuickFixes: KtAnalysisSession.(DIAGNOSTIC) -> List<HLApplicatorWithTargetAndInput<TARGET_PSI, INPUT>>
|
||||
): HLDiagnosticFixFactory<DIAGNOSTIC_PSI, DIAGNOSTIC, TARGET_PSI, INPUT> =
|
||||
HLDiagnosticFixFactoryWithVariableApplicator(createQuickFixes)
|
||||
|
||||
Reference in New Issue
Block a user