[RDCT] RDCT-1224: Add support for per-client persistent state components

Such components must never be saved on disk with a non-local clientId. They should only store data in memory.

IJ-MR-130819

GitOrigin-RevId: d99fa4e43aedae2cb520768a8e9f25822b3fe38f
This commit is contained in:
Vyacheslav Moklev
2024-04-09 12:29:01 +03:00
committed by intellij-monorepo-bot
parent bdc9ccfcee
commit 4e5b50ebac
3 changed files with 30 additions and 2 deletions

View File

@@ -29,7 +29,7 @@
order="last"/>
<applicationService serviceInterface="com.intellij.psi.stubs.SerializationManagerEx"
serviceImplementation="com.intellij.psi.stubs.SerializationManagerImpl" preload="true"/>
<applicationService serviceImplementation="com.intellij.codeInsight.CodeInsightSettings"/>
<applicationService serviceImplementation="com.intellij.codeInsight.CodeInsightSettings" client="all"/>
<applicationService serviceInterface="com.intellij.codeInsight.completion.CompletionService"
serviceImplementation="com.intellij.codeInsight.completion.BaseCompletionService"/>
<applicationService serviceInterface="com.intellij.ide.plugins.PluginUtil"

View File

@@ -2,6 +2,7 @@
package com.intellij.codeInsight;
import com.intellij.codeInsight.editorActions.SmartBackspaceMode;
import com.intellij.codeWithMe.ClientId;
import com.intellij.configurationStore.XmlSerializer;
import com.intellij.ide.ui.UINumericRange;
import com.intellij.openapi.Disposable;
@@ -213,6 +214,10 @@ public class CodeInsightSettings implements PersistentStateComponent<Element>, C
@Override
public Element getState() {
if (!ClientId.isCurrentlyUnderLocalId()) {
throw new RuntimeException("Settings must be saved only under local clientId, current is " + ClientId.getCurrentOrNull());
}
Element element = new Element("state");
writeExternal(element);
return element;

View File

@@ -30,6 +30,7 @@ import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
import com.intellij.util.ArrayUtilRt
import com.intellij.util.ResourceUtil
import com.intellij.util.ThreeState
import com.intellij.util.application
import com.intellij.util.concurrency.annotations.RequiresEdt
import com.intellij.util.messages.MessageBus
import com.intellij.util.xmlb.SettingsInternalApi
@@ -742,20 +743,42 @@ abstract class ComponentStoreImpl : IComponentStore {
}
}
private fun tryReloadPerClientState(componentClass: Class<out PersistentStateComponent<*>>,
info: ComponentInfo,
changedStorages: Set<StateStorage>): Boolean {
val perClientComponent = (project ?: application).getService(componentClass)
if (perClientComponent == null || perClientComponent === info.component) {
return false
}
val newInfo = ComponentInfoImpl(info.pluginId, perClientComponent, info.stateSpec)
initComponent(info = newInfo, changedStorages = changedStorages.ifEmpty { null }, reloadData = ThreeState.YES)
return true
}
final override fun reloadState(componentClass: Class<out PersistentStateComponent<*>>) {
val stateSpec = getStateSpecOrError(componentClass)
val info = components.get(stateSpec.name) ?: return
(info.component as? PersistentStateComponent<*>)?.let {
if (tryReloadPerClientState(it.javaClass, info, emptySet())) {
return
}
initComponent(info = info, changedStorages = emptySet(), reloadData = ThreeState.YES)
}
}
private fun reloadState(componentName: String, changedStorages: Set<StateStorage>): Boolean {
val info = components.get(componentName) ?: return false
if (info.component !is PersistentStateComponent<*>) {
val component = info.component
if (component !is PersistentStateComponent<*>) {
return false
}
if (tryReloadPerClientState(component.javaClass, info, changedStorages)) {
return true
}
val isChangedStoragesEmpty = changedStorages.isEmpty()
initComponent(info = info, changedStorages = if (isChangedStoragesEmpty) null else changedStorages, reloadData = ThreeState.UNSURE)
return true