提交 0d9991eb 编写于 作者: T Tianyu Geng 提交者: Ilya Kirillov

FIR IDE: allow HLDiagnosticFixFactory creating any intention

It seems unnecessary to force all quickfixes to fit the `HLQuickfix`
API, especially for those existing trivial fixes that simply modifies
PSI tree. This change further loosen the API of `HLDiagnosticFixFactory`
to allow it to create arbitrary `IntentionAction` objects. This also
avoids code duplication (for example, specify the family name again in
`ReplaceCallFixFactories`).

`HLQuickfix` and the input/target paradighm can still be used where
applicable.
上级 56096451
......@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.diagnostics.KtDiagnosticWithPsi
sealed class HLDiagnosticFixFactory<in DIAGNOSTIC : KtDiagnosticWithPsi<*>> {
abstract fun KtAnalysisSession.createQuickFixes(diagnostic: DIAGNOSTIC): List<HLQuickFix<*, *>>
abstract fun KtAnalysisSession.createQuickFixes(diagnostic: DIAGNOSTIC): List<IntentionAction>
}
private class HLDiagnosticFixFactoryWithFixedApplicator<DIAGNOSTIC : KtDiagnosticWithPsi<*>, TARGET_PSI : PsiElement, INPUT : HLApplicatorInput>(
......@@ -25,9 +25,9 @@ private class HLDiagnosticFixFactoryWithFixedApplicator<DIAGNOSTIC : KtDiagnosti
}
private class HLDiagnosticFixFactoryWithVariableApplicator<DIAGNOSTIC : KtDiagnosticWithPsi<*>>(
private val createQuickFixes: KtAnalysisSession.(DIAGNOSTIC) -> List<HLQuickFix<*, *>>
private val createQuickFixes: KtAnalysisSession.(DIAGNOSTIC) -> List<IntentionAction>
) : HLDiagnosticFixFactory<DIAGNOSTIC>() {
override fun KtAnalysisSession.createQuickFixes(diagnostic: DIAGNOSTIC): List<HLQuickFix<*, *>> =
override fun KtAnalysisSession.createQuickFixes(diagnostic: DIAGNOSTIC): List<IntentionAction> =
createQuickFixes.invoke(this, diagnostic)
}
......@@ -50,6 +50,6 @@ fun <DIAGNOSTIC : KtDiagnosticWithPsi<*>, TARGET_PSI : PsiElement, INPUT : HLApp
* Returns a [HLDiagnosticFixFactory] that creates [HLQuickFix]es from a diagnostic.
*/
fun <DIAGNOSTIC : KtDiagnosticWithPsi<*>> diagnosticFixFactory(
createQuickFixes: KtAnalysisSession.(DIAGNOSTIC) -> List<HLQuickFix<*, *>>
createQuickFixes: KtAnalysisSession.(DIAGNOSTIC) -> List<IntentionAction>
): HLDiagnosticFixFactory<DIAGNOSTIC> =
HLDiagnosticFixFactoryWithVariableApplicator(createQuickFixes)
......@@ -5,15 +5,10 @@
package org.jetbrains.kotlin.idea.quickfix.fixes
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.HLQuickFix
import org.jetbrains.kotlin.idea.fir.api.fixes.diagnosticFixFactory
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
import org.jetbrains.kotlin.idea.quickfix.ReplaceCallFix
import org.jetbrains.kotlin.idea.quickfix.ReplaceImplicitReceiverCallFix
import org.jetbrains.kotlin.idea.quickfix.ReplaceWithSafeCallFix
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
......@@ -21,23 +16,6 @@ import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
object ReplaceCallFixFactories {
private val replaceWithSafeCallFixApplicator =
applicatorByQuickFix<KtExpression, Input, ReplaceCallFix>(
getFamilyName = KotlinBundle.lazyMessage("replace.with.safe.call"),
isApplicableByPsi = { psi -> psi is KtDotQualifiedExpression }
) { psi, input ->
ReplaceWithSafeCallFix(psi as KtDotQualifiedExpression, input.notNullNeeded)
}
private val replaceImplicitReceiverCallFixApplicator =
applicatorByQuickFix<KtExpression, Input, ReplaceImplicitReceiverCallFix>(
getFamilyName = KotlinBundle.lazyMessage("replace.with.safe.this.call")
) { psi, input ->
ReplaceImplicitReceiverCallFix(psi, input.notNullNeeded)
}
class Input(val notNullNeeded: Boolean) : HLApplicatorInput
val unsafeCallFactory =
diagnosticFixFactory<KtFirDiagnostic.UnsafeCall> { diagnostic ->
fun KtExpression.shouldHaveNotNullType(): Boolean {
......@@ -48,13 +26,13 @@ object ReplaceCallFixFactories {
}
when (val psi = diagnostic.psi) {
is KtDotQualifiedExpression -> listOf(HLQuickFix(psi, Input(psi.shouldHaveNotNullType()), replaceWithSafeCallFixApplicator))
is KtDotQualifiedExpression -> listOf(ReplaceWithSafeCallFix(psi, psi.shouldHaveNotNullType()))
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(HLQuickFix(psi, Input(psi.shouldHaveNotNullType()), replaceImplicitReceiverCallFixApplicator))
listOf(ReplaceImplicitReceiverCallFix(psi, psi.shouldHaveNotNullType()))
}
else -> emptyList()
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册