FIR IDE: Simplify the diagnosticFixFactory() API by removing

HLApplicatorWithTargetAndInput and making HLQuickFix public.
This commit is contained in:
Mark Punzalan
2021-03-22 18:12:55 +00:00
committed by Ilya Kirillov
parent 062adf21de
commit 5baa2e0e7c
4 changed files with 15 additions and 45 deletions
@@ -1,19 +0,0 @@
/*
* 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
}
@@ -13,30 +13,28 @@ 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> {
abstract fun KtAnalysisSession.createTargets(diagnostic: DIAGNOSTIC): List<HLApplicatorWithTargetAndInput<TARGET_PSI, INPUT>>
abstract fun KtAnalysisSession.createQuickFixes(diagnostic: DIAGNOSTIC): List<HLQuickFix<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>>
private val createTargets: KtAnalysisSession.(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) }
override fun KtAnalysisSession.createQuickFixes(diagnostic: DIAGNOSTIC): List<HLQuickFix<TARGET_PSI, INPUT>> =
createTargets.invoke(this, diagnostic).map { (target, input) -> HLQuickFix(target, input, applicator) }
}
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>>
private val createQuickFixes: KtAnalysisSession.(DIAGNOSTIC) -> List<HLQuickFix<TARGET_PSI, INPUT>>
) : HLDiagnosticFixFactory<DIAGNOSTIC_PSI, DIAGNOSTIC, TARGET_PSI, INPUT>() {
override fun KtAnalysisSession.createTargets(diagnostic: DIAGNOSTIC): List<HLApplicatorWithTargetAndInput<TARGET_PSI, INPUT>> =
override fun KtAnalysisSession.createQuickFixes(diagnostic: DIAGNOSTIC): List<HLQuickFix<TARGET_PSI, INPUT>> =
createQuickFixes.invoke(this, diagnostic)
}
internal fun <DIAGNOSTIC : KtDiagnosticWithPsi<PsiElement>> KtAnalysisSession.createPlatformQuickFixes(
diagnostic: DIAGNOSTIC,
factory: HLDiagnosticFixFactory<PsiElement, DIAGNOSTIC, PsiElement, HLApplicatorInput>
): List<IntentionAction> = with(factory) {
createTargets(diagnostic).map { (applicator, target, input) -> HLQuickFix(target, input, applicator) }
}
): List<IntentionAction> = with(factory) { createQuickFixes(diagnostic) }
/**
* Returns a [HLDiagnosticFixFactory] that creates targets and inputs ([HLApplicatorTargetWithInput]) from a diagnostic.
@@ -44,15 +42,14 @@ internal fun <DIAGNOSTIC : KtDiagnosticWithPsi<PsiElement>> KtAnalysisSession.cr
*/
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>>
createTargets: KtAnalysisSession.(DIAGNOSTIC) -> List<HLApplicatorTargetWithInput<TARGET_PSI, INPUT>>
): HLDiagnosticFixFactory<DIAGNOSTIC_PSI, DIAGNOSTIC, TARGET_PSI, INPUT> =
HLDiagnosticFixFactoryWithFixedApplicator(applicator, createQuickFixes)
HLDiagnosticFixFactoryWithFixedApplicator(applicator, createTargets)
/**
* 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.
* Returns a [HLDiagnosticFixFactory] that creates [HLQuickFix]es from a diagnostic.
*/
fun <DIAGNOSTIC_PSI : PsiElement, DIAGNOSTIC : KtDiagnosticWithPsi<DIAGNOSTIC_PSI>, TARGET_PSI : PsiElement, INPUT : HLApplicatorInput> diagnosticFixFactory(
createQuickFixes: KtAnalysisSession.(DIAGNOSTIC) -> List<HLApplicatorWithTargetAndInput<TARGET_PSI, INPUT>>
createQuickFixes: KtAnalysisSession.(DIAGNOSTIC) -> List<HLQuickFix<TARGET_PSI, INPUT>>
): HLDiagnosticFixFactory<DIAGNOSTIC_PSI, DIAGNOSTIC, TARGET_PSI, INPUT> =
HLDiagnosticFixFactoryWithVariableApplicator(createQuickFixes)
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.idea.fir.api.applicator.HLApplicatorInput
import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
import org.jetbrains.kotlin.psi.KtFile
internal class HLQuickFix<PSI : PsiElement, in INPUT : HLApplicatorInput>(
class HLQuickFix<PSI : PsiElement, in INPUT : HLApplicatorInput>(
target: PSI,
private val input: INPUT,
val applicator: HLApplicator<PSI, INPUT>,
@@ -9,9 +9,8 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.fir.api.applicator.HLApplicatorInput
import org.jetbrains.kotlin.idea.fir.api.applicator.applicatorByQuickFix
import org.jetbrains.kotlin.idea.fir.api.fixes.HLApplicatorWithTargetAndInput
import org.jetbrains.kotlin.idea.fir.api.fixes.HLQuickFix
import org.jetbrains.kotlin.idea.fir.api.fixes.diagnosticFixFactory
import org.jetbrains.kotlin.idea.fir.api.fixes.withInput
import org.jetbrains.kotlin.idea.frontend.api.fir.diagnostics.KtFirDiagnostic
import org.jetbrains.kotlin.idea.frontend.api.types.KtTypeNullability
import org.jetbrains.kotlin.idea.frontend.api.types.KtTypeWithNullability
@@ -50,20 +49,13 @@ object ReplaceCallFixFactories {
}
when (val psi = diagnostic.psi) {
is KtDotQualifiedExpression -> listOf(
HLApplicatorWithTargetAndInput(replaceWithSafeCallFixApplicator, psi withInput Input(psi.shouldHaveNotNullType()))
)
is KtDotQualifiedExpression -> listOf(HLQuickFix(psi, Input(psi.shouldHaveNotNullType()), replaceWithSafeCallFixApplicator))
is KtNameReferenceExpression -> {
// TODO: As a safety precaution, resolve the expression to determine if it is a call with an implicit receiver.
// This is a defensive check to ensure that the diagnostic was reported on such a call and not some other name reference.
// This isn't strictly needed because FIR checkers aren't reporting on wrong elements, but ReplaceWithSafeCallFixFactory
// in FE1.0 does so.
listOf(
HLApplicatorWithTargetAndInput(
replaceImplicitReceiverCallFixApplicator,
psi withInput Input(psi.shouldHaveNotNullType())
)
)
listOf(HLQuickFix(psi, Input(psi.shouldHaveNotNullType()), replaceImplicitReceiverCallFixApplicator))
}
else -> emptyList()
}