[RDCT] RDCT-1224: Remove @RemoteSetting annotation and replace it with a static map in RdSettingsStorageService

There are only a handful of PersistentStateComponent that we want to synchronize. After a discussion with @develar, we decided not to have an extension point and special annotations in the platform, but to list all of such components in our code.
Components' names will not be changed to keep backward compatibility for XML settings, so it is a safe approach. In the future, we will sunset PSC anyway and migrate them to the new SettingsController API.

IJ-MR-130819

GitOrigin-RevId: 7c9b974d406f8f4179d671f6483fd7143b6618d9
This commit is contained in:
Vyacheslav Moklev
2024-05-09 14:44:09 +03:00
committed by intellij-monorepo-bot
parent 11730cb8a6
commit 918f867d82
14 changed files with 24 additions and 61 deletions

View File

@@ -28,7 +28,6 @@ import java.lang.reflect.Field;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@RemoteSetting(direction = RemoteSettingDirection.FromHost, allowedInCwm = true)
@State(name = "CodeInsightSettings", storages = @Storage("editor.xml"), category = SettingsCategory.CODE)
public class CodeInsightSettings implements PersistentStateComponent<Element>, Cloneable {
private static final Logger LOG = Logger.getInstance(CodeInsightSettings.class);

View File

@@ -129,7 +129,7 @@ abstract class SaveSessionProducerBase : SaveSessionProducer, SafeWriteRequestor
val element: Element?
try {
element = serializeState(state = state, component = component, componentName = componentName, pluginId = pluginId, controller = controller, roamingType = roamingType)
element = serializeState(state = state, componentName = componentName, pluginId = pluginId, controller = controller, roamingType = roamingType)
}
catch (e: WriteExternalException) {
LOG.debug(e)
@@ -148,7 +148,7 @@ abstract class SaveSessionProducerBase : SaveSessionProducer, SafeWriteRequestor
abstract fun setSerializedState(componentName: String, element: Element?)
}
internal fun serializeState(state: Any, component: Any?, componentName: String, pluginId: PluginId, controller: SettingsController?, roamingType: RoamingType?): Element? {
internal fun serializeState(state: Any, componentName: String, pluginId: PluginId, controller: SettingsController?, roamingType: RoamingType?): Element? {
@Suppress("DEPRECATION")
when (state) {
is Element -> {
@@ -156,7 +156,7 @@ internal fun serializeState(state: Any, component: Any?, componentName: String,
val key = SettingDescriptor(
key = createSettingKey(componentName = componentName, binding = null),
pluginId = pluginId,
tags = createTags(componentName, component, roamingType, extraTag = null),
tags = createTags(componentName, roamingType, extraTag = null),
serializer = JsonElementSettingSerializerDescriptor,
)
@@ -182,7 +182,6 @@ internal fun serializeState(state: Any, component: Any?, componentName: String,
rootBinding = rootBinding,
state = state,
filter = filter,
component = component,
componentName = componentName,
pluginId = pluginId,
controller = controller,
@@ -190,7 +189,7 @@ internal fun serializeState(state: Any, component: Any?, componentName: String,
)
}
else if (rootBinding is KotlinxSerializationBinding) {
val keyTags = createTags(componentName, component, roamingType, extraTag = null)
val keyTags = createTags(componentName, roamingType, extraTag = null)
val key = SettingDescriptor(
key = createSettingKey(componentName = componentName, binding = null),
pluginId = pluginId,
@@ -216,53 +215,40 @@ internal fun serializeState(state: Any, component: Any?, componentName: String,
}
}
private inline fun <reified T: Annotation> getAnnotationInSuperclass(value: Any): T? {
return generateSequence(value.javaClass) { it.superclass }
.mapNotNull { it.annotations.filterIsInstance<T>().firstOrNull() }
.firstOrNull()
}
private fun createTags(componentName: String, component: Any?, roamingType: RoamingType?, extraTag: SettingTag?): List<SettingTag> {
val tags = mutableListOf<SettingTag>(PersistenceStateComponentPropertyTag(componentName))
private fun createTags(componentName: String, roamingType: RoamingType?, extraTag: SettingTag?): List<SettingTag> {
val componentPropertyTag = PersistenceStateComponentPropertyTag(componentName)
if (roamingType == RoamingType.DISABLED) {
tags.add(NonShareableTag)
}
if (extraTag != null) {
tags.add(extraTag)
}
// TODO move rdct-specific code to some extension
if (component != null) {
getAnnotationInSuperclass<RemoteSetting>(component)?.let {
tags.add(RemoteSettingTag(it.direction.toString(), it.allowedInCwm))
if (extraTag == null) {
return java.util.List.of(componentPropertyTag, NonShareableTag)
}
else {
return java.util.List.of(componentPropertyTag, NonShareableTag, extraTag)
}
}
else {
if (extraTag == null) {
return java.util.List.of(componentPropertyTag)
}
else {
return java.util.List.of(componentPropertyTag, extraTag)
}
}
return tags
}
private fun createTagsForBinding(rootTags: List<SettingTag>, binding: NestedBinding): List<SettingTag> {
val remoteSetting = binding.accessor.getAnnotation(RemoteSetting::class.java)
?: return rootTags
val remoteSettingTag = RemoteSettingTag(remoteSetting.direction.toString(), remoteSetting.allowedInCwm)
return rootTags.filter { it !is RemoteSettingTag } + remoteSettingTag
}
private fun serializeWithController(
rootBinding: BeanBinding,
state: Any,
filter: SkipDefaultsSerializationFilter,
component: Any?,
componentName: String,
pluginId: PluginId,
controller: SettingsController,
roamingType: RoamingType?
): Element? {
val keyTags = createTags(componentName, component, roamingType, extraTag = null)
val keyTags = createTags(componentName, roamingType, extraTag = null)
var element: Element? = null
for (binding in rootBinding.bindings!!) {
val isPropertySkipped = isPropertySkipped(filter = filter, binding = binding, bean = state, rootBinding = rootBinding, isFilterPropertyItself = true)
val key = SettingDescriptor(key = createSettingKey(componentName, binding), pluginId = pluginId, tags = createTagsForBinding(keyTags, binding), serializer = JsonElementSettingSerializerDescriptor)
val key = SettingDescriptor(key = createSettingKey(componentName, binding), pluginId = pluginId, tags = keyTags, serializer = JsonElementSettingSerializerDescriptor)
val result = controller.doSetItem(key = key, value = if (isPropertySkipped) null else binding.toJson(state, filter))
if (isPropertySkipped) {
continue
@@ -310,7 +296,7 @@ internal fun <T : Any> deserializeStateWithController(
controller = controller,
componentName = componentName,
pluginId = pluginId,
tags = createTags(componentName, component = null, roamingType, extraTag = OldLocalValueSupplierTag(supplier = SynchronizedClearableLazy {
tags = createTags(componentName, roamingType, extraTag = OldLocalValueSupplierTag(supplier = SynchronizedClearableLazy {
stateElement?.let {
jdomToJson(it)
}

View File

@@ -458,7 +458,7 @@ private class StateGetterImpl<S : Any>(
serializedState
}
else {
serializeState(state = stateAfterLoad, component = component, componentName = componentName, pluginId = pluginId, controller = null, roamingType = null)?.let {
serializeState(state = stateAfterLoad, componentName = componentName, pluginId = pluginId, controller = null, roamingType = null)?.let {
normalizeRootName(it)
}?.takeIf { !it.isEmpty }
}

View File

@@ -27,7 +27,6 @@ import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.*;
@RemoteSetting(direction = RemoteSettingDirection.FromHost, allowedInCwm = true)
@State(name = "EditorSettings", storages = @Storage("editor.xml"), category = SettingsCategory.CODE)
public class EditorSettingsExternalizable implements PersistentStateComponent<EditorSettingsExternalizable.OptionSet> {
/**

View File

@@ -17,7 +17,6 @@ import org.jetbrains.annotations.ApiStatus.Internal
import org.jetbrains.annotations.SystemDependent
@RemoteSetting(direction = RemoteSettingDirection.FromHost)
@State(name = "GeneralSettings", storages = [Storage(GeneralSettings.IDE_GENERAL_XML)], category = SettingsCategory.SYSTEM)
class GeneralSettings : PersistentStateComponent<GeneralSettingsState> {
private var state = GeneralSettingsState()
@@ -231,7 +230,6 @@ data class GeneralSettingsState(
@ReportValue
@JvmField
var confirmOpenNewProject2: Int? = null,
@field:RemoteSetting(direction = RemoteSettingDirection.FromClient)
@JvmField
var processCloseConfirmation: ProcessCloseConfirmation = ProcessCloseConfirmation.ASK,
@JvmField

View File

@@ -12,7 +12,6 @@ import org.jetbrains.annotations.NotNull;
import java.util.*;
@RemoteSetting(direction = RemoteSettingDirection.FromClient)
@State(name = "ConsoleFoldingSettings", storages = @Storage("consoleFolding.xml"), category = SettingsCategory.CODE)
public final class ConsoleFoldingSettings implements PersistentStateComponent<ConsoleFoldingSettings.MyBean> {
private final List<String> myPositivePatterns = new ArrayList<>();

View File

@@ -8,7 +8,6 @@ import com.intellij.openapi.editor.colors.EditorColorsManager
import com.intellij.psi.codeStyle.CodeStyleScheme
import kotlinx.coroutines.CoroutineScope
@RemoteSetting(direction = RemoteSettingDirection.Both, allowedInCwm = true)
@State(name = "ReaderModeSettings", storages = [Storage(StoragePathMacros.PRODUCT_WORKSPACE_FILE)])
class ReaderModeSettingsImpl(override val coroutineScope: CoroutineScope) : PersistentStateComponentWithModificationTracker<ReaderModeSettingsImpl.State>,
ReaderModeSettings {

View File

@@ -12,7 +12,6 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
@RemoteSetting(direction = RemoteSettingDirection.FromClient)
@State(name = "NotificationConfiguration", storages = @Storage("notifications.xml"), category = SettingsCategory.UI)
public final class NotificationsConfigurationImpl extends NotificationsConfiguration implements PersistentStateComponent<Element>, Disposable {
private static final Logger LOG = Logger.getInstance(NotificationsConfigurationImpl.class);

View File

@@ -32,7 +32,6 @@ private const val RECENT_TW_TAG = "recentWindows"
private const val MORE_BUTTON_TAG = "moreButton"
@ApiStatus.Internal
//@DoNotSynchronizeSetting
@State(name = "ToolWindowManager", storages = [Storage(StoragePathMacros.PRODUCT_WORKSPACE_FILE)])
class ToolWindowManagerStateImpl : ToolWindowManagerState {
private val isNewUi = ExperimentalUI.isNewUI()

View File

@@ -1,7 +0,0 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.components
annotation class RemoteSetting(val direction: RemoteSettingDirection, val allowedInCwm: Boolean = false)
enum class RemoteSettingDirection { FromHost, FromClient, Both, None }
// TODO remove Both and None, rename to initial value source

View File

@@ -54,9 +54,4 @@ class OldLocalValueSupplierTag(private val supplier: Supplier<JsonElement?>) : S
get() = supplier.get()
override fun toString(): String = "OldLocalValueSupplierTag"
}
// TODO move rdct-specific tags to some extension
// TODO obviously a hack to avoid dependencies between `intellij.platform.settings` and `intellij.platform.projectModel`
// TODO creation of tags must be extracted into some extension point, implemented in `intellij.cwm.common`
class RemoteSettingTag(val direction: String, val allowedInCwm: Boolean) : SettingTag
}

View File

@@ -22,7 +22,6 @@ import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
@RemoteSetting(direction = RemoteSettingDirection.FromHost)
@State(name = "XDebuggerSettings", storages = @Storage("debugger.xml"), category = SettingsCategory.TOOLS)
public final class XDebuggerSettingManagerImpl extends XDebuggerSettingsManager
implements PersistentStateComponent<XDebuggerSettingManagerImpl.SettingsState>, Disposable {

View File

@@ -4,7 +4,6 @@ import com.intellij.openapi.components.*
import org.jetbrains.annotations.ApiStatus
@ApiStatus.Experimental
@RemoteSetting(direction = RemoteSettingDirection.FromHost)
@State(name = "MarkdownCodeInsightSettings",
category = SettingsCategory.CODE,
storages = [(Storage("markdown.xml"))])

View File

@@ -10,7 +10,6 @@ import org.intellij.plugins.markdown.ui.preview.MarkdownHtmlPanelProvider
import org.intellij.plugins.markdown.ui.preview.jcef.JCEFHtmlPanelProvider
@Service(Service.Level.PROJECT)
@RemoteSetting(direction = RemoteSettingDirection.FromClient)
@State(name = "MarkdownSettings", storages = [(Storage("markdown.xml"))])
class MarkdownSettings(internal val project: Project): SimplePersistentStateComponent<MarkdownSettingsState>(MarkdownSettingsState()) {
var areInjectionsEnabled