plugins/kotlin/docs/fir-ide/architecture/code-insights.md
Intentions are actions that a user can apply to change code, like specifying a variable type or adding an argument name, and so on. Intentions can be considered as small refactoring actions.
kotlin.code-insight.intentions.k2kotlin.code-insight.intentions.sharedPreferably, an intention should extend KotlinApplicableModCommandAction.
It works over the ModCommand API that allows to perform analysis on a background thread.
To learn more about the ModCommand API,
read the short API description and migration guide.
KotlinApplicableModCommandActionThe most important methods you need to implement:
getApplicableRanges(element)
ApplicabilityRanges.isApplicableByPsi(element)
prepareContext(element)
invoke.null if it is not applicable by analysis.prepareContext return type must be non-nullable Unit, and the prepareContext body must be empty.invoke(actionContext, element, elementContext, updater)
actionContext is a ModCommand API action context.element is a non-physical PSI.elementContext is an Analysis API context.updater (see ModPsiUpdater) to perform editor-like actions like moving caret or highlighting an element.getPresentation(context, element)
getPresentation is Presentation.of(familyName).ModCommandAction priority, use Presentation#withPriority andHighPriorityAction and LowPriorityAction marker interfaces for ModCommandActions,SelfTargetingIntention and SelfTargetingRangeIntentionstartInWriteAction()
isApplicableTo(element, caretOffset)
applyTo(element, editor)
SelfTargetingIntention and SelfTargetingRangeIntention when the action must not be invoked inside a write action.Inspections are some kind of checkers, or linters. They inspect code and report some kind of warnings and can recommend how to change code to improve it.
kotlin.code-insight.inspections.k2kotlin.code-insight.inspections.sharedThere are several classes for inspections: KotlinApplicableInspectionBase.Simple, KotlinDiagnosticBasedInspectionBase,
and AbstractKotlinInspection.
KotlinApplicableInspectionBase.SimpleisApplicableByPsi(element), getApplicableRanges(element), and prepareContext(element).
KotlinApplicableModCommandAction.createQuickFix(element, context)
KotlinModCommandQuickFix.HighPriorityAction and LowPriorityAction marker interfaces apply to KotlinModCommandQuickFix.KotlinDiagnosticBasedInspectionBaseA subclass of KotlinApplicableInspectionBase.Simple that is intended
to create inspections from extra compiler checks
(KaDiagnosticCheckerFilter.ONLY_EXTENDED_CHECKERS), whose warnings are not highlighted by default, unlike warnings
from regular checks (KaDiagnosticCheckerFilter.ONLY_COMMON_CHECKERS).
Extending KotlinDiagnosticBasedInspectionBase also allows to run extra compiler checks and possibly apply fixes in batch.
prepareContextByDiagnostic(element, diagnostic)
getProblemDescription and createQuickFix.element is a physical PSI.diagnostic is a specific diagnostic associated with the element.AbstractKotlinInspectionAbstractKotlinInspection if the quick fix cannot be KotlinModCommandQuickFixQuick fixes are actions on errors and warnings provided by the compiler – they are registered in KotlinK2QuickFixRegistrar.
kotlin.code-insight.fixes.k2kotlin.fir.frontend-independentThere are two ways to register a quick-fix factory:
registerFactory(factory)
factory can be:
KotlinQuickFixFactory.ModCommandBased, which is preferable as the one that produces a list of ModCommandActions:
PsiUpdateModCommandAction if no element context is required.KotlinPsiUpdateModCommandAction.ElementBased if an element context is required.KotlinQuickFixFactory.IntentionBased, which produces a list of IntentionAction.registerPsiQuickFixes(diagnosticClass, factories)
factories are pure PSI-based quick-fix factories that do not make Analysis API calls.
They can be created using quickFixesPsiBasedFactory.// PRIORITY directive in test data files.
For example:// PRIORITY: HIGH
If you call updater.moveCaretTo() or editor.moveCaret() inside the invoke or applyTo method,
including <caret> in the after-test data file is recommended.
See the documentation for com.intellij.codeInsight.completion.CompletionParameters.getPosition.
To modify the dummy identifier string which is inserted into the copied file at the caret offset,
change org.jetbrains.kotlin.idea.completion.api.CompletionDummyIdentifierProviderService.provideDummyIdentifier.
See the documentation for com.intellij.codeInsight.completion.CompletionContributor.
The contributor for the Kotlin plugin is org.jetbrains.kotlin.idea.completion.KotlinFirCompletionContributor. It performs the following tasks:
org.jetbrains.kotlin.idea.util.positionContext for existing position contexts.FirCompletionContributor subclasses defined for the detected position context.
See org.jetbrains.kotlin.idea.completion.impl.k2.Completions for the context-to-contributors mapping.To add a new type of completion, consider the following options:
FirCompletionContributor.Test data: community/plugins/kotlin/completion/testData/basic.
The order of lookup elements is controlled by com.intellij.codeInsight.lookup.LookupElementWeigher.
See org.jetbrains.kotlin.idea.completion.weighers for existing weighers.
Test data: community/plugins/kotlin/completion/testData/weighers. Note that:
// WITH_ORDER directive in community/plugins/kotlin/completion/testData/basic
and specify the elements with their tail texts.See the documentation for com.intellij.codeInsight.completion.CompletionContributor.
See the documentation for com.intellij.codeInsight.lookup.LookupElement.handleInsert.
Test data: community/plugins/kotlin/completion/testData/handlers.
To distinguish between lookup elements with the same item text, use the // TAIL_TEXT: directive.
Test data: community/plugins/kotlin/completion/testData/handlers/charFilter.
IJ Refresher Course: Completion by Peter Gromov