mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
LSP-270 Un-hack user data
GitOrigin-RevId: a2d7c8196baefcac898d2169a86721072e6a5c22
This commit is contained in:
committed by
intellij-monorepo-bot
parent
30c410f055
commit
bf42314169
@@ -2,7 +2,6 @@
|
||||
package com.intellij.openapi.util;
|
||||
|
||||
import com.intellij.ReviseWhenPortedToJDK;
|
||||
import com.intellij.openapi.util.userData.ExternalUserDataStorage;
|
||||
import com.intellij.util.containers.VarHandleWrapper;
|
||||
import com.intellij.util.keyFMap.KeyFMap;
|
||||
import com.intellij.util.xmlb.annotations.Transient;
|
||||
@@ -10,26 +9,12 @@ import org.jetbrains.annotations.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
|
||||
@ReviseWhenPortedToJDK("11") // rewrite to real VarHandles
|
||||
@Transient
|
||||
public class UserDataHolderBase implements UserDataHolderEx, Serializable {
|
||||
private static final Key<KeyFMap> COPYABLE_USER_MAP_KEY = Key.create("COPYABLE_USER_MAP_KEY");
|
||||
|
||||
@Nullable
|
||||
private static Function<@NotNull UserDataHolderBase, @Nullable ExternalUserDataStorage> ourExternalUserDataStorage = null;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void setExternalUserDataStorage(@Nullable Function<@NotNull UserDataHolderBase, @Nullable ExternalUserDataStorage> provider) {
|
||||
ourExternalUserDataStorage = provider;
|
||||
}
|
||||
|
||||
private @Nullable ExternalUserDataStorage externalStorage() {
|
||||
Function<@NotNull UserDataHolderBase, @Nullable ExternalUserDataStorage> provider = ourExternalUserDataStorage;
|
||||
return provider == null ? null : provider.apply(this);
|
||||
}
|
||||
|
||||
private volatile @NotNull KeyFMap value = KeyFMap.EMPTY_MAP;
|
||||
private static final VarHandleWrapper VALUE_HANDLE = VarHandleWrapper.getFactory().create(UserDataHolderBase.class, "value", KeyFMap.class);
|
||||
|
||||
@@ -62,43 +47,25 @@ public class UserDataHolderBase implements UserDataHolderEx, Serializable {
|
||||
|
||||
@Override
|
||||
public <T> T getUserData(@NotNull Key<T> key) {
|
||||
ExternalUserDataStorage external = externalStorage();
|
||||
if (external != null) {
|
||||
return external.getUserData(this, key);
|
||||
}
|
||||
else {
|
||||
T t = getUserMap().get(key);
|
||||
if (t == null && key instanceof KeyWithDefaultValue) {
|
||||
t = putUserDataIfAbsent(key, ((KeyWithDefaultValue<T>)key).getDefaultValue());
|
||||
}
|
||||
return t;
|
||||
T t = getUserMap().get(key);
|
||||
if (t == null && key instanceof KeyWithDefaultValue) {
|
||||
t = putUserDataIfAbsent(key, ((KeyWithDefaultValue<T>)key).getDefaultValue());
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public @NotNull KeyFMap getUserMap() {
|
||||
ExternalUserDataStorage external = externalStorage();
|
||||
if (external != null) {
|
||||
return external.getUserMap(this);
|
||||
}
|
||||
else {
|
||||
return value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void putUserData(@NotNull Key<T> key, @Nullable T value) {
|
||||
ExternalUserDataStorage external = externalStorage();
|
||||
if (external != null) {
|
||||
external.putUserData(this, key, value);
|
||||
}
|
||||
else {
|
||||
while (true) {
|
||||
KeyFMap map = getUserMap();
|
||||
KeyFMap newMap = value == null ? map.minus(key) : map.plus(key, value);
|
||||
if (newMap == map || changeUserMap(map, newMap)) {
|
||||
break;
|
||||
}
|
||||
while (true) {
|
||||
KeyFMap map = getUserMap();
|
||||
KeyFMap newMap = value == null ? map.minus(key) : map.plus(key, value);
|
||||
if (newMap == map || changeUserMap(map, newMap)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,88 +80,45 @@ public class UserDataHolderBase implements UserDataHolderEx, Serializable {
|
||||
}
|
||||
|
||||
public <T> void putCopyableUserData(@NotNull Key<T> key, T value) {
|
||||
ExternalUserDataStorage external = externalStorage();
|
||||
if (external != null) {
|
||||
while (true) {
|
||||
KeyFMap oldCopyableMap = getUserData(COPYABLE_USER_MAP_KEY);
|
||||
KeyFMap newCopyableMap = oldCopyableMap;
|
||||
if (oldCopyableMap == null) {
|
||||
if (value == null) {
|
||||
//nothing
|
||||
}
|
||||
else {
|
||||
newCopyableMap = KeyFMap.EMPTY_MAP.plus(key, value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (value == null) {
|
||||
newCopyableMap = oldCopyableMap.minus(key);
|
||||
}
|
||||
else {
|
||||
newCopyableMap = oldCopyableMap.plus(key, value);
|
||||
}
|
||||
}
|
||||
if (
|
||||
oldCopyableMap == newCopyableMap ||
|
||||
external.compareAndPutUserData(this, COPYABLE_USER_MAP_KEY, oldCopyableMap, newCopyableMap)
|
||||
) {
|
||||
break;
|
||||
}
|
||||
while (true) {
|
||||
KeyFMap map = getUserMap();
|
||||
KeyFMap copyableMap = map.get(COPYABLE_USER_MAP_KEY);
|
||||
if (copyableMap == null) {
|
||||
copyableMap = KeyFMap.EMPTY_MAP;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (true) {
|
||||
KeyFMap map = getUserMap();
|
||||
KeyFMap copyableMap = map.get(COPYABLE_USER_MAP_KEY);
|
||||
if (copyableMap == null) {
|
||||
copyableMap = KeyFMap.EMPTY_MAP;
|
||||
}
|
||||
KeyFMap newCopyableMap = value == null ? copyableMap.minus(key) : copyableMap.plus(key, value);
|
||||
KeyFMap newMap = newCopyableMap.isEmpty() ? map.minus(COPYABLE_USER_MAP_KEY) : map.plus(COPYABLE_USER_MAP_KEY, newCopyableMap);
|
||||
if (newMap == map || changeUserMap(map, newMap)) {
|
||||
return;
|
||||
}
|
||||
KeyFMap newCopyableMap = value == null ? copyableMap.minus(key) : copyableMap.plus(key, value);
|
||||
KeyFMap newMap = newCopyableMap.isEmpty() ? map.minus(COPYABLE_USER_MAP_KEY) : map.plus(COPYABLE_USER_MAP_KEY, newCopyableMap);
|
||||
if (newMap == map || changeUserMap(map, newMap)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> boolean replace(@NotNull Key<T> key, @Nullable T oldValue, @Nullable T newValue) {
|
||||
ExternalUserDataStorage external = externalStorage();
|
||||
if (external != null) {
|
||||
return external.compareAndPutUserData(this, key, oldValue, newValue);
|
||||
}
|
||||
else {
|
||||
while (true) {
|
||||
KeyFMap map = getUserMap();
|
||||
if (map.get(key) != oldValue) {
|
||||
return false;
|
||||
}
|
||||
KeyFMap newMap = newValue == null ? map.minus(key) : map.plus(key, newValue);
|
||||
if (newMap == map || changeUserMap(map, newMap)) {
|
||||
return true;
|
||||
}
|
||||
while (true) {
|
||||
KeyFMap map = getUserMap();
|
||||
if (map.get(key) != oldValue) {
|
||||
return false;
|
||||
}
|
||||
KeyFMap newMap = newValue == null ? map.minus(key) : map.plus(key, newValue);
|
||||
if (newMap == map || changeUserMap(map, newMap)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull <T> T putUserDataIfAbsent(final @NotNull Key<T> key, final @NotNull T value) {
|
||||
ExternalUserDataStorage external = externalStorage();
|
||||
if (external != null) {
|
||||
return external.putUserDataIfAbsent(this, key, value);
|
||||
}
|
||||
else {
|
||||
while (true) {
|
||||
KeyFMap map = getUserMap();
|
||||
T oldValue = map.get(key);
|
||||
if (oldValue != null) {
|
||||
return oldValue;
|
||||
}
|
||||
KeyFMap newMap = map.plus(key, value);
|
||||
if (newMap == map || changeUserMap(map, newMap)) {
|
||||
return value;
|
||||
}
|
||||
while (true) {
|
||||
KeyFMap map = getUserMap();
|
||||
T oldValue = map.get(key);
|
||||
if (oldValue != null) {
|
||||
return oldValue;
|
||||
}
|
||||
KeyFMap newMap = map.plus(key, value);
|
||||
if (newMap == map || changeUserMap(map, newMap)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,13 +137,7 @@ public class UserDataHolderBase implements UserDataHolderEx, Serializable {
|
||||
}
|
||||
|
||||
protected void setUserMap(@NotNull KeyFMap map) {
|
||||
ExternalUserDataStorage external = externalStorage();
|
||||
if (external != null) {
|
||||
external.setUserMap(this, map);
|
||||
}
|
||||
else {
|
||||
value = map;
|
||||
}
|
||||
value = map;
|
||||
}
|
||||
|
||||
public boolean isUserDataEmpty() {
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
package com.intellij.openapi.util.userData
|
||||
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.openapi.util.UserDataHolder
|
||||
import com.intellij.util.keyFMap.KeyFMap
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
@ApiStatus.Internal
|
||||
interface ExternalUserDataStorage {
|
||||
|
||||
fun <T : Any> getUserData(obj: UserDataHolder, key: Key<T>): T?
|
||||
|
||||
fun <T : Any> putUserData(obj: UserDataHolder, key: Key<T>, value: T?)
|
||||
|
||||
fun <T : Any> compareAndPutUserData(obj: UserDataHolder, key: Key<T>, oldValue: T?, newValue: T?): Boolean
|
||||
|
||||
fun getUserMap(obj: UserDataHolder): KeyFMap
|
||||
|
||||
fun setUserMap(obj: UserDataHolder, userMap: KeyFMap)
|
||||
|
||||
fun <T : Any> putUserDataIfAbsent(obj: UserDataHolder, key: Key<T>, value: T): T
|
||||
}
|
||||
Reference in New Issue
Block a user