mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-04 17:20:55 +07:00
[kotlin] KTIJ-29028 KotlinApplicatorBasedModCommand, ModCommandBased.ModCommandBased totally replaced with KotlinModCommandAction
GitOrigin-RevId: 17b58dfe86dcf66b10379588a0368c2eb730d988
This commit is contained in:
committed by
intellij-monorepo-bot
parent
ede7bd81c2
commit
973c16e195
@@ -1,16 +1,13 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
|
||||
package org.jetbrains.kotlin.idea.codeinsight.api.applicators
|
||||
|
||||
import com.intellij.codeInsight.intention.FileModifier
|
||||
import com.intellij.codeInspection.util.IntentionFamilyName
|
||||
import com.intellij.codeInspection.util.IntentionName
|
||||
import com.intellij.modcommand.ActionContext
|
||||
import com.intellij.modcommand.ModPsiUpdater
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
|
||||
|
||||
/**
|
||||
* Applies a fix to the PSI, used as intention/inspection/quickfix action
|
||||
@@ -60,23 +57,4 @@ sealed interface KotlinApplicator<in PSI : PsiElement, in INPUT : KotlinApplicat
|
||||
|
||||
fun startInWriteAction(): Boolean = true
|
||||
}
|
||||
|
||||
interface ModCommandBased<in PSI : PsiElement, in INPUT : KotlinApplicatorInput> : KotlinApplicator<PSI, INPUT> {
|
||||
|
||||
/**
|
||||
* Applies some fix to given [psi], cannot use resolve, so all needed data should be precalculated and stored in [input]
|
||||
*
|
||||
* To be invoked on a background thread only.
|
||||
*
|
||||
* @param psi a non-physical [PsiElement] to apply fix to
|
||||
* @param input additional data needed to apply the fix
|
||||
*/
|
||||
@RequiresBackgroundThread
|
||||
fun applyTo(
|
||||
psi: PSI,
|
||||
input: INPUT,
|
||||
context: ActionContext,
|
||||
updater: ModPsiUpdater,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.kotlin.idea.codeinsight.api.applicators.fixes
|
||||
|
||||
import com.intellij.codeInsight.intention.FileModifier
|
||||
import com.intellij.modcommand.ActionContext
|
||||
import com.intellij.modcommand.ModPsiUpdater
|
||||
import com.intellij.modcommand.Presentation
|
||||
import com.intellij.modcommand.PsiUpdateModCommandAction
|
||||
import com.intellij.openapi.diagnostic.ReportingClassSubstitutor
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.applicators.KotlinApplicator
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.applicators.KotlinApplicatorInput
|
||||
|
||||
class KotlinApplicatorBasedModCommand<PSI : PsiElement, in INPUT : KotlinApplicatorInput>(
|
||||
target: PSI,
|
||||
@FileModifier.SafeFieldForPreview
|
||||
private val input: INPUT,
|
||||
@FileModifier.SafeFieldForPreview
|
||||
private val applicator: KotlinApplicator.ModCommandBased<PSI, INPUT>,
|
||||
) : PsiUpdateModCommandAction<PSI>(target),
|
||||
ReportingClassSubstitutor {
|
||||
|
||||
override fun getFamilyName(): String =
|
||||
applicator.getFamilyName()
|
||||
|
||||
override fun getPresentation(context: ActionContext, element: PSI): Presentation =
|
||||
Presentation.of(applicator.getActionName(element, input))
|
||||
|
||||
override fun invoke(context: ActionContext, element: PSI, updater: ModPsiUpdater) {
|
||||
applicator.applyTo(element, input, context, updater)
|
||||
}
|
||||
|
||||
override fun getSubstitutedClass(): Class<*> = applicator.javaClass
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
|
||||
package org.jetbrains.kotlin.idea.codeinsight.api.applicators.fixes
|
||||
|
||||
@@ -45,7 +45,7 @@ class KotlinApplicatorBasedQuickFix<PSI : PsiElement, in INPUT : KotlinApplicato
|
||||
return if (input.isValidFor(element)) {
|
||||
applicator.getActionName(element, input)
|
||||
} else {
|
||||
applicator.getFamilyName()
|
||||
familyName
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
|
||||
package org.jetbrains.kotlin.idea.codeinsight.api.applicators.fixes
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.applicators.KotlinApplicatorInput
|
||||
|
||||
@Deprecated("To be totally replaced with actual Intentions/ModCommandActions")
|
||||
class KotlinApplicatorTargetWithInput<PSI : PsiElement, INPUT : KotlinApplicatorInput>(
|
||||
val target: PSI,
|
||||
val input: INPUT,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
|
||||
package org.jetbrains.kotlin.idea.codeinsight.api.applicators.fixes
|
||||
|
||||
@@ -23,11 +23,15 @@ sealed class KotlinDiagnosticFixFactory<DIAGNOSTIC : KtDiagnosticWithPsi<*>> {
|
||||
abstract val diagnosticClass: KClass<DIAGNOSTIC>
|
||||
}
|
||||
|
||||
sealed class KotlinDiagnosticModCommandFixFactory<DIAGNOSTIC : KtDiagnosticWithPsi<*>> {
|
||||
context(KtAnalysisSession)
|
||||
abstract fun createModCommandQuickFixes(diagnostic: DIAGNOSTIC): List<ModCommandAction>
|
||||
// todo make fun interface
|
||||
// todo common base interface
|
||||
// todo add second type argument
|
||||
interface KotlinDiagnosticModCommandFixFactory<DIAGNOSTIC : KtDiagnosticWithPsi<*>> {
|
||||
|
||||
abstract val diagnosticClass: KClass<DIAGNOSTIC>
|
||||
context(KtAnalysisSession)
|
||||
fun createModCommandQuickFixes(diagnostic: DIAGNOSTIC): List<ModCommandAction>
|
||||
|
||||
val diagnosticClass: KClass<DIAGNOSTIC> // todo to be extracted
|
||||
}
|
||||
|
||||
private class KotlinDiagnosticFixFactoryWithFixedApplicator<DIAGNOSTIC : KtDiagnosticWithPsi<*>, TARGET_PSI : PsiElement, INPUT : KotlinApplicatorInput>(
|
||||
@@ -51,29 +55,6 @@ private class KotlinDiagnosticFixFactoryUsingQuickFixActionBase<DIAGNOSTIC : KtD
|
||||
}
|
||||
}
|
||||
|
||||
private class KotlinDiagnosticModCommandFixFactoryUsingModCommands<DIAGNOSTIC : KtDiagnosticWithPsi<*>>(
|
||||
override val diagnosticClass: KClass<DIAGNOSTIC>,
|
||||
private val createQuickFixes: context(KtAnalysisSession)(DIAGNOSTIC) -> List<ModCommandAction>
|
||||
) : KotlinDiagnosticModCommandFixFactory<DIAGNOSTIC>() {
|
||||
context(KtAnalysisSession)
|
||||
override fun createModCommandQuickFixes(diagnostic: DIAGNOSTIC): List<ModCommandAction> {
|
||||
return createQuickFixes.invoke(this@KtAnalysisSession, diagnostic)
|
||||
}
|
||||
}
|
||||
|
||||
private class KotlinDiagnosticModCommandFixFactoryWithFixedApplicator<DIAGNOSTIC : KtDiagnosticWithPsi<*>, TARGET_PSI : PsiElement, INPUT : KotlinApplicatorInput>(
|
||||
override val diagnosticClass: KClass<DIAGNOSTIC>,
|
||||
private val applicator: KotlinApplicator.ModCommandBased<TARGET_PSI, INPUT>,
|
||||
private val createTargets: context(KtAnalysisSession)(DIAGNOSTIC) -> List<KotlinApplicatorTargetWithInput<TARGET_PSI, INPUT>>,
|
||||
) : KotlinDiagnosticModCommandFixFactory<DIAGNOSTIC>() {
|
||||
context(KtAnalysisSession)
|
||||
override fun createModCommandQuickFixes(diagnostic: DIAGNOSTIC): List<ModCommandAction> =
|
||||
createTargets.invoke(this@KtAnalysisSession, diagnostic)
|
||||
.map { (target, input) -> KotlinApplicatorBasedModCommand(target, input, applicator) }
|
||||
}
|
||||
|
||||
|
||||
|
||||
context(KtAnalysisSession)
|
||||
internal fun <DIAGNOSTIC : KtDiagnosticWithPsi<PsiElement>> createPlatformQuickFixes(
|
||||
diagnostic: DIAGNOSTIC,
|
||||
@@ -97,17 +78,6 @@ fun <DIAGNOSTIC : KtDiagnosticWithPsi<*>, TARGET_PSI : PsiElement, INPUT : Kotli
|
||||
): KotlinDiagnosticFixFactory<DIAGNOSTIC> =
|
||||
KotlinDiagnosticFixFactoryWithFixedApplicator(diagnosticClass, applicator, createTargets)
|
||||
|
||||
/**
|
||||
* Returns a [KotlinDiagnosticModCommandFixFactory] that creates targets and inputs ([KotlinApplicatorTargetWithInput]) from a diagnostic.
|
||||
* The targets and inputs are consumed by the given applicator to apply fixes.
|
||||
*/
|
||||
fun <DIAGNOSTIC : KtDiagnosticWithPsi<*>, TARGET_PSI : PsiElement, INPUT : KotlinApplicatorInput> diagnosticModCommandFixFactory(
|
||||
diagnosticClass: KClass<DIAGNOSTIC>,
|
||||
applicator: KotlinApplicator.ModCommandBased<TARGET_PSI, INPUT>,
|
||||
createTargets: context(KtAnalysisSession)(DIAGNOSTIC) -> List<KotlinApplicatorTargetWithInput<TARGET_PSI, INPUT>>
|
||||
): KotlinDiagnosticModCommandFixFactory<DIAGNOSTIC> =
|
||||
KotlinDiagnosticModCommandFixFactoryWithFixedApplicator(diagnosticClass, applicator, createTargets)
|
||||
|
||||
/**
|
||||
* Returns a [KotlinDiagnosticFixFactory] that creates [QuickFixActionBase]s from a diagnostic.
|
||||
*/
|
||||
@@ -130,21 +100,16 @@ fun <DIAGNOSTIC_PSI : PsiElement, DIAGNOSTIC : KtDiagnosticWithPsi<DIAGNOSTIC_PS
|
||||
/**
|
||||
* Returns a [KotlinDiagnosticModCommandFixFactory] that creates [ModCommandAction]s from a diagnostic.
|
||||
*/
|
||||
fun <DIAGNOSTIC : KtDiagnosticWithPsi<*>> diagnosticModCommandFixFactory(
|
||||
diagnosticClass: KClass<DIAGNOSTIC>,
|
||||
createQuickFixes: context(KtAnalysisSession)(DIAGNOSTIC) -> List<ModCommandAction>
|
||||
): KotlinDiagnosticModCommandFixFactory<DIAGNOSTIC> =
|
||||
KotlinDiagnosticModCommandFixFactoryUsingModCommands(diagnosticClass, createQuickFixes)
|
||||
// todo to be inlined as Kotlin...Factory { ... }
|
||||
inline fun <reified TARGET_PSI : PsiElement, reified DIAGNOSTIC : KtDiagnosticWithPsi<TARGET_PSI>> diagnosticModCommandFixFactory(
|
||||
crossinline createTargets: context(KtAnalysisSession)(DIAGNOSTIC) -> List<ModCommandAction>,
|
||||
): KotlinDiagnosticModCommandFixFactory<DIAGNOSTIC> = object : KotlinDiagnosticModCommandFixFactory<DIAGNOSTIC> {
|
||||
|
||||
/**
|
||||
* Returns a [Collection] of [KotlinDiagnosticModCommandFixFactory] that creates [ModCommandAction]s from a diagnostic that
|
||||
* have the same type of [PsiElement].
|
||||
*/
|
||||
fun <DIAGNOSTIC : KtDiagnosticWithPsi<*>> diagnosticModCommandFixFactories(
|
||||
vararg diagnosticClasses: KClass<out DIAGNOSTIC>,
|
||||
createQuickFixes: context(KtAnalysisSession)(DIAGNOSTIC) -> List<ModCommandAction>
|
||||
): Collection<KotlinDiagnosticModCommandFixFactory<out DIAGNOSTIC>> =
|
||||
diagnosticClasses.map { KotlinDiagnosticModCommandFixFactoryUsingModCommands(it, createQuickFixes) }
|
||||
override val diagnosticClass: KClass<DIAGNOSTIC> get() = DIAGNOSTIC::class
|
||||
|
||||
context(KtAnalysisSession)
|
||||
override fun createModCommandQuickFixes(diagnostic: DIAGNOSTIC): List<ModCommandAction> = createTargets(analysisSession, diagnostic)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a [KotlinDiagnosticFixFactory] that creates [IntentionAction]s from a diagnostic.
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.kotlin.idea.codeinsight.api.applicators.fixes
|
||||
|
||||
import com.intellij.codeInsight.intention.FileModifier
|
||||
import com.intellij.codeInspection.util.IntentionName
|
||||
import com.intellij.modcommand.*
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
|
||||
|
||||
abstract class KotlinModCommandAction<E : PsiElement, C : KotlinModCommandAction.ElementContext>(
|
||||
element: E,
|
||||
@FileModifier.SafeFieldForPreview private val elementContext: C,
|
||||
) : PsiBasedModCommandAction<E>(element) {
|
||||
|
||||
interface ElementContext {
|
||||
|
||||
fun isValid(context: ActionContext): Boolean = true
|
||||
}
|
||||
|
||||
/**
|
||||
* @see [PsiUpdateModCommandAction.perform]
|
||||
*/
|
||||
@RequiresBackgroundThread
|
||||
final override fun perform(
|
||||
context: ActionContext,
|
||||
element: E,
|
||||
): ModCommand = try {
|
||||
val input = getElementContext(context)
|
||||
|
||||
if (input != null) {
|
||||
ModCommand.psiUpdate(element) { e, updater ->
|
||||
invoke(context, e, input, updater)
|
||||
}
|
||||
} else {
|
||||
ModNothing.NOTHING
|
||||
}
|
||||
} catch (e: ProcessCanceledException) {
|
||||
throw e
|
||||
} catch (e: RuntimeException) {
|
||||
throw RuntimeException("When launching $familyName (${javaClass.name})", e)
|
||||
}
|
||||
|
||||
/**
|
||||
* @see [PsiUpdateModCommandAction.invoke]
|
||||
*/
|
||||
@RequiresBackgroundThread
|
||||
protected abstract fun invoke(
|
||||
context: ActionContext,
|
||||
element: E,
|
||||
elementContext: C,
|
||||
updater: ModPsiUpdater,
|
||||
)
|
||||
|
||||
protected open fun getActionName(
|
||||
context: ActionContext,
|
||||
element: E,
|
||||
elementContext: C,
|
||||
): @IntentionName String = familyName
|
||||
|
||||
override fun getPresentation(
|
||||
context: ActionContext,
|
||||
element: E,
|
||||
): Presentation? = getElementContext(context)
|
||||
?.let { getActionName(context, element, it) }
|
||||
?.let { Presentation.of(it) }
|
||||
|
||||
private fun getElementContext(context: ActionContext): C? = elementContext
|
||||
.takeIf { it.isValid(context) }
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
|
||||
package org.jetbrains.kotlin.idea.codeinsight.api.applicators.fixes
|
||||
|
||||
@@ -101,12 +101,6 @@ class KtQuickFixesListBuilder private constructor() {
|
||||
quickFixFactories.forEach(::registerApplicator)
|
||||
}
|
||||
|
||||
fun <DIAGNOSTIC : KtDiagnosticWithPsi<*>> registerModCommandApplicators(
|
||||
quickFixFactories: Collection<KotlinDiagnosticModCommandFixFactory<out DIAGNOSTIC>>
|
||||
) {
|
||||
quickFixFactories.forEach(::registerApplicator)
|
||||
}
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
fun <DIAGNOSTIC : KtDiagnosticWithPsi<*>> registerApplicator(
|
||||
quickFixFactory: KotlinDiagnosticFixFactory<out DIAGNOSTIC>
|
||||
|
||||
Reference in New Issue
Block a user