mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[remote development tooling] IJPL-231068 Sync split mode inspections state with master branch to offer devs who do not use nightly builds the same tooling that the safe push checks use
GitOrigin-RevId: be32cc21e0147ac93fefaef9dfd802483f3d98aa
This commit is contained in:
committed by
intellij-monorepo-bot
parent
4395850ca3
commit
76883f9413
@@ -123,6 +123,7 @@ jvm_library(
|
||||
"//libraries/jackson/jackson",
|
||||
"//libraries/jackson/databind",
|
||||
"//libraries/kotlinx/collections-immutable:libraries-kotlinx-collections-immutable",
|
||||
"//platform/workspace/jps",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -231,6 +232,7 @@ jvm_library(
|
||||
"//libraries/jackson/jackson:jackson_test_lib",
|
||||
"//libraries/jackson/databind:databind_test_lib",
|
||||
"//libraries/kotlinx/collections-immutable:libraries-kotlinx-collections-immutable_test_lib",
|
||||
"//platform/workspace/jps:jps_test_lib",
|
||||
],
|
||||
)
|
||||
### auto-generated section `build intellij.devkit.core` end
|
||||
|
||||
@@ -123,5 +123,6 @@
|
||||
<orderEntry type="module" module-name="intellij.libraries.jackson" />
|
||||
<orderEntry type="module" module-name="intellij.libraries.jackson.databind" />
|
||||
<orderEntry type="module" module-name="intellij.libraries.kotlinx.collections.immutable" />
|
||||
<orderEntry type="module" module-name="intellij.platform.workspace.jps" />
|
||||
</component>
|
||||
</module>
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--suppress ModuleNotRegisteredAsPluginContent -->
|
||||
<!--suppress PluginXmlPluginLogo -->
|
||||
<idea-plugin>
|
||||
<id>com.example.backend.plugin</id>
|
||||
<vendor>JetBrains</vendor>
|
||||
<!--/*<# Backend XML descriptor #>*/-->
|
||||
<dependencies>
|
||||
<module name="intellij.platform.backend"/>
|
||||
</dependencies>
|
||||
</idea-plugin>
|
||||
@@ -159,15 +159,17 @@
|
||||
<registryKey key="devkit.split.mode.report.implicit.module.kind" defaultValue="true"
|
||||
description="Enables reporting errors about modules that effectively work only on frontend or backend, but do not explicitly state that fact via platform dependency"/>
|
||||
<registryKey key="devkit.split.mode.custom.icons" defaultValue="false"
|
||||
description="Enables custom file and directory icons for split-mode frontend/backend/shared modules in DevKit."/>
|
||||
description="Enables deferred accurate split-mode icon resolution for DevKit descriptor and directory icons."/>
|
||||
<registryKey key="devkit.split.mode.inlay.plugin.descriptor.kind" defaultValue="true"
|
||||
description="Shows inline split-mode compatibility hints for DevKit plugin descriptors."/>
|
||||
<registryKey key="devkit.split.mode.run.jps.to.bazel.in.quick.fix" defaultValue="false"
|
||||
description="Automatically run JPS to Bazel conversion after applying a fix that touches runtime/compile dependencies"/>
|
||||
|
||||
<registryKey key="devkit.split.mode.analysis.api.restrictions.source" defaultValue="[bundled*|project|project-or-bundled]"
|
||||
description="Source of ApiRestrictions.json for DevKit split-mode inspections."
|
||||
description="Source of ApiRestrictions.json5 for DevKit split-mode inspections."
|
||||
restartRequired="true"/>
|
||||
<registryKey key="devkit.split.mode.analysis.predefined.module.kinds.source" defaultValue="[bundled*|project|project-or-bundled]"
|
||||
description="Source of PredefinedModuleKinds.json for DevKit split-mode inspections."
|
||||
description="Source of PredefinedModuleKinds.json5 for DevKit split-mode inspections."
|
||||
restartRequired="true"/>
|
||||
<registryKey key="devkit.split.mode.qodana.analysis.scope.source" defaultValue="[bundled|project*|project-or-bundled]"
|
||||
description="Source of SplitModeQodanaAnalysisScope.json for DevKit split-mode inspections."
|
||||
@@ -781,6 +783,15 @@
|
||||
implementationClass="org.jetbrains.idea.devkit.references.DevKitRelatedPropertiesProvider"/>
|
||||
<codeInsight.lineMarkerProvider language="XML"
|
||||
implementationClass="org.jetbrains.idea.devkit.navigation.DescriptorsIncludingContentModuleLineMarkerProvider"/>
|
||||
<codeInsight.declarativeInlayProvider
|
||||
providerId="devkit.plugin.descriptor.split.mode.kind"
|
||||
bundle="messages.DevKitBundle"
|
||||
nameKey="inlay.split.mode.module.kind.name"
|
||||
descriptionKey="inlay.split.mode.module.kind.description"
|
||||
group="OTHER_GROUP"
|
||||
implementationClass="org.jetbrains.idea.devkit.navigation.DescriptorSplitModeInlayHintsProvider"
|
||||
isEnabledByDefault="true"
|
||||
language="XML"/>
|
||||
<psi.referenceContributor
|
||||
language="Properties"
|
||||
implementation="org.jetbrains.idea.devkit.references.MessageBundleReferenceContributor"/>
|
||||
|
||||
@@ -753,6 +753,17 @@ inspections.meta.information.json.schema.display.name=IntelliJ Inspections Metai
|
||||
inlay.threading.name=IJ Platform threading
|
||||
# suppress inspection "GrazieInspection"
|
||||
inlay.threading.description=IntelliJ Platform threading and read/write lock related annotations, e.g., <code>@RequiresEdt</code>, <code>@RequiresReadLock</code>.<br><br>Experimental, enabled in IDEA project only.
|
||||
inlay.split.mode.module.kind.name=Plugin descriptor split-mode kind
|
||||
inlay.split.mode.module.kind.description=Shows whether a plugin descriptor is a frontend, backend, shared, or monolith plugin/content module/XML descriptor.
|
||||
inlay.split.mode.module.kind.presentation={0} {1}
|
||||
inlay.split.mode.module.kind.tooltip=Split mode compatibility: {0} can be installed into {1}. Reason: {2}
|
||||
inlay.split.mode.module.kind.compatibility.frontend=frontend IDE
|
||||
inlay.split.mode.module.kind.compatibility.backend=backend IDE
|
||||
inlay.split.mode.module.kind.compatibility.shared=both frontend and backend IDE
|
||||
inlay.split.mode.module.kind.compatibility.monolith=monolith IDE
|
||||
inlay.split.mode.module.kind.content.module=content module
|
||||
inlay.split.mode.module.kind.plugin=plugin
|
||||
inlay.split.mode.module.kind.xml.descriptor=XML descriptor
|
||||
|
||||
inspections.static.initialization.in.extensions.name=Static initialization in extension point implementations
|
||||
inspections.static.initialization.in.extensions.message=Extension point implementations must not use static initialization
|
||||
@@ -836,8 +847,8 @@ inspection.message.return.value.without.path.annotation.where.expected=Return va
|
||||
inspection.remote.dev.missing.runtime.dependency.name=Missing frontend or backend runtime dependency
|
||||
inspection.remote.dev.missing.runtime.dependency.message=The name of the current module ''{0}'' ends with ''{1}'', but the dependency on ''{2}'' is missing
|
||||
inspection.remote.dev.missing.runtime.dependency.fix.add=Add the ''{0}'' dependency
|
||||
inspection.remote.dev.add.to.split.mode.exclusions.fix.name=Add this violation to the exclusions list
|
||||
inspection.remote.dev.add.to.split.mode.exclusions.command.name=Add This Violation to the Exclusions List
|
||||
inspection.remote.dev.increase.split.mode.baseline.fix.name=Bypass incremental Split Mode safe-push tests
|
||||
inspection.remote.dev.increase.split.mode.baseline.command.name=Increase Split Mode Compatibility Baseline Version
|
||||
inspection.split.mode.mixed.dependencies.display.name=Split mode compatibility inspection
|
||||
inspection.split.mode.implicit.module.kind.display.name=Implicit split mode module kind inspection
|
||||
inspection.remote.dev.mixed.dependencies.message=This module effectively depends on frontend-only and backend-only modules simultaneously. It will not get loaded in Split Mode.
|
||||
|
||||
+326
-301
@@ -1,317 +1,342 @@
|
||||
// Split-mode API restrictions consumed by DevKit inspections.
|
||||
// JSON5 comments, single-quoted strings, unquoted field names, and trailing commas are supported.
|
||||
//
|
||||
// Entry structure:
|
||||
// {
|
||||
// "apiName": "fully.qualified.ApiName", // Required, unique API identifier used by code inspections.
|
||||
// "extensionPointNames": ["com.intellij.extensionPoint"], // Optional. XML extension point names mapped to this API restriction.
|
||||
// "targetModules": ["frontend", "backend", "shared"], // Required, non-empty. Allowed values: "frontend", "backend", "shared", "monolith".
|
||||
// "restrictionKind": "genericPlatformApi", // Required. Allowed values: "genericPlatformApi", "ui".
|
||||
// "hint": "Extra guidance shown by the inspection" // Optional. Added to the text user/agent sees when an error is reported by inspections
|
||||
// }
|
||||
//
|
||||
// APIs with "restrictionKind": "ui" are forbidden in modules with the backendWithNonUiApiPermit policy, others are allowed. These modules are rider and clion specific backend modules
|
||||
[
|
||||
{"apiName": "com.intellij.openapi.wm.ToolWindowFactory", "extensionPointNames": ["com.intellij.toolWindow"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.wm.ToolWindow", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.editor.toolbar.floating.FloatingToolbarProvider", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.ui.DialogWrapper", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.ui.popup.JBPopupFactory", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.fileEditor.FileEditorManagerListener", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.fileEditor.FileEditorProvider", "extensionPointNames": ["com.intellij.fileEditorProvider"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.editor.event.DocumentListener", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.editor.NonWriteAccessTypedHandler", "extensionPointNames": ["com.intellij.nonWriteAccessTypedHandler"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.fileEditor.FileEditorManager.getFocusedEditor", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.execution.services.ServiceViewContributor", "extensionPointNames": ["com.intellij.serviceViewContributor"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.ui.tree.AsyncTreeModel", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.ui.jcef.JBCefClient", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.notification.NotificationGroup", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.jetbrains.rdclient.daemon.FrontendHighlighterSuppressionHandler", "extensionPointNames": ["com.intellij.rdclient.highlighterSuppressionHandler"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.jetbrains.rdclient.actions.base.BackendDelegatingActionCustomization", "extensionPointNames": ["com.intellij.rdclient.actionCustomization"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.jetbrains.rdclient.editorActions.cwm.FrontendEditorActionHandlerStrategyCustomizer", "extensionPointNames": ["com.intellij.rdclient.editorActionHandlerStrategyCustomizer"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.wm.StatusBarWidgetFactory", "extensionPointNames": ["com.intellij.statusBarWidgetFactory"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.application.options.editor.EditorOptionsPageCustomizer", "extensionPointNames": ["com.intellij.generalEditorOptionsCustomizer"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.codeInsight.folding.CollapseBlockHandler", "extensionPointNames": ["com.intellij.codeInsight.folding.collapseBlockHandler"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.editor.LineWrapPositionStrategy", "extensionPointNames": ["com.intellij.lang.lineWrapStrategy"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.editor.actionSystem.EditorActionHandler", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.editor.event.CaretListener", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.editor.event.EditorMouseMotionListener", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.editor.event.EditorMouseListener", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.editor.event.SelectionListener", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.editor.event.VisibleAreaListener", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.editor.ex.FoldingListener", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.ui.popup.JBPopupListener", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.actionSystem.CommonDataKeys.EDITOR", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.actionSystem.PlatformDataKeys.TOOL_WINDOW", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.actionSystem.PlatformCoreDataKeys.SELECTED_ITEM", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.actionSystem.PlatformCoreDataKeys.SELECTED_ITEMS", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.actionSystem.PlatformCoreDataKeys.CONTEXT_COMPONENT", "extensionPointNames": [], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.codeInsight.lookup.impl.LookupDisplayStrategy", "extensionPointNames": ["com.intellij.lookup.displayStrategy"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.codeInsight.lookup.LookupBottomPanelProvider", "extensionPointNames": ["com.intellij.lookup.bottomPanelProvider"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.codeInsight.lookup.LookupBottomPanelAdvertiserCustomizer", "extensionPointNames": ["com.intellij.lookup.bottomPanelAdvertiserCustomizer"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.codeInsight.lookup.LookupMayHaveCustomPreviewProvider", "extensionPointNames": ["com.intellij.lookup.may.have.custom.preview.provider"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.codeInsight.completion.TemplateParameterTraversalPolicy", "extensionPointNames": ["com.intellij.templateParameterTraversalPolicy"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.options.UnnamedConfigurable", "extensionPointNames": ["com.intellij.codeCompletionConfigurable", "com.intellij.generalEditorOptionsExtension", "com.intellij.inlineCompletionConfigurable", "com.intellij.mlCodeCompletionConfigurable"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.profile.codeInspection.ui.ErrorOptionsProvider", "extensionPointNames": ["com.intellij.errorOptionsProvider"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.application.options.editor.CodeFoldingOptionsProvider", "extensionPointNames": ["com.intellij.codeFoldingOptionsProvider"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.application.options.editor.AutoImportOptionsProvider", "extensionPointNames": ["com.intellij.autoImportOptionsProvider"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.application.options.editor.EditorOptionsProvider", "extensionPointNames": ["com.intellij.editorOptionsProvider"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.application.options.editor.InlineDocsAdditionalConfigurable", "extensionPointNames": ["com.intellij.editorAppearanceInlineDocHandler"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.openapi.roots.ui.configuration.LibrarySettingsProvider", "extensionPointNames": ["com.intellij.librarySettingsProvider"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.profile.codeInspection.ui.InspectionProfileActionProvider", "extensionPointNames": ["com.intellij.inspectionProfileActionProvider"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.profile.codeInspection.ui.InspectionTreeAdvertiser", "extensionPointNames": ["com.intellij.inspectionTreeAdvertiser"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.analysis.problemsView.toolWindow.ProblemsViewPanelProvider", "extensionPointNames": ["com.intellij.problemsViewPanelProvider"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.analysis.problemsView.toolWindow.HighlightingProblemFactory", "extensionPointNames": ["com.intellij.problemsViewHighlightingProblemFactory"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.find.impl.livePreview.EditorSearchAreaProvider", "extensionPointNames": ["com.intellij.editorSearchAreaProvider"], "targetModules": ["frontend"]},
|
||||
{"apiName": "com.intellij.codeInsight.intention.impl.IntentionPopupProvider", "extensionPointNames": ["com.intellij.intentionPopupProvider"], "targetModules": ["frontend"]},
|
||||
// frontend ui apis
|
||||
{"apiName": "com.intellij.openapi.wm.ToolWindowFactory", "extensionPointNames": ["com.intellij.toolWindow"], "targetModules": ["frontend"], "restrictionKind": "ui"},
|
||||
{"apiName": "com.intellij.openapi.wm.ToolWindow", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "ui"},
|
||||
{"apiName": "com.intellij.openapi.editor.toolbar.floating.FloatingToolbarProvider", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "ui"},
|
||||
{"apiName": "com.intellij.openapi.ui.DialogWrapper", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "ui"},
|
||||
{"apiName": "com.intellij.openapi.ui.popup.JBPopupFactory", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "ui"},
|
||||
{"apiName": "com.intellij.ui.tree.AsyncTreeModel", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "ui"},
|
||||
{"apiName": "com.intellij.ui.jcef.JBCefClient", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "ui"},
|
||||
{"apiName": "com.intellij.openapi.wm.StatusBarWidgetFactory", "extensionPointNames": ["com.intellij.statusBarWidgetFactory"], "targetModules": ["frontend"], "restrictionKind": "ui"},
|
||||
{"apiName": "com.intellij.openapi.fileEditor.FileEditorManagerListener", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "ui"},
|
||||
{"apiName": "com.intellij.openapi.fileEditor.FileEditorProvider", "extensionPointNames": ["com.intellij.fileEditorProvider"], "targetModules": ["frontend"], "restrictionKind": "ui"},
|
||||
{"apiName": "com.intellij.openapi.fileEditor.FileEditorManager.getFocusedEditor", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "ui"},
|
||||
{"apiName": "com.intellij.execution.services.ServiceViewContributor", "extensionPointNames": ["com.intellij.serviceViewContributor"], "targetModules": ["frontend"], "restrictionKind": "ui"},
|
||||
{"apiName": "com.intellij.openapi.editor.event.CaretListener", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "ui"},
|
||||
{"apiName": "com.intellij.openapi.editor.event.EditorMouseMotionListener", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "ui"},
|
||||
{"apiName": "com.intellij.openapi.editor.event.EditorMouseListener", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "ui"},
|
||||
{"apiName": "com.intellij.openapi.editor.event.SelectionListener", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "ui"},
|
||||
{"apiName": "com.intellij.openapi.editor.event.VisibleAreaListener", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "ui"},
|
||||
{"apiName": "com.intellij.openapi.ui.popup.JBPopupListener", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "ui"},
|
||||
{"apiName": "com.intellij.openapi.editor.ex.FoldingListener", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.analysis.problemsView.toolWindow.ProblemsViewPanelProvider", "extensionPointNames": ["com.intellij.problemsViewPanelProvider"], "targetModules": ["frontend"], "restrictionKind": "ui"},
|
||||
{"apiName": "com.intellij.openapi.options.Configurable", "extensionPointNames": ["com.intellij.applicationConfigurable", "com.intellij.projectConfigurable"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
|
||||
|
||||
// frontend generic apis
|
||||
{"apiName": "com.intellij.openapi.editor.event.DocumentListener", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.editor.NonWriteAccessTypedHandler", "extensionPointNames": ["com.intellij.nonWriteAccessTypedHandler"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.notification.NotificationGroup", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.jetbrains.rdclient.daemon.FrontendHighlighterSuppressionHandler", "extensionPointNames": ["com.intellij.rdclient.highlighterSuppressionHandler"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.jetbrains.rdclient.actions.base.BackendDelegatingActionCustomization", "extensionPointNames": ["com.intellij.rdclient.actionCustomization"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.jetbrains.rdclient.editorActions.cwm.FrontendEditorActionHandlerStrategyCustomizer", "extensionPointNames": ["com.intellij.rdclient.editorActionHandlerStrategyCustomizer"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.application.options.editor.EditorOptionsPageCustomizer", "extensionPointNames": ["com.intellij.generalEditorOptionsCustomizer"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.folding.CollapseBlockHandler", "extensionPointNames": ["com.intellij.codeInsight.folding.collapseBlockHandler"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.editor.actionSystem.EditorActionHandler", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.actionSystem.CommonDataKeys.EDITOR", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.actionSystem.PlatformDataKeys.TOOL_WINDOW", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.actionSystem.PlatformCoreDataKeys.SELECTED_ITEM", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.actionSystem.PlatformCoreDataKeys.SELECTED_ITEMS", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.actionSystem.PlatformCoreDataKeys.CONTEXT_COMPONENT", "extensionPointNames": [], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.lookup.impl.LookupDisplayStrategy", "extensionPointNames": ["com.intellij.lookup.displayStrategy"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.lookup.LookupBottomPanelProvider", "extensionPointNames": ["com.intellij.lookup.bottomPanelProvider"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.lookup.LookupBottomPanelAdvertiserCustomizer", "extensionPointNames": ["com.intellij.lookup.bottomPanelAdvertiserCustomizer"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.lookup.LookupMayHaveCustomPreviewProvider", "extensionPointNames": ["com.intellij.lookup.may.have.custom.preview.provider"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.completion.TemplateParameterTraversalPolicy", "extensionPointNames": ["com.intellij.templateParameterTraversalPolicy"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.options.UnnamedConfigurable", "extensionPointNames": ["com.intellij.codeCompletionConfigurable", "com.intellij.generalEditorOptionsExtension", "com.intellij.inlineCompletionConfigurable", "com.intellij.mlCodeCompletionConfigurable"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.profile.codeInspection.ui.ErrorOptionsProvider", "extensionPointNames": ["com.intellij.errorOptionsProvider"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.application.options.editor.CodeFoldingOptionsProvider", "extensionPointNames": ["com.intellij.codeFoldingOptionsProvider"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.application.options.editor.AutoImportOptionsProvider", "extensionPointNames": ["com.intellij.autoImportOptionsProvider"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.application.options.editor.EditorOptionsProvider", "extensionPointNames": ["com.intellij.editorOptionsProvider"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.application.options.editor.InlineDocsAdditionalConfigurable", "extensionPointNames": ["com.intellij.editorAppearanceInlineDocHandler"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.roots.ui.configuration.LibrarySettingsProvider", "extensionPointNames": ["com.intellij.librarySettingsProvider"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.profile.codeInspection.ui.InspectionProfileActionProvider", "extensionPointNames": ["com.intellij.inspectionProfileActionProvider"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.profile.codeInspection.ui.InspectionTreeAdvertiser", "extensionPointNames": ["com.intellij.inspectionTreeAdvertiser"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.analysis.problemsView.toolWindow.HighlightingProblemFactory", "extensionPointNames": ["com.intellij.problemsViewHighlightingProblemFactory"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.find.impl.livePreview.EditorSearchAreaProvider", "extensionPointNames": ["com.intellij.editorSearchAreaProvider"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.intention.impl.IntentionPopupProvider", "extensionPointNames": ["com.intellij.intentionPopupProvider"], "targetModules": ["frontend"], "restrictionKind": "genericPlatformApi"},
|
||||
|
||||
|
||||
|
||||
{"apiName": "com.intellij.openapi.vfs.VirtualFileManager", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.openapi.vfs.VfsUtil", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.psi.stubs.StubIndex", "extensionPointNames": ["com.intellij.stubIndex"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.psi.stubs.StubIndexExtension", "extensionPointNames": ["com.intellij.stubIndex"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.util.indexing.IndexExtension", "extensionPointNames": ["com.intellij.fileBasedIndex"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.util.indexing.FileBasedIndexExtension", "extensionPointNames": ["com.intellij.fileBasedIndex"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.configurations.ConfigurationType", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.psi.search.searches.ReferencesSearch", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.model.search.SearchService", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.util.Query", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.hints.InlayHintsProvider", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.hints.declarative.InlayHintsProvider", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.daemon.LineMarkerProvider", "extensionPointNames": ["com.intellij.codeInsight.lineMarkerProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInspection.LocalInspectionTool", "extensionPointNames": ["com.intellij.localInspection"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInspection.incorrectFormatting.IncorrectFormattingResultHandlerProvider", "extensionPointNames": ["com.intellij.resultHandlerProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.psi.PsiReferenceContributor", "extensionPointNames": ["com.intellij.psi.referenceContributor"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.jetbrains.jsonSchema.extension.JsonSchemaProviderFactory", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.actions.RunConfigurationProducer", "extensionPointNames": ["com.intellij.runConfigurationProducer"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.structureView.StructureViewBuilder", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.openapi.vfs.AsyncFileListener", "extensionPointNames": ["com.intellij.vfs.asyncListener", "com.intellij.vfs.asyncListenerBackgroundable"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.psi.ResolveScopeProvider", "extensionPointNames": ["com.intellij.resolveScopeProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.openapi.vfs.VirtualFileListener", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.platform.backend.workspace.WorkspaceModelChangeListener", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.openapi.project.ProjectManagerListener", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.process.ProcessHandler", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.openapi.actionSystem.CommonDataKeys.SYMBOLS", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.openapi.actionSystem.PlatformCoreDataKeys.MODULE", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.openapi.actionSystem.LangDataKeys.MODULE_CONTEXT", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.openapi.actionSystem.LangDataKeys.MODIFIABLE_MODULE_MODEL", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.completion.CompletionPreselectionBehaviourProvider", "extensionPointNames": ["com.intellij.completion.preselectionBehaviourProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.completion.ml.ContextFeatureProvider", "extensionPointNames": ["com.intellij.completion.ml.contextFeatures"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.internal.ml.completion.RankingModelProvider", "extensionPointNames": ["com.intellij.completion.ml.model"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.completion.ml.ElementFeatureProvider", "extensionPointNames": ["com.intellij.completion.ml.elementFeatures"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.completion.PlainTextSymbolCompletionContributor", "extensionPointNames": ["com.intellij.completion.plainTextSymbol"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.lang.WordCompletionElementFilter", "extensionPointNames": ["com.intellij.codeInsight.wordCompletionFilter"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.completion.ml.MLFeatureProvider", "extensionPointNames": ["com.intellij.internal.ml.featureProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.modcompletion.ModCompletionItemProvider", "extensionPointNames": ["com.intellij.modcompletion.completionItemProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.modcompletion.ModCompletionItemFilter", "extensionPointNames": ["com.intellij.modcompletion.completionItemFilter"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.completion.command.CommandCompletionFactory", "extensionPointNames": ["com.intellij.codeInsight.completion.command.factory"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.completion.command.CommandProvider", "extensionPointNames": ["com.intellij.codeInsight.completion.command.provider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.completion.command.commands.IntentionCommandSkipper", "extensionPointNames": ["com.intellij.codeInsight.completion.intention.skipper"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.completion.command.commands.ErrorFixCommandProvider", "extensionPointNames": ["com.intellij.codeInsight.completion.error.intention"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.completion.command.commands.IntentionCommandOffsetProvider", "extensionPointNames": ["com.intellij.codeInsight.completion.intention.offset.provider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.lang.refactoring.RefactoringSupportProvider", "extensionPointNames": ["com.intellij.lang.refactoringSupport"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.lang.refactoring.NamesValidator", "extensionPointNames": ["com.intellij.lang.namesValidator"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.rename.RenameHandler", "extensionPointNames": ["com.intellij.renameHandler"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.rename.RenamePsiElementProcessorBase", "extensionPointNames": ["com.intellij.renamePsiElementProcessor"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.psi.impl.file.UpdateAddedFileProcessor", "extensionPointNames": ["com.intellij.updateAddedFileProcessor"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.rename.naming.AutomaticRenamerFactory", "extensionPointNames": ["com.intellij.automaticRenamerFactory"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.rename.NameSuggestionProvider", "extensionPointNames": ["com.intellij.nameSuggestionProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.rename.RenamerFactory", "extensionPointNames": ["com.intellij.renamerFactory"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.RefactoringHelper", "extensionPointNames": ["com.intellij.refactoring.helper"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.lang.refactoring.InlineActionHandler", "extensionPointNames": ["com.intellij.inlineActionHandler"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.lang.refactoring.InlineHandler", "extensionPointNames": ["com.intellij.refactoring.inlineHandler"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.rename.ResolveSnapshotProvider", "extensionPointNames": ["com.intellij.rename.inplace.resolveSnapshotProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.rename.RenameInputValidator", "extensionPointNames": ["com.intellij.renameInputValidator"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.listeners.RefactoringElementListenerProvider", "extensionPointNames": ["com.intellij.refactoring.elementListenerProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.find.FindInProjectSearchEngine", "extensionPointNames": ["com.intellij.findInProjectSearchEngine"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.actions.QualifiedNameProvider", "extensionPointNames": ["com.intellij.qualifiedNameProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.actions.VirtualFileQualifiedNameProvider", "extensionPointNames": ["com.intellij.virtualFileQualifiedNameProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.openapi.roots.TestSourcesFilter", "extensionPointNames": ["com.intellij.testSourcesFilter"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.classMembers.ClassMembersRefactoringSupport", "extensionPointNames": ["com.intellij.lang.refactoringSupport.classMembersRefactoringSupport"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.copy.CopyHandlerDelegate", "extensionPointNames": ["com.intellij.refactoring.copyHandler"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.move.MoveHandlerDelegate", "extensionPointNames": ["com.intellij.refactoring.moveHandler"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.introduceParameterObject.IntroduceParameterObjectDelegate", "extensionPointNames": ["com.intellij.refactoring.introduceParameterObject"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.memberPushDown.PushDownDelegate", "extensionPointNames": ["com.intellij.refactoring.pushDown"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.move.moveClassesOrPackages.MoveDirectoryWithClassesHelper", "extensionPointNames": ["com.intellij.refactoring.moveDirectoryWithClassesHelper"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.safeDelete.SafeDeleteProcessorDelegate", "extensionPointNames": ["com.intellij.refactoring.safeDeleteProcessor"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.RefactoringActionHandler", "extensionPointNames": ["com.intellij.refactoring.extractIncludeHandler"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.changeSignature.ChangeSignatureUsageProcessor", "extensionPointNames": ["com.intellij.refactoring.changeSignatureUsageProcessor"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.move.moveFilesOrDirectories.MoveFileHandler", "extensionPointNames": ["com.intellij.moveFileHandler"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.rename.symbol.SymbolRenameTargetFactory", "extensionPointNames": ["com.intellij.rename.symbolRenameTargetFactory"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.actions.RenameFileActionProvider", "extensionPointNames": ["com.intellij.renameFileActionProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.changeSignature.inplace.LanguageChangeSignatureDetector", "extensionPointNames": ["com.intellij.changeSignatureDetector"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.suggested.SuggestedRefactoringSupport", "extensionPointNames": ["com.intellij.suggestedRefactoringSupport"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.changeSignature.ChangeSignatureUsageProvider", "extensionPointNames": ["com.intellij.changeSignature.usageProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeHighlighting.TextEditorHighlightingPassFactoryRegistrar", "extensionPointNames": ["com.intellij.highlightingPassFactory"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.RunConfigurationProducerSuppressor", "extensionPointNames": ["com.intellij.runConfigurationProducerSuppressor"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.psi.search.IndexPatternProvider", "extensionPointNames": ["com.intellij.indexPatternProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInspection.reference.RefGraphAnnotator", "extensionPointNames": ["com.intellij.refGraphAnnotator"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.daemon.impl.HighlightVisitor", "extensionPointNames": ["com.intellij.highlightVisitor"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.daemon.impl.analysis.ErrorQuickFixProvider", "extensionPointNames": ["com.intellij.errorQuickFixProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.openapi.paths.PathReferenceProvider", "extensionPointNames": ["com.intellij.pathReferenceProvider", "com.intellij.anchorReferenceProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.openapi.paths.DynamicContextProvider", "extensionPointNames": ["com.intellij.dynamicContextProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider", "extensionPointNames": ["com.intellij.codeInsight.unresolvedReferenceQuickFixProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.lang.ExternalAnnotatorsFilter", "extensionPointNames": ["com.intellij.daemon.externalAnnotatorsFilter"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.daemon.ChangeLocalityDetector", "extensionPointNames": ["com.intellij.daemon.changeLocalityDetector"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.daemon.ImplicitUsageProvider", "extensionPointNames": ["com.intellij.implicitUsageProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.lang.injection.ConcatenationAwareInjector", "extensionPointNames": ["com.intellij.concatenationAwareInjector"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.psi.injection.ReferenceInjector", "extensionPointNames": ["com.intellij.referenceInjector"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.lang.annotation.ExternalAnnotator", "extensionPointNames": ["com.intellij.externalAnnotator"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.lang.findUsages.FindUsagesProvider", "extensionPointNames": ["com.intellij.lang.findUsagesProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.lang.cacheBuilder.WordsScanner", "extensionPointNames": ["com.intellij.cacheBuilder"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.model.search.Searcher", "extensionPointNames": ["com.intellij.searcher"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.psi.search.SearchScopeProvider", "extensionPointNames": ["com.intellij.searchScopesProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.util.gotoByName.GotoActionAliasMatcher", "extensionPointNames": ["com.intellij.gotoActionAliasMatcher"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.navigation.ChooseByNameContributor", "extensionPointNames": ["com.intellij.gotoClassContributor", "com.intellij.gotoSymbolContributor", "com.intellij.gotoFileContributor"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.navigation.GotoRelatedProvider", "extensionPointNames": ["com.intellij.gotoRelatedProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.navigation.AnonymousElementProvider", "extensionPointNames": ["com.intellij.anonymousElementProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributorFactory", "extensionPointNames": ["com.intellij.searchEverywhereContributor"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.actions.searcheverywhere.SEResultsEqualityProvider", "extensionPointNames": ["com.intellij.searchEverywhereResultsEqualityProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.actions.searcheverywhere.SearchEverywhereMlService", "extensionPointNames": ["com.intellij.searchEverywhereMlService"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.actions.searcheverywhere.SearchEverywhereMlContributorReplacement", "extensionPointNames": ["com.intellij.searchEverywhereMlContributorReplacement"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.actions.searcheverywhere.SearchEverywhereSpellingCorrectorFactory", "extensionPointNames": ["com.intellij.searchEverywhereSpellingCorrector"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.actions.searcheverywhere.SearchEverywhereEssentialContributorMarker", "extensionPointNames": ["com.intellij.searchEverywhereEssentialContributorsMarker"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.actions.searcheverywhere.remote.RemoteSearchEverywhereConverterSupplier", "extensionPointNames": ["com.intellij.searchEverywhereRemoteConverter"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.actions.searcheverywhere.SearchEverywhereReorderingService", "extensionPointNames": ["com.intellij.searchEverywhereReorderingService"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.actions.searcheverywhere.SearchEverywherePreviewPrimaryUsageFinder", "extensionPointNames": ["com.intellij.searchEverywherePreviewPrimaryUsageFinder"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.actions.SearchEverywhereManagerFactory", "extensionPointNames": ["com.intellij.searchEverywhere.manager"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.actions.runAnything.activity.RunAnythingProvider", "extensionPointNames": ["com.intellij.runAnything.executionProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.actions.runAnything.handlers.RunAnythingCommandHandler", "extensionPointNames": ["com.intellij.runAnything.commandHandler"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.actions.runAnything.groups.RunAnythingHelpGroup", "extensionPointNames": ["com.intellij.runAnything.helpGroup"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.actions.runAnything.commands.RunAnythingCommandCustomizer", "extensionPointNames": ["com.intellij.runAnything.commandCustomizer"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.highlighting.HighlightUsagesHandlerFactory", "extensionPointNames": ["com.intellij.highlightUsagesHandlerFactory"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.usages.UsageTargetProvider", "extensionPointNames": ["com.intellij.usageTargetProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.usages.UsageToPsiElementProvider", "extensionPointNames": ["com.intellij.usageToPsiElementProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.find.impl.FindInProjectExtension", "extensionPointNames": ["com.intellij.findInProjectExtension"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.model.psi.PsiSymbolDeclarationProvider", "extensionPointNames": ["com.intellij.psi.declarationProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.navigation.actions.TypeDeclarationProvider", "extensionPointNames": ["com.intellij.typeDeclarationProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.navigation.GotoTargetRendererProvider", "extensionPointNames": ["com.intellij.gotoTargetRendererProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.navigation.GotoTargetPresentationProvider", "extensionPointNames": ["com.intellij.gotoTargetPresentationProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.find.usages.symbol.SymbolSearchTargetFactory", "extensionPointNames": ["com.intellij.lang.symbolSearchTarget"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.find.findUsages.FindUsagesHandlerFactory", "extensionPointNames": ["com.intellij.findUsagesHandlerFactory"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.find.findUsages.CustomUsageSearcher", "extensionPointNames": ["com.intellij.customUsageSearcher"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.platform.ide.navigation.NavigationHandler", "extensionPointNames": ["com.intellij.navigation.navigationHandler"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.impl.RunConfigurationTemplateProvider", "extensionPointNames": ["com.intellij.runConfigurationTemplateProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.configurations.RunConfigurationsSettings", "extensionPointNames": ["com.intellij.runConfigurationsSettings"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.runners.ProgramRunner", "extensionPointNames": ["com.intellij.programRunner"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.task.ProjectTaskRunner", "extensionPointNames": ["com.intellij.projectTaskRunner"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.Executor", "extensionPointNames": ["com.intellij.executor"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.runToolbar.RunToolbarProcess", "extensionPointNames": ["com.intellij.runToolbarProcess"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.ExecutionTargetProvider", "extensionPointNames": ["com.intellij.executionTargetProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.BeforeRunTaskProvider", "extensionPointNames": ["com.intellij.stepsBeforeRunProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.impl.RunConfigurationBeforeRunProviderDelegate", "extensionPointNames": ["com.intellij.runConfigurationBeforeRunProviderDelegate"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.target.RunConfigurationTargetEnvironmentAdjuster$Factory", "extensionPointNames": ["com.intellij.runConfigurationTargetEnvironmentAdjusterFactory"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.target.TargetEnvironmentType", "extensionPointNames": ["com.intellij.executionTargetType"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.target.LanguageRuntimeType", "extensionPointNames": ["com.intellij.executionTargetLanguageRuntimeType"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.filters.ConsoleFilterProvider", "extensionPointNames": ["com.intellij.consoleFilterProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.filters.ConsoleInputFilterProvider", "extensionPointNames": ["com.intellij.consoleInputFilterProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.actions.ConsoleActionsPostProcessor", "extensionPointNames": ["com.intellij.consoleActionsPostProcessor"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.junit.RuntimeConfigurationProducer", "extensionPointNames": ["com.intellij.configurationProducer"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.lineMarker.RunLineMarkerContributor", "extensionPointNames": ["com.intellij.runLineMarkerContributor"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.actions.MultipleRunLocationsProvider", "extensionPointNames": ["com.intellij.multipleRunLocationsProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.dashboard.RunDashboardCustomizer", "extensionPointNames": ["com.intellij.runDashboardCustomizer"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.dashboard.LegacyRunDashboardServiceSubstitutor", "extensionPointNames": ["com.intellij.legacyRunDashboardServiceSubstitutor"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.dashboard.RunDashboardDefaultTypesProvider", "extensionPointNames": ["com.intellij.runDashboardDefaultTypesProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.navigation.MethodNavigationOffsetProvider", "extensionPointNames": ["com.intellij.methodNavigationOffsetProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.testIntegration.TestFinder", "extensionPointNames": ["com.intellij.testFinder"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.testIntegration.TestLocationProvider", "extensionPointNames": ["com.intellij.testSrcLocator"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.testIntegration.TestCreator", "extensionPointNames": ["com.intellij.testCreator"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.hierarchy.HierarchyProvider", "extensionPointNames": ["com.intellij.callHierarchyProvider", "com.intellij.methodHierarchyProvider", "com.intellij.typeHierarchyProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.TargetElementUtilExtender", "extensionPointNames": ["com.intellij.targetElementUtilExtender"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.TargetElementEvaluator", "extensionPointNames": ["com.intellij.targetElementEvaluator"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.psi.impl.cache.impl.id.IdIndexer", "extensionPointNames": ["com.intellij.idIndexer"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.daemon.ProblemHighlightFilter", "extensionPointNames": ["com.intellij.problemHighlightFilter"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.filters.Filter", "extensionPointNames": ["com.intellij.analyzeStacktraceFilter"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.unscramble.StacktraceTabContentProvider", "extensionPointNames": ["com.intellij.analyzeStacktraceRunContentProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.actions.SearchEverywhereClassifier", "extensionPointNames": ["com.intellij.searchEverywhereClassifier"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.util.gotoByName.GotoFileCustomizer", "extensionPointNames": ["com.intellij.gotoFileCustomizer"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.util.fuzzyMatching.GotoFileFuzzyMatcherFactory", "extensionPointNames": ["com.intellij.gotoFileFuzzyMatcherFactory"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.slicer.SliceLanguageSupportProvider", "extensionPointNames": ["com.intellij.lang.sliceProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.console.ConsoleHistoryModelProvider", "extensionPointNames": ["com.intellij.consoleHistoryModelProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.execution.update.RunningApplicationUpdaterProvider", "extensionPointNames": ["com.intellij.runningApplicationUpdaterProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.hint.ImplementationViewSessionFactory", "extensionPointNames": ["com.intellij.implementationViewSessionFactory"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.hint.ImplementationViewDocumentFactory", "extensionPointNames": ["com.intellij.implementationViewDocumentFactory"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.platform.backend.documentation.DocumentationTargetProvider", "extensionPointNames": ["com.intellij.platform.backend.documentation.targetProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.platform.backend.documentation.SymbolDocumentationTargetProvider", "extensionPointNames": ["com.intellij.platform.backend.documentation.symbolTargetProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.platform.backend.documentation.PsiDocumentationTargetProvider", "extensionPointNames": ["com.intellij.platform.backend.documentation.psiTargetProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.platform.backend.documentation.LookupElementDocumentationTargetProvider", "extensionPointNames": ["com.intellij.platform.backend.documentation.lookupElementTargetProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.platform.backend.documentation.InlineDocumentationProvider", "extensionPointNames": ["com.intellij.platform.backend.documentation.inlineDocumentationProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.platform.backend.documentation.DocumentationLinkHandler", "extensionPointNames": ["com.intellij.platform.backend.documentation.linkHandler"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.refactoring.safeDelete.api.SafeDeleteTargetProvider", "extensionPointNames": ["com.intellij.safeDeleteTargetProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.navigation.DirectNavigationProvider", "extensionPointNames": ["com.intellij.lang.directNavigationProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.codeInsight.navigation.SymbolTypeProvider", "extensionPointNames": ["com.intellij.lang.symbolTypeProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.openapi.application.ApplicationListener", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.openapi.project.ProjectListener", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.openapi.project.ProjectCloseListener", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.openapi.project.VetoableProjectManagerListener", "extensionPointNames": [], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.projectView.TreeStructureProvider", "extensionPointNames": ["com.intellij.treeStructureProvider"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.projectView.impl.AbstractProjectViewPane", "extensionPointNames": ["com.intellij.projectViewPane"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.projectView.impl.ProjectViewPaneSelectionHelper", "extensionPointNames": ["com.intellij.projectViewPaneSelectionHelper"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.projectView.ProjectViewNodeDecorator", "extensionPointNames": ["com.intellij.projectViewNodeDecorator"], "targetModules": ["backend"]},
|
||||
{"apiName": "com.intellij.ide.projectView.ProjectViewNestingRulesProvider", "extensionPointNames": ["com.intellij.projectViewNestingRulesProvider"], "targetModules": ["backend"]},
|
||||
// backend generic apis
|
||||
{"apiName": "com.intellij.openapi.vfs.VirtualFileManager", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.vfs.VfsUtil", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.roots.FileIndex", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.roots.ModuleFileIndex", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.roots.ProjectFileIndex", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.stubs.StubIndex", "extensionPointNames": ["com.intellij.stubIndex"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.stubs.StubIndexExtension", "extensionPointNames": ["com.intellij.stubIndex"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.util.indexing.IndexExtension", "extensionPointNames": ["com.intellij.fileBasedIndex"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.util.indexing.FileBasedIndexExtension", "extensionPointNames": ["com.intellij.fileBasedIndex"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.configurations.ConfigurationType", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.search.searches.ReferencesSearch", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.model.search.SearchService", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.util.Query", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.hints.InlayHintsProvider", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.hints.declarative.InlayHintsProvider", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.daemon.LineMarkerProvider", "extensionPointNames": ["com.intellij.codeInsight.lineMarkerProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInspection.LocalInspectionTool", "extensionPointNames": ["com.intellij.localInspection"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInspection.incorrectFormatting.IncorrectFormattingResultHandlerProvider", "extensionPointNames": ["com.intellij.resultHandlerProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.PsiReferenceContributor", "extensionPointNames": ["com.intellij.psi.referenceContributor"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.jetbrains.jsonSchema.extension.JsonSchemaProviderFactory", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.actions.RunConfigurationProducer", "extensionPointNames": ["com.intellij.runConfigurationProducer"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.structureView.StructureViewBuilder", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.vfs.AsyncFileListener", "extensionPointNames": ["com.intellij.vfs.asyncListener", "com.intellij.vfs.asyncListenerBackgroundable"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.ResolveScopeProvider", "extensionPointNames": ["com.intellij.resolveScopeProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.vfs.VirtualFileListener", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.platform.backend.workspace.WorkspaceModelChangeListener", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.project.ProjectManagerListener", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.process.ProcessHandler", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.actionSystem.CommonDataKeys.SYMBOLS", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.actionSystem.PlatformCoreDataKeys.MODULE", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.actionSystem.LangDataKeys.MODULE_CONTEXT", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.actionSystem.LangDataKeys.MODIFIABLE_MODULE_MODEL", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.completion.CompletionPreselectionBehaviourProvider", "extensionPointNames": ["com.intellij.completion.preselectionBehaviourProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.completion.ml.ContextFeatureProvider", "extensionPointNames": ["com.intellij.completion.ml.contextFeatures"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.internal.ml.completion.RankingModelProvider", "extensionPointNames": ["com.intellij.completion.ml.model"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.completion.ml.ElementFeatureProvider", "extensionPointNames": ["com.intellij.completion.ml.elementFeatures"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.completion.PlainTextSymbolCompletionContributor", "extensionPointNames": ["com.intellij.completion.plainTextSymbol"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.lang.WordCompletionElementFilter", "extensionPointNames": ["com.intellij.codeInsight.wordCompletionFilter"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.completion.ml.MLFeatureProvider", "extensionPointNames": ["com.intellij.internal.ml.featureProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.modcompletion.ModCompletionItemProvider", "extensionPointNames": ["com.intellij.modcompletion.completionItemProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.modcompletion.ModCompletionItemFilter", "extensionPointNames": ["com.intellij.modcompletion.completionItemFilter"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.completion.command.CommandCompletionFactory", "extensionPointNames": ["com.intellij.codeInsight.completion.command.factory"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.completion.command.CommandProvider", "extensionPointNames": ["com.intellij.codeInsight.completion.command.provider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.completion.command.commands.IntentionCommandSkipper", "extensionPointNames": ["com.intellij.codeInsight.completion.intention.skipper"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.completion.command.commands.ErrorFixCommandProvider", "extensionPointNames": ["com.intellij.codeInsight.completion.error.intention"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.completion.command.commands.IntentionCommandOffsetProvider", "extensionPointNames": ["com.intellij.codeInsight.completion.intention.offset.provider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.lang.refactoring.RefactoringSupportProvider", "extensionPointNames": ["com.intellij.lang.refactoringSupport"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.lang.refactoring.NamesValidator", "extensionPointNames": ["com.intellij.lang.namesValidator"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.rename.RenameHandler", "extensionPointNames": ["com.intellij.renameHandler"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.rename.RenamePsiElementProcessorBase", "extensionPointNames": ["com.intellij.renamePsiElementProcessor"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.impl.file.UpdateAddedFileProcessor", "extensionPointNames": ["com.intellij.updateAddedFileProcessor"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.rename.naming.AutomaticRenamerFactory", "extensionPointNames": ["com.intellij.automaticRenamerFactory"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.rename.NameSuggestionProvider", "extensionPointNames": ["com.intellij.nameSuggestionProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.rename.RenamerFactory", "extensionPointNames": ["com.intellij.renamerFactory"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.RefactoringHelper", "extensionPointNames": ["com.intellij.refactoring.helper"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.lang.refactoring.InlineActionHandler", "extensionPointNames": ["com.intellij.inlineActionHandler"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.lang.refactoring.InlineHandler", "extensionPointNames": ["com.intellij.refactoring.inlineHandler"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.rename.ResolveSnapshotProvider", "extensionPointNames": ["com.intellij.rename.inplace.resolveSnapshotProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.rename.RenameInputValidator", "extensionPointNames": ["com.intellij.renameInputValidator"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.listeners.RefactoringElementListenerProvider", "extensionPointNames": ["com.intellij.refactoring.elementListenerProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.find.FindInProjectSearchEngine", "extensionPointNames": ["com.intellij.findInProjectSearchEngine"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.actions.QualifiedNameProvider", "extensionPointNames": ["com.intellij.qualifiedNameProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.actions.VirtualFileQualifiedNameProvider", "extensionPointNames": ["com.intellij.virtualFileQualifiedNameProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.roots.TestSourcesFilter", "extensionPointNames": ["com.intellij.testSourcesFilter"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.classMembers.ClassMembersRefactoringSupport", "extensionPointNames": ["com.intellij.lang.refactoringSupport.classMembersRefactoringSupport"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.copy.CopyHandlerDelegate", "extensionPointNames": ["com.intellij.refactoring.copyHandler"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.move.MoveHandlerDelegate", "extensionPointNames": ["com.intellij.refactoring.moveHandler"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.introduceParameterObject.IntroduceParameterObjectDelegate", "extensionPointNames": ["com.intellij.refactoring.introduceParameterObject"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.memberPushDown.PushDownDelegate", "extensionPointNames": ["com.intellij.refactoring.pushDown"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.move.moveClassesOrPackages.MoveDirectoryWithClassesHelper", "extensionPointNames": ["com.intellij.refactoring.moveDirectoryWithClassesHelper"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.safeDelete.SafeDeleteProcessorDelegate", "extensionPointNames": ["com.intellij.refactoring.safeDeleteProcessor"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.RefactoringActionHandler", "extensionPointNames": ["com.intellij.refactoring.extractIncludeHandler"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.changeSignature.ChangeSignatureUsageProcessor", "extensionPointNames": ["com.intellij.refactoring.changeSignatureUsageProcessor"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.move.moveFilesOrDirectories.MoveFileHandler", "extensionPointNames": ["com.intellij.moveFileHandler"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.rename.symbol.SymbolRenameTargetFactory", "extensionPointNames": ["com.intellij.rename.symbolRenameTargetFactory"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.actions.RenameFileActionProvider", "extensionPointNames": ["com.intellij.renameFileActionProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.changeSignature.inplace.LanguageChangeSignatureDetector", "extensionPointNames": ["com.intellij.changeSignatureDetector"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.suggested.SuggestedRefactoringSupport", "extensionPointNames": ["com.intellij.suggestedRefactoringSupport"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.changeSignature.ChangeSignatureUsageProvider", "extensionPointNames": ["com.intellij.changeSignature.usageProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeHighlighting.TextEditorHighlightingPassFactoryRegistrar", "extensionPointNames": ["com.intellij.highlightingPassFactory"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.RunConfigurationProducerSuppressor", "extensionPointNames": ["com.intellij.runConfigurationProducerSuppressor"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.search.IndexPatternProvider", "extensionPointNames": ["com.intellij.indexPatternProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInspection.reference.RefGraphAnnotator", "extensionPointNames": ["com.intellij.refGraphAnnotator"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.daemon.impl.HighlightVisitor", "extensionPointNames": ["com.intellij.highlightVisitor"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.daemon.impl.analysis.ErrorQuickFixProvider", "extensionPointNames": ["com.intellij.errorQuickFixProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.paths.PathReferenceProvider", "extensionPointNames": ["com.intellij.pathReferenceProvider", "com.intellij.anchorReferenceProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.paths.DynamicContextProvider", "extensionPointNames": ["com.intellij.dynamicContextProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider", "extensionPointNames": ["com.intellij.codeInsight.unresolvedReferenceQuickFixProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.lang.ExternalAnnotatorsFilter", "extensionPointNames": ["com.intellij.daemon.externalAnnotatorsFilter"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.daemon.ChangeLocalityDetector", "extensionPointNames": ["com.intellij.daemon.changeLocalityDetector"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.daemon.ImplicitUsageProvider", "extensionPointNames": ["com.intellij.implicitUsageProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.lang.injection.ConcatenationAwareInjector", "extensionPointNames": ["com.intellij.concatenationAwareInjector"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.injection.ReferenceInjector", "extensionPointNames": ["com.intellij.referenceInjector"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.lang.annotation.ExternalAnnotator", "extensionPointNames": ["com.intellij.externalAnnotator"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.lang.findUsages.FindUsagesProvider", "extensionPointNames": ["com.intellij.lang.findUsagesProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.lang.cacheBuilder.WordsScanner", "extensionPointNames": ["com.intellij.cacheBuilder"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.model.search.Searcher", "extensionPointNames": ["com.intellij.searcher"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.search.SearchScopeProvider", "extensionPointNames": ["com.intellij.searchScopesProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.util.gotoByName.GotoActionAliasMatcher", "extensionPointNames": ["com.intellij.gotoActionAliasMatcher"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.navigation.ChooseByNameContributor", "extensionPointNames": ["com.intellij.gotoClassContributor", "com.intellij.gotoSymbolContributor", "com.intellij.gotoFileContributor"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.navigation.GotoRelatedProvider", "extensionPointNames": ["com.intellij.gotoRelatedProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.navigation.AnonymousElementProvider", "extensionPointNames": ["com.intellij.anonymousElementProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributorFactory", "extensionPointNames": ["com.intellij.searchEverywhereContributor"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.actions.searcheverywhere.SEResultsEqualityProvider", "extensionPointNames": ["com.intellij.searchEverywhereResultsEqualityProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.actions.searcheverywhere.SearchEverywhereMlService", "extensionPointNames": ["com.intellij.searchEverywhereMlService"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.actions.searcheverywhere.SearchEverywhereMlContributorReplacement", "extensionPointNames": ["com.intellij.searchEverywhereMlContributorReplacement"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.actions.searcheverywhere.SearchEverywhereSpellingCorrectorFactory", "extensionPointNames": ["com.intellij.searchEverywhereSpellingCorrector"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.actions.searcheverywhere.SearchEverywhereEssentialContributorMarker", "extensionPointNames": ["com.intellij.searchEverywhereEssentialContributorsMarker"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.actions.searcheverywhere.remote.RemoteSearchEverywhereConverterSupplier", "extensionPointNames": ["com.intellij.searchEverywhereRemoteConverter"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.actions.searcheverywhere.SearchEverywhereReorderingService", "extensionPointNames": ["com.intellij.searchEverywhereReorderingService"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.actions.searcheverywhere.SearchEverywherePreviewPrimaryUsageFinder", "extensionPointNames": ["com.intellij.searchEverywherePreviewPrimaryUsageFinder"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.actions.SearchEverywhereManagerFactory", "extensionPointNames": ["com.intellij.searchEverywhere.manager"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.actions.runAnything.activity.RunAnythingProvider", "extensionPointNames": ["com.intellij.runAnything.executionProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.actions.runAnything.handlers.RunAnythingCommandHandler", "extensionPointNames": ["com.intellij.runAnything.commandHandler"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.actions.runAnything.groups.RunAnythingHelpGroup", "extensionPointNames": ["com.intellij.runAnything.helpGroup"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.actions.runAnything.commands.RunAnythingCommandCustomizer", "extensionPointNames": ["com.intellij.runAnything.commandCustomizer"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.highlighting.HighlightUsagesHandlerFactory", "extensionPointNames": ["com.intellij.highlightUsagesHandlerFactory"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.usages.UsageTargetProvider", "extensionPointNames": ["com.intellij.usageTargetProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.usages.UsageToPsiElementProvider", "extensionPointNames": ["com.intellij.usageToPsiElementProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.find.impl.FindInProjectExtension", "extensionPointNames": ["com.intellij.findInProjectExtension"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.model.psi.PsiSymbolDeclarationProvider", "extensionPointNames": ["com.intellij.psi.declarationProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.navigation.actions.TypeDeclarationProvider", "extensionPointNames": ["com.intellij.typeDeclarationProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.navigation.GotoTargetRendererProvider", "extensionPointNames": ["com.intellij.gotoTargetRendererProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.navigation.GotoTargetPresentationProvider", "extensionPointNames": ["com.intellij.gotoTargetPresentationProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.find.usages.symbol.SymbolSearchTargetFactory", "extensionPointNames": ["com.intellij.lang.symbolSearchTarget"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.find.findUsages.FindUsagesHandlerFactory", "extensionPointNames": ["com.intellij.findUsagesHandlerFactory"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.find.findUsages.CustomUsageSearcher", "extensionPointNames": ["com.intellij.customUsageSearcher"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.platform.ide.navigation.NavigationHandler", "extensionPointNames": ["com.intellij.navigation.navigationHandler"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.impl.RunConfigurationTemplateProvider", "extensionPointNames": ["com.intellij.runConfigurationTemplateProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.configurations.RunConfigurationsSettings", "extensionPointNames": ["com.intellij.runConfigurationsSettings"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.runners.ProgramRunner", "extensionPointNames": ["com.intellij.programRunner"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.task.ProjectTaskRunner", "extensionPointNames": ["com.intellij.projectTaskRunner"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.Executor", "extensionPointNames": ["com.intellij.executor"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.runToolbar.RunToolbarProcess", "extensionPointNames": ["com.intellij.runToolbarProcess"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.ExecutionTargetProvider", "extensionPointNames": ["com.intellij.executionTargetProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.BeforeRunTaskProvider", "extensionPointNames": ["com.intellij.stepsBeforeRunProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.impl.RunConfigurationBeforeRunProviderDelegate", "extensionPointNames": ["com.intellij.runConfigurationBeforeRunProviderDelegate"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.target.RunConfigurationTargetEnvironmentAdjuster$Factory", "extensionPointNames": ["com.intellij.runConfigurationTargetEnvironmentAdjusterFactory"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.target.TargetEnvironmentType", "extensionPointNames": ["com.intellij.executionTargetType"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.target.LanguageRuntimeType", "extensionPointNames": ["com.intellij.executionTargetLanguageRuntimeType"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.filters.ConsoleFilterProvider", "extensionPointNames": ["com.intellij.consoleFilterProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.filters.ConsoleInputFilterProvider", "extensionPointNames": ["com.intellij.consoleInputFilterProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.actions.ConsoleActionsPostProcessor", "extensionPointNames": ["com.intellij.consoleActionsPostProcessor"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.junit.RuntimeConfigurationProducer", "extensionPointNames": ["com.intellij.configurationProducer"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.lineMarker.RunLineMarkerContributor", "extensionPointNames": ["com.intellij.runLineMarkerContributor"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.actions.MultipleRunLocationsProvider", "extensionPointNames": ["com.intellij.multipleRunLocationsProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.dashboard.RunDashboardCustomizer", "extensionPointNames": ["com.intellij.runDashboardCustomizer"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.dashboard.LegacyRunDashboardServiceSubstitutor", "extensionPointNames": ["com.intellij.legacyRunDashboardServiceSubstitutor"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.dashboard.RunDashboardDefaultTypesProvider", "extensionPointNames": ["com.intellij.runDashboardDefaultTypesProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.navigation.MethodNavigationOffsetProvider", "extensionPointNames": ["com.intellij.methodNavigationOffsetProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.testIntegration.TestFinder", "extensionPointNames": ["com.intellij.testFinder"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.testIntegration.TestLocationProvider", "extensionPointNames": ["com.intellij.testSrcLocator"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.testIntegration.TestCreator", "extensionPointNames": ["com.intellij.testCreator"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.hierarchy.HierarchyProvider", "extensionPointNames": ["com.intellij.callHierarchyProvider", "com.intellij.methodHierarchyProvider", "com.intellij.typeHierarchyProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.TargetElementUtilExtender", "extensionPointNames": ["com.intellij.targetElementUtilExtender"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.TargetElementEvaluator", "extensionPointNames": ["com.intellij.targetElementEvaluator"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.impl.cache.impl.id.IdIndexer", "extensionPointNames": ["com.intellij.idIndexer"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.daemon.ProblemHighlightFilter", "extensionPointNames": ["com.intellij.problemHighlightFilter"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.filters.Filter", "extensionPointNames": ["com.intellij.analyzeStacktraceFilter"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.unscramble.StacktraceTabContentProvider", "extensionPointNames": ["com.intellij.analyzeStacktraceRunContentProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.actions.SearchEverywhereClassifier", "extensionPointNames": ["com.intellij.searchEverywhereClassifier"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.util.gotoByName.GotoFileCustomizer", "extensionPointNames": ["com.intellij.gotoFileCustomizer"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.util.fuzzyMatching.GotoFileFuzzyMatcherFactory", "extensionPointNames": ["com.intellij.gotoFileFuzzyMatcherFactory"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.slicer.SliceLanguageSupportProvider", "extensionPointNames": ["com.intellij.lang.sliceProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.console.ConsoleHistoryModelProvider", "extensionPointNames": ["com.intellij.consoleHistoryModelProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.execution.update.RunningApplicationUpdaterProvider", "extensionPointNames": ["com.intellij.runningApplicationUpdaterProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.hint.ImplementationViewSessionFactory", "extensionPointNames": ["com.intellij.implementationViewSessionFactory"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.hint.ImplementationViewDocumentFactory", "extensionPointNames": ["com.intellij.implementationViewDocumentFactory"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.platform.backend.documentation.DocumentationTargetProvider", "extensionPointNames": ["com.intellij.platform.backend.documentation.targetProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.platform.backend.documentation.SymbolDocumentationTargetProvider", "extensionPointNames": ["com.intellij.platform.backend.documentation.symbolTargetProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.platform.backend.documentation.PsiDocumentationTargetProvider", "extensionPointNames": ["com.intellij.platform.backend.documentation.psiTargetProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.platform.backend.documentation.LookupElementDocumentationTargetProvider", "extensionPointNames": ["com.intellij.platform.backend.documentation.lookupElementTargetProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.platform.backend.documentation.InlineDocumentationProvider", "extensionPointNames": ["com.intellij.platform.backend.documentation.inlineDocumentationProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.platform.backend.documentation.DocumentationLinkHandler", "extensionPointNames": ["com.intellij.platform.backend.documentation.linkHandler"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.refactoring.safeDelete.api.SafeDeleteTargetProvider", "extensionPointNames": ["com.intellij.safeDeleteTargetProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.navigation.DirectNavigationProvider", "extensionPointNames": ["com.intellij.lang.directNavigationProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.navigation.SymbolTypeProvider", "extensionPointNames": ["com.intellij.lang.symbolTypeProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.application.ApplicationListener", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.project.ProjectListener", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.project.ProjectCloseListener", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.project.VetoableProjectManagerListener", "extensionPointNames": [], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.projectView.TreeStructureProvider", "extensionPointNames": ["com.intellij.treeStructureProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.projectView.impl.AbstractProjectViewPane", "extensionPointNames": ["com.intellij.projectViewPane"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.projectView.impl.ProjectViewPaneSelectionHelper", "extensionPointNames": ["com.intellij.projectViewPaneSelectionHelper"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.projectView.ProjectViewNodeDecorator", "extensionPointNames": ["com.intellij.projectViewNodeDecorator"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.projectView.ProjectViewNestingRulesProvider", "extensionPointNames": ["com.intellij.projectViewNestingRulesProvider"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.intention.IntentionAction", "extensionPointNames": ["com.intellij.intentionAction"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.editor.actions.FlipCommaIntention.Flipper", "extensionPointNames": ["com.intellij.flipCommaIntention.flipper"], "targetModules": ["backend"], "restrictionKind": "genericPlatformApi"},
|
||||
|
||||
|
||||
|
||||
{"apiName": "com.intellij.lang.ParserDefinition", "extensionPointNames": ["com.intellij.lang.parserDefinition"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.psi.FileViewProviderFactory", "extensionPointNames": ["com.intellij.lang.fileViewProviderFactory"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.lang.ASTFactory", "extensionPointNames": ["com.intellij.lang.ast.factory", "lang.ast.factory"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.lang.PsiParser", "extensionPointNames": [], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.lexer.Lexer", "extensionPointNames": [], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.psi.LanguageInjector", "extensionPointNames": ["com.intellij.languageInjector"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.lang.injection.MultiHostInjector", "extensionPointNames": ["com.intellij.multiHostInjector"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.psi.ElementDescriptionProvider", "extensionPointNames": ["com.intellij.elementDescriptionProvider"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.psi.ElementManipulator", "extensionPointNames": ["com.intellij.lang.elementManipulator"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.openapi.editor.bidi.BidiRegionsSeparator", "extensionPointNames": ["com.intellij.bidiRegionsSeparator"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.openapi.editor.actions.WordBoundaryFilter", "extensionPointNames": ["com.intellij.wordBoundaryFilter"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.openapi.options.colors.ColorAndFontDescriptorsProvider", "extensionPointNames": ["com.intellij.colorAndFontDescriptorProvider"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.application.options.GeneralCodeStyleOptionsProvider", "extensionPointNames": ["com.intellij.generalCodeStyleOptionsProvider"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.psi.codeStyle.FileTypeIndentOptionsProvider", "extensionPointNames": ["com.intellij.fileTypeIndentOptionsProvider"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider", "extensionPointNames": ["com.intellij.langCodeStyleSettingsProvider"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.psi.codeStyle.LanguageCodeStyleSettingsContributor", "extensionPointNames": ["com.intellij.langCodeStyleSettingsContributor"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.psi.codeStyle.PredefinedCodeStyle", "extensionPointNames": ["com.intellij.predefinedCodeStyle"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.psi.templateLanguages.MultipleLangCommentProvider", "extensionPointNames": ["com.intellij.multiLangCommenter"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.psi.codeStyle.arrangement.Rearranger", "extensionPointNames": ["com.intellij.lang.rearranger"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.SelectionQuotingTypedHandler.UnquotingFilter", "extensionPointNames": ["com.intellij.selectionUnquotingFilter"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.openapi.editor.actions.FlipCommaIntention.Flipper", "extensionPointNames": ["com.intellij.flipCommaIntention.flipper"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.lang.Commenter", "extensionPointNames": ["com.intellij.lang.commenter"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.QuoteHandler", "extensionPointNames": ["com.intellij.quoteHandler", "com.intellij.lang.quoteHandler"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.TypedHandlerDelegate", "extensionPointNames": ["com.intellij.typedHandler"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.moveUpDown.StatementUpDownMover", "extensionPointNames": ["com.intellij.statementUpDownMover"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.formatting.InjectedFormattingOptionsProvider", "extensionPointNames": ["com.intellij.formatting.injectedOptions"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.lang.folding.FoldingBuilder", "extensionPointNames": ["com.intellij.lang.foldingBuilder"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.openapi.editor.IndentStrategy", "extensionPointNames": ["com.intellij.lang.indentStrategy"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.psi.codeStyle.lineIndent.LineIndentProvider", "extensionPointNames": ["com.intellij.lineIndentProvider"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.ExtendWordSelectionHandler", "extensionPointNames": ["com.intellij.extendWordSelectionHandler"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.moveLeftRight.MoveElementLeftRightHandler", "extensionPointNames": ["com.intellij.moveLeftRightHandler"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.JoinLinesHandlerDelegate", "extensionPointNames": ["com.intellij.joinLinesHandler"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.BackspaceModeOverride", "extensionPointNames": ["com.intellij.editor.backspaceModeOverride"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.TypingActionsExtension", "extensionPointNames": ["com.intellij.typingActionsExtension"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.BackspaceHandlerDelegate", "extensionPointNames": ["com.intellij.backspaceHandlerDelegate"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.CodeBlockProvider", "extensionPointNames": ["com.intellij.codeBlockProvider"], "targetModules": ["shared"]},
|
||||
{"apiName": "com.intellij.codeInsight.highlighting.CodeBlockSupportHandler", "extensionPointNames": ["com.intellij.codeBlockSupportHandler"], "targetModules": ["shared"]},
|
||||
// shared generic apis
|
||||
{"apiName": "com.intellij.lang.ParserDefinition", "extensionPointNames": ["com.intellij.lang.parserDefinition"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.FileViewProviderFactory", "extensionPointNames": ["com.intellij.lang.fileViewProviderFactory"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.lang.ASTFactory", "extensionPointNames": ["com.intellij.lang.ast.factory", "lang.ast.factory"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.lang.PsiParser", "extensionPointNames": [], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.lexer.Lexer", "extensionPointNames": [], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.LanguageInjector", "extensionPointNames": ["com.intellij.languageInjector"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.lang.injection.MultiHostInjector", "extensionPointNames": ["com.intellij.multiHostInjector"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.ElementManipulator", "extensionPointNames": ["com.intellij.lang.elementManipulator"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.editor.bidi.BidiRegionsSeparator", "extensionPointNames": ["com.intellij.bidiRegionsSeparator"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.editor.actions.WordBoundaryFilter", "extensionPointNames": ["com.intellij.wordBoundaryFilter"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.editor.LineWrapPositionStrategy", "extensionPointNames": ["com.intellij.lang.lineWrapStrategy"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.options.colors.ColorAndFontDescriptorsProvider", "extensionPointNames": ["com.intellij.colorAndFontDescriptorProvider"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.application.options.GeneralCodeStyleOptionsProvider", "extensionPointNames": ["com.intellij.generalCodeStyleOptionsProvider"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.codeStyle.FileTypeIndentOptionsProvider", "extensionPointNames": ["com.intellij.fileTypeIndentOptionsProvider"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider", "extensionPointNames": ["com.intellij.langCodeStyleSettingsProvider"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.codeStyle.LanguageCodeStyleSettingsContributor", "extensionPointNames": ["com.intellij.langCodeStyleSettingsContributor"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.codeStyle.PredefinedCodeStyle", "extensionPointNames": ["com.intellij.predefinedCodeStyle"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.templateLanguages.MultipleLangCommentProvider", "extensionPointNames": ["com.intellij.multiLangCommenter"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.codeStyle.arrangement.Rearranger", "extensionPointNames": ["com.intellij.lang.rearranger"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.SelectionQuotingTypedHandler.UnquotingFilter", "extensionPointNames": ["com.intellij.selectionUnquotingFilter"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.lang.Commenter", "extensionPointNames": ["com.intellij.lang.commenter"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.QuoteHandler", "extensionPointNames": ["com.intellij.quoteHandler", "com.intellij.lang.quoteHandler"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.TypedHandlerDelegate", "extensionPointNames": ["com.intellij.typedHandler"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.moveUpDown.StatementUpDownMover", "extensionPointNames": ["com.intellij.statementUpDownMover"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.formatting.InjectedFormattingOptionsProvider", "extensionPointNames": ["com.intellij.formatting.injectedOptions"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.lang.folding.FoldingBuilder", "extensionPointNames": ["com.intellij.lang.foldingBuilder"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.openapi.editor.IndentStrategy", "extensionPointNames": ["com.intellij.lang.indentStrategy"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.codeStyle.lineIndent.LineIndentProvider", "extensionPointNames": ["com.intellij.lineIndentProvider"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.ExtendWordSelectionHandler", "extensionPointNames": ["com.intellij.extendWordSelectionHandler"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.moveLeftRight.MoveElementLeftRightHandler", "extensionPointNames": ["com.intellij.moveLeftRightHandler"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.JoinLinesHandlerDelegate", "extensionPointNames": ["com.intellij.joinLinesHandler"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.BackspaceModeOverride", "extensionPointNames": ["com.intellij.editor.backspaceModeOverride"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.TypingActionsExtension", "extensionPointNames": ["com.intellij.typingActionsExtension"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.BackspaceHandlerDelegate", "extensionPointNames": ["com.intellij.backspaceHandlerDelegate"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.CodeBlockProvider", "extensionPointNames": ["com.intellij.codeBlockProvider"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.highlighting.CodeBlockSupportHandler", "extensionPointNames": ["com.intellij.codeBlockSupportHandler"], "targetModules": ["shared"], "restrictionKind": "genericPlatformApi"},
|
||||
|
||||
|
||||
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.CopyPastePostProcessor", "extensionPointNames": ["com.intellij.copyPastePostProcessor"], "targetModules": ["backend", "shared"]},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.CopyPastePreProcessor", "extensionPointNames": ["com.intellij.copyPastePreProcessor"], "targetModules": ["backend", "shared"]},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.PreserveIndentOnPasteBean", "extensionPointNames": ["com.intellij.preserveIndentOnPaste"], "targetModules": ["backend", "shared"]},
|
||||
{"apiName": "com.intellij.psi.impl.source.codeStyle.PreFormatProcessor", "extensionPointNames": ["com.intellij.preFormatProcessor"], "targetModules": ["backend", "shared"]},
|
||||
{"apiName": "com.intellij.psi.impl.source.codeStyle.PostFormatProcessor", "extensionPointNames": ["com.intellij.postFormatProcessor"], "targetModules": ["backend", "shared"]},
|
||||
{"apiName": "com.intellij.lang.CustomAutoFormatSyntaxErrorsVerifier", "extensionPointNames": ["com.intellij.lang.formatter.syntaxErrorsVerifier"], "targetModules": ["backend", "shared"]},
|
||||
{"apiName": "com.intellij.formatting.service.FormattingService", "extensionPointNames": ["com.intellij.formattingService"], "targetModules": ["backend", "shared"]},
|
||||
{"apiName": "com.intellij.ide.PasteProvider", "extensionPointNames": ["com.intellij.customPasteProvider"], "targetModules": ["backend", "shared"]},
|
||||
{"apiName": "com.intellij.formatting.FormattingModelBuilder", "extensionPointNames": ["com.intellij.lang.formatter"], "targetModules": ["backend", "shared"]},
|
||||
{"apiName": "com.intellij.lang.LanguageFormattingRestriction", "extensionPointNames": ["com.intellij.lang.formatter.restriction"], "targetModules": ["backend", "shared"]},
|
||||
{"apiName": "com.intellij.psi.formatter.WhiteSpaceFormattingStrategy", "extensionPointNames": ["com.intellij.lang.whiteSpaceFormattingStrategy"], "targetModules": ["backend", "shared"]},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.enter.EnterBetweenBracesDelegate", "extensionPointNames": ["com.intellij.enterBetweenBracesDelegate"], "targetModules": ["backend", "shared"]},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegate", "extensionPointNames": ["com.intellij.enterHandlerDelegate"], "targetModules": ["backend", "shared"]},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegateAdapter", "extensionPointNames": ["com.intellij.enterHandlerDelegate"], "targetModules": ["backend", "shared"]},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.smartEnter.SmartEnterProcessor", "extensionPointNames": ["com.intellij.lang.smartEnterProcessor"], "targetModules": ["backend", "shared"]},
|
||||
{"apiName": "com.intellij.codeInsight.highlighting.BraceMatcher", "extensionPointNames": ["com.intellij.braceMatcher", "com.intellij.lang.braceMatcher"], "targetModules": ["backend", "shared"]},
|
||||
// backend or shared generic apis - ideally shared (better UX), but depending on implementation may require resolve, so backend is also allowed
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.CopyPastePostProcessor", "extensionPointNames": ["com.intellij.copyPastePostProcessor"], "targetModules": ["backend", "shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.CopyPastePreProcessor", "extensionPointNames": ["com.intellij.copyPastePreProcessor"], "targetModules": ["backend", "shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.PreserveIndentOnPasteBean", "extensionPointNames": ["com.intellij.preserveIndentOnPaste"], "targetModules": ["backend", "shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.impl.source.codeStyle.PreFormatProcessor", "extensionPointNames": ["com.intellij.preFormatProcessor"], "targetModules": ["backend", "shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.impl.source.codeStyle.PostFormatProcessor", "extensionPointNames": ["com.intellij.postFormatProcessor"], "targetModules": ["backend", "shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.lang.CustomAutoFormatSyntaxErrorsVerifier", "extensionPointNames": ["com.intellij.lang.formatter.syntaxErrorsVerifier"], "targetModules": ["backend", "shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.formatting.service.FormattingService", "extensionPointNames": ["com.intellij.formattingService"], "targetModules": ["backend", "shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.ide.PasteProvider", "extensionPointNames": ["com.intellij.customPasteProvider"], "targetModules": ["backend", "shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.formatting.FormattingModelBuilder", "extensionPointNames": ["com.intellij.lang.formatter"], "targetModules": ["backend", "shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.lang.LanguageFormattingRestriction", "extensionPointNames": ["com.intellij.lang.formatter.restriction"], "targetModules": ["backend", "shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.psi.formatter.WhiteSpaceFormattingStrategy", "extensionPointNames": ["com.intellij.lang.whiteSpaceFormattingStrategy"], "targetModules": ["backend", "shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.enter.EnterBetweenBracesDelegate", "extensionPointNames": ["com.intellij.enterBetweenBracesDelegate"], "targetModules": ["backend", "shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegate", "extensionPointNames": ["com.intellij.enterHandlerDelegate"], "targetModules": ["backend", "shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegateAdapter", "extensionPointNames": ["com.intellij.enterHandlerDelegate"], "targetModules": ["backend", "shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.editorActions.smartEnter.SmartEnterProcessor", "extensionPointNames": ["com.intellij.lang.smartEnterProcessor"], "targetModules": ["backend", "shared"], "restrictionKind": "genericPlatformApi"},
|
||||
{"apiName": "com.intellij.codeInsight.highlighting.BraceMatcher", "extensionPointNames": ["com.intellij.braceMatcher", "com.intellij.lang.braceMatcher"], "targetModules": ["backend", "shared"], "restrictionKind": "genericPlatformApi"},
|
||||
|
||||
|
||||
|
||||
{"apiName": "com.intellij.openapi.util.registry.RegistryValueListener", "extensionPointNames": [], "targetModules": ["frontend", "backend"], "hint": "Registry values are different on frontend and backend, prefer listening to them explicitly in desired IDE part"},
|
||||
{"apiName": "com.intellij.ide.plugins.DynamicPluginListener", "extensionPointNames": [], "targetModules": ["frontend", "backend"], "hint": "Plugin lists are different on frontend and backend, prefer listening to them explicitly in desired IDE part"},
|
||||
{"apiName": "com.intellij.openapi.options.Configurable", "extensionPointNames": ["com.intellij.applicationConfigurable", "com.intellij.projectConfigurable"], "targetModules": ["frontend", "backend"]},
|
||||
{"apiName": "com.intellij.lang.annotation.Annotator", "extensionPointNames": ["com.intellij.annotator"], "targetModules": ["frontend", "backend"], "hint": "Resolve-dependent annotators belong to the backend, while lightweight ones belong to frontend"},
|
||||
{"apiName": "com.intellij.lang.annotation.ContributedReferencesAnnotator", "extensionPointNames": ["com.intellij.contributedReferencesAnnotator"], "targetModules": ["frontend", "backend"], "hint": "Resolve-dependent annotators belong to the backend, while lightweight ones belong to frontend"},
|
||||
// frontend or backend generic apis - suggested to be explicitly registered in a dedicated module type to make sure the developer understands where the code is going to be executed.
|
||||
// example: shared plugin loading listener with logic touching VFS will not effectively work in frontend, so either there must be two different implementations, or a single registered where the necessary resources (VFS) exist
|
||||
{"apiName": "com.intellij.openapi.util.registry.RegistryValueListener", "extensionPointNames": [], "targetModules": ["frontend", "backend"], "restrictionKind": "genericPlatformApi", "hint": "Registry values are different on frontend and backend, prefer listening to them explicitly in desired IDE part"},
|
||||
{"apiName": "com.intellij.ide.plugins.DynamicPluginListener", "extensionPointNames": [], "targetModules": ["frontend", "backend"], "restrictionKind": "genericPlatformApi", "hint": "Plugin lists are different on frontend and backend, prefer listening to them explicitly in desired IDE part"},
|
||||
{"apiName": "com.intellij.lang.annotation.Annotator", "extensionPointNames": ["com.intellij.annotator"], "targetModules": ["frontend", "backend"], "restrictionKind": "genericPlatformApi", "hint": "Resolve-dependent annotators belong to the backend, while lightweight ones belong to frontend"},
|
||||
{"apiName": "com.intellij.lang.annotation.ContributedReferencesAnnotator", "extensionPointNames": ["com.intellij.contributedReferencesAnnotator"], "targetModules": ["frontend", "backend"], "restrictionKind": "genericPlatformApi", "hint": "Resolve-dependent annotators belong to the backend, while lightweight ones belong to frontend"},
|
||||
|
||||
|
||||
|
||||
{"apiName": "com.intellij.psi.codeStyle.arrangement.std.ArrangementUiComponent.Factory", "extensionPointNames": ["com.intellij.rearranger.ui"], "targetModules": ["frontend", "shared"], "hint": "Language supporting extensions belong to shared, if the language supports injections. Otherwise frontend."},
|
||||
{"apiName": "com.intellij.openapi.options.colors.ColorSettingsPage", "extensionPointNames": ["com.intellij.colorSettingsPage"], "targetModules": ["frontend", "shared"], "hint": "Language supporting extensions belong to shared, if the language supports injections. Otherwise frontend."},
|
||||
{"apiName": "com.intellij.application.options.colors.ColorAndFontPanelFactory", "extensionPointNames": ["com.intellij.colorAndFontPanelFactory"], "targetModules": ["frontend", "shared"], "hint": "Language supporting extensions belong to shared, if the language supports injections. Otherwise frontend."},
|
||||
{"apiName": "com.intellij.psi.codeStyle.CodeStyleSettingsProvider", "extensionPointNames": ["com.intellij.codeStyleSettingsProvider"], "targetModules": ["frontend", "shared"], "hint": "Language supporting extensions belong to shared, if the language supports injections. Otherwise frontend."},
|
||||
{"apiName": "com.intellij.openapi.fileTypes.SyntaxHighlighter", "extensionPointNames": ["com.intellij.syntaxHighlighter", "com.intellij.lang.syntaxHighlighter"], "targetModules": ["frontend", "shared"], "hint": "Language supporting extensions belong to shared, if the language supports injections. Otherwise frontend."},
|
||||
{"apiName": "com.intellij.openapi.fileTypes.SyntaxHighlighterFactory", "extensionPointNames": ["com.intellij.lang.syntaxHighlighterFactory"], "targetModules": ["frontend", "shared"], "hint": "Language supporting extensions belong to shared, if the language supports injections. Otherwise frontend."},
|
||||
{"apiName": "com.intellij.openapi.fileTypes.EditorHighlighterProvider", "extensionPointNames": ["com.intellij.editorHighlighterProvider"], "targetModules": ["frontend", "shared"], "hint": "Language supporting extensions belong to shared, if the language supports injections. Otherwise frontend."}
|
||||
]
|
||||
// frontend or shared generic apis
|
||||
{"apiName": "com.intellij.openapi.options.colors.ColorSettingsPage", "extensionPointNames": ["com.intellij.colorSettingsPage"], "targetModules": ["frontend", "shared"], "restrictionKind": "genericPlatformApi", "hint": "Language supporting extensions belong to shared, if the language supports injections. Otherwise frontend."},
|
||||
{"apiName": "com.intellij.application.options.colors.ColorAndFontPanelFactory", "extensionPointNames": ["com.intellij.colorAndFontPanelFactory"], "targetModules": ["frontend", "shared"], "restrictionKind": "genericPlatformApi", "hint": "Language supporting extensions belong to shared, if the language supports injections. Otherwise frontend."},
|
||||
{"apiName": "com.intellij.psi.codeStyle.CodeStyleSettingsProvider", "extensionPointNames": ["com.intellij.codeStyleSettingsProvider"], "targetModules": ["frontend", "shared"], "restrictionKind": "genericPlatformApi", "hint": "Language supporting extensions belong to shared, if the language supports injections. Otherwise frontend."},
|
||||
{"apiName": "com.intellij.openapi.fileTypes.SyntaxHighlighter", "extensionPointNames": ["com.intellij.syntaxHighlighter", "com.intellij.lang.syntaxHighlighter"], "targetModules": ["frontend", "shared"], "restrictionKind": "genericPlatformApi", "hint": "Language supporting extensions belong to shared, if the language supports injections. Otherwise frontend."},
|
||||
{"apiName": "com.intellij.openapi.fileTypes.SyntaxHighlighterFactory", "extensionPointNames": ["com.intellij.lang.syntaxHighlighterFactory"], "targetModules": ["frontend", "shared"], "restrictionKind": "genericPlatformApi", "hint": "Language supporting extensions belong to shared, if the language supports injections. Otherwise frontend."},
|
||||
{"apiName": "com.intellij.openapi.fileTypes.EditorHighlighterProvider", "extensionPointNames": ["com.intellij.editorHighlighterProvider"], "targetModules": ["frontend", "shared"], "restrictionKind": "genericPlatformApi", "hint": "Language supporting extensions belong to shared, if the language supports injections. Otherwise frontend."}
|
||||
]
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"exclusions": [
|
||||
{
|
||||
"inspection": "SplitModeApiUsage",
|
||||
"file": "community/python/python-type-engine/src/com/intellij/python/typeEngine/PyTypeEngineStatusBarWidget.kt",
|
||||
"line": 49,
|
||||
"reason": "PY-90092: Python LSP/type-engine tools were moved from PyCharm Pro into PyCharm Community. The type engine status bar widget is monolith-only UI that has not been split into frontend/backend yet."
|
||||
},
|
||||
{
|
||||
"inspection": "SplitModeApiUsage",
|
||||
"file": "community/python/python-type-engine/src/com/intellij/python/typeEngine/PyTypeEngineStatusBarWidget.kt",
|
||||
"line": 132,
|
||||
"reason": "PY-90092: JBPopupFactory usage in the monolith-only Python type engine status bar widget (not yet split for remote dev)."
|
||||
},
|
||||
{
|
||||
"inspection": "SplitModeXmlApiUsage",
|
||||
"file": "community/python/python-type-engine/resources/intellij.python.typeEngine.xml",
|
||||
"line": 42,
|
||||
"reason": "PY-90092: statusBarWidgetFactory registration for the monolith-only Python type engine widget (not yet split for remote dev)."
|
||||
}
|
||||
]
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
// Monorepo features that are not inspected by DevKit split-mode inspections yet.
|
||||
// This file is the source of truth for SplitModeExcludedModules.xml IDE scopes.
|
||||
// Use pathPatterns for repository paths and moduleNames for IntelliJ module names.\
|
||||
|
||||
// After making changes to this file run the SplitModeExcludedModulesScopeConsistencyTest
|
||||
// and apply changes to the config files generated from the MonorepoFeaturesWithoutSplitModeSupport.json5
|
||||
{
|
||||
pathPatterns: [
|
||||
"plugins/llm//*",
|
||||
"plugins/llm-experimental//*",
|
||||
"plugins/llm-installer//*",
|
||||
"plugins/llm-sandbox//*",
|
||||
"community/python//*",
|
||||
"language-server//*"
|
||||
],
|
||||
|
||||
moduleNames: [
|
||||
"intellij.platform.resources",
|
||||
"intellij.platform.ui.jcef",
|
||||
"intellij.platform.util",
|
||||
"intellij.platform.projectModel",
|
||||
"intellij.platform.projectModel.impl",
|
||||
"intellij.platform.refactoring",
|
||||
"intellij.platform.split",
|
||||
"intellij.platform.split.connection",
|
||||
"intellij.platform.ide.bootstrap",
|
||||
"intellij.platform.ide.core",
|
||||
"intellij.platform.ide.core.impl",
|
||||
"intellij.platform.ide.impl",
|
||||
"intellij.platform.indexing",
|
||||
"intellij.platform.indexing.impl",
|
||||
"intellij.platform.lang",
|
||||
"intellij.platform.lang.core",
|
||||
"intellij.platform.lang.impl",
|
||||
"intellij.platform.editor.ex",
|
||||
"intellij.platform.editor.ui",
|
||||
"intellij.platform.frontend.split",
|
||||
"intellij.platform.frontend.split.base",
|
||||
"intellij.platform.ide",
|
||||
"intellij.platform.analysis",
|
||||
"intellij.platform.analysis.impl",
|
||||
"intellij.platform.backend.split",
|
||||
"intellij.platform.codeStyle",
|
||||
"intellij.platform.codeStyle.impl",
|
||||
"intellij.platform.commercial",
|
||||
"intellij.platform.commercial.license",
|
||||
"intellij.platform.completion.common",
|
||||
"intellij.platform.core",
|
||||
"intellij.platform.core.impl",
|
||||
],
|
||||
}
|
||||
-190
@@ -1,190 +0,0 @@
|
||||
[
|
||||
{"moduleName": "intellij.platform.monolith", "moduleKind": "monolith"},
|
||||
|
||||
{"moduleName": "intellij.platform.frontend", "moduleKind": "frontend"},
|
||||
{"moduleName": "intellij.platform.frontend.split", "moduleKind": "frontend"},
|
||||
{"moduleName": "intellij.platform.plugins.frontend.split", "moduleKind": "frontend"},
|
||||
{"moduleName": "com.intellij.jetbrains.client", "moduleKind": "frontend"},
|
||||
{"moduleName": "com.intellij.jetbrains.client.git", "moduleKind": "frontend"},
|
||||
{"moduleName": "intellij.cwm.frontend", "moduleKind": "frontend"},
|
||||
{"moduleName": "intellij.cwm.connection.frontend.split", "moduleKind": "frontend"},
|
||||
|
||||
{"moduleName": "intellij.platform.backend", "moduleKind": "backend"},
|
||||
{"moduleName": "intellij.platform.backend.split", "moduleKind": "backend"},
|
||||
{"moduleName": "intellij.platform.kernel.backend", "moduleKind": "backend"},
|
||||
{"moduleName": "com.jetbrains.remoteDevelopment", "moduleKind": "backend"},
|
||||
{"moduleName": "intellij.cwm", "moduleKind": "backend"},
|
||||
{"moduleName": "intellij.cwm.plugin", "moduleKind": "backend"},
|
||||
{"moduleName": "intellij.cwm.plugin.provisioner", "moduleKind": "backend"},
|
||||
{"moduleName": "intellij.cwm.connection.backend", "moduleKind": "backend"},
|
||||
{"moduleName": "intellij.cwm.connection.backend.license", "moduleKind": "backend"},
|
||||
{"moduleName": "intellij.cwm.vcs", "moduleKind": "backend"},
|
||||
{"moduleName": "intellij.cwm.enabler", "moduleKind": "backend"},
|
||||
{"moduleName": "intellij.cwm.enabler.core", "moduleKind": "backend"},
|
||||
{"moduleName": "intellij.codeWithMe.abstract.main", "moduleKind": "backend"},
|
||||
{"moduleName": "intellij.codeWithMe.idea.community.main", "moduleKind": "backend"},
|
||||
{"moduleName": "intellij.codeWithMe.idea.ultimate.main.android", "moduleKind": "backend"},
|
||||
{"moduleName": "intellij.codeWithMe.datagrip.main", "moduleKind": "backend"},
|
||||
{"moduleName": "intellij.codeWithMe.pycharm.community.main", "moduleKind": "backend"},
|
||||
{"moduleName": "intellij.codeWithMe.appcode.main", "moduleKind": "backend"},
|
||||
|
||||
{"moduleName": "intellij.cwm.connection", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.cwm.plugin.common", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.rd.client.base", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.rd.client", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.driver.client", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.driver.impl", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.driver.model", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.driver.sdk", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.analysis", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.analysis.impl", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.boot", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.bootstrap", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.bootstrap.coroutine", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.bootstrap.dev", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.buildScripts", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.buildScripts.api", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.buildScripts.bazel", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.buildScripts.codeOptimizer", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.buildScripts.devBuildServer", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.buildScripts.downloader", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.buildScripts.licenses", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.buildScripts.productDsl", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.buildScripts.usages", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.codeStyle", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.codeStyle.impl", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.concurrency", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.configurationStore.impl", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.core", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.core.impl", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.core.nio.fs", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.core.ui", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.diagnostic", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.diagnostic.freezeAnalyzer", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.diagnostic.startUpPerformanceReporter", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.diagnostic.telemetry", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.diagnostic.telemetry.agent.extension", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.diagnostic.telemetry.exporters", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.diagnostic.telemetry.impl", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.diagnostic.telemetry.rt", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.editor", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.editor.ex", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.editor.ui", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.eel", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.eel.codegen", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.eel.impl", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.eel.impl.base", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.eel.nioFs", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.eel.nioFs.impl", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.eel.provider", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.eel.tcp", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.eelHelper", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.extensions", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.foldings", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.icons", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.icons.api", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.icons.api.rendering", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.icons.impl", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.icons.impl.intellij", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.ide", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.ide.bootstrap", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.ide.bootstrap.eel", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.ide.bootstrap.kernel", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.ide.codeinsight.inline", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.ide.concurrency", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.ide.core", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.ide.core.impl", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.ide.core.plugins", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.ide.impl", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.ide.internal", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.ide.rpc", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.ide.ui", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.ide.util.io", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.ide.util.io.impl", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.ide.util.netty", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.kernel", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.kernel.impl", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.lang", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.lang.core", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.lang.impl", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.locking.impl", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.project", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.runtime.repository", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.base", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.base.multiplatform", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.classLoader", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.commonsLangV2Shim", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.coroutines", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.diff", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.ex", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.http", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.immutableKeyValueStore", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.immutableKeyValueStore.benchmark", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.io.storages", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.jdom", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.multiplatform", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.nanoxml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.progress", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.rt", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.rt.java8", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.text.matching", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.trove", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.troveCompileOnly", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.ui", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.xmlDom", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.util.zip", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.remoteDev.util", "moduleKind": "shared"},
|
||||
|
||||
{"pluginId": "com.intellij.modules.ultimate", "moduleKind": "shared"},
|
||||
{"pluginId": "com.intellij.modules.lang", "moduleKind": "shared"},
|
||||
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/PlatformLangPlugin.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/PlatformLangComponents.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/idea/PriorityEditorLangActions.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/idea/PlatformActions.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/PlatformExecutionActions.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/idea/ExecutionActions.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/idea/LangActions.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/idea/UsageViewActions.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/idea/ProblemsViewActions.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/Core.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/CoreImpl.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/Analysis.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/AnalysisImpl.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/WorkspaceModel.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/WorkspaceModelImpl.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/ProjectModel.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/ProjectModelImpl.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/ProjectModelPlatform.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/Indexing.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/Editor.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/EditorEx.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/IdeCore.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/PlatformExtensionPoints.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/MinimapExtensionPoints.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/Refactoring.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/LangExtensionPoints.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/PlatformExtensions.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/PlatformExecutionExtensions.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/LangExtensions.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/ProjectModelLangExtensions.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/SearchEverywhereCodeInsightContributors.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/OpenTelemetryExtensions.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/WorkspaceModelExtensions.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/intellij.platform.feedback.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/IJent.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/intellij.platform.syntax.psi.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/CompletionExtensionPoints.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/RefactoringExtensionPoints.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/RefactoringLangExtensionPoints.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/FormatterExtensionPoints.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/EditorExtensionPoints.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/CodeStyle.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/META-INF/RemoteDevUtil.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/intellij.platform.project.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/intellij.platform.ide.progress.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.platform.resources", "descriptorRelativePath": "src/intellij.platform.experiment.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.rd.client.base", "descriptorRelativePath": "resources/intellij.rd.client.base.xml", "moduleKind": "shared"},
|
||||
{"moduleName": "intellij.rd.client", "descriptorRelativePath": "resources/intellij.rd.client.xml", "moduleKind": "shared"}
|
||||
]
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// The file carries the current project baseline version for Split Mode Compatibility safe-push checks.
|
||||
// Increase currentProjectBaselineVersion only when incremental Split Mode Compatibility tests incorrectly
|
||||
// report pre-existing violations after large refactorings.
|
||||
// Changing this value is a legal bypass: the affected safe push may skip the incremental Split Mode
|
||||
// Compatibility tests for that run, allowing the refactoring to proceed while the baseline catches up.
|
||||
// Do not use it for real new violations. Fix those instead; see Split Mode documentation IJPL-A-632.
|
||||
// Contact the RemDev team in #ij-remote-dev if unsure.
|
||||
{
|
||||
"currentProjectBaselineVersion": 12
|
||||
}
|
||||
+1
-404
@@ -1,406 +1,3 @@
|
||||
{
|
||||
"moduleNames": [
|
||||
"intellij.ml.llm",
|
||||
"intellij.ml.llm.activation",
|
||||
"intellij.ml.llm.activation.config",
|
||||
"intellij.ml.llm.activation.data.mock",
|
||||
"intellij.ml.llm.activation.data.model",
|
||||
"intellij.ml.llm.activation.data.repos",
|
||||
"intellij.ml.llm.activation.facade",
|
||||
"intellij.ml.llm.activation.facade.impl",
|
||||
"intellij.ml.llm.activation.ij",
|
||||
"intellij.ml.llm.activation.ij.daemon",
|
||||
"intellij.ml.llm.activation.ij.grazie",
|
||||
"intellij.ml.llm.activation.platform",
|
||||
"intellij.ml.llm.activation.platform.tests",
|
||||
"intellij.ml.llm.activation.presentation",
|
||||
"intellij.ml.llm.activation.presentation.tests",
|
||||
"intellij.ml.llm.activation.state.impl",
|
||||
"intellij.ml.llm.activation.state.impl.tests",
|
||||
"intellij.ml.llm.activation.state.manager",
|
||||
"intellij.ml.llm.activation.state.model",
|
||||
"intellij.ml.llm.activation.tests.runtime",
|
||||
"intellij.ml.llm.activation.util",
|
||||
"intellij.ml.llm.activation.util.tests",
|
||||
"intellij.ml.llm.agents",
|
||||
"intellij.ml.llm.agents.acp",
|
||||
"intellij.ml.llm.agents.acp.embeddedMcp",
|
||||
"intellij.ml.llm.agents.acp.embeddedMcp.tests",
|
||||
"intellij.ml.llm.agents.acp.json",
|
||||
"intellij.ml.llm.agents.acp.tests",
|
||||
"intellij.ml.llm.agents.acp.view.tests",
|
||||
"intellij.ml.llm.agents.contrib",
|
||||
"intellij.ml.llm.agents.contrib.contract",
|
||||
"intellij.ml.llm.agents.contrib.ide.datagrip",
|
||||
"intellij.ml.llm.agents.contrib.ide.idea",
|
||||
"intellij.ml.llm.agents.contrib.ide.pycharm",
|
||||
"intellij.ml.llm.agents.contrib.ide.rider",
|
||||
"intellij.ml.llm.agents.contrib.ide.rubymine",
|
||||
"intellij.ml.llm.agents.contrib.ide.rubymine.tests",
|
||||
"intellij.ml.llm.agents.contrib.shared.vcs",
|
||||
"intellij.ml.llm.agents.contrib.tests",
|
||||
"intellij.ml.llm.agents.frontend",
|
||||
"intellij.ml.llm.agents.frontend.tests",
|
||||
"intellij.ml.llm.agents.impl",
|
||||
"intellij.ml.llm.agents.impl.tests",
|
||||
"intellij.ml.llm.agents.shared",
|
||||
"intellij.ml.llm.agents.skills",
|
||||
"intellij.ml.llm.agents.skills.tests",
|
||||
"intellij.ml.llm.android",
|
||||
"intellij.ml.llm.android.tests",
|
||||
"intellij.ml.llm.apiTestsWithJava",
|
||||
"intellij.ml.llm.aui.events",
|
||||
"intellij.ml.llm.aui.events.tests",
|
||||
"intellij.ml.llm.automation",
|
||||
"intellij.ml.llm.build",
|
||||
"intellij.ml.llm.chat",
|
||||
"intellij.ml.llm.chat.completion",
|
||||
"intellij.ml.llm.chat.completion.tests",
|
||||
"intellij.ml.llm.chat.frontend",
|
||||
"intellij.ml.llm.chat.history.migration",
|
||||
"intellij.ml.llm.chat.shared",
|
||||
"intellij.ml.llm.chat.tests",
|
||||
"intellij.ml.llm.chat.testsWithKotlin",
|
||||
"intellij.ml.llm.chatInputLanguage",
|
||||
"intellij.ml.llm.chatInputLanguage.grazie",
|
||||
"intellij.ml.llm.chatInputLanguage.markdown",
|
||||
"intellij.ml.llm.chatInputLanguage.tests",
|
||||
"intellij.ml.llm.chatInputLanguage.testsWithJava",
|
||||
"intellij.ml.llm.chatInputLanguage.testsWithKotlin",
|
||||
"intellij.ml.llm.cloudEnabledTests",
|
||||
"intellij.ml.llm.cloudEnabledTests.withJava",
|
||||
"intellij.ml.llm.cloudEnabledTests.withMcp",
|
||||
"intellij.ml.llm.codeEngine",
|
||||
"intellij.ml.llm.codeEngine.tests",
|
||||
"intellij.ml.llm.codeGeneration",
|
||||
"intellij.ml.llm.codeGeneration.tests",
|
||||
"intellij.ml.llm.completion",
|
||||
"intellij.ml.llm.completion.cloud.testFramework",
|
||||
"intellij.ml.llm.completion.latest",
|
||||
"intellij.ml.llm.completion.nextEdits.proxy",
|
||||
"intellij.ml.llm.completion.testFramework",
|
||||
"intellij.ml.llm.completion.tests",
|
||||
"intellij.ml.llm.content",
|
||||
"intellij.ml.llm.context",
|
||||
"intellij.ml.llm.context.airules",
|
||||
"intellij.ml.llm.context.airules.tests",
|
||||
"intellij.ml.llm.context.ide",
|
||||
"intellij.ml.llm.context.llm",
|
||||
"intellij.ml.llm.context.runtime",
|
||||
"intellij.ml.llm.context.runtime.jvm",
|
||||
"intellij.ml.llm.context.runtime.jvm.tests",
|
||||
"intellij.ml.llm.contextRankerFeatures",
|
||||
"intellij.ml.llm.core",
|
||||
"intellij.ml.llm.core.grazieClient",
|
||||
"intellij.ml.llm.core.httpClient",
|
||||
"intellij.ml.llm.core.tests",
|
||||
"intellij.ml.llm.core.tests.runtime",
|
||||
"intellij.ml.llm.cpp",
|
||||
"intellij.ml.llm.cpp.cmake",
|
||||
"intellij.ml.llm.cpp.common",
|
||||
"intellij.ml.llm.cpp.completion",
|
||||
"intellij.ml.llm.cpp.nextEdits.backend",
|
||||
"intellij.ml.llm.cpp.tests",
|
||||
"intellij.ml.llm.cpp.testsClassic",
|
||||
"intellij.ml.llm.css",
|
||||
"intellij.ml.llm.css.completion",
|
||||
"intellij.ml.llm.css.less.completion",
|
||||
"intellij.ml.llm.css.nextEdits.backend",
|
||||
"intellij.ml.llm.css.postcss.completion",
|
||||
"intellij.ml.llm.css.sass.completion",
|
||||
"intellij.ml.llm.css.tests",
|
||||
"intellij.ml.llm.devkit",
|
||||
"intellij.ml.llm.devkit.tests",
|
||||
"intellij.ml.llm.diagram.frontend",
|
||||
"intellij.ml.llm.domains",
|
||||
"intellij.ml.llm.domains.ide",
|
||||
"intellij.ml.llm.editor.backend",
|
||||
"intellij.ml.llm.editor.common",
|
||||
"intellij.ml.llm.editor.frontend",
|
||||
"intellij.ml.llm.embeddings",
|
||||
"intellij.ml.llm.embeddings.latest",
|
||||
"intellij.ml.llm.embeddings.tests",
|
||||
"intellij.ml.llm.erb.completion",
|
||||
"intellij.ml.llm.erb.completion.tests",
|
||||
"intellij.ml.llm.experimental",
|
||||
"intellij.ml.llm.experimental.aidiff",
|
||||
"intellij.ml.llm.experimental.aidiff.tests",
|
||||
"intellij.ml.llm.experimental.build",
|
||||
"intellij.ml.llm.experimental.insights",
|
||||
"intellij.ml.llm.experimental.insights.java",
|
||||
"intellij.ml.llm.experimental.insights.kotlin",
|
||||
"intellij.ml.llm.experimental.insights.provenance",
|
||||
"intellij.ml.llm.experimental.insights.python",
|
||||
"intellij.ml.llm.experimental.insights.tests",
|
||||
"intellij.ml.llm.experimental.recap",
|
||||
"intellij.ml.llm.experimental.recap.tests",
|
||||
"intellij.ml.llm.experiments",
|
||||
"intellij.ml.llm.experiments.platformAb",
|
||||
"intellij.ml.llm.experiments.platformAb.tests",
|
||||
"intellij.ml.llm.experiments.tests",
|
||||
"intellij.ml.llm.figma",
|
||||
"intellij.ml.llm.git.nextEdits.backend",
|
||||
"intellij.ml.llm.github",
|
||||
"intellij.ml.llm.github.latest",
|
||||
"intellij.ml.llm.gitlab",
|
||||
"intellij.ml.llm.go",
|
||||
"intellij.ml.llm.go.completion",
|
||||
"intellij.ml.llm.go.embeddings",
|
||||
"intellij.ml.llm.go.inlinePromptDetector",
|
||||
"intellij.ml.llm.go.inlinePromptDetector.tests",
|
||||
"intellij.ml.llm.go.nextEdits.backend",
|
||||
"intellij.ml.llm.go.tests",
|
||||
"intellij.ml.llm.gradle",
|
||||
"intellij.ml.llm.groovy.inlinePromptDetector",
|
||||
"intellij.ml.llm.html.completion",
|
||||
"intellij.ml.llm.html.nextEdits.backend",
|
||||
"intellij.ml.llm.html.tests",
|
||||
"intellij.ml.llm.httpClient",
|
||||
"intellij.ml.llm.idea.product.modules",
|
||||
"intellij.ml.llm.ideolog",
|
||||
"intellij.ml.llm.inlinePromptDetector",
|
||||
"intellij.ml.llm.inlinePromptDetector.tests",
|
||||
"intellij.ml.llm.integration.testFramework",
|
||||
"intellij.ml.llm.integration.testFramework.tests",
|
||||
"intellij.ml.llm.integration.tests",
|
||||
"intellij.ml.llm.java",
|
||||
"intellij.ml.llm.java.completion",
|
||||
"intellij.ml.llm.java.domains",
|
||||
"intellij.ml.llm.java.embeddings",
|
||||
"intellij.ml.llm.java.embeddings.tests",
|
||||
"intellij.ml.llm.java.inlinePromptDetector",
|
||||
"intellij.ml.llm.java.inlinePromptDetector.tests",
|
||||
"intellij.ml.llm.java.nextEdits.backend",
|
||||
"intellij.ml.llm.java.tests",
|
||||
"intellij.ml.llm.javaee",
|
||||
"intellij.ml.llm.javaee.jpa",
|
||||
"intellij.ml.llm.javaee.spring",
|
||||
"intellij.ml.llm.javaee.spring.completion",
|
||||
"intellij.ml.llm.javaee.spring.data",
|
||||
"intellij.ml.llm.javaee.spring.mvc",
|
||||
"intellij.ml.llm.javaee.spring.security",
|
||||
"intellij.ml.llm.javascript",
|
||||
"intellij.ml.llm.javascript.astro",
|
||||
"intellij.ml.llm.javascript.astro.completion",
|
||||
"intellij.ml.llm.javascript.astro.nextEdits.backend",
|
||||
"intellij.ml.llm.javascript.completion",
|
||||
"intellij.ml.llm.javascript.embeddings",
|
||||
"intellij.ml.llm.javascript.inlinePromptDetector",
|
||||
"intellij.ml.llm.javascript.latest",
|
||||
"intellij.ml.llm.javascript.nextEdits.backend",
|
||||
"intellij.ml.llm.javascript.nextEdits.ultimate.backend",
|
||||
"intellij.ml.llm.javascript.svelte",
|
||||
"intellij.ml.llm.javascript.svelte.completion",
|
||||
"intellij.ml.llm.javascript.svelte.nextEdits.backend",
|
||||
"intellij.ml.llm.javascript.tests",
|
||||
"intellij.ml.llm.javascript.vue",
|
||||
"intellij.ml.llm.javascript.vue.completion",
|
||||
"intellij.ml.llm.javascript.vue.nextEdits.backend",
|
||||
"intellij.ml.llm.json.completion",
|
||||
"intellij.ml.llm.json.nextEdits.backend",
|
||||
"intellij.ml.llm.json.tests",
|
||||
"intellij.ml.llm.jupyter.common",
|
||||
"intellij.ml.llm.jupyter.common.nextEdits.backend",
|
||||
"intellij.ml.llm.jupyter.common.nextEdits.frontend",
|
||||
"intellij.ml.llm.jupyter.kotlin",
|
||||
"intellij.ml.llm.jupyter.kotlin.completion",
|
||||
"intellij.ml.llm.jupyter.python",
|
||||
"intellij.ml.llm.jupyter.python.completion",
|
||||
"intellij.ml.llm.jupyter.python.nextEdits.backend",
|
||||
"intellij.ml.llm.jupyter.python.tests",
|
||||
"intellij.ml.llm.jupyter.tests",
|
||||
"intellij.ml.llm.kotlin",
|
||||
"intellij.ml.llm.kotlin.completion",
|
||||
"intellij.ml.llm.kotlin.embeddings",
|
||||
"intellij.ml.llm.kotlin.inlinePromptDetector",
|
||||
"intellij.ml.llm.kotlin.j2k",
|
||||
"intellij.ml.llm.kotlin.nextEdits.backend",
|
||||
"intellij.ml.llm.kotlin.tests",
|
||||
"intellij.ml.llm.libraries.grazie",
|
||||
"intellij.ml.llm.libraries.grazie.cloud",
|
||||
"intellij.ml.llm.libraries.jcp",
|
||||
"intellij.ml.llm.libraries.junie.a2a",
|
||||
"intellij.ml.llm.libraries.molecule",
|
||||
"intellij.ml.llm.licensetool",
|
||||
"intellij.ml.llm.localization",
|
||||
"intellij.ml.llm.logicalStructure",
|
||||
"intellij.ml.llm.markdown.completion",
|
||||
"intellij.ml.llm.markdown.completion.tests",
|
||||
"intellij.ml.llm.markdown.nextEdits.backend",
|
||||
"intellij.ml.llm.maven",
|
||||
"intellij.ml.llm.mcp",
|
||||
"intellij.ml.llm.mcp.embedded",
|
||||
"intellij.ml.llm.mcp.json",
|
||||
"intellij.ml.llm.mcp.perforce",
|
||||
"intellij.ml.llm.mcp.tests",
|
||||
"intellij.ml.llm.mdx.nextEdits.backend",
|
||||
"intellij.ml.llm.microservices",
|
||||
"intellij.ml.llm.nextEdits.acp.backend",
|
||||
"intellij.ml.llm.nextEdits.agents.backend",
|
||||
"intellij.ml.llm.nextEdits.backend",
|
||||
"intellij.ml.llm.nextEdits.common",
|
||||
"intellij.ml.llm.nextEdits.frontend",
|
||||
"intellij.ml.llm.nextEdits.monolith",
|
||||
"intellij.ml.llm.nextEdits.testFramework",
|
||||
"intellij.ml.llm.nextEdits.tests",
|
||||
"intellij.ml.llm.performanceTesting",
|
||||
"intellij.ml.llm.performanceTesting.embeddings",
|
||||
"intellij.ml.llm.performanceTesting.embeddings.commands",
|
||||
"intellij.ml.llm.php",
|
||||
"intellij.ml.llm.php.completion",
|
||||
"intellij.ml.llm.php.embeddings",
|
||||
"intellij.ml.llm.php.inlinePromptDetector",
|
||||
"intellij.ml.llm.php.inlinePromptDetector.tests",
|
||||
"intellij.ml.llm.php.mcp",
|
||||
"intellij.ml.llm.php.mcp.tests",
|
||||
"intellij.ml.llm.php.nextEdits.backend",
|
||||
"intellij.ml.llm.php.tests",
|
||||
"intellij.ml.llm.platform",
|
||||
"intellij.ml.llm.playground",
|
||||
"intellij.ml.llm.playground.latest",
|
||||
"intellij.ml.llm.privacy",
|
||||
"intellij.ml.llm.privacy.filter",
|
||||
"intellij.ml.llm.privacy.shared",
|
||||
"intellij.ml.llm.privacy.shared.tests",
|
||||
"intellij.ml.llm.privacy.tests",
|
||||
"intellij.ml.llm.properties.completion",
|
||||
"intellij.ml.llm.properties.completion.tests",
|
||||
"intellij.ml.llm.provider",
|
||||
"intellij.ml.llm.provider.anthropic",
|
||||
"intellij.ml.llm.provider.google",
|
||||
"intellij.ml.llm.provider.lmstudio",
|
||||
"intellij.ml.llm.provider.ollama",
|
||||
"intellij.ml.llm.provider.ollama.tests",
|
||||
"intellij.ml.llm.provider.openai",
|
||||
"intellij.ml.llm.provider.openai.tests",
|
||||
"intellij.ml.llm.python",
|
||||
"intellij.ml.llm.python.completion",
|
||||
"intellij.ml.llm.python.domains",
|
||||
"intellij.ml.llm.python.embeddings",
|
||||
"intellij.ml.llm.python.inlinePromptDetector",
|
||||
"intellij.ml.llm.python.nextEdits.backend",
|
||||
"intellij.ml.llm.python.tests",
|
||||
"intellij.ml.llm.python.ultimate",
|
||||
"intellij.ml.llm.qodana",
|
||||
"intellij.ml.llm.qodana.agents",
|
||||
"intellij.ml.llm.qodana.agents.tests",
|
||||
"intellij.ml.llm.qodana.common",
|
||||
"intellij.ml.llm.qodana.inspectionKts",
|
||||
"intellij.ml.llm.qodana.inspectionKts.tests",
|
||||
"intellij.ml.llm.qodana.inspectionsGenerator",
|
||||
"intellij.ml.llm.rbs.completion",
|
||||
"intellij.ml.llm.rbs.completion.tests",
|
||||
"intellij.ml.llm.rider",
|
||||
"intellij.ml.llm.rider.cpp",
|
||||
"intellij.ml.llm.rider.cpp.completion",
|
||||
"intellij.ml.llm.rider.cpp.nextEdits.backend",
|
||||
"intellij.ml.llm.rider.csharp",
|
||||
"intellij.ml.llm.rider.csharp.completion",
|
||||
"intellij.ml.llm.rider.csharp.inlinePromptDetector",
|
||||
"intellij.ml.llm.rider.csharp.nextEdits.backend",
|
||||
"intellij.ml.llm.rider.csharp.razor",
|
||||
"intellij.ml.llm.rider.dotTools",
|
||||
"intellij.ml.llm.rider.fsharp",
|
||||
"intellij.ml.llm.rider.fsharp.completion",
|
||||
"intellij.ml.llm.rider.godot.completion",
|
||||
"intellij.ml.llm.rider.hlsl.completion",
|
||||
"intellij.ml.llm.rider.shaderlab.completion",
|
||||
"intellij.ml.llm.rider.unrealengine.completion",
|
||||
"intellij.ml.llm.ruby",
|
||||
"intellij.ml.llm.ruby.completion",
|
||||
"intellij.ml.llm.ruby.embeddings",
|
||||
"intellij.ml.llm.ruby.embeddings.tests",
|
||||
"intellij.ml.llm.ruby.inlinePromptDetector",
|
||||
"intellij.ml.llm.ruby.inlinePromptDetector.tests",
|
||||
"intellij.ml.llm.ruby.mcp",
|
||||
"intellij.ml.llm.ruby.mcp.tests",
|
||||
"intellij.ml.llm.ruby.nextEdits.backend",
|
||||
"intellij.ml.llm.ruby.test",
|
||||
"intellij.ml.llm.rust",
|
||||
"intellij.ml.llm.rust.completion",
|
||||
"intellij.ml.llm.rust.nextEdits.backend",
|
||||
"intellij.ml.llm.rust.test",
|
||||
"intellij.ml.llm.sandbox",
|
||||
"intellij.ml.llm.sandbox.build",
|
||||
"intellij.ml.llm.sandbox.selfReviewDaemon",
|
||||
"intellij.ml.llm.sandbox.spec",
|
||||
"intellij.ml.llm.sandbox.spec.mcp",
|
||||
"intellij.ml.llm.sandbox.spec.wysiwyg",
|
||||
"intellij.ml.llm.searchEverywhere",
|
||||
"intellij.ml.llm.searchEverywhere.embeddings",
|
||||
"intellij.ml.llm.searchEverywhere.embeddings.datagrip",
|
||||
"intellij.ml.llm.searchEverywhere.embeddings.radler",
|
||||
"intellij.ml.llm.searchEverywhere.embeddings.rider",
|
||||
"intellij.ml.llm.searchEverywhere.embeddings.rider.tests",
|
||||
"intellij.ml.llm.searchEverywhere.tests",
|
||||
"intellij.ml.llm.sh",
|
||||
"intellij.ml.llm.smartChat",
|
||||
"intellij.ml.llm.smartChat.embeddings",
|
||||
"intellij.ml.llm.space",
|
||||
"intellij.ml.llm.space.latest",
|
||||
"intellij.ml.llm.sql",
|
||||
"intellij.ml.llm.sql.completion",
|
||||
"intellij.ml.llm.sql.completion.tests",
|
||||
"intellij.ml.llm.sql.datagrip",
|
||||
"intellij.ml.llm.sql.embeddings",
|
||||
"intellij.ml.llm.sql.inlinePromptDetector",
|
||||
"intellij.ml.llm.sql.inlinePromptDetector.tests",
|
||||
"intellij.ml.llm.sql.tests",
|
||||
"intellij.ml.llm.starter",
|
||||
"intellij.ml.llm.starter.tests",
|
||||
"intellij.ml.llm.tasks",
|
||||
"intellij.ml.llm.telemetry",
|
||||
"intellij.ml.llm.terminal",
|
||||
"intellij.ml.llm.terminal.completion",
|
||||
"intellij.ml.llm.terminal.completion.tests",
|
||||
"intellij.ml.llm.terminal.context",
|
||||
"intellij.ml.llm.terminal.context.tests",
|
||||
"intellij.ml.llm.terminal.tests",
|
||||
"intellij.ml.llm.terraform.completion",
|
||||
"intellij.ml.llm.tests",
|
||||
"intellij.ml.llm.testsWithKotlinAndJava",
|
||||
"intellij.ml.llm.testsWithPython",
|
||||
"intellij.ml.llm.text.completion",
|
||||
"intellij.ml.llm.textmate",
|
||||
"intellij.ml.llm.textmate.tests",
|
||||
"intellij.ml.llm.tokenizer",
|
||||
"intellij.ml.llm.tokenizer.tests",
|
||||
"intellij.ml.llm.uiTestGeneration",
|
||||
"intellij.ml.llm.vcs",
|
||||
"intellij.ml.llm.vcs.completion",
|
||||
"intellij.ml.llm.vcs.completion.tests",
|
||||
"intellij.ml.llm.vcs.core",
|
||||
"intellij.ml.llm.vcs.latest",
|
||||
"intellij.ml.llm.vcs.markdown",
|
||||
"intellij.ml.llm.vcs.tests",
|
||||
"intellij.ml.llm.voice",
|
||||
"intellij.ml.llm.xdebugger.completion",
|
||||
"intellij.ml.llm.xdebugger.completion.tests",
|
||||
"intellij.ml.llm.xml.completion",
|
||||
"intellij.ml.llm.xml.nextEdits.backend",
|
||||
"intellij.ml.llm.xml.tests",
|
||||
"intellij.ml.llm.yaml.completion",
|
||||
"intellij.ml.llm.yaml.inlinePromptDetector",
|
||||
"intellij.ml.llm.yaml.inlinePromptDetector.tests",
|
||||
"intellij.ml.llm.yaml.javaee.spring.completion",
|
||||
"intellij.ml.llm.yaml.json.completion",
|
||||
"intellij.ml.llm.yaml.nextEdits.backend",
|
||||
"intellij.ml.llm.yaml.tests",
|
||||
"intellij.platform.recentFiles",
|
||||
"intellij.platform.recentFiles.backend",
|
||||
"intellij.platform.recentFiles.frontend",
|
||||
"intellij.platform.recentFiles.plugin",
|
||||
"intellij.swagger",
|
||||
"intellij.swagger.codegen",
|
||||
"intellij.swagger.core",
|
||||
"intellij.swagger.core.tests",
|
||||
"intellij.swagger.endpoints",
|
||||
"intellij.swagger.endpoints.tests",
|
||||
"intellij.swagger.gradle",
|
||||
"intellij.swagger.java",
|
||||
"intellij.swagger.maven",
|
||||
"intellij.hibernate.debugger",
|
||||
"intellij.hibernate.debugger.core",
|
||||
"intellij.hibernate.debugger.ide"
|
||||
]
|
||||
"moduleNames": []
|
||||
}
|
||||
|
||||
@@ -25,11 +25,9 @@ final class PluginDescriptorDomFileDescription extends DomFileDescription<IdeaPl
|
||||
IdeaPlugin ideaPlugin = DescriptorUtil.getIdeaPlugin(file);
|
||||
if (ideaPlugin == null) return null;
|
||||
|
||||
if (SplitModeModuleKindIcons.isCustomIconsEnabled()) {
|
||||
Icon splitModeIcon = SplitModeModuleKindIcons.getDescriptorIcon(file);
|
||||
if (splitModeIcon != null) {
|
||||
return splitModeIcon;
|
||||
}
|
||||
Icon splitModeIcon = SplitModeModuleKindIcons.getDescriptorIcon(file);
|
||||
if (splitModeIcon != null) {
|
||||
return splitModeIcon;
|
||||
}
|
||||
|
||||
if (ideaPlugin.isV2Descriptor()) {
|
||||
|
||||
+3
-10
@@ -45,23 +45,16 @@ internal class MissingFrontendOrBackendRuntimeDependencyInspection : DevKitPlugi
|
||||
val requiredModuleKind = recognizeExplicitDependencyKind(requiredRuntimeDependency)
|
||||
?: error("Unsupported split-mode runtime dependency: $requiredRuntimeDependency")
|
||||
val reportedElement = if (dependencies.exists()) dependencies else element
|
||||
val reportedXmlElement = reportedElement.xmlElement ?: return
|
||||
if (reportedElement.xmlElement == null) return
|
||||
val currentXmlFile = holder.fileElement.file
|
||||
if (SplitModeInspectionExclusionsService.getInstance(currentXmlFile.project).isExcluded(reportedXmlElement,
|
||||
MISSING_RUNTIME_DEPENDENCY_SHORT_NAME)) {
|
||||
return
|
||||
}
|
||||
val regularFixes = arrayOf(
|
||||
SplitModeDependencyQuickFixes.createAddExplicitDependencyFix(
|
||||
currentModuleName,
|
||||
requiredModuleKind,
|
||||
)
|
||||
)
|
||||
val suppressionFix = SplitModeInspectionExclusionsService.getInstance(currentXmlFile.project).createSuppressionFixIfApplicable(
|
||||
reportedXmlElement,
|
||||
MISSING_RUNTIME_DEPENDENCY_SHORT_NAME,
|
||||
)
|
||||
val fixes = if (suppressionFix != null) regularFixes + suppressionFix else regularFixes
|
||||
val suppressionFixes = SplitModeInspectionExclusionsService.getInstance(currentXmlFile.project).createCommonSuppressionQuickFixes()
|
||||
val fixes = regularFixes + suppressionFixes
|
||||
holder.createProblem(
|
||||
reportedElement,
|
||||
message(
|
||||
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@file:Suppress("HardCodedStringLiteral")
|
||||
|
||||
package org.jetbrains.idea.devkit.inspections.remotedev
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException
|
||||
import com.fasterxml.jackson.core.json.JsonReadFeature
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.SerializationException
|
||||
import kotlinx.serialization.json.Json
|
||||
import java.io.IOException
|
||||
|
||||
internal const val MONOREPO_FEATURES_WITHOUT_SPLIT_MODE_SUPPORT_FILE_NAME: String = "MonorepoFeaturesWithoutSplitModeSupport.json5"
|
||||
internal const val MONOREPO_FEATURES_WITHOUT_SPLIT_MODE_SUPPORT_RESOURCE_PATH: String =
|
||||
"remotedevInspectionData/$MONOREPO_FEATURES_WITHOUT_SPLIT_MODE_SUPPORT_FILE_NAME"
|
||||
internal const val MONOREPO_FEATURES_WITHOUT_SPLIT_MODE_SUPPORT_RELATIVE_PATH: String =
|
||||
"community/plugins/devkit/devkit-core/resources/$MONOREPO_FEATURES_WITHOUT_SPLIT_MODE_SUPPORT_RESOURCE_PATH"
|
||||
|
||||
internal const val SPLIT_MODE_EXCLUDED_MODULES_SCOPE_FILE_NAME: String = "SplitModeExcludedModules.xml"
|
||||
internal val SPLIT_MODE_EXCLUDED_MODULES_SCOPE_RELATIVE_PATHS: List<String> = listOf(
|
||||
".idea/scopes/$SPLIT_MODE_EXCLUDED_MODULES_SCOPE_FILE_NAME",
|
||||
".idea.bazel/scopes/$SPLIT_MODE_EXCLUDED_MODULES_SCOPE_FILE_NAME",
|
||||
)
|
||||
|
||||
internal fun createSplitModeExcludedModulesScopeXml(
|
||||
resourceReader: SplitModeInspectionResourceReader,
|
||||
readMode: SplitModeInspectionResourceReadMode,
|
||||
): String {
|
||||
val configurationText = requireNotNull(
|
||||
resourceReader.readText(MONOREPO_FEATURES_WITHOUT_SPLIT_MODE_SUPPORT_RESOURCE_PATH, readMode)
|
||||
) {
|
||||
"Cannot load $MONOREPO_FEATURES_WITHOUT_SPLIT_MODE_SUPPORT_RELATIVE_PATH"
|
||||
}
|
||||
return createSplitModeExcludedModulesScopeXml(configurationText)
|
||||
}
|
||||
|
||||
internal fun createSplitModeExcludedModulesScopeXml(json5Text: String): String {
|
||||
val configuration = parseMonorepoFeaturesWithoutSplitModeSupport(json5Text)
|
||||
val scopePattern = createSplitModeExcludedModulesScopePattern(configuration)
|
||||
return """
|
||||
<component name="DependencyValidationManager">
|
||||
<scope name="SplitModeExcludedModules" pattern="${scopePattern.escapeXmlAttributeValue()}" />
|
||||
</component>
|
||||
""".trimIndent() + "\n"
|
||||
}
|
||||
|
||||
private fun parseMonorepoFeaturesWithoutSplitModeSupport(json5Text: String): MonorepoFeaturesWithoutSplitModeSupportFile {
|
||||
val normalizedJson = try {
|
||||
json5.readTree(json5Text).toString()
|
||||
}
|
||||
catch (e: JsonProcessingException) {
|
||||
throw IllegalArgumentException("Cannot parse $MONOREPO_FEATURES_WITHOUT_SPLIT_MODE_SUPPORT_RELATIVE_PATH", e)
|
||||
}
|
||||
catch (e: IOException) {
|
||||
throw IllegalArgumentException("Cannot parse $MONOREPO_FEATURES_WITHOUT_SPLIT_MODE_SUPPORT_RELATIVE_PATH", e)
|
||||
}
|
||||
|
||||
val configuration = try {
|
||||
json.decodeFromString<MonorepoFeaturesWithoutSplitModeSupportFile>(normalizedJson)
|
||||
}
|
||||
catch (e: SerializationException) {
|
||||
throw IllegalArgumentException("Cannot parse $MONOREPO_FEATURES_WITHOUT_SPLIT_MODE_SUPPORT_RELATIVE_PATH", e)
|
||||
}
|
||||
catch (e: IllegalArgumentException) {
|
||||
throw IllegalArgumentException("Cannot parse $MONOREPO_FEATURES_WITHOUT_SPLIT_MODE_SUPPORT_RELATIVE_PATH", e)
|
||||
}
|
||||
|
||||
validateEntries("pathPatterns", configuration.pathPatterns) { entry ->
|
||||
require(!entry.startsWith("file:")) {
|
||||
"pathPatterns entries must not include the generated 'file:' prefix: $entry"
|
||||
}
|
||||
}
|
||||
validateEntries("moduleNames", configuration.moduleNames) { entry ->
|
||||
require('/' !in entry && '[' !in entry && ']' !in entry) {
|
||||
"moduleNames entries must be raw module names: $entry"
|
||||
}
|
||||
}
|
||||
return configuration
|
||||
}
|
||||
|
||||
private fun createSplitModeExcludedModulesScopePattern(configuration: MonorepoFeaturesWithoutSplitModeSupportFile): String {
|
||||
val pathPatterns = configuration.pathPatterns.map { "file:$it" }
|
||||
val modulePatterns = configuration.moduleNames.map { "file[$it]:*/" }
|
||||
val patterns = pathPatterns + modulePatterns
|
||||
require(patterns.isNotEmpty()) {
|
||||
"$MONOREPO_FEATURES_WITHOUT_SPLIT_MODE_SUPPORT_RELATIVE_PATH must define at least one pathPatterns or moduleNames entry"
|
||||
}
|
||||
require(patterns.size == patterns.toSet().size) {
|
||||
"$MONOREPO_FEATURES_WITHOUT_SPLIT_MODE_SUPPORT_RELATIVE_PATH contains entries that generate duplicate scope patterns"
|
||||
}
|
||||
return patterns.joinToString("||")
|
||||
}
|
||||
|
||||
private fun validateEntries(
|
||||
fieldName: String,
|
||||
entries: List<String>,
|
||||
validateEntry: (String) -> Unit,
|
||||
) {
|
||||
val duplicates = entries.groupingBy { it }.eachCount().filterValues { it > 1 }.keys
|
||||
require(duplicates.isEmpty()) {
|
||||
"$MONOREPO_FEATURES_WITHOUT_SPLIT_MODE_SUPPORT_RELATIVE_PATH contains duplicate $fieldName entries: ${duplicates.joinToString()}"
|
||||
}
|
||||
|
||||
for (entry in entries) {
|
||||
require(entry.isNotBlank()) {
|
||||
"$MONOREPO_FEATURES_WITHOUT_SPLIT_MODE_SUPPORT_RELATIVE_PATH contains blank $fieldName entry"
|
||||
}
|
||||
require(entry == entry.trim()) {
|
||||
"$MONOREPO_FEATURES_WITHOUT_SPLIT_MODE_SUPPORT_RELATIVE_PATH contains $fieldName entry with leading or trailing whitespace: $entry"
|
||||
}
|
||||
require("||" !in entry) {
|
||||
"$MONOREPO_FEATURES_WITHOUT_SPLIT_MODE_SUPPORT_RELATIVE_PATH entries must not contain scope pattern separators: $entry"
|
||||
}
|
||||
validateEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.escapeXmlAttributeValue(): String {
|
||||
return buildString(length) {
|
||||
for (character in this@escapeXmlAttributeValue) {
|
||||
when (character) {
|
||||
'&' -> append("&")
|
||||
'"' -> append(""")
|
||||
'<' -> append("<")
|
||||
'>' -> append(">")
|
||||
else -> append(character)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
private data class MonorepoFeaturesWithoutSplitModeSupportFile(
|
||||
@SerialName("pathPatterns")
|
||||
val pathPatterns: List<String> = emptyList(),
|
||||
|
||||
@SerialName("moduleNames")
|
||||
val moduleNames: List<String> = emptyList(),
|
||||
)
|
||||
|
||||
private val json5: ObjectMapper = JsonMapper.builder()
|
||||
.enable(
|
||||
JsonReadFeature.ALLOW_JAVA_COMMENTS,
|
||||
JsonReadFeature.ALLOW_SINGLE_QUOTES,
|
||||
JsonReadFeature.ALLOW_UNQUOTED_FIELD_NAMES,
|
||||
JsonReadFeature.ALLOW_TRAILING_COMMA,
|
||||
)
|
||||
.build()
|
||||
|
||||
private val json = Json {
|
||||
ignoreUnknownKeys = true
|
||||
isLenient = true
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
owner 'RD Split Kernel'
|
||||
+8
-13
@@ -17,7 +17,7 @@ import org.jetbrains.annotations.VisibleForTesting
|
||||
import org.jetbrains.idea.devkit.inspections.DevKitUastInspectionBase
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.SplitModeInspectionUtil.buildModuleKindMismatchMessage
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.SplitModeInspectionUtil.buildModuleKindMismatchTooltipMessage
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.analysis.SplitModeModuleKindResolver.doesApiKindMatchExpectedModuleKind
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.analysis.SplitModeModuleKindResolver.isApiUsageAllowed
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.analysis.ModuleAnalysis
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.analysis.SplitModeApiRestrictionsService
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.analysis.SplitModeQodanaInspectionScopeLimiter
|
||||
@@ -26,7 +26,6 @@ import org.jetbrains.uast.UCallExpression
|
||||
import org.jetbrains.uast.UClass
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UExpression
|
||||
import org.jetbrains.uast.UField
|
||||
import org.jetbrains.uast.UMethod
|
||||
import org.jetbrains.uast.UQualifiedReferenceExpression
|
||||
import org.jetbrains.uast.USimpleNameReferenceExpression
|
||||
@@ -38,7 +37,7 @@ import org.jetbrains.uast.visitor.AbstractUastVisitor
|
||||
|
||||
@VisibleForTesting
|
||||
@ApiStatus.Internal
|
||||
class SplitModeApiUsageInspection : DevKitUastInspectionBase(UClass::class.java, UField::class.java, UMethod::class.java) {
|
||||
class SplitModeApiUsageInspection : DevKitUastInspectionBase(UClass::class.java, UMethod::class.java) {
|
||||
|
||||
override fun isAllowed(holder: ProblemsHolder): Boolean {
|
||||
return super.isAllowed(holder)
|
||||
@@ -115,29 +114,25 @@ class SplitModeApiUsageInspection : DevKitUastInspectionBase(UClass::class.java,
|
||||
val resolvedApi = resolveApiUsage(expression) ?: return
|
||||
val sourcePsi = expression.sourcePsi ?: return
|
||||
val restrictionsService = SplitModeApiRestrictionsService.getInstance(sourcePsi.project)
|
||||
val expectedModuleKind = restrictionsService.getCodeApiKind(resolvedApi.qualifiedName, resolvedApi.owner) ?: return
|
||||
val apiRestriction = restrictionsService.getCodeApiRestriction(resolvedApi.qualifiedName, resolvedApi.owner) ?: return
|
||||
val expectedModuleKind = apiRestriction.targetModuleKind
|
||||
val currentModuleType = currentModuleAnalysis.resolvedModuleKind
|
||||
|
||||
if (!doesApiKindMatchExpectedModuleKind(currentModuleType, expectedModuleKind)) {
|
||||
if (!isApiUsageAllowed(currentModuleAnalysis, apiRestriction)) {
|
||||
val hint = restrictionsService.getCodeApiHint(resolvedApi.qualifiedName)
|
||||
val message = buildModuleKindMismatchMessage(resolvedApi.qualifiedName, expectedModuleKind, currentModuleType, hint)
|
||||
val tooltipMessage = buildModuleKindMismatchTooltipMessage(resolvedApi.qualifiedName, expectedModuleKind, currentModuleType, hint)
|
||||
val module = ModuleUtilCore.findModuleForPsiElement(sourcePsi) ?: return
|
||||
if (SplitModeInspectionExclusionsService.getInstance(sourcePsi.project).isExcluded(sourcePsi, SPLIT_MODE_API_USAGE_SHORT_NAME)) {
|
||||
return
|
||||
}
|
||||
val regularFixes = SplitModeDependencyQuickFixes.createMismatchFixes(module, null, expectedModuleKind)
|
||||
val suppressionFix =
|
||||
SplitModeInspectionExclusionsService.getInstance(sourcePsi.project).createSuppressionFixIfApplicable(sourcePsi,
|
||||
SPLIT_MODE_API_USAGE_SHORT_NAME)
|
||||
val fixes = if (suppressionFix != null) regularFixes + suppressionFix else regularFixes
|
||||
val suppressionFixes = SplitModeInspectionExclusionsService.getInstance(sourcePsi.project).createCommonSuppressionQuickFixes()
|
||||
val fixes = regularFixes + suppressionFixes
|
||||
|
||||
descriptors.add(
|
||||
manager.createProblemDescriptor(
|
||||
sourcePsi,
|
||||
null,
|
||||
message,
|
||||
ProblemHighlightType.WEAK_WARNING,
|
||||
ProblemHighlightType.WARNING,
|
||||
tooltipMessage,
|
||||
isOnTheFly,
|
||||
*fixes,
|
||||
|
||||
+29
-6
@@ -1,6 +1,7 @@
|
||||
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.idea.devkit.inspections.remotedev
|
||||
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewUtils
|
||||
import com.intellij.codeInspection.LocalQuickFix
|
||||
import com.intellij.codeInspection.ProblemDescriptor
|
||||
@@ -188,18 +189,29 @@ internal object SplitModeDependencyQuickFixes {
|
||||
|
||||
override fun startInWriteAction(): Boolean = IntentionPreviewUtils.isIntentionPreviewActive()
|
||||
|
||||
override fun generatePreview(project: Project, previewDescriptor: ProblemDescriptor): IntentionPreviewInfo {
|
||||
if (previewDescriptor.psiElement.containingFile !is XmlFile) {
|
||||
return IntentionPreviewInfo.EMPTY
|
||||
}
|
||||
return super.generatePreview(project, previewDescriptor)
|
||||
}
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val ideaPlugin = findQuickFixTargetDescriptor(descriptor) ?: return
|
||||
val module = findTargetModule(descriptor)
|
||||
val xmlFile = ideaPlugin.xmlElement?.containingFile ?: return
|
||||
if (!IntentionPreviewUtils.prepareElementForWrite(xmlFile)) return
|
||||
|
||||
if (IntentionPreviewUtils.isIntentionPreviewActive()) {
|
||||
applyDependencyFixInPreview(ideaPlugin, module, desiredModuleKind)
|
||||
if (IntentionPreviewUtils.isPreviewElement(xmlFile)) {
|
||||
applyDependencyFixInPreview(ideaPlugin, module, desiredModuleKind)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val commandName: @NlsContexts.Command String = message("inspection.remote.dev.make.only.kind.dependencies.fix.progress.title", desiredModuleKind.id)
|
||||
if (!IntentionPreviewUtils.prepareElementForWrite(xmlFile)) return
|
||||
|
||||
val commandName: @NlsContexts.Command String =
|
||||
message("inspection.remote.dev.make.only.kind.dependencies.fix.progress.title", desiredModuleKind.id)
|
||||
|
||||
runWithModalProgressBlocking(project, commandName) {
|
||||
applyDependencyFix(project, ideaPlugin, module, desiredModuleKind, commandName)
|
||||
@@ -223,18 +235,29 @@ internal object SplitModeDependencyQuickFixes {
|
||||
|
||||
override fun startInWriteAction(): Boolean = IntentionPreviewUtils.isIntentionPreviewActive()
|
||||
|
||||
override fun generatePreview(project: Project, previewDescriptor: ProblemDescriptor): IntentionPreviewInfo {
|
||||
if (previewDescriptor.psiElement.containingFile !is XmlFile) {
|
||||
return IntentionPreviewInfo.EMPTY
|
||||
}
|
||||
return super.generatePreview(project, previewDescriptor)
|
||||
}
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val ideaPlugin = findQuickFixTargetDescriptor(descriptor) ?: return
|
||||
val module = findTargetModule(descriptor)
|
||||
val xmlFile = ideaPlugin.xmlElement?.containingFile ?: return
|
||||
if (!IntentionPreviewUtils.prepareElementForWrite(xmlFile)) return
|
||||
|
||||
if (IntentionPreviewUtils.isIntentionPreviewActive()) {
|
||||
applyDependencyFixInPreview(ideaPlugin, module, desiredModuleKind)
|
||||
if (IntentionPreviewUtils.isPreviewElement(xmlFile)) {
|
||||
applyDependencyFixInPreview(ideaPlugin, module, desiredModuleKind)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val commandName: @NlsContexts.Command String = message("inspection.remote.dev.make.only.kind.dependencies.fix.progress.title", desiredModuleKind.id)
|
||||
if (!IntentionPreviewUtils.prepareElementForWrite(xmlFile)) return
|
||||
|
||||
val commandName: @NlsContexts.Command String =
|
||||
message("inspection.remote.dev.make.only.kind.dependencies.fix.progress.title", desiredModuleKind.id)
|
||||
|
||||
runWithModalProgressBlocking(project, commandName) {
|
||||
applyDependencyFix(project, ideaPlugin, module, desiredModuleKind, commandName)
|
||||
|
||||
+3
-9
@@ -28,11 +28,8 @@ internal class SplitModeImplicitModuleKindInspection : DevKitPluginXmlInspection
|
||||
|
||||
val module = element.module ?: return
|
||||
val currentXmlFile = holder.fileElement.file
|
||||
val xmlElement = element.xmlElement ?: return
|
||||
if (element.xmlElement == null) return
|
||||
val exclusionsService = SplitModeInspectionExclusionsService.getInstance(currentXmlFile.project)
|
||||
if (exclusionsService.isExcluded(xmlElement, SPLIT_MODE_IMPLICIT_MODULE_KIND_SHORT_NAME)) {
|
||||
return
|
||||
}
|
||||
|
||||
val moduleAnalysis = SplitModeModuleKindResolver.getOrComputeModuleAnalysis(module, currentXmlFile)
|
||||
if (!SplitModeInspectionUtil.isImplicitFrontendOrBackendMainPluginXml(currentXmlFile, moduleAnalysis)) {
|
||||
@@ -41,11 +38,8 @@ internal class SplitModeImplicitModuleKindInspection : DevKitPluginXmlInspection
|
||||
|
||||
val regularFixes =
|
||||
SplitModeDependencyQuickFixes.createAddExplicitDependenciesFixes(module, element, moduleAnalysis.resolvedModuleKind.kind)
|
||||
val suppressionFix = exclusionsService.createSuppressionFixIfApplicable(
|
||||
xmlElement,
|
||||
SPLIT_MODE_IMPLICIT_MODULE_KIND_SHORT_NAME,
|
||||
)
|
||||
val quickFixes = if (suppressionFix != null) regularFixes + suppressionFix else regularFixes
|
||||
val suppressionFixes = exclusionsService.createCommonSuppressionQuickFixes()
|
||||
val quickFixes = regularFixes + suppressionFixes
|
||||
holder.createProblem(
|
||||
element,
|
||||
ProblemHighlightType.WEAK_WARNING,
|
||||
|
||||
+64
-169
@@ -3,7 +3,6 @@
|
||||
|
||||
package org.jetbrains.idea.devkit.inspections.remotedev
|
||||
|
||||
import com.intellij.codeInsight.intention.FileModifier.SafeTypeForPreview
|
||||
import com.intellij.codeInsight.intention.LowPriorityAction
|
||||
import com.intellij.codeInspection.LocalQuickFix
|
||||
import com.intellij.codeInspection.ProblemDescriptor
|
||||
@@ -12,7 +11,6 @@ import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor
|
||||
import com.intellij.openapi.project.IntelliJProjectUtil
|
||||
import com.intellij.openapi.project.Project
|
||||
@@ -21,9 +19,8 @@ import com.intellij.openapi.vfs.VfsUtil
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.writeText
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.fasterxml.jackson.core.json.JsonReadFeature
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.SerializationException
|
||||
@@ -31,24 +28,9 @@ import kotlinx.serialization.json.Json
|
||||
import org.jetbrains.idea.devkit.DevKitBundle.message
|
||||
import java.io.IOException
|
||||
|
||||
internal const val EXCLUSIONS_FILE_NAME: String = "DevKitSplitModeInspectionExclusions.json"
|
||||
internal const val EXCLUSIONS_RESOURCE_PATH: String = "remotedevInspectionData/$EXCLUSIONS_FILE_NAME"
|
||||
internal const val EXCLUSIONS_RELATIVE_PATH: String =
|
||||
"community/plugins/devkit/devkit-core/resources/$EXCLUSIONS_RESOURCE_PATH"
|
||||
|
||||
internal const val SPLIT_MODE_API_USAGE_SHORT_NAME: String = "SplitModeApiUsage"
|
||||
internal const val SPLIT_MODE_XML_API_USAGE_SHORT_NAME: String = "SplitModeXmlApiUsage"
|
||||
internal const val SPLIT_MODE_MIXED_DEPENDENCIES_SHORT_NAME: String = "SplitModeMixedDependencies"
|
||||
internal const val SPLIT_MODE_IMPLICIT_MODULE_KIND_SHORT_NAME: String = "SplitModeImplicitModuleKind"
|
||||
internal const val MISSING_RUNTIME_DEPENDENCY_SHORT_NAME: String = "MissingFrontendOrBackendRuntimeDependency"
|
||||
|
||||
@SafeTypeForPreview
|
||||
internal data class SplitModeInspectionExclusionProblem(
|
||||
val inspection: String,
|
||||
val file: String,
|
||||
val line: Int,
|
||||
val reason: String = "",
|
||||
)
|
||||
internal const val PROJECT_BASELINE_VERSION_FILE_NAME: String = "SplitModeProjectBaselineVersion.json5"
|
||||
internal const val PROJECT_BASELINE_VERSION_RELATIVE_PATH: String =
|
||||
"community/plugins/devkit/devkit-core/resources/remotedevInspectionData/$PROJECT_BASELINE_VERSION_FILE_NAME"
|
||||
|
||||
@Service(Service.Level.PROJECT)
|
||||
internal class SplitModeInspectionExclusionsService(private val project: Project) {
|
||||
@@ -56,55 +38,22 @@ internal class SplitModeInspectionExclusionsService(private val project: Project
|
||||
fun getInstance(project: Project): SplitModeInspectionExclusionsService = project.service()
|
||||
}
|
||||
|
||||
private val resourceReader = SplitModeInspectionResourceReader.getInstance(project)
|
||||
|
||||
private val exclusionsResource = object : SplitModeInspectionReloadableResource<SplitModeInspectionExclusionsSnapshot>(
|
||||
resourceReader = resourceReader,
|
||||
resourcePath = EXCLUSIONS_RESOURCE_PATH,
|
||||
readMode = SplitModeInspectionResourceReadMode.PROJECT_ONLY,
|
||||
) {
|
||||
override fun parse(text: String): SplitModeInspectionExclusionsSnapshot {
|
||||
return SplitModeInspectionExclusionsSnapshot(parseExclusionsFile(text).exclusions)
|
||||
}
|
||||
|
||||
override fun getDefaultValue(): SplitModeInspectionExclusionsSnapshot {
|
||||
return SplitModeInspectionExclusionsSnapshot()
|
||||
}
|
||||
fun createCommonSuppressionQuickFixes(): Array<LocalQuickFix> {
|
||||
if (!isBaselineFixAvailable()) return LocalQuickFix.EMPTY_ARRAY
|
||||
return arrayOf(IncreaseSplitModeProjectBaselineVersionFix())
|
||||
}
|
||||
|
||||
fun createSuppressionFixIfApplicable(
|
||||
element: PsiElement,
|
||||
inspectionShortName: String,
|
||||
): LocalQuickFix? {
|
||||
if (!isExclusionFixAvailable()) return null
|
||||
val problem = createProblem(inspectionShortName, element) ?: return null
|
||||
return AddToSplitModeInspectionExclusionsFix(problem)
|
||||
fun increaseProjectBaselineVersion(): VirtualFile? {
|
||||
val baselineVersionFile = findOrCreateProjectBaselineVersionFile() ?: return null
|
||||
val currentFile = parseProjectBaselineVersionFile(VfsUtilCore.loadText(baselineVersionFile))
|
||||
val updatedFile = currentFile.copy(
|
||||
currentProjectBaselineVersion = currentFile.currentProjectBaselineVersion + 1,
|
||||
)
|
||||
baselineVersionFile.writeText(createProjectBaselineVersionJson5(updatedFile))
|
||||
return baselineVersionFile
|
||||
}
|
||||
|
||||
fun isExcluded(element: PsiElement, inspectionShortName: String): Boolean {
|
||||
val problem = createProblem(inspectionShortName, element) ?: return false
|
||||
return isExcluded(problem)
|
||||
}
|
||||
|
||||
fun isExcluded(problem: SplitModeInspectionExclusionProblem): Boolean {
|
||||
return getSnapshot().exclusions.any { it.matches(problem) }
|
||||
}
|
||||
|
||||
fun appendExclusion(problem: SplitModeInspectionExclusionProblem): VirtualFile? {
|
||||
val exclusionsFile = findOrCreateExclusionsFile() ?: return null
|
||||
val currentFile = SplitModeInspectionExclusionsFile(getSnapshot().exclusions)
|
||||
val newEntry = problem.toEntry()
|
||||
if (currentFile.exclusions.any { it.matches(newEntry) }) {
|
||||
return exclusionsFile
|
||||
}
|
||||
|
||||
val updatedFile = currentFile.copy(exclusions = currentFile.exclusions + newEntry)
|
||||
exclusionsFile.writeText(json.encodeToString(updatedFile) + "\n")
|
||||
exclusionsResource.invalidate()
|
||||
return exclusionsFile
|
||||
}
|
||||
|
||||
private fun isExclusionFixAvailable(): Boolean {
|
||||
private fun isBaselineFixAvailable(): Boolean {
|
||||
return IntelliJProjectUtil.isIntelliJPlatformProject(project) && getProjectRoot() != null
|
||||
}
|
||||
|
||||
@@ -112,152 +61,98 @@ internal class SplitModeInspectionExclusionsService(private val project: Project
|
||||
return project.guessProjectDir()
|
||||
}
|
||||
|
||||
private fun getProjectRelativePath(file: PsiFile): String? {
|
||||
val virtualFile = file.originalFile.virtualFile ?: file.virtualFile ?: return null
|
||||
val projectRoot = getProjectRoot() ?: return null
|
||||
return VfsUtilCore.getRelativePath(virtualFile, projectRoot, '/')
|
||||
}
|
||||
|
||||
private fun createProblem(
|
||||
inspectionShortName: String,
|
||||
element: PsiElement,
|
||||
): SplitModeInspectionExclusionProblem? {
|
||||
val file = element.containingFile ?: return null
|
||||
val filePath = getProjectRelativePath(file) ?: return null
|
||||
val line = getLineNumber(file, element) ?: return null
|
||||
return SplitModeInspectionExclusionProblem(
|
||||
inspection = inspectionShortName,
|
||||
file = filePath,
|
||||
line = line,
|
||||
reason = "",
|
||||
)
|
||||
}
|
||||
|
||||
private fun getLineNumber(file: PsiFile, element: PsiElement): Int? {
|
||||
val document = PsiDocumentManager.getInstance(file.project).getDocument(file)
|
||||
?: file.viewProvider.document
|
||||
?: return null
|
||||
return document.getLineNumber(element.textRange.startOffset) + 1
|
||||
}
|
||||
|
||||
private fun getSnapshot(): SplitModeInspectionExclusionsSnapshot {
|
||||
return exclusionsResource.getValue()
|
||||
}
|
||||
|
||||
private fun findOrCreateExclusionsFile(): VirtualFile? {
|
||||
private fun findOrCreateProjectBaselineVersionFile(): VirtualFile? {
|
||||
val projectRoot = getProjectRoot() ?: return null
|
||||
return try {
|
||||
val parentDirectory = VfsUtil.createDirectoryIfMissing(projectRoot, EXCLUSIONS_DIRECTORY_RELATIVE_PATH)
|
||||
parentDirectory.findChild(EXCLUSIONS_FILE_NAME)
|
||||
?: parentDirectory.createChildData(this, EXCLUSIONS_FILE_NAME).also { file ->
|
||||
file.writeText(INITIAL_EXCLUSIONS_JSON)
|
||||
parentDirectory.findChild(PROJECT_BASELINE_VERSION_FILE_NAME)
|
||||
?: parentDirectory.createChildData(this, PROJECT_BASELINE_VERSION_FILE_NAME).also { file ->
|
||||
file.writeText(createProjectBaselineVersionJson5(SplitModeProjectBaselineVersionFile(currentProjectBaselineVersion = 0)))
|
||||
}
|
||||
}
|
||||
catch (e: IOException) {
|
||||
LOG.warn("Cannot create $EXCLUSIONS_RELATIVE_PATH", e)
|
||||
LOG.warn("Cannot create $PROJECT_BASELINE_VERSION_RELATIVE_PATH", e)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseExclusionsFile(text: String): SplitModeInspectionExclusionsFile {
|
||||
private fun parseProjectBaselineVersionFile(text: String): SplitModeProjectBaselineVersionFile {
|
||||
if (text.isBlank()) {
|
||||
return SplitModeInspectionExclusionsFile()
|
||||
return SplitModeProjectBaselineVersionFile(currentProjectBaselineVersion = 0)
|
||||
}
|
||||
|
||||
return try {
|
||||
json.decodeFromString(text)
|
||||
val normalizedJson = json5.readTree(text).toString()
|
||||
json.decodeFromString(normalizedJson)
|
||||
}
|
||||
catch (e: SerializationException) {
|
||||
LOG.warn("Cannot parse $EXCLUSIONS_RELATIVE_PATH", e)
|
||||
SplitModeInspectionExclusionsFile()
|
||||
LOG.warn("Cannot parse $PROJECT_BASELINE_VERSION_RELATIVE_PATH", e)
|
||||
SplitModeProjectBaselineVersionFile(currentProjectBaselineVersion = 0)
|
||||
}
|
||||
catch (e: IOException) {
|
||||
LOG.warn("Cannot parse $PROJECT_BASELINE_VERSION_RELATIVE_PATH", e)
|
||||
SplitModeProjectBaselineVersionFile(currentProjectBaselineVersion = 0)
|
||||
}
|
||||
catch (e: IllegalArgumentException) {
|
||||
LOG.warn("Cannot parse $EXCLUSIONS_RELATIVE_PATH", e)
|
||||
SplitModeInspectionExclusionsFile()
|
||||
LOG.warn("Cannot parse $PROJECT_BASELINE_VERSION_RELATIVE_PATH", e)
|
||||
SplitModeProjectBaselineVersionFile(currentProjectBaselineVersion = 0)
|
||||
}
|
||||
}
|
||||
|
||||
private fun SplitModeInspectionExclusionEntry.matches(problem: SplitModeInspectionExclusionProblem): Boolean {
|
||||
if (inspection != problem.inspection) return false
|
||||
if (file != problem.file) return false
|
||||
if (line != problem.line) return false
|
||||
return true
|
||||
}
|
||||
|
||||
private fun SplitModeInspectionExclusionEntry.matches(other: SplitModeInspectionExclusionEntry): Boolean {
|
||||
if (inspection != other.inspection) return false
|
||||
if (file != other.file) return false
|
||||
if (line != other.line) return false
|
||||
return true
|
||||
}
|
||||
|
||||
private fun SplitModeInspectionExclusionProblem.toEntry(): SplitModeInspectionExclusionEntry {
|
||||
return SplitModeInspectionExclusionEntry(
|
||||
inspection = inspection,
|
||||
file = file,
|
||||
line = line,
|
||||
reason = reason,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class AddToSplitModeInspectionExclusionsFix(
|
||||
private val problem: SplitModeInspectionExclusionProblem,
|
||||
) : LocalQuickFix, LowPriorityAction {
|
||||
private class IncreaseSplitModeProjectBaselineVersionFix : LocalQuickFix, LowPriorityAction {
|
||||
override fun getName(): String = familyName
|
||||
|
||||
override fun getFamilyName(): String {
|
||||
return message("inspection.remote.dev.add.to.split.mode.exclusions.fix.name")
|
||||
return message("inspection.remote.dev.increase.split.mode.baseline.fix.name")
|
||||
}
|
||||
|
||||
override fun startInWriteAction(): Boolean = false
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val exclusionsFile = WriteCommandAction.writeCommandAction(project)
|
||||
.withName(message("inspection.remote.dev.add.to.split.mode.exclusions.command.name"))
|
||||
val baselineVersionFile = WriteCommandAction.writeCommandAction(project)
|
||||
.withName(message("inspection.remote.dev.increase.split.mode.baseline.command.name"))
|
||||
.compute<VirtualFile?, Throwable> {
|
||||
SplitModeInspectionExclusionsService.getInstance(project).appendExclusion(problem)
|
||||
SplitModeInspectionExclusionsService.getInstance(project).increaseProjectBaselineVersion()
|
||||
}
|
||||
|
||||
if (exclusionsFile == null) {
|
||||
if (baselineVersionFile == null) {
|
||||
return
|
||||
}
|
||||
|
||||
val document = FileDocumentManager.getInstance().getDocument(exclusionsFile)
|
||||
val lastLine = maxOf((document?.lineCount ?: 1) - 1, 0)
|
||||
OpenFileDescriptor(project, exclusionsFile, lastLine, 0).navigate(true)
|
||||
OpenFileDescriptor(project, baselineVersionFile, 0, 0).navigate(true)
|
||||
}
|
||||
}
|
||||
|
||||
private data class SplitModeInspectionExclusionsSnapshot(
|
||||
val exclusions: List<SplitModeInspectionExclusionEntry> = emptyList(),
|
||||
)
|
||||
|
||||
@Serializable
|
||||
internal data class SplitModeInspectionExclusionsFile(
|
||||
@SerialName("exclusions")
|
||||
val exclusions: List<SplitModeInspectionExclusionEntry> = emptyList(),
|
||||
)
|
||||
|
||||
@Serializable
|
||||
internal data class SplitModeInspectionExclusionEntry(
|
||||
@SerialName("inspection")
|
||||
val inspection: String,
|
||||
|
||||
@SerialName("file")
|
||||
val file: String = "",
|
||||
|
||||
@SerialName("line")
|
||||
val line: Int = -1,
|
||||
|
||||
@SerialName("reason")
|
||||
val reason: String? = null,
|
||||
private data class SplitModeProjectBaselineVersionFile(
|
||||
@SerialName("currentProjectBaselineVersion")
|
||||
val currentProjectBaselineVersion: Int,
|
||||
)
|
||||
|
||||
private val LOG: Logger = logger<SplitModeInspectionExclusionsService>()
|
||||
|
||||
private const val EXCLUSIONS_DIRECTORY_RELATIVE_PATH: String = "community/plugins/devkit/devkit-core/resources/remotedevInspectionData"
|
||||
private const val INITIAL_EXCLUSIONS_JSON: String = "{ \"exclusions\": [] }\n"
|
||||
private val json5 = JsonMapper.builder()
|
||||
.enable(
|
||||
JsonReadFeature.ALLOW_JAVA_COMMENTS,
|
||||
JsonReadFeature.ALLOW_SINGLE_QUOTES,
|
||||
JsonReadFeature.ALLOW_UNQUOTED_FIELD_NAMES,
|
||||
JsonReadFeature.ALLOW_TRAILING_COMMA,
|
||||
)
|
||||
.build()
|
||||
|
||||
private fun createProjectBaselineVersionJson5(file: SplitModeProjectBaselineVersionFile): String {
|
||||
return """
|
||||
// The file carries the current project baseline version for Split Mode Compatibility safe-push checks.
|
||||
// Increase currentProjectBaselineVersion only when incremental Split Mode Compatibility tests incorrectly
|
||||
// report pre-existing violations after large refactorings.
|
||||
// Changing this value is a legal bypass: the affected safe push may skip the incremental Split Mode
|
||||
// Compatibility tests for that run, allowing the refactoring to proceed while the baseline catches up.
|
||||
// Do not use it for real new violations. Fix those instead; see Split Mode documentation IJPL-A-632.
|
||||
// Contact the RemDev team in #ij-remote-dev if unsure.
|
||||
""".trimIndent() + "\n" + json.encodeToString(file) + "\n"
|
||||
}
|
||||
|
||||
private val json = Json {
|
||||
ignoreUnknownKeys = true
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.Nls
|
||||
import org.jetbrains.idea.devkit.DevKitBundle
|
||||
import org.jetbrains.idea.devkit.dom.ContentDescriptor.ModuleDescriptor
|
||||
import org.jetbrains.idea.devkit.dom.index.PluginIdDependenciesIndex
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.analysis.ApiUsagePolicy
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.analysis.ModuleAnalysis
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.analysis.ResolvedModuleKind
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.analysis.SplitModeAnalysisFlags
|
||||
@@ -187,7 +188,7 @@ internal object SplitModeInspectionUtil {
|
||||
restrictionsService.getPredefinedModuleKind(module, ideaPlugin = ideaPlugin)
|
||||
}
|
||||
|
||||
return predefinedModuleKind != null
|
||||
return predefinedModuleKind != null && predefinedModuleKind.apiUsagePolicy == ApiUsagePolicy.DEFAULT
|
||||
}
|
||||
|
||||
fun shouldSuppressForSingleModuleExternalPlugin(file: PsiFile): Boolean {
|
||||
|
||||
+3
-10
@@ -27,20 +27,13 @@ internal class SplitModeMixedDependenciesInspection : DevKitPluginXmlInspectionB
|
||||
|
||||
val module = element.module ?: return
|
||||
val currentXmlFile = holder.fileElement.file
|
||||
val xmlElement = element.xmlElement ?: return
|
||||
if (SplitModeInspectionExclusionsService.getInstance(currentXmlFile.project)
|
||||
.isExcluded(xmlElement, SPLIT_MODE_MIXED_DEPENDENCIES_SHORT_NAME)) {
|
||||
return
|
||||
}
|
||||
if (element.xmlElement == null) return
|
||||
|
||||
val moduleAnalysis = SplitModeModuleKindResolver.getOrComputeModuleAnalysis(module, currentXmlFile)
|
||||
if (moduleAnalysis.resolvedModuleKind.kind == SplitModeApiRestrictionsService.ModuleKind.MIXED) {
|
||||
val regularFixes = SplitModeDependencyQuickFixes.createMixedModuleFixes(module, element)
|
||||
val suppressionFix = SplitModeInspectionExclusionsService.getInstance(currentXmlFile.project).createSuppressionFixIfApplicable(
|
||||
xmlElement,
|
||||
SPLIT_MODE_MIXED_DEPENDENCIES_SHORT_NAME,
|
||||
)
|
||||
val quickFixes = if (suppressionFix != null) regularFixes + suppressionFix else regularFixes
|
||||
val suppressionFixes = SplitModeInspectionExclusionsService.getInstance(currentXmlFile.project).createCommonSuppressionQuickFixes()
|
||||
val quickFixes = regularFixes + suppressionFixes
|
||||
val mixedDependenciesMessage = buildMixedModuleDependenciesMessage(moduleAnalysis.resolvedModuleKind.reasoning)
|
||||
holder.createProblem(
|
||||
element,
|
||||
|
||||
+9
-13
@@ -11,7 +11,7 @@ import org.jetbrains.idea.devkit.inspections.remotedev.SplitModeInspectionUtil.b
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.analysis.SplitModeApiRestrictionsService
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.analysis.SplitModeQodanaInspectionScopeLimiter
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.analysis.SplitModeModuleKindResolver
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.analysis.SplitModeModuleKindResolver.doesApiKindMatchExpectedModuleKind
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.analysis.SplitModeModuleKindResolver.isApiUsageAllowed
|
||||
import org.jetbrains.idea.devkit.util.DescriptorUtil
|
||||
|
||||
internal class SplitModeXmlApiUsageInspection : DevKitPluginXmlInspectionBase() {
|
||||
@@ -19,7 +19,8 @@ internal class SplitModeXmlApiUsageInspection : DevKitPluginXmlInspectionBase()
|
||||
override fun isAllowed(holder: DomElementAnnotationHolder): Boolean {
|
||||
return super.isAllowed(holder)
|
||||
&& SplitModeInspectionUtil.isAllowedForSplitModeInspection(holder.fileElement.file)
|
||||
&& SplitModeQodanaInspectionScopeLimiter.getInstance(holder.fileElement.file.project).shouldInspectFileInQodanaMode(holder.fileElement.file)
|
||||
&& SplitModeQodanaInspectionScopeLimiter.getInstance(holder.fileElement.file.project)
|
||||
.shouldInspectFileInQodanaMode(holder.fileElement.file)
|
||||
}
|
||||
|
||||
override fun checkDomElement(element: DomElement, holder: DomElementAnnotationHolder, helper: DomHighlightingHelper) {
|
||||
@@ -30,25 +31,20 @@ internal class SplitModeXmlApiUsageInspection : DevKitPluginXmlInspectionBase()
|
||||
val module = element.module ?: return
|
||||
val currentXmlFile = holder.fileElement.file
|
||||
val restrictionsService = SplitModeApiRestrictionsService.getInstance(currentXmlFile.project)
|
||||
val expectedModuleKind = restrictionsService.getExtensionPointKind(extensionPointName) ?: return
|
||||
val apiRestriction = restrictionsService.getExtensionPointRestriction(extensionPointName) ?: return
|
||||
val expectedModuleKind = apiRestriction.targetModuleKind
|
||||
val moduleAnalysis = SplitModeModuleKindResolver.getOrComputeModuleAnalysis(module, currentXmlFile)
|
||||
if (SplitModeInspectionUtil.shouldReportSinglePluginLevelErrorInsteadOfManyNestedErrors(currentXmlFile, moduleAnalysis)) return
|
||||
val actualModuleKind = moduleAnalysis.resolvedModuleKind
|
||||
|
||||
if (doesApiKindMatchExpectedModuleKind(actualModuleKind, expectedModuleKind)) return
|
||||
if (isApiUsageAllowed(moduleAnalysis, apiRestriction)) return
|
||||
|
||||
val currentlyOpenedDescriptor = DescriptorUtil.getIdeaPlugin(holder.fileElement.file)
|
||||
val hint = restrictionsService.getExtensionPointHint(extensionPointName)
|
||||
val xmlElement = element.xmlElement ?: return
|
||||
if (SplitModeInspectionExclusionsService.getInstance(currentXmlFile.project).isExcluded(xmlElement, SPLIT_MODE_XML_API_USAGE_SHORT_NAME)) {
|
||||
return
|
||||
}
|
||||
if (element.xmlElement == null) return
|
||||
val regularFixes = SplitModeDependencyQuickFixes.createMismatchFixes(module, currentlyOpenedDescriptor, expectedModuleKind)
|
||||
val suppressionFix = SplitModeInspectionExclusionsService.getInstance(currentXmlFile.project).createSuppressionFixIfApplicable(
|
||||
xmlElement,
|
||||
SPLIT_MODE_XML_API_USAGE_SHORT_NAME,
|
||||
)
|
||||
val fixes = if (suppressionFix != null) regularFixes + suppressionFix else regularFixes
|
||||
val suppressionFixes = SplitModeInspectionExclusionsService.getInstance(currentXmlFile.project).createCommonSuppressionQuickFixes()
|
||||
val fixes = regularFixes + suppressionFixes
|
||||
holder.createProblem(
|
||||
element,
|
||||
buildModuleKindMismatchMessage(extensionPointName, expectedModuleKind, actualModuleKind, hint),
|
||||
|
||||
+6
@@ -6,8 +6,14 @@ import com.intellij.openapi.util.NlsSafe
|
||||
internal data class ModuleAnalysis(
|
||||
val resolvedModuleKind: ResolvedModuleKind,
|
||||
val evidence: ModuleKindEvidence = ModuleKindEvidence(),
|
||||
val apiUsagePolicy: ApiUsagePolicy = ApiUsagePolicy.DEFAULT,
|
||||
)
|
||||
|
||||
internal enum class ApiUsagePolicy(val id: String) {
|
||||
DEFAULT("default"),
|
||||
BACKEND_WITH_NON_UI_API_PERMIT("backendWithNonUiApiPermit"),
|
||||
}
|
||||
|
||||
internal data class ModuleKindEvidence(
|
||||
val hasOwnFrontendEvidence: Boolean = false,
|
||||
val hasOwnBackendEvidence: Boolean = false,
|
||||
|
||||
+139
-65
@@ -14,6 +14,9 @@ import com.intellij.openapi.util.NlsSafe
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.psi.PsiModifierListOwner
|
||||
import com.intellij.psi.xml.XmlFile
|
||||
import com.fasterxml.jackson.core.json.JsonReadFeature
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -45,8 +48,8 @@ class SplitModeApiRestrictionsService(
|
||||
|
||||
companion object {
|
||||
private val LOG: Logger = logger<SplitModeApiRestrictionsService>()
|
||||
private const val API_RESTRICTIONS_RESOURCE_PATH = "remotedevInspectionData/ApiRestrictions.json"
|
||||
private const val PREDEFINED_MODULE_KINDS_RESOURCE_PATH = "remotedevInspectionData/PredefinedModuleKinds.json"
|
||||
private const val API_RESTRICTIONS_RESOURCE_PATH = "remotedevInspectionData/ApiRestrictions.json5"
|
||||
private const val PREDEFINED_MODULE_KINDS_RESOURCE_PATH = "remotedevInspectionData/PredefinedModuleKinds.json5"
|
||||
private const val BACKEND_API_ANNOTATION = "com.intellij.util.remdev.BackendApi"
|
||||
private const val FRONTEND_API_ANNOTATION = "com.intellij.util.remdev.FrontendApi"
|
||||
|
||||
@@ -96,10 +99,29 @@ class SplitModeApiRestrictionsService(
|
||||
}
|
||||
}
|
||||
|
||||
enum class ApiRestrictionKind(val id: String) {
|
||||
GENERIC_PLATFORM_API("genericPlatformApi"),
|
||||
UI("ui"),
|
||||
}
|
||||
|
||||
private enum class PredefinedModuleKindEntryKind(val id: String) {
|
||||
MODULE_ID("moduleId"),
|
||||
PLUGIN_ID("pluginId"),
|
||||
XML_DESCRIPTOR_FILE("xmlDescriptorFile"),
|
||||
}
|
||||
|
||||
private val json = Json {
|
||||
ignoreUnknownKeys = true
|
||||
isLenient = true
|
||||
}
|
||||
private val json5: ObjectMapper = JsonMapper.builder()
|
||||
.enable(
|
||||
JsonReadFeature.ALLOW_JAVA_COMMENTS,
|
||||
JsonReadFeature.ALLOW_SINGLE_QUOTES,
|
||||
JsonReadFeature.ALLOW_UNQUOTED_FIELD_NAMES,
|
||||
JsonReadFeature.ALLOW_TRAILING_COMMA,
|
||||
)
|
||||
.build()
|
||||
|
||||
private val resourceReader = SplitModeInspectionResourceReader.getInstance(project)
|
||||
private val backgroundLoadScheduled = AtomicBoolean(false)
|
||||
@@ -135,10 +157,18 @@ class SplitModeApiRestrictionsService(
|
||||
}
|
||||
|
||||
fun getCodeApiKind(apiName: String, apiOwner: PsiModifierListOwner?): ModuleKind? {
|
||||
return getAnnotatedApiKind(apiOwner) ?: getRestrictionsSnapshot().codeRestrictions[apiName]
|
||||
return getCodeApiRestriction(apiName, apiOwner)?.targetModuleKind
|
||||
}
|
||||
|
||||
fun getExtensionPointKind(extensionPointName: String): ModuleKind? {
|
||||
internal fun getCodeApiRestriction(apiName: String, apiOwner: PsiModifierListOwner?): ApiRestrictionMatch? {
|
||||
val annotatedApiKind = getAnnotatedApiKind(apiOwner)
|
||||
if (annotatedApiKind != null) {
|
||||
return ApiRestrictionMatch(annotatedApiKind, ApiRestrictionKind.GENERIC_PLATFORM_API)
|
||||
}
|
||||
return getRestrictionsSnapshot().codeRestrictions[apiName]
|
||||
}
|
||||
|
||||
internal fun getExtensionPointRestriction(extensionPointName: String): ApiRestrictionMatch? {
|
||||
val restrictions = getRestrictionsSnapshot()
|
||||
val apiName = restrictions.extensionPointToApiName[extensionPointName] ?: return null
|
||||
return restrictions.codeRestrictions[apiName]
|
||||
@@ -156,11 +186,11 @@ class SplitModeApiRestrictionsService(
|
||||
|
||||
fun getPredefinedDependencyKind(dependencyId: String): ModuleKind? {
|
||||
val predefinedModuleKinds = getRestrictionsSnapshot().predefinedModuleKinds
|
||||
val moduleKind = predefinedModuleKinds.moduleNames[dependencyId]
|
||||
if (moduleKind != null) {
|
||||
return moduleKind
|
||||
val moduleInfo = predefinedModuleKinds.moduleIds[dependencyId]
|
||||
if (moduleInfo != null) {
|
||||
return moduleInfo.moduleKind
|
||||
}
|
||||
return predefinedModuleKinds.pluginIds[dependencyId]
|
||||
return predefinedModuleKinds.pluginIds[dependencyId]?.moduleKind
|
||||
}
|
||||
|
||||
internal fun getPredefinedModuleKind(
|
||||
@@ -172,10 +202,11 @@ class SplitModeApiRestrictionsService(
|
||||
val descriptorRelativePath = if (descriptorFile == null) null else computeDescriptorRelativePath(module, descriptorFile)
|
||||
if (descriptorRelativePath != null) {
|
||||
val selector = DescriptorPathSelector(module.name, descriptorRelativePath)
|
||||
val moduleKind = lookup.descriptorPaths[selector]
|
||||
if (moduleKind != null) {
|
||||
val moduleInfo = lookup.descriptorPaths[selector]
|
||||
if (moduleInfo != null) {
|
||||
return PredefinedModuleKindMatch(
|
||||
moduleKind = moduleKind,
|
||||
moduleKind = moduleInfo.moduleKind,
|
||||
apiUsagePolicy = moduleInfo.apiUsagePolicy,
|
||||
cacheKey = "descriptor|${module.name}|$descriptorRelativePath",
|
||||
reasoning = "Predefined module kind for descriptor '$descriptorRelativePath' in module '${module.name}'",
|
||||
)
|
||||
@@ -185,10 +216,11 @@ class SplitModeApiRestrictionsService(
|
||||
if (ideaPlugin != null) {
|
||||
val pluginSelectorIds = collectPluginSelectorIds(ideaPlugin)
|
||||
for (pluginSelectorId in pluginSelectorIds) {
|
||||
val moduleKind = lookup.pluginIds[pluginSelectorId]
|
||||
if (moduleKind != null) {
|
||||
val moduleInfo = lookup.pluginIds[pluginSelectorId]
|
||||
if (moduleInfo != null) {
|
||||
return PredefinedModuleKindMatch(
|
||||
moduleKind = moduleKind,
|
||||
moduleKind = moduleInfo.moduleKind,
|
||||
apiUsagePolicy = moduleInfo.apiUsagePolicy,
|
||||
cacheKey = "plugin|$pluginSelectorId",
|
||||
reasoning = "Predefined module kind for plugin/module id '$pluginSelectorId'",
|
||||
)
|
||||
@@ -196,9 +228,10 @@ class SplitModeApiRestrictionsService(
|
||||
}
|
||||
}
|
||||
|
||||
val moduleKind = lookup.moduleNames[module.name] ?: return null
|
||||
val moduleInfo = lookup.moduleIds[module.name] ?: return null
|
||||
return PredefinedModuleKindMatch(
|
||||
moduleKind = moduleKind,
|
||||
moduleKind = moduleInfo.moduleKind,
|
||||
apiUsagePolicy = moduleInfo.apiUsagePolicy,
|
||||
cacheKey = "module|${module.name}",
|
||||
reasoning = "Predefined module kind for module '${module.name}'",
|
||||
)
|
||||
@@ -293,7 +326,8 @@ class SplitModeApiRestrictionsService(
|
||||
readMode = readMode,
|
||||
) {
|
||||
override fun parse(text: String): RestrictionsLookup {
|
||||
return buildApiRestrictionsLookup(json.decodeFromString<List<ApiRestriction>>(text))
|
||||
val normalizedJson = json5.readTree(text).toString()
|
||||
return buildApiRestrictionsLookup(json.decodeFromString<List<ApiRestriction>>(normalizedJson))
|
||||
}
|
||||
|
||||
override fun getDefaultValue(): RestrictionsLookup {
|
||||
@@ -311,7 +345,8 @@ class SplitModeApiRestrictionsService(
|
||||
readMode = readMode,
|
||||
) {
|
||||
override fun parse(text: String): PredefinedModuleKindsLookup {
|
||||
return buildPredefinedModuleKindsLookup(json.decodeFromString<List<PredefinedModuleKind>>(text))
|
||||
val normalizedJson = json5.readTree(text).toString()
|
||||
return buildPredefinedModuleKindsLookup(json.decodeFromString<List<PredefinedModuleKind>>(normalizedJson))
|
||||
}
|
||||
|
||||
override fun getDefaultValue(): PredefinedModuleKindsLookup {
|
||||
@@ -321,13 +356,14 @@ class SplitModeApiRestrictionsService(
|
||||
}
|
||||
|
||||
private fun buildApiRestrictionsLookup(data: List<ApiRestriction>): RestrictionsLookup {
|
||||
val codeRestrictions = mutableMapOf<String, ModuleKind>()
|
||||
val codeRestrictions = mutableMapOf<String, ApiRestrictionMatch>()
|
||||
val extensionPointToApiName = mutableMapOf<String, String>()
|
||||
val apiHints = mutableMapOf<String, String>()
|
||||
|
||||
for (restriction in data) {
|
||||
val targetModuleKind = toTargetModuleKind(restriction)
|
||||
val existingCodeRestriction = codeRestrictions.putIfAbsent(restriction.apiName, targetModuleKind)
|
||||
val apiRestriction = ApiRestrictionMatch(targetModuleKind, parseApiRestrictionKind(restriction.restrictionKind))
|
||||
val existingCodeRestriction = codeRestrictions.putIfAbsent(restriction.apiName, apiRestriction)
|
||||
check(existingCodeRestriction == null) {
|
||||
"Duplicate API restriction for '${restriction.apiName}'"
|
||||
}
|
||||
@@ -337,7 +373,7 @@ class SplitModeApiRestrictionsService(
|
||||
for (extensionPointName in restriction.extensionPointNames) {
|
||||
val existingApiName = extensionPointToApiName[extensionPointName]
|
||||
val existingExtensionPointRestriction = if (existingApiName == null) null else codeRestrictions[existingApiName]
|
||||
check(existingExtensionPointRestriction == null || existingExtensionPointRestriction == targetModuleKind) {
|
||||
check(existingExtensionPointRestriction == null || existingExtensionPointRestriction == apiRestriction) {
|
||||
"Conflicting extension point restriction for '$extensionPointName'"
|
||||
}
|
||||
if (existingApiName == null) {
|
||||
@@ -354,50 +390,47 @@ class SplitModeApiRestrictionsService(
|
||||
}
|
||||
|
||||
private fun buildPredefinedModuleKindsLookup(data: List<PredefinedModuleKind>): PredefinedModuleKindsLookup {
|
||||
val moduleNames = mutableMapOf<String, ModuleKind>()
|
||||
val pluginIds = mutableMapOf<String, ModuleKind>()
|
||||
val descriptorPaths = mutableMapOf<DescriptorPathSelector, ModuleKind>()
|
||||
val moduleIds = mutableMapOf<String, PredefinedModuleKindInfo>()
|
||||
val pluginIds = mutableMapOf<String, PredefinedModuleKindInfo>()
|
||||
val descriptorPaths = mutableMapOf<DescriptorPathSelector, PredefinedModuleKindInfo>()
|
||||
|
||||
for ((moduleName, pluginId, descriptorRelativePath, moduleKindId) in data) {
|
||||
for ((entryKindId, entryId, moduleName, descriptorRelativePath, moduleKindId, apiUsagePolicyId) in data) {
|
||||
val moduleKind = parsePredefinedModuleKind(moduleKindId)
|
||||
val hasModuleName = !moduleName.isNullOrBlank()
|
||||
val hasPluginId = !pluginId.isNullOrBlank()
|
||||
|
||||
check(hasModuleName != hasPluginId) {
|
||||
"Predefined module kind must specify exactly one of moduleName or pluginId"
|
||||
}
|
||||
check(descriptorRelativePath == null || hasModuleName) {
|
||||
"descriptorRelativePath is only supported together with moduleName"
|
||||
}
|
||||
check(descriptorRelativePath == null || descriptorRelativePath.isNotBlank()) {
|
||||
"descriptorRelativePath must not be blank"
|
||||
}
|
||||
|
||||
if (descriptorRelativePath != null) {
|
||||
val selector = DescriptorPathSelector(moduleName!!, descriptorRelativePath)
|
||||
val previousModuleKind = descriptorPaths.putIfAbsent(selector, moduleKind)
|
||||
check(previousModuleKind == null) {
|
||||
"Duplicate predefined module kind for descriptor '${selector.descriptorRelativePath}' in module '${selector.moduleName}'"
|
||||
val moduleInfo = PredefinedModuleKindInfo(moduleKind, parseApiUsagePolicy(apiUsagePolicyId))
|
||||
when (parsePredefinedModuleKindEntryKind(entryKindId)) {
|
||||
PredefinedModuleKindEntryKind.MODULE_ID -> {
|
||||
check(moduleName == null) { "Predefined moduleId entry must not specify moduleName" }
|
||||
check(descriptorRelativePath == null) { "Predefined moduleId entry must not specify descriptorRelativePath" }
|
||||
check(!entryId.isNullOrBlank()) { "Predefined moduleId entry must specify non-blank id" }
|
||||
val previousModuleKind = moduleIds.putIfAbsent(entryId, moduleInfo)
|
||||
check(previousModuleKind == null) {
|
||||
"Duplicate predefined module kind for module id '$entryId'"
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if (hasModuleName) {
|
||||
val previousModuleKind = moduleNames.putIfAbsent(moduleName, moduleKind)
|
||||
check(previousModuleKind == null) {
|
||||
"Duplicate predefined module kind for module '$moduleName'"
|
||||
PredefinedModuleKindEntryKind.PLUGIN_ID -> {
|
||||
check(moduleName == null) { "Predefined pluginId entry must not specify moduleName" }
|
||||
check(descriptorRelativePath == null) { "Predefined pluginId entry must not specify descriptorRelativePath" }
|
||||
check(!entryId.isNullOrBlank()) { "Predefined pluginId entry must specify non-blank id" }
|
||||
val previousModuleKind = pluginIds.putIfAbsent(entryId, moduleInfo)
|
||||
check(previousModuleKind == null) {
|
||||
"Duplicate predefined module kind for plugin/module id '$entryId'"
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
val previousModuleKind = pluginIds.putIfAbsent(pluginId!!, moduleKind)
|
||||
check(previousModuleKind == null) {
|
||||
"Duplicate predefined module kind for plugin/module id '$pluginId'"
|
||||
PredefinedModuleKindEntryKind.XML_DESCRIPTOR_FILE -> {
|
||||
check(entryId == null) { "Predefined xmlDescriptorFile entry must not specify id" }
|
||||
check(!moduleName.isNullOrBlank()) { "Predefined xmlDescriptorFile entry must specify non-blank moduleName" }
|
||||
check(!descriptorRelativePath.isNullOrBlank()) { "Predefined xmlDescriptorFile entry must specify non-blank descriptorRelativePath" }
|
||||
val selector = DescriptorPathSelector(moduleName, descriptorRelativePath)
|
||||
val previousModuleKind = descriptorPaths.putIfAbsent(selector, moduleInfo)
|
||||
check(previousModuleKind == null) {
|
||||
"Duplicate predefined module kind for descriptor '${selector.descriptorRelativePath}' in module '${selector.moduleName}'"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PredefinedModuleKindsLookup(
|
||||
moduleNames = moduleNames,
|
||||
moduleIds = moduleIds,
|
||||
pluginIds = pluginIds,
|
||||
descriptorPaths = descriptorPaths,
|
||||
)
|
||||
@@ -426,6 +459,27 @@ class SplitModeApiRestrictionsService(
|
||||
return moduleKind
|
||||
}
|
||||
|
||||
private fun parseApiRestrictionKind(restrictionKindId: String): ApiRestrictionKind {
|
||||
return ApiRestrictionKind.entries.firstOrNull { it.id.equals(restrictionKindId, ignoreCase = true) }
|
||||
?: error("Unknown split-mode API restriction kind '$restrictionKindId'")
|
||||
}
|
||||
|
||||
private fun parsePredefinedModuleKindEntryKind(entryKindId: String): PredefinedModuleKindEntryKind {
|
||||
return PredefinedModuleKindEntryKind.entries.firstOrNull { it.id == entryKindId }
|
||||
?: error("Unknown predefined module kind entry kind '$entryKindId'")
|
||||
}
|
||||
|
||||
private fun parseApiUsagePolicy(apiUsagePolicyId: String?): ApiUsagePolicy {
|
||||
if (apiUsagePolicyId == null) {
|
||||
return ApiUsagePolicy.DEFAULT
|
||||
}
|
||||
return when (apiUsagePolicyId) {
|
||||
ApiUsagePolicy.DEFAULT.id -> ApiUsagePolicy.DEFAULT
|
||||
ApiUsagePolicy.BACKEND_WITH_NON_UI_API_PERMIT.id -> ApiUsagePolicy.BACKEND_WITH_NON_UI_API_PERMIT
|
||||
else -> error("Unknown split-mode API usage policy '$apiUsagePolicyId'")
|
||||
}
|
||||
}
|
||||
|
||||
private fun parsePredefinedModuleKind(moduleKindId: String): ModuleKind {
|
||||
val moduleKind = parseModuleKindId(moduleKindId)
|
||||
check(moduleKind != ModuleKind.MIXED) { "'mixed' is not supported in predefined module kinds" }
|
||||
@@ -467,13 +521,13 @@ class SplitModeApiRestrictionsService(
|
||||
}
|
||||
|
||||
private data class RestrictionsLookup(
|
||||
val codeRestrictions: Map<String, ModuleKind> = emptyMap(),
|
||||
val codeRestrictions: Map<String, ApiRestrictionMatch> = emptyMap(),
|
||||
val extensionPointToApiName: Map<String, String> = emptyMap(),
|
||||
val apiHints: Map<String, String> = emptyMap(),
|
||||
)
|
||||
|
||||
private data class RestrictionsSnapshot(
|
||||
val codeRestrictions: Map<String, ModuleKind> = emptyMap(),
|
||||
val codeRestrictions: Map<String, ApiRestrictionMatch> = emptyMap(),
|
||||
val extensionPointToApiName: Map<String, String> = emptyMap(),
|
||||
val apiHints: Map<String, String> = emptyMap(),
|
||||
val predefinedModuleKinds: PredefinedModuleKindsLookup = PredefinedModuleKindsLookup(),
|
||||
@@ -481,25 +535,36 @@ class SplitModeApiRestrictionsService(
|
||||
|
||||
internal data class PredefinedModuleKindMatch(
|
||||
val moduleKind: ModuleKind,
|
||||
val apiUsagePolicy: ApiUsagePolicy,
|
||||
val cacheKey: String,
|
||||
val reasoning: @NlsSafe String,
|
||||
)
|
||||
|
||||
internal data class ApiRestrictionMatch(
|
||||
val targetModuleKind: ModuleKind,
|
||||
val restrictionKind: ApiRestrictionKind,
|
||||
)
|
||||
|
||||
private data class DescriptorPathSelector(
|
||||
val moduleName: String,
|
||||
val descriptorRelativePath: String,
|
||||
)
|
||||
|
||||
private data class PredefinedModuleKindsLookup(
|
||||
val moduleNames: Map<String, ModuleKind> = emptyMap(),
|
||||
val pluginIds: Map<String, ModuleKind> = emptyMap(),
|
||||
val descriptorPaths: Map<DescriptorPathSelector, ModuleKind> = emptyMap(),
|
||||
val moduleIds: Map<String, PredefinedModuleKindInfo> = emptyMap(),
|
||||
val pluginIds: Map<String, PredefinedModuleKindInfo> = emptyMap(),
|
||||
val descriptorPaths: Map<DescriptorPathSelector, PredefinedModuleKindInfo> = emptyMap(),
|
||||
) {
|
||||
fun size(): Int {
|
||||
return moduleNames.size + pluginIds.size + descriptorPaths.size
|
||||
return moduleIds.size + pluginIds.size + descriptorPaths.size
|
||||
}
|
||||
}
|
||||
|
||||
private data class PredefinedModuleKindInfo(
|
||||
val moduleKind: ModuleKind,
|
||||
val apiUsagePolicy: ApiUsagePolicy,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
private data class ApiRestriction(
|
||||
@SerialName("apiName")
|
||||
@@ -511,22 +576,31 @@ class SplitModeApiRestrictionsService(
|
||||
@SerialName("targetModules")
|
||||
val targetModules: List<String>,
|
||||
|
||||
@SerialName("restrictionKind")
|
||||
val restrictionKind: String = ApiRestrictionKind.GENERIC_PLATFORM_API.id,
|
||||
|
||||
@SerialName("hint")
|
||||
val hint: @Nls String? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
private data class PredefinedModuleKind(
|
||||
@SerialName("kind")
|
||||
val kind: String,
|
||||
|
||||
@SerialName("id")
|
||||
val id: String? = null,
|
||||
|
||||
@SerialName("moduleName")
|
||||
val moduleName: String? = null,
|
||||
|
||||
@SerialName("pluginId")
|
||||
val pluginId: String? = null,
|
||||
|
||||
@SerialName("descriptorRelativePath")
|
||||
val descriptorRelativePath: String? = null,
|
||||
|
||||
@SerialName("moduleKind")
|
||||
val moduleKind: String,
|
||||
|
||||
@SerialName("apiUsagePolicy")
|
||||
val apiUsagePolicy: String? = null,
|
||||
)
|
||||
}
|
||||
|
||||
+22
-8
@@ -87,7 +87,9 @@ internal object SplitModeDescriptorDependencyAnalyzer {
|
||||
val descriptorLocation = getDescriptorLocation(ideaPlugin)
|
||||
val accumulator = DependencyFactsAccumulator(descriptorLocation)
|
||||
val directDependencies = collectDirectDependencies(ideaPlugin).toList()
|
||||
for ((dependencyName, dependencyDescriptors) in directDependencies) {
|
||||
for (dependency in directDependencies) {
|
||||
val dependencyName = dependency.name
|
||||
val dependencyDescriptors = dependency.resolveDescriptors()
|
||||
var hasPredefinedDependencyFacts = false
|
||||
for (dependencyDescriptor in dependencyDescriptors) {
|
||||
val predefinedDependencyFacts = getPredefinedDependencyFacts(dependencyDescriptor) ?: continue
|
||||
@@ -118,7 +120,9 @@ internal object SplitModeDescriptorDependencyAnalyzer {
|
||||
return accumulator.toDependencyFacts()
|
||||
}
|
||||
|
||||
for ((dependencyName, dependencyDescriptors) in directDependencies) {
|
||||
for (dependency in directDependencies) {
|
||||
val dependencyName = dependency.name
|
||||
val dependencyDescriptors = dependency.resolveDescriptors()
|
||||
for (dependencyDescriptor in dependencyDescriptors) {
|
||||
val dependencyFacts = getOrComputeOwnDescriptorDependencyFacts(dependencyDescriptor, analysisStates)
|
||||
accumulator.recordTransitiveDependencies(dependencyName, dependencyFacts)
|
||||
@@ -162,7 +166,9 @@ internal object SplitModeDescriptorDependencyAnalyzer {
|
||||
continue
|
||||
}
|
||||
val dependencyName = dependency.rawText ?: dependency.stringValue ?: continue
|
||||
yield(DirectDependency(dependencyName, resolvePluginDependencyDescriptors(ideaPlugin, dependencyName)))
|
||||
yield(DirectDependency(dependencyName) {
|
||||
resolvePluginDependencyDescriptors(ideaPlugin, dependencyName)
|
||||
})
|
||||
}
|
||||
|
||||
val pluginDependencies = ideaPlugin.dependencies
|
||||
@@ -172,12 +178,16 @@ internal object SplitModeDescriptorDependencyAnalyzer {
|
||||
|
||||
for (moduleDescriptor in pluginDependencies.moduleEntry) {
|
||||
val dependencyName = moduleDescriptor.name.stringValue ?: continue
|
||||
yield(DirectDependency(dependencyName, listOfNotNull(moduleDescriptor.name.value)))
|
||||
yield(DirectDependency(dependencyName) {
|
||||
listOfNotNull(moduleDescriptor.name.value)
|
||||
})
|
||||
}
|
||||
|
||||
for (pluginDescriptor in pluginDependencies.plugin) {
|
||||
val dependencyName = pluginDescriptor.id.stringValue ?: continue
|
||||
yield(DirectDependency(dependencyName, resolvePluginDependencyDescriptors(ideaPlugin, dependencyName)))
|
||||
yield(DirectDependency(dependencyName) {
|
||||
resolvePluginDependencyDescriptors(ideaPlugin, dependencyName)
|
||||
})
|
||||
}
|
||||
}
|
||||
.distinctBy { it.name }
|
||||
@@ -378,10 +388,14 @@ private class DependencyFactsAccumulator(
|
||||
}
|
||||
}
|
||||
|
||||
private data class DirectDependency(
|
||||
private class DirectDependency(
|
||||
val name: String,
|
||||
val descriptors: List<IdeaPlugin>,
|
||||
)
|
||||
descriptorResolver: () -> List<IdeaPlugin>,
|
||||
) {
|
||||
private val descriptors by lazy(LazyThreadSafetyMode.NONE) { descriptorResolver() }
|
||||
|
||||
fun resolveDescriptors(): List<IdeaPlugin> = descriptors
|
||||
}
|
||||
|
||||
private data class ContentModuleDependency(
|
||||
val moduleName: String,
|
||||
|
||||
+77
-9
@@ -5,25 +5,33 @@ import com.intellij.devkit.core.icons.DevkitCoreIcons.BackendModule
|
||||
import com.intellij.devkit.core.icons.DevkitCoreIcons.FrontendModule
|
||||
import com.intellij.devkit.core.icons.DevkitCoreIcons.SharedModule
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.lang.xml.XMLLanguage
|
||||
import com.intellij.openapi.application.smartReadAction
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.openapi.util.registry.RegistryManager
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.util.CachedValueProvider
|
||||
import com.intellij.psi.util.CachedValuesManager
|
||||
import com.intellij.psi.xml.XmlFile
|
||||
import com.intellij.ui.IconDeferrer
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.idea.devkit.util.DescriptorUtil
|
||||
import javax.swing.Icon
|
||||
|
||||
@ApiStatus.Internal
|
||||
object SplitModeModuleKindIcons {
|
||||
@JvmStatic
|
||||
fun isCustomIconsEnabled(): Boolean {
|
||||
return Registry.`is`("devkit.split.mode.custom.icons", false)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getDescriptorIcon(descriptorFile: PsiFile): Icon? {
|
||||
if (!isCustomIconsEnabled() || DumbService.isDumb(descriptorFile.project)) return null
|
||||
val kind = recognizeSplitModeModuleKind(descriptorFile)?.kind ?: return null
|
||||
return getKindIcon(kind, descriptorFile.name)
|
||||
val fastIcon = getFastDescriptorIcon(descriptorFile) ?: return null
|
||||
if (!isAccurateIconsEnabled() || DumbService.isDumb(descriptorFile.project)) return fastIcon
|
||||
|
||||
val virtualFile = descriptorFile.virtualFile ?: return fastIcon
|
||||
return IconDeferrer.getInstance().deferAsync(fastIcon, DescriptorIconDeferredKey(descriptorFile.project, virtualFile)) {
|
||||
getAccurateDescriptorIcon(descriptorFile, fastIcon)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@@ -43,4 +51,64 @@ object SplitModeModuleKindIcons {
|
||||
private fun followsSharedModuleNamingConvention(moduleName: @NlsSafe String): Boolean {
|
||||
return moduleName.endsWith(".shared.xml") || moduleName.endsWith(".common.xml") || moduleName.contains(".frontback")
|
||||
}
|
||||
|
||||
private fun isAccurateIconsEnabled(): Boolean {
|
||||
return RegistryManager.getInstance().`is`("devkit.split.mode.custom.icons")
|
||||
}
|
||||
|
||||
private fun getFastDescriptorIcon(descriptorFile: PsiFile): Icon? {
|
||||
val kind = getOrComputeModuleKindFast(descriptorFile) ?: return null
|
||||
return getKindIcon(kind, descriptorFile.name)
|
||||
}
|
||||
|
||||
private suspend fun getAccurateDescriptorIcon(descriptorFile: PsiFile, fastIcon: Icon): Icon {
|
||||
return smartReadAction(descriptorFile.project) {
|
||||
val kind = recognizeSplitModeModuleKind(descriptorFile)?.kind
|
||||
kind?.let { getKindIcon(it, descriptorFile.name) } ?: fastIcon
|
||||
}
|
||||
}
|
||||
|
||||
private fun recognizeLightweightModuleKind(descriptorFile: PsiFile): SplitModeApiRestrictionsService.ModuleKind? {
|
||||
val explicitDependencyKinds = collectExplicitDependencyKinds(descriptorFile)
|
||||
return when {
|
||||
explicitDependencyKinds.size > 1 -> SplitModeApiRestrictionsService.ModuleKind.MIXED
|
||||
explicitDependencyKinds.size == 1 -> explicitDependencyKinds.single()
|
||||
else -> inferModuleKindFromFileName(descriptorFile.name)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getOrComputeModuleKindFast(descriptorFile: PsiFile): SplitModeApiRestrictionsService.ModuleKind? {
|
||||
return CachedValuesManager.getCachedValue(descriptorFile) {
|
||||
CachedValueProvider.Result.create(
|
||||
recognizeLightweightModuleKind(descriptorFile),
|
||||
descriptorFile.manager.modificationTracker.forLanguage(XMLLanguage.INSTANCE),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun collectExplicitDependencyKinds(descriptorFile: PsiFile): Set<SplitModeApiRestrictionsService.ModuleKind> {
|
||||
val xmlFile = descriptorFile as? XmlFile ?: return emptySet()
|
||||
val ideaPlugin = DescriptorUtil.getIdeaPlugin(xmlFile) ?: return emptySet()
|
||||
val explicitDependencyKinds = LinkedHashSet<SplitModeApiRestrictionsService.ModuleKind>()
|
||||
for (dependencyName in SplitModeDescriptorDependencyAnalyzer.collectDirectDependencyNames(ideaPlugin)) {
|
||||
val dependencyKind = recognizeExplicitDependencyKind(dependencyName) ?: continue
|
||||
explicitDependencyKinds.add(dependencyKind)
|
||||
}
|
||||
return explicitDependencyKinds
|
||||
}
|
||||
|
||||
private fun inferModuleKindFromFileName(descriptorFileName: @NlsSafe String): SplitModeApiRestrictionsService.ModuleKind? {
|
||||
return when {
|
||||
descriptorFileName == "plugin.xml" -> SplitModeApiRestrictionsService.ModuleKind.SHARED
|
||||
descriptorFileName.endsWith(".frontend.xml") || descriptorFileName.endsWith(".frontend.split.xml") -> SplitModeApiRestrictionsService.ModuleKind.FRONTEND
|
||||
descriptorFileName.endsWith(".backend.xml") || descriptorFileName.endsWith(".backend.split.xml") -> SplitModeApiRestrictionsService.ModuleKind.BACKEND
|
||||
followsSharedModuleNamingConvention(descriptorFileName) -> SplitModeApiRestrictionsService.ModuleKind.SHARED
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private data class DescriptorIconDeferredKey(
|
||||
val project: Project,
|
||||
val virtualFile: VirtualFile,
|
||||
)
|
||||
|
||||
+43
-1
@@ -1,15 +1,27 @@
|
||||
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.idea.devkit.inspections.remotedev.analysis
|
||||
|
||||
import com.intellij.lang.xml.XMLLanguage
|
||||
import com.intellij.openapi.diagnostic.debug
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.ModuleUtilCore
|
||||
import com.intellij.openapi.roots.ProjectRootModificationTracker
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.psi.util.CachedValue
|
||||
import com.intellij.psi.util.CachedValueProvider
|
||||
import com.intellij.psi.util.CachedValuesManager
|
||||
import com.intellij.psi.xml.XmlFile
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.SplitModeInspectionUtil.findDependingContentModuleEntriesInFile
|
||||
import org.jetbrains.idea.devkit.module.PluginModuleType
|
||||
import org.jetbrains.idea.devkit.util.DescriptorUtil
|
||||
|
||||
private val MODULE_ID_ANALYSIS_KEY =
|
||||
Key.create<CachedValue<ModuleAnalysis>>("SplitModeModuleKindResolver.moduleIdAnalysis")
|
||||
|
||||
private val MODULE_DESCRIPTOR_ANALYSIS_KEY =
|
||||
Key.create<CachedValue<ModuleAnalysis>>("SplitModeModuleKindResolver.moduleDescriptorAnalysis")
|
||||
|
||||
internal object SplitModeModuleKindResolver {
|
||||
private val LOG = logger<SplitModeModuleKindResolver>()
|
||||
|
||||
@@ -20,17 +32,47 @@ internal object SplitModeModuleKindResolver {
|
||||
return expectedKind.accepts(actualApiUsageModuleKind.kind)
|
||||
}
|
||||
|
||||
fun isApiUsageAllowed(
|
||||
actualModuleAnalysis: ModuleAnalysis,
|
||||
apiRestriction: SplitModeApiRestrictionsService.ApiRestrictionMatch,
|
||||
): Boolean {
|
||||
val actualModuleKind = actualModuleAnalysis.resolvedModuleKind
|
||||
return doesApiKindMatchExpectedModuleKind(actualModuleKind, apiRestriction.targetModuleKind)
|
||||
|| actualModuleKind.kind == SplitModeApiRestrictionsService.ModuleKind.BACKEND
|
||||
&& actualModuleAnalysis.apiUsagePolicy == ApiUsagePolicy.BACKEND_WITH_NON_UI_API_PERMIT
|
||||
&& apiRestriction.restrictionKind == SplitModeApiRestrictionsService.ApiRestrictionKind.GENERIC_PLATFORM_API
|
||||
}
|
||||
|
||||
fun getOrComputeModuleAnalysis(module: Module, descriptorFile: XmlFile? = null): ModuleAnalysis {
|
||||
val xmlDescriptor = descriptorFile ?: PluginModuleType.getContentModuleDescriptorXml(module) ?: PluginModuleType.getPluginXml(module)
|
||||
if (xmlDescriptor == null) {
|
||||
return ModuleAnalysis(ResolvedModuleKind(SplitModeApiRestrictionsService.ModuleKind.SHARED, ""))
|
||||
}
|
||||
|
||||
val cacheKey = if (descriptorFile == null) MODULE_ID_ANALYSIS_KEY else MODULE_DESCRIPTOR_ANALYSIS_KEY
|
||||
return CachedValuesManager.getManager(module.project).getCachedValue(xmlDescriptor, cacheKey, {
|
||||
CachedValueProvider.Result.create(
|
||||
computeModuleAnalysis(module, descriptorFile),
|
||||
ProjectRootModificationTracker.getInstance(module.project),
|
||||
xmlDescriptor.manager.modificationTracker.forLanguage(XMLLanguage.INSTANCE),
|
||||
)
|
||||
}, false)
|
||||
}
|
||||
|
||||
private fun computeModuleAnalysis(module: Module, descriptorFile: XmlFile? = null): ModuleAnalysis {
|
||||
val xmlDescriptor = descriptorFile ?: PluginModuleType.getContentModuleDescriptorXml(module) ?: PluginModuleType.getPluginXml(module)
|
||||
if (xmlDescriptor == null) {
|
||||
return ModuleAnalysis(ResolvedModuleKind(SplitModeApiRestrictionsService.ModuleKind.SHARED, ""))
|
||||
}
|
||||
|
||||
val parsedXmlDescriptor = DescriptorUtil.getIdeaPlugin(xmlDescriptor)
|
||||
val predefinedModuleKind =
|
||||
SplitModeApiRestrictionsService.getInstance(module.project).getPredefinedModuleKind(module, xmlDescriptor, parsedXmlDescriptor)
|
||||
if (predefinedModuleKind != null) {
|
||||
return ModuleAnalysis(ResolvedModuleKind(predefinedModuleKind.moduleKind, predefinedModuleKind.reasoning))
|
||||
return ModuleAnalysis(
|
||||
resolvedModuleKind = ResolvedModuleKind(predefinedModuleKind.moduleKind, predefinedModuleKind.reasoning),
|
||||
apiUsagePolicy = predefinedModuleKind.apiUsagePolicy,
|
||||
)
|
||||
}
|
||||
if (parsedXmlDescriptor == null) {
|
||||
return ModuleAnalysis(ResolvedModuleKind(SplitModeApiRestrictionsService.ModuleKind.SHARED, ""))
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.idea.devkit.navigation
|
||||
|
||||
import com.intellij.codeInsight.hints.declarative.HintFormat
|
||||
import com.intellij.codeInsight.hints.declarative.InlayHintsCollector
|
||||
import com.intellij.codeInsight.hints.declarative.InlayHintsProvider
|
||||
import com.intellij.codeInsight.hints.declarative.InlayTreeSink
|
||||
import com.intellij.codeInsight.hints.declarative.InlineInlayPosition
|
||||
import com.intellij.codeInsight.hints.declarative.OwnBypassCollector
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.module.ModuleUtilCore
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.xml.XmlFile
|
||||
import com.intellij.psi.xml.XmlToken
|
||||
import com.intellij.psi.xml.XmlTokenType
|
||||
import com.intellij.xml.util.XmlUtil
|
||||
import org.jetbrains.idea.devkit.DevKitBundle
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.SplitModeInspectionUtil.findDependingContentModuleEntriesInFile
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.analysis.SplitModeApiRestrictionsService.ModuleKind
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.analysis.recognizeSplitModeModuleKind
|
||||
import org.jetbrains.idea.devkit.module.PluginModuleType
|
||||
|
||||
internal class DescriptorSplitModeInlayHintsProvider : InlayHintsProvider {
|
||||
|
||||
override fun createCollector(file: PsiFile, editor: Editor): InlayHintsCollector? {
|
||||
if (!isDescriptorSplitModeInlayEnabled()) return null
|
||||
val xmlFile = file as? XmlFile ?: return null
|
||||
if (findIdeaPluginRootTagNameToken(xmlFile) == null) return null
|
||||
return DescriptorSplitModeInlayHintsCollector()
|
||||
}
|
||||
|
||||
private class DescriptorSplitModeInlayHintsCollector : OwnBypassCollector {
|
||||
override fun collectHintsForFile(file: PsiFile, sink: InlayTreeSink) {
|
||||
val xmlFile = file as? XmlFile ?: return
|
||||
val tagNameToken = findIdeaPluginRootTagNameToken(xmlFile) ?: return
|
||||
val inlayInfo = getDescriptorSplitModeInlayInfo(xmlFile) ?: return
|
||||
|
||||
sink.addPresentation(
|
||||
InlineInlayPosition(tagNameToken.textRange.endOffset, true),
|
||||
tooltip = inlayInfo.tooltip,
|
||||
hintFormat = HintFormat.default,
|
||||
) {
|
||||
text(inlayInfo.text)
|
||||
}
|
||||
}
|
||||
|
||||
override fun shouldSuggestToggling(project: Project, editor: Editor, file: PsiFile): Boolean {
|
||||
return isDescriptorSplitModeInlayEnabled() && file is XmlFile && findIdeaPluginRootTagNameToken(file) != null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal data class DescriptorSplitModeInlayInfo(
|
||||
val text: String,
|
||||
val tooltip: String,
|
||||
)
|
||||
|
||||
internal fun getDescriptorSplitModeInlayInfo(xmlFile: XmlFile): DescriptorSplitModeInlayInfo? {
|
||||
val recognizedModuleKind = recognizeSplitModeModuleKind(xmlFile) ?: return null
|
||||
val descriptorKindMessageKey = getDescriptorKindMessageKey(xmlFile)
|
||||
val descriptorKind = DevKitBundle.message(descriptorKindMessageKey)
|
||||
return DescriptorSplitModeInlayInfo(
|
||||
DevKitBundle.message(
|
||||
"inlay.split.mode.module.kind.presentation",
|
||||
getPresentableModuleKind(recognizedModuleKind.kind),
|
||||
descriptorKind,
|
||||
),
|
||||
DevKitBundle.message(
|
||||
"inlay.split.mode.module.kind.tooltip",
|
||||
descriptorKind,
|
||||
getCompatibilityTarget(recognizedModuleKind.kind),
|
||||
normalizeTooltipReasoning(recognizedModuleKind.reasoning),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun normalizeTooltipReasoning(reasoning: String): String {
|
||||
return reasoning.lineSequence().map(String::trim).filter(String::isNotEmpty).joinToString(" ")
|
||||
}
|
||||
|
||||
private fun isDescriptorSplitModeInlayEnabled(): Boolean {
|
||||
return Registry.`is`("devkit.split.mode.inlay.plugin.descriptor.kind")
|
||||
}
|
||||
|
||||
private fun getPresentableModuleKind(kind: ModuleKind): String {
|
||||
val presentableId = when (kind) {
|
||||
ModuleKind.FRONTEND -> ModuleKind.FRONTEND.id
|
||||
ModuleKind.BACKEND -> ModuleKind.BACKEND.id
|
||||
ModuleKind.SHARED -> ModuleKind.SHARED.id
|
||||
ModuleKind.MONOLITH,
|
||||
ModuleKind.MIXED,
|
||||
-> ModuleKind.MONOLITH.id
|
||||
is ModuleKind.Composite -> kind.id
|
||||
}
|
||||
return StringUtil.capitalize(presentableId)
|
||||
}
|
||||
|
||||
private fun getCompatibilityTarget(kind: ModuleKind): String {
|
||||
val messageKey = when (kind) {
|
||||
ModuleKind.FRONTEND -> "inlay.split.mode.module.kind.compatibility.frontend"
|
||||
ModuleKind.BACKEND -> "inlay.split.mode.module.kind.compatibility.backend"
|
||||
ModuleKind.SHARED -> "inlay.split.mode.module.kind.compatibility.shared"
|
||||
ModuleKind.MONOLITH,
|
||||
ModuleKind.MIXED,
|
||||
-> "inlay.split.mode.module.kind.compatibility.monolith"
|
||||
is ModuleKind.Composite -> "inlay.split.mode.module.kind.compatibility.shared"
|
||||
}
|
||||
return DevKitBundle.message(messageKey)
|
||||
}
|
||||
|
||||
private fun getDescriptorKindMessageKey(xmlFile: XmlFile): String {
|
||||
if (xmlFile.name == "plugin.xml") {
|
||||
return "inlay.split.mode.module.kind.plugin"
|
||||
}
|
||||
if (isContentModuleDescriptor(xmlFile)) {
|
||||
return "inlay.split.mode.module.kind.content.module"
|
||||
}
|
||||
return "inlay.split.mode.module.kind.xml.descriptor"
|
||||
}
|
||||
|
||||
private fun isContentModuleDescriptor(xmlFile: XmlFile): Boolean {
|
||||
val module = ModuleUtilCore.findModuleForPsiElement(xmlFile)
|
||||
if (PluginModuleType.getContentModuleDescriptorXml(module)?.virtualFile == xmlFile.virtualFile) {
|
||||
return true
|
||||
}
|
||||
if (module != null && xmlFile.name in computePossibleContentModuleDescriptorNames(module.name)) {
|
||||
return true
|
||||
}
|
||||
return findDependingContentModuleEntriesInFile(xmlFile).any()
|
||||
}
|
||||
|
||||
private fun computePossibleContentModuleDescriptorNames(moduleName: String): List<String> {
|
||||
return listOf(
|
||||
"$moduleName.xml",
|
||||
"${moduleName.replace(".main", "")}.xml",
|
||||
"${moduleName.replace("_", ".").replace(".main", "")}.xml",
|
||||
)
|
||||
}
|
||||
|
||||
private fun findIdeaPluginRootTagNameToken(xmlFile: XmlFile): XmlToken? {
|
||||
val rootTag = xmlFile.rootTag ?: return null
|
||||
val tagNameToken = XmlUtil.getTokenOfType(rootTag, XmlTokenType.XML_NAME) ?: return null
|
||||
return tagNameToken.takeIf(::isIdeaPluginElementNameLeaf)
|
||||
}
|
||||
+10
-10
@@ -47,15 +47,6 @@ internal class DescriptorsIncludingContentModuleLineMarkerProvider : DevkitRelat
|
||||
}
|
||||
}
|
||||
|
||||
private fun isIdeaPluginElementNameLeaf(leaf: PsiElement): Boolean {
|
||||
if (leaf !is XmlToken) return false
|
||||
if (leaf.getNode().elementType != XmlTokenType.XML_NAME) return false
|
||||
val prev = PsiTreeUtil.getPrevSiblingOfType(leaf, XmlToken::class.java)
|
||||
if (prev == null || prev.node.elementType !== XmlTokenType.XML_START_TAG_START) return false
|
||||
if (!leaf.textMatches("idea-plugin")) return false
|
||||
return DomUtil.getDomElement(leaf) is IdeaPlugin
|
||||
}
|
||||
|
||||
private fun findDependingContentModuleEntries(element: PsiElement): List<ModuleDescriptor> {
|
||||
val xmlFile = element.containingFile as? XmlFile ?: return emptyList()
|
||||
return findDependingContentModuleEntriesInFile(xmlFile).toList()
|
||||
@@ -109,4 +100,13 @@ internal class DescriptorsIncludingContentModuleLineMarkerProvider : DevkitRelat
|
||||
return moduleDescriptor.loading.value?.value ?: "optional"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun isIdeaPluginElementNameLeaf(leaf: PsiElement): Boolean {
|
||||
if (leaf !is XmlToken) return false
|
||||
if (leaf.getNode().elementType != XmlTokenType.XML_NAME) return false
|
||||
val prev = PsiTreeUtil.getPrevSiblingOfType(leaf, XmlToken::class.java)
|
||||
if (prev == null || prev.node.elementType !== XmlTokenType.XML_START_TAG_START) return false
|
||||
if (!leaf.textMatches("idea-plugin")) return false
|
||||
return DomUtil.getDomElement(leaf) is IdeaPlugin
|
||||
}
|
||||
|
||||
@@ -130,6 +130,8 @@ jvm_library(
|
||||
"//java/compiler:compiler-tests_test_lib",
|
||||
"//java/testFramework",
|
||||
"//java/testFramework:testFramework_test_lib",
|
||||
"//plugins/junit",
|
||||
"//plugins/junit:junit_test_lib",
|
||||
"//xml/dom-tests",
|
||||
"//xml/dom-tests:dom-tests_test_lib",
|
||||
"//plugins/properties:properties-backend",
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
<orderEntry type="module" module-name="intellij.platform.testFramework.junit5.codeInsight" />
|
||||
<orderEntry type="module" module-name="intellij.java.compiler.tests" scope="TEST" />
|
||||
<orderEntry type="module" module-name="intellij.java.testFramework" scope="TEST" />
|
||||
<orderEntry type="module" module-name="intellij.junit" scope="TEST" />
|
||||
<orderEntry type="module" module-name="intellij.xml.dom.tests" scope="TEST" />
|
||||
<orderEntry type="module" module-name="intellij.properties.backend" />
|
||||
<orderEntry type="module" module-name="intellij.platform.core.ui" />
|
||||
|
||||
+91
-40
@@ -2,11 +2,11 @@
|
||||
package org.jetbrains.idea.devkit.descriptor
|
||||
|
||||
import com.intellij.devkit.core.icons.DevkitCoreIcons
|
||||
import com.intellij.ide.IconProvider
|
||||
import com.intellij.icons.AllIcons.Nodes.Plugin
|
||||
import com.intellij.openapi.application.invokeAndWaitIfNeeded
|
||||
import com.intellij.openapi.application.runReadActionBlocking
|
||||
import com.intellij.openapi.project.IntelliJProjectUtil
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.testFramework.IndexingTestUtil
|
||||
import com.intellij.testFramework.PsiTestUtil
|
||||
@@ -38,45 +38,85 @@ internal class PluginDescriptorSplitModeIconsTest {
|
||||
|
||||
@Test
|
||||
@RegistryKey(key = "devkit.plugin.directory.icons", value = "true")
|
||||
fun `descriptor and directory icons follow split mode kind`() {
|
||||
Registry.get("devkit.split.mode.custom.icons").setValue(true)
|
||||
@RegistryKey(key = "devkit.split.mode.custom.icons", value = "false")
|
||||
fun `descriptor and directory icons use fast split mode kind when accurate icons are disabled`() {
|
||||
IntelliJProjectUtil.markAsIntelliJPlatformProject(project, true)
|
||||
try {
|
||||
createModuleDescriptor("module.shared", "module.shared.xml", """
|
||||
<idea-plugin>
|
||||
</idea-plugin>
|
||||
""".trimIndent())
|
||||
createSharedPluginDescriptor("""
|
||||
<idea-plugin>
|
||||
</idea-plugin>
|
||||
""".trimIndent())
|
||||
createFrontendPluginDescriptor("""
|
||||
<idea-plugin>
|
||||
<dependencies>
|
||||
<module name="intellij.platform.frontend"/>
|
||||
</dependencies>
|
||||
</idea-plugin>
|
||||
""".trimIndent())
|
||||
createModuleDescriptor("module.backend", "module.backend.xml", """
|
||||
<idea-plugin>
|
||||
<dependencies>
|
||||
<module name="intellij.platform.backend"/>
|
||||
</dependencies>
|
||||
</idea-plugin>
|
||||
""".trimIndent())
|
||||
IndexingTestUtil.waitUntilIndexesAreReady(project)
|
||||
createSplitModeIconFixtures()
|
||||
|
||||
assertFileIcon("shared.plugin/resources/META-INF/plugin.xml", Plugin)
|
||||
assertFileIcon("module.shared/resources/module.shared.xml", DevkitCoreIcons.SharedModule)
|
||||
assertFileIcon("frontend.plugin/resources/META-INF/plugin.xml", DevkitCoreIcons.FrontendModule)
|
||||
assertFileIcon(
|
||||
"intellij.transitive.frontend/resources/intellij.transitive.frontend.xml",
|
||||
DevkitCoreIcons.FrontendModule,
|
||||
)
|
||||
assertFileIcon("module.backend/resources/module.backend.xml", DevkitCoreIcons.BackendModule)
|
||||
assertFileIcon("transitive.consumer/resources/META-INF/plugin.xml", Plugin)
|
||||
assertDirectoryIcon("frontend.plugin", DevkitCoreIcons.FrontendModule)
|
||||
assertDirectoryIcon("transitive.consumer", Plugin)
|
||||
}
|
||||
finally {
|
||||
IntelliJProjectUtil.markAsIntelliJPlatformProject(project, false)
|
||||
Registry.get("devkit.split.mode.custom.icons").setValue(false)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@RegistryKey(key = "devkit.plugin.directory.icons", value = "true")
|
||||
@RegistryKey(key = "devkit.split.mode.custom.icons", value = "true")
|
||||
fun `descriptor and directory icons resolve accurate split mode kind when enabled`() {
|
||||
IntelliJProjectUtil.markAsIntelliJPlatformProject(project, true)
|
||||
try {
|
||||
createSplitModeIconFixtures()
|
||||
|
||||
assertFileIcon("transitive.consumer/resources/META-INF/plugin.xml", DevkitCoreIcons.FrontendModule)
|
||||
assertDirectoryIcon("transitive.consumer", DevkitCoreIcons.FrontendModule)
|
||||
}
|
||||
finally {
|
||||
IntelliJProjectUtil.markAsIntelliJPlatformProject(project, false)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createSplitModeIconFixtures() {
|
||||
createModuleDescriptor("module.shared", "module.shared.xml", """
|
||||
<idea-plugin>
|
||||
</idea-plugin>
|
||||
""".trimIndent())
|
||||
createSharedPluginDescriptor("""
|
||||
<idea-plugin>
|
||||
</idea-plugin>
|
||||
""".trimIndent())
|
||||
createFrontendPluginDescriptor("""
|
||||
<idea-plugin>
|
||||
<dependencies>
|
||||
<module name="intellij.platform.frontend"/>
|
||||
</dependencies>
|
||||
</idea-plugin>
|
||||
""".trimIndent())
|
||||
createModuleDescriptor("intellij.transitive.frontend", "intellij.transitive.frontend.xml", """
|
||||
<idea-plugin>
|
||||
<dependencies>
|
||||
<module name="intellij.platform.frontend"/>
|
||||
</dependencies>
|
||||
</idea-plugin>
|
||||
""".trimIndent())
|
||||
createModuleDescriptor("module.backend", "module.backend.xml", """
|
||||
<idea-plugin>
|
||||
<dependencies>
|
||||
<module name="intellij.platform.backend"/>
|
||||
</dependencies>
|
||||
</idea-plugin>
|
||||
""".trimIndent())
|
||||
createPluginDescriptor("transitive.consumer", """
|
||||
<idea-plugin>
|
||||
<dependencies>
|
||||
<module name="intellij.transitive.frontend"/>
|
||||
</dependencies>
|
||||
</idea-plugin>
|
||||
""".trimIndent())
|
||||
IndexingTestUtil.waitUntilIndexesAreReady(project)
|
||||
}
|
||||
|
||||
private fun createModuleDescriptor(moduleName: String, descriptorName: String, descriptorText: String) {
|
||||
val moduleRoot = projectModel.baseProjectDir.newVirtualDirectory(moduleName)
|
||||
val module = PsiTestUtil.addModule(project, PluginModuleType.getInstance(), moduleName, moduleRoot)
|
||||
@@ -86,18 +126,14 @@ internal class PluginDescriptorSplitModeIconsTest {
|
||||
}
|
||||
|
||||
private fun createFrontendPluginDescriptor(descriptorText: String) {
|
||||
val moduleName = "frontend.plugin"
|
||||
val moduleRoot = projectModel.baseProjectDir.newVirtualDirectory(moduleName)
|
||||
val module = PsiTestUtil.addModule(project, PluginModuleType.getInstance(), moduleName, moduleRoot)
|
||||
val resourcesRoot = projectModel.baseProjectDir.newVirtualDirectory("$moduleName/resources")
|
||||
PsiTestUtil.addSourceRoot(module, resourcesRoot, JavaResourceRootType.RESOURCE)
|
||||
val descriptorFile =
|
||||
projectModel.baseProjectDir.newVirtualFile("$moduleName/resources/META-INF/plugin.xml", descriptorText.toByteArray())
|
||||
PluginBuildConfiguration.getInstance(module)!!.setPluginXmlFromVirtualFile(descriptorFile)
|
||||
createPluginDescriptor("frontend.plugin", descriptorText)
|
||||
}
|
||||
|
||||
private fun createSharedPluginDescriptor(descriptorText: String) {
|
||||
val moduleName = "shared.plugin"
|
||||
createPluginDescriptor("shared.plugin", descriptorText)
|
||||
}
|
||||
|
||||
private fun createPluginDescriptor(moduleName: String, descriptorText: String) {
|
||||
val moduleRoot = projectModel.baseProjectDir.newVirtualDirectory(moduleName)
|
||||
val module = PsiTestUtil.addModule(project, PluginModuleType.getInstance(), moduleName, moduleRoot)
|
||||
val resourcesRoot = projectModel.baseProjectDir.newVirtualDirectory("$moduleName/resources")
|
||||
@@ -109,13 +145,28 @@ internal class PluginDescriptorSplitModeIconsTest {
|
||||
|
||||
private fun assertFileIcon(relativePath: String, expectedIcon: Icon) {
|
||||
assertIcon(expectedIcon) {
|
||||
PsiManager.getInstance(project).findFile(projectModel.baseProjectDir.virtualFileRoot.findFileByRelativePath(relativePath)!!)!!
|
||||
val file = PsiManager.getInstance(project).findFile(projectModel.baseProjectDir.virtualFileRoot.findFileByRelativePath(relativePath)!!)!!
|
||||
PsiIconUtil.getIconFromProviders(file, 0)
|
||||
}
|
||||
}
|
||||
|
||||
private fun assertIcon(expectedIcon: Icon, psiElementProvider: () -> com.intellij.psi.PsiElement) {
|
||||
private fun assertDirectoryIcon(relativePath: String, expectedIcon: Icon) {
|
||||
assertIcon(expectedIcon) {
|
||||
val directory = PsiManager.getInstance(project)
|
||||
.findDirectory(projectModel.baseProjectDir.virtualFileRoot.findFileByRelativePath(relativePath)!!)!!
|
||||
getScaffoldingDirectoryIconProvider().getIcon(directory, 0)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getScaffoldingDirectoryIconProvider(): IconProvider {
|
||||
return IconProvider.EXTENSION_POINT_NAME.extensionList.single {
|
||||
it.javaClass.name == "com.intellij.devkit.scaffolding.ScaffoldingDirectoryIconProvider"
|
||||
}
|
||||
}
|
||||
|
||||
private fun assertIcon(expectedIcon: Icon, iconProvider: () -> Icon?) {
|
||||
val iconFromProviders = runReadActionBlocking {
|
||||
PsiIconUtil.getIconFromProviders(psiElementProvider(), 0)
|
||||
iconProvider()
|
||||
}
|
||||
checkNotNull(iconFromProviders)
|
||||
awaitDeferredIcons(iconFromProviders)
|
||||
@@ -130,13 +181,13 @@ internal class PluginDescriptorSplitModeIconsTest {
|
||||
is DeferredIconImpl<*> -> runBlocking {
|
||||
icon.awaitEvaluation()
|
||||
}
|
||||
is RetrievableIcon -> awaitDeferredIcons(icon.retrieveIcon())
|
||||
is CompositeIcon -> {
|
||||
for (i in 0 until icon.iconCount) {
|
||||
val nestedIcon = icon.getIcon(i) ?: continue
|
||||
awaitDeferredIcons(nestedIcon)
|
||||
}
|
||||
}
|
||||
is RetrievableIcon -> awaitDeferredIcons(icon.retrieveIcon())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-136
@@ -1,18 +1,12 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.idea.devkit.inspections
|
||||
|
||||
import com.intellij.openapi.command.WriteCommandAction
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager
|
||||
import com.intellij.openapi.project.IntelliJProjectUtil
|
||||
import com.intellij.openapi.vfs.VfsUtil
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.testFramework.PsiTestUtil
|
||||
import com.intellij.testFramework.fixtures.CodeInsightTestFixture
|
||||
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.EXCLUSIONS_RELATIVE_PATH
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.MissingFrontendOrBackendRuntimeDependencyInspection
|
||||
import org.jetbrains.idea.devkit.module.PluginModuleType
|
||||
|
||||
@@ -49,48 +43,6 @@ internal class MissingFrontendOrBackendRuntimeDependencyInspectionTest : JavaCod
|
||||
fun testShouldNotCrashOnCyclicDependencyInFrontend() = testShouldNotCrashOnCyclicDependency("frontend")
|
||||
fun testShouldNotCrashOnCyclicDependencyInBackend() = testShouldNotCrashOnCyclicDependency("backend")
|
||||
|
||||
fun testShouldNotReportExcludedFrontendDependency() {
|
||||
myFixture.addSplitModeExclusionsFile(splitModeExclusionsJson(
|
||||
missingRuntimeDependencyExclusion("intellij.test.feature.frontend.xml", 2)
|
||||
))
|
||||
|
||||
val testedFile = myFixture.addXmlFile("intellij.test.feature.frontend.xml", """
|
||||
<idea-plugin>
|
||||
<dependencies>
|
||||
<!-- no dependency -->
|
||||
</dependencies>
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
)
|
||||
testHighlighting(testedFile)
|
||||
}
|
||||
|
||||
fun testShouldReportWhenExclusionsFileIsEmpty() {
|
||||
myFixture.addSplitModeExclusionsFile("")
|
||||
testReportDependency("frontend")
|
||||
}
|
||||
|
||||
fun testExclusionsInvalidatedAfterJsonChange() {
|
||||
val exclusionsFile = myFixture.addSplitModeExclusionsFile("""{ "exclusions": [] }""")
|
||||
val testedFile = myFixture.addXmlFile("intellij.test.feature.frontend.xml", """
|
||||
<idea-plugin>
|
||||
<dependencies>
|
||||
<!-- no dependency -->
|
||||
</dependencies>
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
)
|
||||
assertTrue(hasMissingFrontendRuntimeDependencyWarning(testedFile))
|
||||
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
VfsUtil.saveText(exclusionsFile.virtualFile, splitModeExclusionsJson(
|
||||
missingRuntimeDependencyExclusion("intellij.test.feature.frontend.xml", 2)
|
||||
))
|
||||
}
|
||||
|
||||
assertFalse(hasMissingFrontendRuntimeDependencyWarning(testedFile))
|
||||
}
|
||||
|
||||
private fun testReportDependency(frontendOrBackend: String) {
|
||||
val testedFile = myFixture.addXmlFile("intellij.test.feature.$frontendOrBackend.xml", """
|
||||
<idea-plugin>
|
||||
@@ -212,13 +164,6 @@ internal class MissingFrontendOrBackendRuntimeDependencyInspectionTest : JavaCod
|
||||
private fun testHighlighting(testedFile: PsiFile) {
|
||||
myFixture.testHighlighting(true, true, true, testedFile.virtualFile)
|
||||
}
|
||||
|
||||
private fun hasMissingFrontendRuntimeDependencyWarning(testedFile: PsiFile): Boolean {
|
||||
val expectedDescription = "The name of the current module 'intellij.test.feature.frontend' ends with '.frontend', " +
|
||||
"but the dependency on 'intellij.platform.frontend' is missing"
|
||||
myFixture.configureFromExistingVirtualFile(testedFile.virtualFile)
|
||||
return myFixture.doHighlighting().any { it.description == expectedDescription }
|
||||
}
|
||||
}
|
||||
|
||||
internal class MissingFrontendOrBackendRuntimeDependencyFixTest : JavaCodeInsightFixtureTestCase() {
|
||||
@@ -236,57 +181,6 @@ internal class MissingFrontendOrBackendRuntimeDependencyFixTest : JavaCodeInsigh
|
||||
|
||||
fun testAddingBackendDependencyWhenDependenciesElementDoesNotExist() = testAddingDependencyWhenDependenciesElementDoesNotExist("backend")
|
||||
|
||||
fun testAddToExclusionsFixIsHiddenOutsideIntelliJProject() {
|
||||
IntelliJProjectUtil.markAsIntelliJPlatformProject(project, false)
|
||||
|
||||
val testedFile = myFixture.addXmlFile("intellij.test.feature.frontend.xml", """
|
||||
<idea-<caret>plugin>
|
||||
<!-- no dependency -->
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
)
|
||||
myFixture.configureFromExistingVirtualFile(testedFile.virtualFile)
|
||||
|
||||
val splitModeFixes = myFixture.getAllQuickFixes().map { it.text }
|
||||
assertFalse(splitModeFixes.contains(addToExclusionsFixName()))
|
||||
}
|
||||
|
||||
fun testAddToExclusionsFixIsLastAndAppendsEntry() {
|
||||
IntelliJProjectUtil.markAsIntelliJPlatformProject(project, true)
|
||||
|
||||
val testedFile = myFixture.addXmlFile("intellij.test.feature.frontend.xml", """
|
||||
<idea-<caret>plugin>
|
||||
<!-- no dependency -->
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
)
|
||||
myFixture.configureFromExistingVirtualFile(testedFile.virtualFile)
|
||||
|
||||
val dependencyFixName = addRuntimeDependencyFixName("frontend")
|
||||
val exclusionsFixName = addToExclusionsFixName()
|
||||
val splitModeFixes = myFixture.getAllQuickFixes()
|
||||
.map { it.text }
|
||||
.filter { it == dependencyFixName || it == exclusionsFixName }
|
||||
assertSameElements(splitModeFixes, dependencyFixName, exclusionsFixName)
|
||||
assertEquals(exclusionsFixName, splitModeFixes.last())
|
||||
|
||||
val intention = myFixture.findSingleIntention(exclusionsFixName)
|
||||
myFixture.launchAction(intention)
|
||||
|
||||
val exclusionsFile = myFixture.findFileInTempDir(EXCLUSIONS_RELATIVE_PATH)
|
||||
val exclusionsText = VfsUtilCore.loadText(exclusionsFile)
|
||||
assertTrue(exclusionsText.contains("\"inspection\": \"MissingFrontendOrBackendRuntimeDependency\""))
|
||||
assertTrue(exclusionsText.contains("\"file\": \"intellij.test.feature.frontend.xml\""))
|
||||
assertTrue(exclusionsText.contains("\"line\": 1"))
|
||||
assertTrue(exclusionsText.contains("\"reason\": \"\""))
|
||||
|
||||
val fileEditorManager = FileEditorManager.getInstance(project)
|
||||
assertEquals(exclusionsFile, fileEditorManager.selectedEditor?.file)
|
||||
val selectedTextEditor = fileEditorManager.selectedTextEditor
|
||||
assertNotNull(selectedTextEditor)
|
||||
assertEquals(selectedTextEditor!!.document.lineCount - 1, selectedTextEditor.caretModel.logicalPosition.line)
|
||||
}
|
||||
|
||||
private fun testAddingDependency(frontendOrBackend: String) {
|
||||
doTest(
|
||||
frontendOrBackend,
|
||||
@@ -328,42 +222,12 @@ internal class MissingFrontendOrBackendRuntimeDependencyFixTest : JavaCodeInsigh
|
||||
assertTrue(fileText.contains("<dependencies>"))
|
||||
assertTrue(fileText.contains("intellij.platform.$frontendOrBackend"))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun CodeInsightTestFixture.addXmlFile(relativePath: String, @Language("XML") fileText: String): PsiFile {
|
||||
return this.addFileToProject(relativePath, fileText)
|
||||
}
|
||||
|
||||
private fun CodeInsightTestFixture.addSplitModeExclusionsFile(@Language("JSON") fileText: String): PsiFile {
|
||||
return addFileToProject(EXCLUSIONS_RELATIVE_PATH, fileText)
|
||||
}
|
||||
|
||||
private fun splitModeExclusionsJson(entry: String): String {
|
||||
return """
|
||||
{
|
||||
"exclusions": [
|
||||
$entry
|
||||
]
|
||||
}
|
||||
""".trimIndent()
|
||||
}
|
||||
|
||||
private fun missingRuntimeDependencyExclusion(file: String, line: Int, reason: String = "Documented test exclusion"): String {
|
||||
return """
|
||||
{
|
||||
"inspection": "MissingFrontendOrBackendRuntimeDependency",
|
||||
"file": "$file",
|
||||
"line": $line,
|
||||
"reason": "$reason"
|
||||
}
|
||||
""".trimIndent()
|
||||
}
|
||||
|
||||
private fun addRuntimeDependencyFixName(frontendOrBackend: String): String {
|
||||
return "Make module 'intellij.test.feature.$frontendOrBackend' work in '$frontendOrBackend' only"
|
||||
}
|
||||
|
||||
private fun addToExclusionsFixName(): String {
|
||||
return "Add this violation to the exclusions list"
|
||||
}
|
||||
+24
-1
@@ -7,7 +7,7 @@ import org.jetbrains.idea.devkit.inspections.remotedev.analysis.SplitModeApiRest
|
||||
import org.junit.Assert
|
||||
|
||||
private const val API_RESTRICTIONS_PROJECT_RELATIVE_PATH =
|
||||
"community/plugins/devkit/devkit-core/resources/remotedevInspectionData/ApiRestrictions.json"
|
||||
"community/plugins/devkit/devkit-core/resources/remotedevInspectionData/ApiRestrictions.json5"
|
||||
|
||||
internal class SplitModeApiRestrictionsSourceModeTest : BasePlatformTestCase() {
|
||||
fun testProjectApiRestrictionsOverrideBundledListWhenProjectModeEnabled() {
|
||||
@@ -36,6 +36,29 @@ internal class SplitModeApiRestrictionsSourceModeTest : BasePlatformTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
fun testProjectApiRestrictionKindCanBeRead() {
|
||||
withApiRestrictionsSourceMode(
|
||||
"project",
|
||||
"""
|
||||
// Project-mode restrictions may use JSON5 comments.
|
||||
[
|
||||
{apiName: 'custom.split.mode.ui.api', targetModules: ['frontend'], restrictionKind: 'ui'},
|
||||
/* Generic platform APIs may be explicitly marked as non-UI restrictions. */
|
||||
{apiName: 'custom.split.mode.generic.api', targetModules: ['frontend'], restrictionKind: 'genericPlatformApi'},
|
||||
]
|
||||
""".trimIndent(),
|
||||
) { service ->
|
||||
Assert.assertEquals(
|
||||
SplitModeApiRestrictionsService.ApiRestrictionKind.UI,
|
||||
service.getCodeApiRestriction("custom.split.mode.ui.api", null)?.restrictionKind,
|
||||
)
|
||||
Assert.assertEquals(
|
||||
SplitModeApiRestrictionsService.ApiRestrictionKind.GENERIC_PLATFORM_API,
|
||||
service.getCodeApiRestriction("custom.split.mode.generic.api", null)?.restrictionKind,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun testProjectApiRestrictionsReloadAfterProjectFileChange() {
|
||||
withApiRestrictionsSourceMode(
|
||||
"project",
|
||||
|
||||
+7
-3
@@ -55,8 +55,12 @@ internal class SplitModeDependencyQuickFixesTest : JavaCodeInsightFixtureTestCas
|
||||
)
|
||||
myFixture.configureFromExistingVirtualFile(pluginXml.virtualFile)
|
||||
|
||||
launchActionAndWait("Make module 'unique.module.name.quick.fix.1' work in 'frontend' only") {
|
||||
getModuleDependencyNames(pluginXml).contains("intellij.platform.frontend")
|
||||
val intention = myFixture.findSingleIntention("Make module 'unique.module.name.quick.fix.1' work in 'frontend' only")
|
||||
myFixture.checkPreviewAndLaunchAction(intention)
|
||||
timeoutRunBlocking {
|
||||
waitUntil("Quick fix was not applied", 5.seconds) {
|
||||
getModuleDependencyNames(pluginXml).contains("intellij.platform.frontend")
|
||||
}
|
||||
}
|
||||
|
||||
val result = myFixture.file.text
|
||||
@@ -293,7 +297,7 @@ internal class SplitModeDependencyQuickFixesTest : JavaCodeInsightFixtureTestCas
|
||||
<module name="intellij.platform.core"/>
|
||||
</dependencies>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<applicationConfigurable<caret>/>
|
||||
<annotator<caret>/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.idea.devkit.inspections
|
||||
|
||||
import com.intellij.openapi.application.PathManager
|
||||
import com.intellij.testFramework.junit5.TestApplication
|
||||
import com.intellij.testFramework.junit5.fixture.projectFixture
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.MONOREPO_FEATURES_WITHOUT_SPLIT_MODE_SUPPORT_RELATIVE_PATH
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.SPLIT_MODE_EXCLUDED_MODULES_SCOPE_RELATIVE_PATHS
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.SplitModeInspectionResourceReadMode
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.SplitModeInspectionResourceReader
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.createSplitModeExcludedModulesScopeXml
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.io.path.exists
|
||||
import kotlin.io.path.readText
|
||||
import kotlin.io.path.writeText
|
||||
|
||||
private const val UPDATE_SPLIT_MODE_EXCLUDED_MODULES_SCOPE_PROPERTY = "devkit.split.mode.excluded.modules.scope.update"
|
||||
|
||||
@TestApplication
|
||||
internal class SplitModeExcludedModulesScopeConsistencyTest {
|
||||
companion object {
|
||||
private val projectFixture = projectFixture()
|
||||
}
|
||||
|
||||
private val project get() = projectFixture.get()
|
||||
|
||||
@Test
|
||||
fun `SplitModeExcludedModules scopes are generated from monorepo features without split mode support`() {
|
||||
val projectRoot = getMonorepoRoot()
|
||||
val expectedXml = createSplitModeExcludedModulesScopeXml(
|
||||
SplitModeInspectionResourceReader.getInstance(project),
|
||||
SplitModeInspectionResourceReadMode.BUNDLED_ONLY,
|
||||
)
|
||||
|
||||
for (relativePath in SPLIT_MODE_EXCLUDED_MODULES_SCOPE_RELATIVE_PATHS) {
|
||||
val scopeFile = projectRoot.resolve(relativePath)
|
||||
if (java.lang.Boolean.getBoolean(UPDATE_SPLIT_MODE_EXCLUDED_MODULES_SCOPE_PROPERTY)) {
|
||||
scopeFile.writeText(expectedXml)
|
||||
}
|
||||
|
||||
val actualXml = scopeFile.readText()
|
||||
assertEquals(
|
||||
expectedXml,
|
||||
actualXml,
|
||||
"$relativePath must be generated from $MONOREPO_FEATURES_WITHOUT_SPLIT_MODE_SUPPORT_RELATIVE_PATH",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getMonorepoRoot() = sequenceOf(PathManager.getHomeDir(), PathManager.getHomeDir().parent)
|
||||
.filterNotNull()
|
||||
.firstOrNull { it.resolve(MONOREPO_FEATURES_WITHOUT_SPLIT_MODE_SUPPORT_RELATIVE_PATH).exists() }
|
||||
?: PathManager.getHomeDir()
|
||||
}
|
||||
+36
-24
@@ -1,50 +1,62 @@
|
||||
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.idea.devkit.inspections
|
||||
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.project.IntelliJProjectUtil
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.testFramework.fixtures.BasePlatformTestCase
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.EXCLUSIONS_RELATIVE_PATH
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.SPLIT_MODE_API_USAGE_SHORT_NAME
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.SplitModeInspectionExclusionProblem
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.PROJECT_BASELINE_VERSION_RELATIVE_PATH
|
||||
import org.jetbrains.idea.devkit.inspections.remotedev.SplitModeInspectionExclusionsService
|
||||
import org.junit.Assert
|
||||
|
||||
internal class SplitModeInspectionExclusionsReloadTest : BasePlatformTestCase() {
|
||||
fun testExclusionsReloadAfterProjectFileChange() {
|
||||
val exclusionsFile = createProjectResourceFile(
|
||||
fun testQuickFixesContainOnlyBaselineByDefault() {
|
||||
IntelliJProjectUtil.markAsIntelliJPlatformProject(project, true)
|
||||
val fixes = SplitModeInspectionExclusionsService.getInstance(project).createCommonSuppressionQuickFixes()
|
||||
|
||||
Assert.assertEquals(
|
||||
listOf("Bypass incremental Split Mode safe-push tests"),
|
||||
fixes.map { it.familyName },
|
||||
)
|
||||
}
|
||||
|
||||
fun testBaselineVersionIncreasesExistingProjectFile() {
|
||||
val baselineVersionFile = createProjectResourceFile(
|
||||
project,
|
||||
EXCLUSIONS_RELATIVE_PATH,
|
||||
PROJECT_BASELINE_VERSION_RELATIVE_PATH,
|
||||
"""
|
||||
// Keep this comment.
|
||||
{
|
||||
"exclusions": [
|
||||
{"inspection": "$SPLIT_MODE_API_USAGE_SHORT_NAME", "file": "src/example.kt", "line": 7}
|
||||
]
|
||||
"currentProjectBaselineVersion": 41
|
||||
}
|
||||
""".trimIndent(),
|
||||
)
|
||||
val service = SplitModeInspectionExclusionsService.getInstance(project)
|
||||
val problem = SplitModeInspectionExclusionProblem(
|
||||
inspection = SPLIT_MODE_API_USAGE_SHORT_NAME,
|
||||
file = "src/example.kt",
|
||||
line = 7,
|
||||
)
|
||||
|
||||
try {
|
||||
Assert.assertTrue(service.isExcluded(problem))
|
||||
val updatedFile = runWriteAction {
|
||||
SplitModeInspectionExclusionsService.getInstance(project).increaseProjectBaselineVersion()
|
||||
}
|
||||
|
||||
createProjectResourceFile(
|
||||
project,
|
||||
EXCLUSIONS_RELATIVE_PATH,
|
||||
Assert.assertEquals(baselineVersionFile, updatedFile)
|
||||
Assert.assertEquals(
|
||||
"""
|
||||
// The file carries the current project baseline version for Split Mode Compatibility safe-push checks.
|
||||
// Increase currentProjectBaselineVersion only when incremental Split Mode Compatibility tests incorrectly
|
||||
// report pre-existing violations after large refactorings.
|
||||
// Changing this value is a legal bypass: the affected safe push may skip the incremental Split Mode
|
||||
// Compatibility tests for that run, allowing the refactoring to proceed while the baseline catches up.
|
||||
// Do not use it for real new violations. Fix those instead; see Split Mode documentation IJPL-A-632.
|
||||
// Contact the RemDev team in #ij-remote-dev if unsure.
|
||||
{
|
||||
"exclusions": []
|
||||
"currentProjectBaselineVersion": 42
|
||||
}
|
||||
""".trimIndent(),
|
||||
)
|
||||
|
||||
Assert.assertFalse(service.isExcluded(problem))
|
||||
""".trimIndent(),
|
||||
VfsUtilCore.loadText(baselineVersionFile),
|
||||
)
|
||||
}
|
||||
finally {
|
||||
deleteProjectResourceFile(project, exclusionsFile)
|
||||
deleteProjectResourceFile(project, baselineVersionFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-4
@@ -7,7 +7,7 @@ import org.jetbrains.idea.devkit.inspections.remotedev.analysis.SplitModeApiRest
|
||||
import org.junit.Assert
|
||||
|
||||
private const val PREDEFINED_MODULE_KINDS_PROJECT_RELATIVE_PATH =
|
||||
"community/plugins/devkit/devkit-core/resources/remotedevInspectionData/PredefinedModuleKinds.json"
|
||||
"community/plugins/devkit/devkit-core/resources/remotedevInspectionData/PredefinedModuleKinds.json5"
|
||||
|
||||
internal class SplitModePredefinedModuleKindsSourceModeTest : BasePlatformTestCase() {
|
||||
fun testProjectPredefinedModuleKindsOverrideBundledListWhenProjectModeEnabled() {
|
||||
@@ -15,7 +15,8 @@ internal class SplitModePredefinedModuleKindsSourceModeTest : BasePlatformTestCa
|
||||
"project",
|
||||
"""
|
||||
[
|
||||
{"moduleName": "custom.split.mode.frontend", "moduleKind": "frontend"}
|
||||
// JSON5 project overrides are accepted.
|
||||
{kind: 'moduleId', id: 'custom.split.mode.frontend', moduleKind: 'frontend'},
|
||||
]
|
||||
""".trimIndent(),
|
||||
) { service ->
|
||||
@@ -49,7 +50,7 @@ internal class SplitModePredefinedModuleKindsSourceModeTest : BasePlatformTestCa
|
||||
"project",
|
||||
"""
|
||||
[
|
||||
{"moduleName": "custom.split.mode.frontend", "moduleKind": "frontend"}
|
||||
{kind: 'moduleId', id: 'custom.split.mode.frontend', moduleKind: 'frontend'},
|
||||
]
|
||||
""".trimIndent(),
|
||||
) { service ->
|
||||
@@ -65,7 +66,7 @@ internal class SplitModePredefinedModuleKindsSourceModeTest : BasePlatformTestCa
|
||||
PREDEFINED_MODULE_KINDS_PROJECT_RELATIVE_PATH,
|
||||
"""
|
||||
[
|
||||
{"moduleName": "custom.split.mode.backend", "moduleKind": "backend"}
|
||||
{kind: 'moduleId', id: 'custom.split.mode.backend', moduleKind: 'backend'},
|
||||
]
|
||||
""".trimIndent(),
|
||||
)
|
||||
|
||||
+75
@@ -1053,6 +1053,81 @@ No frontend or backend dependencies were found for descriptor 'unique.module.nam
|
||||
.setValue(true, testRootDisposable)
|
||||
}
|
||||
|
||||
fun testNonUiExtensionsInBackendWithNonUiApiPermitModule() {
|
||||
val pluginXml = addModuleWithXmlDescriptor(
|
||||
moduleName = "intellij.clion.radler.core",
|
||||
descriptorRelativePathToResourcesDirectory = "META-INF/plugin.xml",
|
||||
"""
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<rdclient.actionCustomization/>
|
||||
<lang.parserDefinition/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
)
|
||||
myFixture.configureFromExistingVirtualFile(pluginXml.virtualFile)
|
||||
|
||||
myFixture.checkHighlighting()
|
||||
}
|
||||
|
||||
fun testFrontendApiExtensionInOrdinaryBackendModule() {
|
||||
val pluginXml = addModuleWithXmlDescriptor(
|
||||
moduleName = "unique.module.name.64",
|
||||
descriptorRelativePathToResourcesDirectory = "META-INF/plugin.xml",
|
||||
"""
|
||||
<idea-plugin>
|
||||
<dependencies>
|
||||
<module name="intellij.platform.backend"/>
|
||||
</dependencies>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<<warning>rdclient.actionCustomization</warning>/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
)
|
||||
myFixture.configureFromExistingVirtualFile(pluginXml.virtualFile)
|
||||
|
||||
myFixture.checkHighlighting()
|
||||
}
|
||||
|
||||
fun testUiExtensionInBackendWithNonUiApiPermitModule() {
|
||||
val pluginXml = addModuleWithXmlDescriptor(
|
||||
moduleName = "intellij.clion.radler.core",
|
||||
descriptorRelativePathToResourcesDirectory = "META-INF/plugin.xml",
|
||||
"""
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<<warning>toolWindow</warning>/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
)
|
||||
myFixture.configureFromExistingVirtualFile(pluginXml.virtualFile)
|
||||
|
||||
myFixture.checkHighlighting()
|
||||
}
|
||||
|
||||
fun testBackendWithNonUiApiPermitModuleIsBackendDependencyEvidence() {
|
||||
val pluginXml = addModuleWithXmlDescriptor(
|
||||
moduleName = "unique.module.name.65",
|
||||
descriptorRelativePathToResourcesDirectory = "META-INF/plugin.xml",
|
||||
"""
|
||||
<idea-plugin>
|
||||
<dependencies>
|
||||
<module name="intellij.clion.radler.core"/>
|
||||
</dependencies>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<<warning>lang.parserDefinition</warning>/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
)
|
||||
myFixture.configureFromExistingVirtualFile(pluginXml.virtualFile)
|
||||
|
||||
myFixture.checkHighlighting()
|
||||
}
|
||||
|
||||
fun testSharedExtensionInBackendModule() {
|
||||
val pluginXml = addModuleWithXmlDescriptor(
|
||||
moduleName = "unique.module.name.48",
|
||||
|
||||
+256
@@ -0,0 +1,256 @@
|
||||
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.idea.devkit.navigation
|
||||
|
||||
import com.intellij.codeInsight.hints.declarative.InlayProviderPassInfo
|
||||
import com.intellij.codeInsight.hints.declarative.impl.DeclarativeInlayHintsPass
|
||||
import com.intellij.codeInsight.hints.declarative.impl.inlayRenderer.DeclarativeInlayRenderer
|
||||
import com.intellij.codeInsight.hints.declarative.impl.views.InlayPresentationList
|
||||
import com.intellij.codeInsight.hints.declarative.impl.views.TextInlayPresentationEntry
|
||||
import com.intellij.codeInsight.multiverse.codeInsightContext
|
||||
import com.intellij.openapi.actionSystem.ex.ActionUtil
|
||||
import com.intellij.openapi.progress.EmptyProgressIndicator
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.psi.xml.XmlFile
|
||||
import com.intellij.testFramework.PsiTestUtil
|
||||
import com.intellij.testFramework.TestDataPath
|
||||
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.jetbrains.idea.devkit.DevkitJavaTestsUtil
|
||||
import org.jetbrains.idea.devkit.module.PluginModuleType
|
||||
|
||||
@TestDataPath($$"$CONTENT_ROOT/testData/navigation/descriptorsIncludingContentModule")
|
||||
internal class DescriptorSplitModeInlayHintsProviderTest : JavaCodeInsightFixtureTestCase() {
|
||||
|
||||
override fun getBasePath() = DevkitJavaTestsUtil.TESTDATA_PATH + "navigation/descriptorsIncludingContentModule"
|
||||
|
||||
fun testFrontendContentModuleInlay() {
|
||||
createModuleWithModuleDescriptor("declaring.module", "declaring.module.xml", """
|
||||
<idea-plugin>
|
||||
<content>
|
||||
<module name="test.module"/>
|
||||
</content>
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
createModuleWithModuleDescriptor("test.module", "test.module.xml", """
|
||||
<idea-plugin>
|
||||
<dependencies>
|
||||
<module name="intellij.platform.frontend"/>
|
||||
</dependencies>
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
testDescriptorInlay(
|
||||
descriptorPath = "test.module/test.module.xml",
|
||||
expectedInlayText = "Frontend content module",
|
||||
expectedTooltip = expectedTooltip(
|
||||
descriptorKind = "content module",
|
||||
compatibilityTarget = "frontend IDE",
|
||||
reason = "Frontend dependency 'intellij.platform.frontend' from descriptor 'test.module.xml' in module 'test.module'",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun testSharedContentModuleInlay() {
|
||||
createModuleWithModuleDescriptor("declaring.module", "declaring.module.xml", """
|
||||
<idea-plugin>
|
||||
<content>
|
||||
<module name="test.module"/>
|
||||
</content>
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
createModuleWithModuleDescriptor("test.module", "test.module.xml", """
|
||||
<idea-plugin>
|
||||
<!-- any -->
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
testDescriptorInlay(
|
||||
descriptorPath = "test.module/test.module.xml",
|
||||
expectedInlayText = "Shared content module",
|
||||
expectedTooltip = expectedTooltip(
|
||||
descriptorKind = "content module",
|
||||
compatibilityTarget = "both frontend and backend IDE",
|
||||
reason = "No frontend or backend dependencies were found for descriptor 'test.module.xml' in module 'test.module'",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun testBackendPluginInlay() {
|
||||
createModuleWithModuleDescriptor("root.plugin", "plugin.xml", """
|
||||
<idea-plugin>
|
||||
<dependencies>
|
||||
<module name="intellij.platform.backend"/>
|
||||
</dependencies>
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
testDescriptorInlay(
|
||||
descriptorPath = "root.plugin/plugin.xml",
|
||||
expectedInlayText = "Backend plugin",
|
||||
expectedTooltip = expectedTooltip(
|
||||
descriptorKind = "plugin",
|
||||
compatibilityTarget = "backend IDE",
|
||||
reason = "Backend dependency 'intellij.platform.backend' from descriptor 'plugin.xml' in module 'root.plugin'",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun testMixedContentModuleInlayUsesMonolithPresentation() {
|
||||
createModuleWithModuleDescriptor("declaring.module", "declaring.module.xml", """
|
||||
<idea-plugin>
|
||||
<content>
|
||||
<module name="test.module"/>
|
||||
</content>
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
createModuleWithModuleDescriptor("test.module", "test.module.xml", """
|
||||
<idea-plugin>
|
||||
<dependencies>
|
||||
<module name="intellij.platform.frontend"/>
|
||||
<module name="intellij.platform.backend"/>
|
||||
</dependencies>
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
testDescriptorInlay(
|
||||
descriptorPath = "test.module/test.module.xml",
|
||||
expectedInlayText = "Monolith content module",
|
||||
expectedTooltip = expectedTooltip(
|
||||
descriptorKind = "content module",
|
||||
compatibilityTarget = "monolith IDE",
|
||||
reason = """
|
||||
Frontend dependency 'intellij.platform.frontend' from descriptor 'test.module.xml' in module 'test.module'
|
||||
|
||||
Backend dependency 'intellij.platform.backend' from descriptor 'test.module.xml' in module 'test.module'
|
||||
""".trimIndent(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun testMonolithPluginInlay() {
|
||||
createModuleWithModuleDescriptor("root.plugin", "plugin.xml", """
|
||||
<idea-plugin>
|
||||
<dependencies>
|
||||
<module name="intellij.platform.monolith"/>
|
||||
</dependencies>
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
testDescriptorInlay(
|
||||
descriptorPath = "root.plugin/plugin.xml",
|
||||
expectedInlayText = "Monolith plugin",
|
||||
expectedTooltip = expectedTooltip(
|
||||
descriptorKind = "plugin",
|
||||
compatibilityTarget = "monolith IDE",
|
||||
reason = "Monolith dependency 'intellij.platform.monolith' from descriptor 'plugin.xml' in module 'root.plugin'",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun testNonPluginXmlDescriptorInlay() {
|
||||
createModuleWithModuleDescriptor("root.plugin", "root.plugin.optional.xml", """
|
||||
<idea-plugin>
|
||||
<dependencies>
|
||||
<module name="intellij.platform.backend"/>
|
||||
</dependencies>
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
testDescriptorInlay(
|
||||
descriptorPath = "root.plugin/root.plugin.optional.xml",
|
||||
expectedInlayText = "Backend XML descriptor",
|
||||
expectedTooltip = expectedTooltip(
|
||||
descriptorKind = "XML descriptor",
|
||||
compatibilityTarget = "backend IDE",
|
||||
reason = "Backend dependency 'intellij.platform.backend' from descriptor 'root.plugin.optional.xml' in module 'root.plugin'",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun testRegistryDisablesInlay() {
|
||||
Registry.get("devkit.split.mode.inlay.plugin.descriptor.kind").setValue(false, testRootDisposable)
|
||||
|
||||
createModuleWithModuleDescriptor("root.plugin", "plugin.xml", """
|
||||
<idea-plugin>
|
||||
<dependencies>
|
||||
<module name="intellij.platform.backend"/>
|
||||
</dependencies>
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
myFixture.configureFromTempProjectFile("root.plugin/plugin.xml")
|
||||
|
||||
runInlayPass()
|
||||
|
||||
assertEmpty(myFixture.editor.inlayModel.getInlineElementsInRange(0, myFixture.editor.document.textLength))
|
||||
}
|
||||
|
||||
private fun createModuleWithModuleDescriptor(
|
||||
moduleName: String,
|
||||
moduleDescriptorName: String,
|
||||
@Language("XML") moduleDescriptorText: String,
|
||||
) {
|
||||
PsiTestUtil.addModule(
|
||||
project,
|
||||
PluginModuleType.getInstance(),
|
||||
moduleName,
|
||||
myFixture.tempDirFixture.findOrCreateDir(moduleName)
|
||||
)
|
||||
myFixture.addFileToProject("$moduleName/$moduleDescriptorName", moduleDescriptorText)
|
||||
}
|
||||
|
||||
private fun testDescriptorInlay(
|
||||
descriptorPath: String,
|
||||
expectedInlayText: String,
|
||||
expectedTooltip: String,
|
||||
) {
|
||||
val xmlFile = myFixture.configureFromTempProjectFile(descriptorPath) as XmlFile
|
||||
|
||||
runInlayPass()
|
||||
|
||||
val inlay = myFixture.editor.inlayModel
|
||||
.getInlineElementsInRange(0, myFixture.editor.document.textLength, DeclarativeInlayRenderer::class.java)
|
||||
.single()
|
||||
assertEquals(expectedInlayText, inlay.renderer.presentationLists.single().getText())
|
||||
assertEquals(expectedTooltip, inlay.renderer.toInlayData().single().tooltip)
|
||||
|
||||
val inlayInfo = getDescriptorSplitModeInlayInfo(xmlFile)
|
||||
assertNotNull(inlayInfo)
|
||||
assertEquals(expectedInlayText, inlayInfo!!.text)
|
||||
assertEquals(expectedTooltip, inlayInfo.tooltip)
|
||||
}
|
||||
|
||||
private fun expectedTooltip(descriptorKind: String, compatibilityTarget: String, reason: String): String {
|
||||
val normalizedReason = reason.lineSequence().map(String::trim).filter(String::isNotEmpty).joinToString(" ")
|
||||
return "Split mode compatibility: $descriptorKind can be installed into $compatibilityTarget. Reason: $normalizedReason"
|
||||
}
|
||||
|
||||
private fun runInlayPass() {
|
||||
val providerInfo = InlayProviderPassInfo(DescriptorSplitModeInlayHintsProvider(), "test.inlay.provider", emptyMap())
|
||||
val pass = ActionUtil.underModalProgress(project, "") {
|
||||
DeclarativeInlayHintsPass(myFixture.file, myFixture.editor, listOf(providerInfo), isPreview = false)
|
||||
}
|
||||
pass.setContext(myFixture.file.codeInsightContext)
|
||||
ActionUtil.underModalProgress(project, "") {
|
||||
pass.doCollectInformation(EmptyProgressIndicator())
|
||||
}
|
||||
pass.applyInformationToEditor()
|
||||
}
|
||||
|
||||
private fun InlayPresentationList.getText(): String {
|
||||
return getEntries().joinToString(separator = "") { (it as TextInlayPresentationEntry).text }
|
||||
}
|
||||
}
|
||||
+118
-37
@@ -112,6 +112,36 @@ class SplitModeApiUsageInspectionTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
myFixture.addClass(
|
||||
"""
|
||||
package com.intellij.openapi.roots;
|
||||
|
||||
public interface FileIndex {}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
myFixture.addClass(
|
||||
"""
|
||||
package com.intellij.openapi.roots;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
|
||||
public interface ProjectFileIndex extends FileIndex {
|
||||
static ProjectFileIndex getInstance(Project project) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
myFixture.addClass(
|
||||
"""
|
||||
package com.intellij.openapi.roots;
|
||||
|
||||
public interface ModuleFileIndex extends FileIndex {}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
myFixture.addClass(
|
||||
"""
|
||||
package com.intellij.openapi.options;
|
||||
@@ -237,22 +267,22 @@ class SplitModeApiUsageInspectionTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
|
||||
class CustomToolWindowFactory: <weak_warning descr="'com.intellij.openapi.wm.ToolWindowFactory' should be used in 'frontend' module type. Actual module type is 'backend'.
|
||||
class CustomToolWindowFactory: <warning descr="'com.intellij.openapi.wm.ToolWindowFactory' should be used in 'frontend' module type. Actual module type is 'backend'.
|
||||
|
||||
Computed module kind reasoning:
|
||||
|
||||
Backend dependency 'intellij.platform.backend' from descriptor 'plugin.xml' in module 'light_idea_test_case'">ToolWindowFactory</weak_warning> {}
|
||||
Backend dependency 'intellij.platform.backend' from descriptor 'plugin.xml' in module 'light_idea_test_case'">ToolWindowFactory</warning> {}
|
||||
|
||||
class BackendService {
|
||||
fun doStuff() {
|
||||
// no warning here expected
|
||||
VirtualFileManager.getInstance()
|
||||
|
||||
<weak_warning descr="'com.intellij.openapi.fileEditor.FileEditorManager.getFocusedEditor' should be used in 'frontend' module type. Actual module type is 'backend'.
|
||||
<warning descr="'com.intellij.openapi.fileEditor.FileEditorManager.getFocusedEditor' should be used in 'frontend' module type. Actual module type is 'backend'.
|
||||
|
||||
Computed module kind reasoning:
|
||||
|
||||
Backend dependency 'intellij.platform.backend' from descriptor 'plugin.xml' in module 'light_idea_test_case'">FileEditorManager.getInstance().getFocusedEditor()</weak_warning>
|
||||
Backend dependency 'intellij.platform.backend' from descriptor 'plugin.xml' in module 'light_idea_test_case'">FileEditorManager.getInstance().getFocusedEditor()</warning>
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
@@ -306,11 +336,11 @@ Backend dependency 'intellij.platform.backend' from descriptor 'plugin.xml' in m
|
||||
|
||||
class SharedLangModule {
|
||||
fun test() {
|
||||
<weak_warning descr="'com.intellij.openapi.vfs.VirtualFileManager' should be used in 'backend' module type. Actual module type is 'shared'.
|
||||
<warning descr="'com.intellij.openapi.vfs.VirtualFileManager' should be used in 'backend' module type. Actual module type is 'shared'.
|
||||
|
||||
Computed module kind reasoning:
|
||||
|
||||
Predefined module kind for plugin/module id 'com.intellij.modules.lang'">VirtualFileManager</weak_warning>.getInstance()
|
||||
Predefined module kind for plugin/module id 'com.intellij.modules.lang'">VirtualFileManager</warning>.getInstance()
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
@@ -344,11 +374,11 @@ Predefined module kind for plugin/module id 'com.intellij.modules.lang'">Virtual
|
||||
|
||||
class FrontendService {
|
||||
fun doStuff() {
|
||||
<weak_warning descr="'com.intellij.openapi.vfs.VirtualFileManager' should be used in 'backend' module type. Actual module type is 'frontend'.
|
||||
<warning descr="'com.intellij.openapi.vfs.VirtualFileManager' should be used in 'backend' module type. Actual module type is 'frontend'.
|
||||
|
||||
Computed module kind reasoning:
|
||||
|
||||
Frontend dependency 'intellij.platform.frontend' from descriptor 'plugin.xml' in module 'light_idea_test_case'">VirtualFileManager</weak_warning>.getInstance()
|
||||
Frontend dependency 'intellij.platform.frontend' from descriptor 'plugin.xml' in module 'light_idea_test_case'">VirtualFileManager</warning>.getInstance()
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
@@ -357,7 +387,60 @@ Frontend dependency 'intellij.platform.frontend' from descriptor 'plugin.xml' in
|
||||
myFixture.checkHighlighting()
|
||||
}
|
||||
|
||||
fun testConfigurableApiInBackendModule() {
|
||||
fun testFileIndexApiInFrontendModule() {
|
||||
configurePluginXml(
|
||||
"""
|
||||
<idea-plugin>
|
||||
<dependencies>
|
||||
<module name="intellij.platform.frontend"/>
|
||||
</dependencies>
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
myFixture.configureByText(
|
||||
"FrontendFileIndexService.kt", """
|
||||
package com.example.frontend
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.FileIndex
|
||||
import com.intellij.openapi.roots.ModuleFileIndex
|
||||
import com.intellij.openapi.roots.ProjectFileIndex
|
||||
|
||||
class FrontendFileIndexService(private val project: Project) {
|
||||
fun doStuff() {
|
||||
<warning descr="'com.intellij.openapi.roots.ProjectFileIndex' should be used in 'backend' module type. Actual module type is 'frontend'.
|
||||
|
||||
Computed module kind reasoning:
|
||||
|
||||
Frontend dependency 'intellij.platform.frontend' from descriptor 'plugin.xml' in module 'light_idea_test_case'">ProjectFileIndex</warning>.getInstance(project)
|
||||
}
|
||||
}
|
||||
|
||||
class FrontendFileIndex : <warning descr="'com.intellij.openapi.roots.FileIndex' should be used in 'backend' module type. Actual module type is 'frontend'.
|
||||
|
||||
Computed module kind reasoning:
|
||||
|
||||
Frontend dependency 'intellij.platform.frontend' from descriptor 'plugin.xml' in module 'light_idea_test_case'">FileIndex</warning>
|
||||
|
||||
class FrontendProjectFileIndex : <warning descr="'com.intellij.openapi.roots.ProjectFileIndex' should be used in 'backend' module type. Actual module type is 'frontend'.
|
||||
|
||||
Computed module kind reasoning:
|
||||
|
||||
Frontend dependency 'intellij.platform.frontend' from descriptor 'plugin.xml' in module 'light_idea_test_case'">ProjectFileIndex</warning>
|
||||
|
||||
class FrontendModuleFileIndex : <warning descr="'com.intellij.openapi.roots.ModuleFileIndex' should be used in 'backend' module type. Actual module type is 'frontend'.
|
||||
|
||||
Computed module kind reasoning:
|
||||
|
||||
Frontend dependency 'intellij.platform.frontend' from descriptor 'plugin.xml' in module 'light_idea_test_case'">ModuleFileIndex</warning>
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
myFixture.checkHighlighting()
|
||||
}
|
||||
|
||||
fun testFrontendOrBackendApiInBackendModule() {
|
||||
configurePluginXml(
|
||||
"""
|
||||
<idea-plugin>
|
||||
@@ -369,12 +452,12 @@ Frontend dependency 'intellij.platform.frontend' from descriptor 'plugin.xml' in
|
||||
)
|
||||
|
||||
myFixture.configureByText(
|
||||
"BackendConfigurable.kt", """
|
||||
"BackendDynamicPluginListener.kt", """
|
||||
package com.example.backend
|
||||
|
||||
import com.intellij.openapi.options.Configurable
|
||||
import com.intellij.ide.plugins.DynamicPluginListener
|
||||
|
||||
class BackendConfigurable : Configurable
|
||||
class BackendDynamicPluginListener : DynamicPluginListener
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
@@ -398,11 +481,11 @@ Frontend dependency 'intellij.platform.frontend' from descriptor 'plugin.xml' in
|
||||
|
||||
import com.intellij.openapi.fileEditor.FileEditorManagerListener
|
||||
|
||||
class BackendFileEditorListener : <weak_warning descr="'com.intellij.openapi.fileEditor.FileEditorManagerListener' should be used in 'frontend' module type. Actual module type is 'backend'.
|
||||
class BackendFileEditorListener : <warning descr="'com.intellij.openapi.fileEditor.FileEditorManagerListener' should be used in 'frontend' module type. Actual module type is 'backend'.
|
||||
|
||||
Computed module kind reasoning:
|
||||
|
||||
Backend dependency 'intellij.platform.backend' from descriptor 'plugin.xml' in module 'light_idea_test_case'">FileEditorManagerListener</weak_warning>
|
||||
Backend dependency 'intellij.platform.backend' from descriptor 'plugin.xml' in module 'light_idea_test_case'">FileEditorManagerListener</warning>
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
@@ -426,11 +509,11 @@ Backend dependency 'intellij.platform.backend' from descriptor 'plugin.xml' in m
|
||||
|
||||
import com.intellij.lang.ParserDefinition
|
||||
|
||||
class FrontendParserDefinition : <weak_warning descr="'com.intellij.lang.ParserDefinition' should be used in 'shared' module type. Actual module type is 'frontend'.
|
||||
class FrontendParserDefinition : <warning descr="'com.intellij.lang.ParserDefinition' should be used in 'shared' module type. Actual module type is 'frontend'.
|
||||
|
||||
Computed module kind reasoning:
|
||||
|
||||
Frontend dependency 'intellij.platform.frontend' from descriptor 'plugin.xml' in module 'light_idea_test_case'">ParserDefinition</weak_warning>
|
||||
Frontend dependency 'intellij.platform.frontend' from descriptor 'plugin.xml' in module 'light_idea_test_case'">ParserDefinition</warning>
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
@@ -454,11 +537,11 @@ Frontend dependency 'intellij.platform.frontend' from descriptor 'plugin.xml' in
|
||||
|
||||
import com.intellij.openapi.project.ProjectManagerListener
|
||||
|
||||
class FrontendProjectManagerListener : <weak_warning descr="'com.intellij.openapi.project.ProjectManagerListener' should be used in 'backend' module type. Actual module type is 'frontend'.
|
||||
class FrontendProjectManagerListener : <warning descr="'com.intellij.openapi.project.ProjectManagerListener' should be used in 'backend' module type. Actual module type is 'frontend'.
|
||||
|
||||
Computed module kind reasoning:
|
||||
|
||||
Frontend dependency 'intellij.platform.frontend' from descriptor 'plugin.xml' in module 'light_idea_test_case'">ProjectManagerListener</weak_warning>
|
||||
Frontend dependency 'intellij.platform.frontend' from descriptor 'plugin.xml' in module 'light_idea_test_case'">ProjectManagerListener</warning>
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
@@ -490,11 +573,11 @@ Frontend dependency 'intellij.platform.frontend' from descriptor 'plugin.xml' in
|
||||
|
||||
class FrontendService {
|
||||
fun doStuff() {
|
||||
<weak_warning descr="'com.intellij.openapi.vfs.VirtualFileManager' should be used in 'backend' module type. Actual module type is 'frontend'.
|
||||
<warning descr="'com.intellij.openapi.vfs.VirtualFileManager' should be used in 'backend' module type. Actual module type is 'frontend'.
|
||||
|
||||
Computed module kind reasoning:
|
||||
|
||||
Frontend dependency 'intellij.platform.frontend' from descriptor 'light_idea_test_case.xml' in module 'light_idea_test_case'">VirtualFileManager</weak_warning>.getInstance()
|
||||
Frontend dependency 'intellij.platform.frontend' from descriptor 'light_idea_test_case.xml' in module 'light_idea_test_case'">VirtualFileManager</warning>.getInstance()
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
@@ -522,11 +605,11 @@ Frontend dependency 'intellij.platform.frontend' from descriptor 'light_idea_tes
|
||||
|
||||
class FrontendService {
|
||||
fun doStuff() {
|
||||
<weak_warning descr="'com.example.annotated.AnnotatedBackendApi' should be used in 'backend' module type. Actual module type is 'frontend'.
|
||||
<warning descr="'com.example.annotated.AnnotatedBackendApi' should be used in 'backend' module type. Actual module type is 'frontend'.
|
||||
|
||||
Computed module kind reasoning:
|
||||
|
||||
Frontend dependency 'intellij.platform.frontend' from descriptor 'plugin.xml' in module 'light_idea_test_case'">AnnotatedBackendApi</weak_warning>.getInstance()
|
||||
Frontend dependency 'intellij.platform.frontend' from descriptor 'plugin.xml' in module 'light_idea_test_case'">AnnotatedBackendApi</warning>.getInstance()
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
@@ -554,11 +637,11 @@ Frontend dependency 'intellij.platform.frontend' from descriptor 'plugin.xml' in
|
||||
|
||||
class BackendService {
|
||||
fun doStuff() {
|
||||
<weak_warning descr="'com.example.annotated.AnnotatedFrontendApi' should be used in 'frontend' module type. Actual module type is 'backend'.
|
||||
<warning descr="'com.example.annotated.AnnotatedFrontendApi' should be used in 'frontend' module type. Actual module type is 'backend'.
|
||||
|
||||
Computed module kind reasoning:
|
||||
|
||||
Backend dependency 'intellij.platform.backend' from descriptor 'plugin.xml' in module 'light_idea_test_case'">AnnotatedFrontendApi</weak_warning>.getInstance()
|
||||
Backend dependency 'intellij.platform.backend' from descriptor 'plugin.xml' in module 'light_idea_test_case'">AnnotatedFrontendApi</warning>.getInstance()
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
@@ -589,19 +672,19 @@ Backend dependency 'intellij.platform.backend' from descriptor 'plugin.xml' in m
|
||||
// both warnings are expected in a shared module
|
||||
class SharedService {
|
||||
fun testFrontendApi() {
|
||||
class MyToolWindow: <weak_warning descr="'com.intellij.openapi.wm.ToolWindowFactory' should be used in 'frontend' module type. Actual module type is 'shared'.
|
||||
class MyToolWindow: <warning descr="'com.intellij.openapi.wm.ToolWindowFactory' should be used in 'frontend' module type. Actual module type is 'shared'.
|
||||
|
||||
Computed module kind reasoning:
|
||||
|
||||
No frontend or backend dependencies were found for module 'light_idea_test_case'">ToolWindowFactory</weak_warning> {}
|
||||
No frontend or backend dependencies were found for module 'light_idea_test_case'">ToolWindowFactory</warning> {}
|
||||
}
|
||||
|
||||
fun testBackendApi() {
|
||||
<weak_warning descr="'com.intellij.openapi.vfs.VirtualFileManager' should be used in 'backend' module type. Actual module type is 'shared'.
|
||||
<warning descr="'com.intellij.openapi.vfs.VirtualFileManager' should be used in 'backend' module type. Actual module type is 'shared'.
|
||||
|
||||
Computed module kind reasoning:
|
||||
|
||||
No frontend or backend dependencies were found for module 'light_idea_test_case'">VirtualFileManager</weak_warning>.getInstance()
|
||||
No frontend or backend dependencies were found for module 'light_idea_test_case'">VirtualFileManager</warning>.getInstance()
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
@@ -627,13 +710,13 @@ No frontend or backend dependencies were found for module 'light_idea_test_case'
|
||||
|
||||
import com.intellij.ide.plugins.DynamicPluginListener
|
||||
|
||||
class SharedDynamicPluginListener : <weak_warning descr="'com.intellij.ide.plugins.DynamicPluginListener' should be used in 'frontend or backend' module type. Actual module type is 'shared'.
|
||||
class SharedDynamicPluginListener : <warning descr="'com.intellij.ide.plugins.DynamicPluginListener' should be used in 'frontend or backend' module type. Actual module type is 'shared'.
|
||||
|
||||
Plugin lists are different on frontend and backend, prefer listening to them explicitly in desired IDE part
|
||||
|
||||
Computed module kind reasoning:
|
||||
|
||||
No frontend or backend dependencies were found for module 'light_idea_test_case'">DynamicPluginListener</weak_warning>
|
||||
No frontend or backend dependencies were found for module 'light_idea_test_case'">DynamicPluginListener</warning>
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
@@ -732,7 +815,9 @@ No frontend or backend dependencies were found for module 'light_idea_test_case'
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
launchActionAndWait("Make module 'light_idea_test_case' work in 'frontend' only") {
|
||||
val intention = myFixture.findSingleIntention("Make module 'light_idea_test_case' work in 'frontend' only")
|
||||
assertNull(myFixture.getIntentionPreviewText(intention))
|
||||
launchActionAndWait(intention) {
|
||||
getModuleDependencyNames().contains("intellij.platform.frontend")
|
||||
}
|
||||
|
||||
@@ -854,7 +939,8 @@ No frontend or backend dependencies were found for module 'light_idea_test_case'
|
||||
)
|
||||
addCurrentModuleDependencies("intellij.platform.frontend")
|
||||
|
||||
launchActionAndWait("Make module 'light_idea_test_case' work in 'backend' only") {
|
||||
val intention = myFixture.findSingleIntention("Make module 'light_idea_test_case' work in 'backend' only")
|
||||
launchActionAndWait(intention) {
|
||||
!getModuleDependencyNames().contains("intellij.platform.frontend")
|
||||
}
|
||||
|
||||
@@ -879,11 +965,6 @@ No frontend or backend dependencies were found for module 'light_idea_test_case'
|
||||
}
|
||||
}
|
||||
|
||||
private fun launchActionAndWait(intentionText: String, condition: () -> Boolean) {
|
||||
val intention = myFixture.findSingleIntention(intentionText)
|
||||
launchActionAndWait(intention, condition)
|
||||
}
|
||||
|
||||
private fun launchActionAndWait(intention: IntentionAction, condition: () -> Boolean) {
|
||||
myFixture.launchAction(intention)
|
||||
timeoutRunBlocking {
|
||||
|
||||
@@ -28,6 +28,9 @@ jvm_library(
|
||||
"//platform/lang-core",
|
||||
"//platform/util",
|
||||
"//java/java-psi-api:psi",
|
||||
"//platform/analysis-api:analysis",
|
||||
"//platform/analysis-impl",
|
||||
"//platform/projectModel-api:projectModel",
|
||||
"//libraries/kotlinx/serialization/json",
|
||||
"//libraries/kotlinx/serialization/core",
|
||||
"//platform/progress/shared:ide-progress",
|
||||
@@ -53,6 +56,9 @@ jvm_library(
|
||||
"//platform/lang-core:lang-core_test_lib",
|
||||
"//platform/util:util_test_lib",
|
||||
"//java/java-psi-api:psi_test_lib",
|
||||
"//platform/analysis-api:analysis_test_lib",
|
||||
"//platform/analysis-impl:analysis-impl_test_lib",
|
||||
"//platform/projectModel-api:projectModel_test_lib",
|
||||
"//libraries/kotlinx/serialization/json:json_test_lib",
|
||||
"//libraries/kotlinx/serialization/core:core_test_lib",
|
||||
"//platform/progress/shared:ide-progress_test_lib",
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
<orderEntry type="module" module-name="intellij.platform.lang.core" />
|
||||
<orderEntry type="module" module-name="intellij.platform.util" />
|
||||
<orderEntry type="module" module-name="intellij.java.psi" />
|
||||
<orderEntry type="module" module-name="intellij.platform.analysis" />
|
||||
<orderEntry type="module" module-name="intellij.platform.analysis.impl" />
|
||||
<orderEntry type="module" module-name="intellij.platform.projectModel" />
|
||||
<orderEntry type="module" module-name="intellij.libraries.kotlinx.serialization.json" />
|
||||
<orderEntry type="module" module-name="intellij.libraries.kotlinx.serialization.core" />
|
||||
<orderEntry type="module" module-name="intellij.platform.ide.progress" />
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
<idea-plugin>
|
||||
<!-- region Generated dependencies - run `Generate Product Layouts` to regenerate -->
|
||||
<dependencies>
|
||||
<module name="intellij.java.backend"/>
|
||||
<!-- region Generated dependencies - run `Generate Product Layouts` to regenerate -->
|
||||
<plugin id="com.intellij.mcpServer"/>
|
||||
<module name="intellij.java.backend"/>
|
||||
<module name="intellij.devkit.core"/>
|
||||
<module name="intellij.devkit.scaffolding"/>
|
||||
<module name="intellij.java.psi"/>
|
||||
<!-- endregion -->
|
||||
<module name="intellij.libraries.kotlinx.serialization.core"/>
|
||||
<module name="intellij.libraries.kotlinx.serialization.json"/>
|
||||
<module name="intellij.platform.analysis"/>
|
||||
<module name="intellij.platform.analysis.impl"/>
|
||||
<module name="intellij.platform.core"/>
|
||||
<module name="intellij.platform.ide.progress"/>
|
||||
<module name="intellij.platform.lang.core"/>
|
||||
<module name="intellij.platform.projectModel"/>
|
||||
</dependencies>
|
||||
<!-- endregion -->
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij.mcpServer">
|
||||
<mcpToolset implementation="com.intellij.devkit.mcp.DevKitMcpToolset" />
|
||||
|
||||
@@ -31,6 +31,8 @@ import java.util.Collections
|
||||
import java.util.EnumSet
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
private const val DEFAULT_SPLIT_MODE_COMPATIBILITY_ANALYSIS_TIMEOUT_MILLISECONDS: Int = 5 * 60 * 1000
|
||||
|
||||
class DevKitMcpToolset : McpToolset {
|
||||
@McpTool
|
||||
@McpDescription(
|
||||
@@ -94,6 +96,41 @@ class DevKitMcpToolset : McpToolset {
|
||||
return recognizeSplitModeModuleKindForPath(descriptorPath)
|
||||
}
|
||||
|
||||
@McpTool
|
||||
@McpDescription(
|
||||
"""
|
||||
|Recognizes the Split Mode API kind for a fully qualified API name using the same DevKit restriction data
|
||||
|as the remdev inspections.
|
||||
|Returns the target module kind when the API is listed in DevKit split-mode restrictions.
|
||||
"""
|
||||
)
|
||||
@Suppress("unused", "FunctionName")
|
||||
suspend fun recognize_split_mode_api_kind(
|
||||
@McpDescription("Fully qualified code API name, for example `com.intellij.openapi.ui.DialogWrapper`.")
|
||||
apiName: String,
|
||||
): RecognizeSplitModeApiKindResult {
|
||||
return recognizeSplitModeApiKind(apiName)
|
||||
}
|
||||
|
||||
@McpTool
|
||||
@McpDescription(
|
||||
"""
|
||||
|Collects Split Mode compatibility issues for all supported files under the given directory.
|
||||
|Runs only the DevKit split-mode compatibility inspection whitelist and returns every found issue.
|
||||
|Whitelisted inspections: SplitModeApiUsage, SplitModeXmlApiUsage, SplitModeMixedDependencies,
|
||||
|SplitModeImplicitModuleKind, MissingFrontendOrBackendRuntimeDependency.
|
||||
"""
|
||||
)
|
||||
@Suppress("unused", "FunctionName")
|
||||
suspend fun collect_split_mode_compatibility_issues(
|
||||
@McpDescription(Constants.RELATIVE_PATH_IN_PROJECT_DESCRIPTION)
|
||||
directoryPath: String,
|
||||
@McpDescription("Analysis timeout in milliseconds.")
|
||||
analysisTimeout: Int = DEFAULT_SPLIT_MODE_COMPATIBILITY_ANALYSIS_TIMEOUT_MILLISECONDS,
|
||||
): SplitModeCompatibilityIssuesResult {
|
||||
return collectSplitModeCompatibilityIssues(directoryPath, analysisTimeout)
|
||||
}
|
||||
|
||||
@McpTool
|
||||
@McpDescription("""
|
||||
|Analyzes the usage of the Read/Write lock for the method under the caret.
|
||||
@@ -169,12 +206,14 @@ class DevKitMcpToolset : McpToolset {
|
||||
mapper: (ConstraintType) -> T,
|
||||
): Pair<List<Pair<T, List<SourceLocation>>>, Boolean> {
|
||||
val project = currentCoroutineContext().project
|
||||
val file = VirtualFileManager.getInstance().findFileByNioPath(project.resolveInProject(filePath)) ?: throw McpExpectedError("Virtual file not found")
|
||||
val file = VirtualFileManager.getInstance().findFileByNioPath(project.resolveInProject(filePath))
|
||||
?: throw McpExpectedError("Virtual file not found")
|
||||
val pointer = readAction {
|
||||
val document = FileDocumentManager.getInstance().getDocument(file)
|
||||
val psiTree = PsiManager.getInstance(project).findFile(file) ?: throw McpExpectedError("PsiFile not found")
|
||||
val offset = document?.getLineStartOffset(line - 1)?.plus(column - 1) ?: throw McpExpectedError("Invalid line/column")
|
||||
val method = LockReqPsiOps.forLanguage(psiTree.language).extractTargetElement(psiTree, offset) ?: throw McpExpectedError("No method found at the specified position")
|
||||
val method = LockReqPsiOps.forLanguage(psiTree.language).extractTargetElement(psiTree, offset)
|
||||
?: throw McpExpectedError("No method found at the specified position")
|
||||
SmartPointerManager.createPointer(method)
|
||||
}
|
||||
|
||||
@@ -183,15 +222,18 @@ class DevKitMcpToolset : McpToolset {
|
||||
val result = withTimeoutOrNull(timeout.milliseconds) {
|
||||
@Suppress("HardCodedStringLiteral")
|
||||
withBackgroundProgress(project, "Analyzing Locking Requirements usage for AI", true) {
|
||||
LockReqAnalyzerParallelBFS().analyzeMethodStreaming(pointer, AnalysisConfig.forProject(project, requirementSet), project, object : LockReqConsumer {
|
||||
override fun onPath(path: ExecutionPath) {
|
||||
val lockType = mapper(path.lockRequirement.constraintType)
|
||||
val locations = path.methodChain.map {
|
||||
SourceLocation(it.containingClassName ?: "<null>", it.methodName)
|
||||
}
|
||||
list.add(lockType to locations)
|
||||
}
|
||||
})
|
||||
LockReqAnalyzerParallelBFS().analyzeMethodStreaming(pointer,
|
||||
AnalysisConfig.forProject(project, requirementSet),
|
||||
project,
|
||||
object : LockReqConsumer {
|
||||
override fun onPath(path: ExecutionPath) {
|
||||
val lockType = mapper(path.lockRequirement.constraintType)
|
||||
val locations = path.methodChain.map {
|
||||
SourceLocation(it.containingClassName ?: "<null>", it.methodName)
|
||||
}
|
||||
list.add(lockType to locations)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
val timeout = result == null
|
||||
@@ -199,7 +241,7 @@ class DevKitMcpToolset : McpToolset {
|
||||
}
|
||||
|
||||
enum class LockType {
|
||||
READ_ASSERTION, WRITE_ASSERTION, WRITE_INTENT_ASSERTION, NO_READ_ASSERTION
|
||||
READ_ASSERTION, WRITE_ASSERTION, WRITE_INTENT_ASSERTION, NO_READ_ASSERTION
|
||||
}
|
||||
|
||||
enum class ThreadType {
|
||||
@@ -250,4 +292,50 @@ class DevKitMcpToolset : McpToolset {
|
||||
@property:McpDescription("Reasoning produced by the same DevKit module-kind analysis used by the remdev inspections.")
|
||||
val reasoning: String,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class RecognizeSplitModeApiKindResult(
|
||||
@property:McpDescription("Fully qualified code API name that was recognized.")
|
||||
val apiName: String,
|
||||
@property:McpDescription("Target Split Mode module kind for this API, or null when no restriction matches.")
|
||||
val kindId: String?,
|
||||
@property:McpDescription("Optional hint from the DevKit split-mode restrictions data.")
|
||||
val hint: String?,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class SplitModeCompatibilityIssuesResult(
|
||||
@property:McpDescription("Directory path that was analyzed, relative to the project root when provided that way.")
|
||||
val directoryPath: String,
|
||||
@property:McpDescription("Split Mode inspection short names used for this analysis.")
|
||||
val inspectionIds: List<String>,
|
||||
@property:McpDescription("Number of supported source files inspected under the directory.")
|
||||
val inspectedFileCount: Int,
|
||||
@property:McpDescription("All found Split Mode compatibility issues from the whitelisted inspections.")
|
||||
val issues: List<SplitModeCompatibilityIssue>,
|
||||
@property:McpDescription(Constants.TIMED_OUT_DESCRIPTION)
|
||||
val timedOut: Boolean,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class SplitModeCompatibilityIssue(
|
||||
@property:McpDescription("Inspection short name that reported the issue.")
|
||||
val inspectionId: String,
|
||||
@property:McpDescription("Problem highlight type reported by the inspection.")
|
||||
val severity: String,
|
||||
@property:McpDescription("Problem file path, relative to the project root when possible.")
|
||||
val filePath: String,
|
||||
@property:McpDescription("1-based start line, if available.")
|
||||
val line: Int?,
|
||||
@property:McpDescription("1-based start column, if available.")
|
||||
val column: Int?,
|
||||
@property:McpDescription("1-based end line, if available.")
|
||||
val endLine: Int?,
|
||||
@property:McpDescription("1-based end column, if available.")
|
||||
val endColumn: Int?,
|
||||
@property:McpDescription("Rendered inspection problem description.")
|
||||
val description: String,
|
||||
@property:McpDescription("Quick-fix family names available in batch mode.")
|
||||
val quickFixes: List<String>,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.devkit.mcp
|
||||
|
||||
import com.intellij.codeInspection.InspectionEngine
|
||||
import com.intellij.codeInspection.ProblemDescriptor
|
||||
import com.intellij.codeInspection.ProblemDescriptorBase
|
||||
import com.intellij.codeInspection.ProblemDescriptorUtil
|
||||
import com.intellij.codeInspection.ex.LocalInspectionToolWrapper
|
||||
import com.intellij.mcpserver.mcpFail
|
||||
import com.intellij.mcpserver.project
|
||||
import com.intellij.mcpserver.util.resolveInProject
|
||||
import com.intellij.openapi.application.smartReadAction
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import com.intellij.openapi.progress.EmptyProgressIndicator
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.progress.checkCanceled
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.ProjectFileIndex
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.openapi.vfs.VirtualFileVisitor
|
||||
import com.intellij.platform.ide.progress.withBackgroundProgress
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.util.PairProcessor
|
||||
import kotlinx.coroutines.currentCoroutineContext
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
private val SPLIT_MODE_COMPATIBILITY_INSPECTION_IDS = listOf(
|
||||
"SplitModeApiUsage",
|
||||
"SplitModeXmlApiUsage",
|
||||
"SplitModeMixedDependencies",
|
||||
"SplitModeImplicitModuleKind",
|
||||
"MissingFrontendOrBackendRuntimeDependency",
|
||||
)
|
||||
|
||||
private val SPLIT_MODE_COMPATIBILITY_FILE_EXTENSIONS = setOf("java", "kt", "kts", "xml")
|
||||
|
||||
internal suspend fun collectSplitModeCompatibilityIssues(
|
||||
directoryPath: String,
|
||||
analysisTimeout: Int,
|
||||
): DevKitMcpToolset.SplitModeCompatibilityIssuesResult {
|
||||
val project = currentCoroutineContext().project
|
||||
val resolvedDirectoryPath = project.resolveInProject(directoryPath)
|
||||
val directory = VirtualFileManager.getInstance().findFileByNioPath(resolvedDirectoryPath)
|
||||
?: VirtualFileManager.getInstance().refreshAndFindFileByNioPath(resolvedDirectoryPath)
|
||||
?: mcpFail("Directory not found: $directoryPath")
|
||||
if (!directory.isDirectory) {
|
||||
mcpFail("Not a directory: $directoryPath")
|
||||
}
|
||||
|
||||
loadSplitModeRestrictions(project)
|
||||
|
||||
var result = SplitModeCompatibilityInspectionRunResult(emptyList(), 0)
|
||||
val timedOut = withTimeoutOrNull(analysisTimeout.milliseconds) {
|
||||
@Suppress("HardCodedStringLiteral")
|
||||
withBackgroundProgress(project, "Collecting Split Mode compatibility issues", true) {
|
||||
val inspectionFiles = smartReadAction(project) {
|
||||
collectInspectionFiles(directory, project)
|
||||
}
|
||||
|
||||
val issues = mutableListOf<DevKitMcpToolset.SplitModeCompatibilityIssue>()
|
||||
var inspectedFileCount = 0
|
||||
for (virtualFile in inspectionFiles) {
|
||||
checkCanceled()
|
||||
val fileIssues = smartReadAction(project) {
|
||||
val psiManager = PsiManager.getInstance(project)
|
||||
val psiFile = psiManager.findFile(virtualFile) ?: return@smartReadAction null
|
||||
val tools = getSplitModeCompatibilityInspectionTools(project)
|
||||
inspectSplitModeCompatibilityFile(project, psiFile, tools)
|
||||
} ?: continue
|
||||
inspectedFileCount++
|
||||
issues += fileIssues
|
||||
}
|
||||
result = SplitModeCompatibilityInspectionRunResult(issues, inspectedFileCount)
|
||||
}
|
||||
} == null
|
||||
|
||||
return DevKitMcpToolset.SplitModeCompatibilityIssuesResult(
|
||||
directoryPath = directoryPath,
|
||||
inspectionIds = SPLIT_MODE_COMPATIBILITY_INSPECTION_IDS,
|
||||
inspectedFileCount = result.inspectedFileCount,
|
||||
issues = result.issues.sortedWith(compareBy(
|
||||
{ it.filePath },
|
||||
{ it.line ?: Int.MAX_VALUE },
|
||||
{ it.column ?: Int.MAX_VALUE },
|
||||
{ it.inspectionId },
|
||||
{ it.description },
|
||||
)),
|
||||
timedOut = timedOut,
|
||||
)
|
||||
}
|
||||
|
||||
private fun getSplitModeCompatibilityInspectionTools(project: Project): List<LocalInspectionToolWrapper> {
|
||||
return SPLIT_MODE_COMPATIBILITY_INSPECTION_IDS.map { inspectionId ->
|
||||
val wrapper = LocalInspectionToolWrapper.findTool2RunInBatch(project, null, inspectionId)
|
||||
?: mcpFail("Inspection not found: $inspectionId")
|
||||
val localWrapper = wrapper as? LocalInspectionToolWrapper
|
||||
?: mcpFail("Inspection is not a local inspection: $inspectionId")
|
||||
localWrapper.createCopy()
|
||||
}
|
||||
}
|
||||
|
||||
private fun collectInspectionFiles(root: VirtualFile, project: Project): List<VirtualFile> {
|
||||
val projectFileIndex = ProjectFileIndex.getInstance(project)
|
||||
val files = mutableListOf<VirtualFile>()
|
||||
VfsUtilCore.visitChildrenRecursively(root, object : VirtualFileVisitor<Unit>() {
|
||||
override fun visitFile(file: VirtualFile): Boolean {
|
||||
ProgressManager.checkCanceled()
|
||||
if (projectFileIndex.isUnderIgnored(file)) {
|
||||
return false
|
||||
}
|
||||
if (file.isDirectory) {
|
||||
return true
|
||||
}
|
||||
|
||||
val extension = file.extension?.lowercase()
|
||||
if (extension in SPLIT_MODE_COMPATIBILITY_FILE_EXTENSIONS && projectFileIndex.getModuleForFile(file, true) != null) {
|
||||
files += file
|
||||
}
|
||||
return true
|
||||
}
|
||||
})
|
||||
return files
|
||||
}
|
||||
|
||||
private fun inspectSplitModeCompatibilityFile(
|
||||
project: Project,
|
||||
psiFile: PsiFile,
|
||||
tools: List<LocalInspectionToolWrapper>,
|
||||
): List<DevKitMcpToolset.SplitModeCompatibilityIssue> {
|
||||
val descriptorsByTool = InspectionEngine.inspectEx(
|
||||
tools,
|
||||
psiFile,
|
||||
psiFile.textRange,
|
||||
psiFile.textRange,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
EmptyProgressIndicator(),
|
||||
PairProcessor.alwaysTrue(),
|
||||
)
|
||||
|
||||
return descriptorsByTool.flatMap { (tool, descriptors) ->
|
||||
descriptors.map { descriptor ->
|
||||
descriptor.toSplitModeCompatibilityIssue(project, tool.shortName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun ProblemDescriptor.toSplitModeCompatibilityIssue(
|
||||
project: Project,
|
||||
inspectionId: String,
|
||||
): DevKitMcpToolset.SplitModeCompatibilityIssue {
|
||||
val textRange = (this as? ProblemDescriptorBase)?.textRange ?: psiElement?.textRange
|
||||
val virtualFile = (this as? ProblemDescriptorBase)?.containingFile ?: psiElement?.containingFile?.virtualFile
|
||||
val position = computePosition(virtualFile, textRange)
|
||||
return DevKitMcpToolset.SplitModeCompatibilityIssue(
|
||||
inspectionId = inspectionId,
|
||||
severity = highlightType.name,
|
||||
filePath = virtualFile?.toProjectRelativePath(project) ?: "<unknown>",
|
||||
line = position?.line,
|
||||
column = position?.column,
|
||||
endLine = position?.endLine,
|
||||
endColumn = position?.endColumn,
|
||||
description = ProblemDescriptorUtil.renderDescriptionMessage(this, psiElement, false),
|
||||
quickFixes = fixes?.map { it.familyName }?.distinct().orEmpty(),
|
||||
)
|
||||
}
|
||||
|
||||
private fun computePosition(
|
||||
virtualFile: VirtualFile?,
|
||||
textRange: TextRange?,
|
||||
): SourcePosition? {
|
||||
if (virtualFile == null || textRange == null) {
|
||||
return null
|
||||
}
|
||||
val document = FileDocumentManager.getInstance().getDocument(virtualFile) ?: return null
|
||||
val startOffset = textRange.startOffset.coerceIn(0, document.textLength)
|
||||
val endOffset = textRange.endOffset.coerceIn(startOffset, document.textLength)
|
||||
return SourcePosition(
|
||||
line = document.getLineNumber(startOffset) + 1,
|
||||
column = startOffset - document.getLineStartOffset(document.getLineNumber(startOffset)) + 1,
|
||||
endLine = document.getLineNumber(endOffset) + 1,
|
||||
endColumn = endOffset - document.getLineStartOffset(document.getLineNumber(endOffset)) + 1,
|
||||
)
|
||||
}
|
||||
|
||||
private fun VirtualFile.toProjectRelativePath(project: Project): String {
|
||||
val basePath = project.basePath ?: return path
|
||||
val relativePath = path.removePrefix(basePath).removePrefix("/")
|
||||
return relativePath.ifEmpty { path }
|
||||
}
|
||||
|
||||
private data class SourcePosition(
|
||||
val line: Int,
|
||||
val column: Int,
|
||||
val endLine: Int,
|
||||
val endColumn: Int,
|
||||
)
|
||||
|
||||
private data class SplitModeCompatibilityInspectionRunResult(
|
||||
val issues: List<DevKitMcpToolset.SplitModeCompatibilityIssue>,
|
||||
val inspectedFileCount: Int,
|
||||
)
|
||||
@@ -5,6 +5,7 @@ import com.intellij.mcpserver.mcpFail
|
||||
import com.intellij.mcpserver.project
|
||||
import com.intellij.mcpserver.util.resolveInProject
|
||||
import com.intellij.openapi.application.readAction
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.psi.PsiManager
|
||||
import kotlinx.coroutines.currentCoroutineContext
|
||||
@@ -19,22 +20,16 @@ internal suspend fun recognizeSplitModeModuleKindForPath(descriptorPath: String)
|
||||
val project = currentCoroutineContext().project
|
||||
val resolvedDescriptorPath = project.resolveInProject(descriptorPath)
|
||||
val descriptorVirtualFile = VirtualFileManager.getInstance().findFileByNioPath(resolvedDescriptorPath)
|
||||
?: VirtualFileManager.getInstance().refreshAndFindFileByNioPath(resolvedDescriptorPath)
|
||||
?: mcpFail("File not found: $descriptorPath")
|
||||
?: VirtualFileManager.getInstance().refreshAndFindFileByNioPath(resolvedDescriptorPath)
|
||||
?: mcpFail("File not found: $descriptorPath")
|
||||
|
||||
val service = SplitModeApiRestrictionsService.getInstance(project)
|
||||
service.scheduleLoadRestrictions()
|
||||
withTimeoutOrNull(5.seconds) {
|
||||
while (!service.isLoaded()) {
|
||||
delay(50.milliseconds)
|
||||
}
|
||||
} ?: mcpFail("Timed out waiting for split-mode module restrictions to load")
|
||||
loadSplitModeRestrictions(project)
|
||||
|
||||
val recognizedKind = readAction {
|
||||
val psiFile = PsiManager.getInstance(project).findFile(descriptorVirtualFile)
|
||||
?: mcpFail("Psi file not found: $descriptorPath")
|
||||
recognizeSplitModeModuleKind(psiFile)
|
||||
?: mcpFail("Descriptor is not an IntelliJ plugin XML file or no IntelliJ module was found: $descriptorPath")
|
||||
?: mcpFail("Descriptor is not an IntelliJ plugin XML file or no IntelliJ module was found: $descriptorPath")
|
||||
}
|
||||
|
||||
return DevKitMcpToolset.RecognizeIjModuleKindResult(
|
||||
@@ -44,3 +39,25 @@ internal suspend fun recognizeSplitModeModuleKindForPath(descriptorPath: String)
|
||||
reasoning = recognizedKind.reasoning,
|
||||
)
|
||||
}
|
||||
|
||||
internal suspend fun recognizeSplitModeApiKind(apiName: String): DevKitMcpToolset.RecognizeSplitModeApiKindResult {
|
||||
val project = currentCoroutineContext().project
|
||||
val service = loadSplitModeRestrictions(project)
|
||||
val apiKind = service.getCodeApiKind(apiName, null)
|
||||
return DevKitMcpToolset.RecognizeSplitModeApiKindResult(
|
||||
apiName = apiName,
|
||||
kindId = apiKind?.id,
|
||||
hint = service.getCodeApiHint(apiName),
|
||||
)
|
||||
}
|
||||
|
||||
internal suspend fun loadSplitModeRestrictions(project: Project): SplitModeApiRestrictionsService {
|
||||
val service = SplitModeApiRestrictionsService.getInstance(project)
|
||||
service.scheduleLoadRestrictions()
|
||||
withTimeoutOrNull(5.seconds) {
|
||||
while (!service.isLoaded()) {
|
||||
delay(50.milliseconds)
|
||||
}
|
||||
} ?: mcpFail("Timed out waiting for split-mode module restrictions to load")
|
||||
return service
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user