mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-04 23:39:07 +07:00
[lombok] IDEA-264579 added cache to prevent multiple file index access for same keys
GitOrigin-RevId: c8a5b1da548f57f3a2bb98a1a163a3e0ca79eb74
This commit is contained in:
committed by
intellij-monorepo-bot
parent
cbfd2f4ad9
commit
20d81fdd6c
@@ -11,7 +11,7 @@ import de.plushnikov.intellij.plugin.lombokconfig.ConfigKey;
|
||||
import de.plushnikov.intellij.plugin.util.PsiAnnotationSearchUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -48,10 +48,10 @@ public class SpringQualifierCopyableLombokAnnotationInspection extends LombokJav
|
||||
if (psiClass != null && PsiAnnotationSearchUtil.isAnnotatedWith(psiClass,
|
||||
LombokClassNames.REQUIRED_ARGS_CONSTRUCTOR,
|
||||
LombokClassNames.ALL_ARGS_CONSTRUCTOR)) {
|
||||
String[] configuredCopyableAnnotations =
|
||||
Collection<String> configuredCopyableAnnotations =
|
||||
ConfigDiscovery.getInstance().getMultipleValueLombokConfigProperty(ConfigKey.COPYABLE_ANNOTATIONS, psiClass);
|
||||
|
||||
if (!Arrays.asList(configuredCopyableAnnotations).contains(SPRING_QUALIFIER_FQN)) {
|
||||
if (!configuredCopyableAnnotations.contains(SPRING_QUALIFIER_FQN)) {
|
||||
holder.registerProblem(annotation,
|
||||
LombokBundle.message("inspection.message.annotation.not.lombok.copyable",
|
||||
SPRING_QUALIFIER_FQN),
|
||||
|
||||
@@ -9,9 +9,10 @@ import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.GlobalSearchScopes;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.util.containers.ConcurrentFactoryMap;
|
||||
import com.intellij.util.indexing.FileBasedIndex;
|
||||
import de.plushnikov.intellij.plugin.psi.LombokLightClassBuilder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -25,12 +26,11 @@ public class ConfigDiscovery {
|
||||
|
||||
@NotNull
|
||||
public String getStringLombokConfigProperty(@NotNull ConfigKey configKey, @NotNull PsiClass psiClass) {
|
||||
@Nullable VirtualFile file = calculateDirectory(psiClass);
|
||||
if (null != file) {
|
||||
return discoverProperty(configKey, file, psiClass.getProject());
|
||||
} else {
|
||||
return configKey.getConfigDefaultValue();
|
||||
@Nullable PsiFile psiFile = calculatePsiFile(psiClass);
|
||||
if (null != psiFile) {
|
||||
return discoverPropertyWithCache(configKey, psiFile);
|
||||
}
|
||||
return configKey.getConfigDefaultValue();
|
||||
}
|
||||
|
||||
public boolean getBooleanLombokConfigProperty(@NotNull ConfigKey configKey, @NotNull PsiClass psiClass) {
|
||||
@@ -38,67 +38,44 @@ public class ConfigDiscovery {
|
||||
return Boolean.parseBoolean(configProperty);
|
||||
}
|
||||
|
||||
public String @NotNull [] getMultipleValueLombokConfigProperty(@NotNull ConfigKey configKey, @NotNull PsiClass psiClass) {
|
||||
final Collection<String> result = new HashSet<>();
|
||||
|
||||
@Nullable VirtualFile file = calculateDirectory(psiClass);
|
||||
if (file != null) {
|
||||
final List<String> properties = discoverProperties(configKey, file, psiClass.getProject());
|
||||
Collections.reverse(properties);
|
||||
|
||||
for (String configProperty : properties) {
|
||||
if (StringUtil.isNotEmpty(configProperty)) {
|
||||
final String[] values = configProperty.split(";");
|
||||
for (String value : values) {
|
||||
if (value.startsWith("+")) {
|
||||
result.add(value.substring(1));
|
||||
} else if (value.startsWith("-")) {
|
||||
result.remove(value.substring(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result.add(configKey.getConfigDefaultValue());
|
||||
public @NotNull Collection<String> getMultipleValueLombokConfigProperty(@NotNull ConfigKey configKey, @NotNull PsiClass psiClass) {
|
||||
@Nullable PsiFile psiFile = calculatePsiFile(psiClass);
|
||||
if (psiFile != null) {
|
||||
return discoverPropertiesWithCache(configKey, psiFile);
|
||||
}
|
||||
return ArrayUtil.toStringArray(result);
|
||||
return Collections.singletonList(configKey.getConfigDefaultValue());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static VirtualFile calculateDirectory(@NotNull PsiClass psiClass) {
|
||||
PsiFile psiFile;
|
||||
if (psiClass instanceof LombokLightClassBuilder) {
|
||||
// Use containing class for all LombokLightClasses
|
||||
final PsiClass containingClass = psiClass.getContainingClass();
|
||||
if (null != containingClass) {
|
||||
psiFile = containingClass.getContainingFile();
|
||||
} else {
|
||||
psiFile = null;
|
||||
}
|
||||
} else {
|
||||
psiFile = psiClass.getContainingFile();
|
||||
}
|
||||
private static PsiFile calculatePsiFile(@NotNull PsiClass psiClass) {
|
||||
PsiFile psiFile = psiClass.getContainingFile();
|
||||
if (psiFile != null) {
|
||||
PsiFile originalFile = psiFile.getOriginalFile();
|
||||
if (originalFile != null) {
|
||||
psiFile = originalFile;
|
||||
}
|
||||
psiFile = psiFile.getOriginalFile();
|
||||
}
|
||||
|
||||
return psiFile != null ? psiFile.getVirtualFile() : null;
|
||||
return psiFile;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String discoverProperty(@NotNull ConfigKey configKey, @Nullable VirtualFile file, @NotNull Project project) {
|
||||
@Nullable VirtualFile currentFile = file;
|
||||
protected String discoverPropertyWithCache(@NotNull ConfigKey configKey, @NotNull PsiFile psiFile) {
|
||||
return CachedValuesManager.getCachedValue(psiFile, () -> {
|
||||
Map<ConfigKey, String> result =
|
||||
ConcurrentFactoryMap.createMap(configKeyInner -> discoverProperty(configKeyInner, psiFile));
|
||||
return CachedValueProvider.Result.create(result, LombokConfigIndex.CONFIG_CHANGE_TRACKER);
|
||||
}).get(configKey);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected String discoverProperty(@NotNull ConfigKey configKey, @NotNull PsiFile psiFile) {
|
||||
@Nullable VirtualFile currentFile = psiFile.getVirtualFile();
|
||||
while (currentFile != null) {
|
||||
ConfigValue configValue = readProperty(configKey, project, currentFile);
|
||||
ConfigValue configValue = readProperty(configKey, psiFile.getProject(), currentFile);
|
||||
if (null != configValue) {
|
||||
if (null == configValue.getValue()) {
|
||||
if (configValue.isStopBubbling()) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return configValue.getValue();
|
||||
}
|
||||
}
|
||||
@@ -125,25 +102,52 @@ public class ConfigDiscovery {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<String> discoverProperties(@NotNull ConfigKey configKey, @Nullable VirtualFile file, @NotNull Project project) {
|
||||
List<String> result = new ArrayList<>();
|
||||
protected Collection<String> discoverPropertiesWithCache(@NotNull ConfigKey configKey, @NotNull PsiFile psiFile) {
|
||||
return CachedValuesManager.getCachedValue(psiFile, () -> {
|
||||
Map<ConfigKey, Collection<String>> result = ConcurrentFactoryMap.createMap(configKeyInner -> discoverProperties(configKeyInner, psiFile));
|
||||
return CachedValueProvider.Result.create(result, LombokConfigIndex.CONFIG_CHANGE_TRACKER);
|
||||
}).get(configKey);
|
||||
}
|
||||
|
||||
@Nullable VirtualFile currentFile = file;
|
||||
@NotNull
|
||||
protected Collection<String> discoverProperties(@NotNull ConfigKey configKey, @NotNull PsiFile file) {
|
||||
List<String> properties = new ArrayList<>();
|
||||
|
||||
@Nullable VirtualFile currentFile = file.getVirtualFile();
|
||||
while (currentFile != null) {
|
||||
final ConfigValue configValue = readProperty(configKey, project, currentFile);
|
||||
final ConfigValue configValue = readProperty(configKey, file.getProject(), currentFile);
|
||||
if (null != configValue) {
|
||||
if (null == configValue.getValue()) {
|
||||
if (configValue.isStopBubbling()) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
result.add(configValue.getValue());
|
||||
}
|
||||
else {
|
||||
properties.add(configValue.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
currentFile = currentFile.getParent();
|
||||
}
|
||||
|
||||
Collections.reverse(properties);
|
||||
|
||||
Set<String> result = new HashSet<>();
|
||||
|
||||
for (String configProperty : properties) {
|
||||
if (StringUtil.isNotEmpty(configProperty)) {
|
||||
final String[] values = configProperty.split(";");
|
||||
for (String value : values) {
|
||||
if (value.startsWith("+")) {
|
||||
result.add(value.substring(1));
|
||||
}
|
||||
else if (value.startsWith("-")) {
|
||||
result.remove(value.substring(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package de.plushnikov.intellij.plugin.lombokconfig;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public enum ConfigKey {
|
||||
|
||||
CONFIG_STOP_BUBBLING("config.stopBubbling", "false"),
|
||||
@@ -89,7 +91,7 @@ public enum ConfigKey {
|
||||
private final String configDefaultValue;
|
||||
|
||||
ConfigKey(String configKey, String configDefaultValue) {
|
||||
this.configKey = configKey.toLowerCase();
|
||||
this.configKey = configKey.toLowerCase(Locale.ENGLISH);
|
||||
this.configDefaultValue = configDefaultValue;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package de.plushnikov.intellij.plugin.lombokconfig;
|
||||
|
||||
import com.intellij.openapi.util.ModificationTracker;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -24,8 +25,12 @@ import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
public class LombokConfigIndex extends FileBasedIndexExtension<ConfigKey, ConfigValue> {
|
||||
private static final AtomicLong configChangeCount = new AtomicLong(1);
|
||||
public static final ModificationTracker CONFIG_CHANGE_TRACKER = configChangeCount::get;
|
||||
|
||||
@NonNls
|
||||
public static final ID<ConfigKey, ConfigValue> NAME = ID.create("LombokConfigIndex");
|
||||
|
||||
@@ -56,7 +61,7 @@ public class LombokConfigIndex extends FileBasedIndexExtension<ConfigKey, Config
|
||||
new ConfigValue(configValues.get(key.getConfigKey()), stopBubblingValue)));
|
||||
}
|
||||
}
|
||||
|
||||
configChangeCount.incrementAndGet();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@@ -103,9 +102,9 @@ public abstract class AbstractProcessor implements Processor {
|
||||
final PsiClass containingClass = psiField.getContainingClass();
|
||||
// append only for BASE_COPYABLE
|
||||
if (copyableAnnotations == LombokUtils.BASE_COPYABLE_ANNOTATIONS && null != containingClass) {
|
||||
String[] configuredCopyableAnnotations =
|
||||
Collection<String> configuredCopyableAnnotations =
|
||||
ConfigDiscovery.getInstance().getMultipleValueLombokConfigProperty(ConfigKey.COPYABLE_ANNOTATIONS, containingClass);
|
||||
combinedListOfCopyableAnnotations.addAll(Arrays.asList(configuredCopyableAnnotations));
|
||||
combinedListOfCopyableAnnotations.addAll(configuredCopyableAnnotations);
|
||||
}
|
||||
|
||||
final List<String> existingAnnotations = ContainerUtil.map(psiField.getAnnotations(), PsiAnnotation::getQualifiedName);
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.intellij.psi.PsiVariable;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import de.plushnikov.intellij.plugin.LombokClassNames;
|
||||
import de.plushnikov.intellij.plugin.lombokconfig.ConfigDiscovery;
|
||||
import de.plushnikov.intellij.plugin.lombokconfig.ConfigKey;
|
||||
@@ -30,7 +31,7 @@ public class AccessorsInfo {
|
||||
this.fluent = fluentValue;
|
||||
this.chain = chainValue;
|
||||
this.doNotUseIsPrefix = doNotUseIsPrefix;
|
||||
this.prefixes = null == prefixes ? new String[0] : prefixes;
|
||||
this.prefixes = null == prefixes ? ArrayUtil.EMPTY_STRING_ARRAY : prefixes;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -109,9 +110,9 @@ public class AccessorsInfo {
|
||||
}
|
||||
|
||||
if (prefixDeclared.isEmpty()) {
|
||||
prefixes = configDiscovery.getMultipleValueLombokConfigProperty(ConfigKey.ACCESSORS_PREFIX, psiClass);
|
||||
prefixes = ArrayUtil.toStringArray(configDiscovery.getMultipleValueLombokConfigProperty(ConfigKey.ACCESSORS_PREFIX, psiClass));
|
||||
} else {
|
||||
prefixes = prefixDeclared.toArray(new String[0]);
|
||||
prefixes = ArrayUtil.toStringArray(prefixDeclared);
|
||||
}
|
||||
|
||||
doNotUseIsPrefix = configDiscovery.getBooleanLombokConfigProperty(ConfigKey.GETTER_NO_IS_PREFIX, psiClass);
|
||||
@@ -119,7 +120,7 @@ public class AccessorsInfo {
|
||||
} else {
|
||||
isFluent = null != fluentDeclaredValue && fluentDeclaredValue;
|
||||
isChained = null != chainDeclaredValue && chainDeclaredValue;
|
||||
prefixes = prefixDeclared.toArray(new String[0]);
|
||||
prefixes = ArrayUtil.toStringArray(prefixDeclared);
|
||||
doNotUseIsPrefix = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,14 +13,12 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.hamcrest.CoreMatchers.hasItems;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -58,10 +56,23 @@ public class ConfigDiscoveryTest {
|
||||
protected FileBasedIndex getFileBasedIndex() {
|
||||
return fileBasedIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull String discoverPropertyWithCache(@NotNull ConfigKey configKey,
|
||||
@NotNull PsiFile psiFile) {
|
||||
return super.discoverProperty(configKey, psiFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull Collection<String> discoverPropertiesWithCache(@NotNull ConfigKey configKey,
|
||||
@NotNull PsiFile psiFile) {
|
||||
return super.discoverProperties(configKey, psiFile);
|
||||
}
|
||||
};
|
||||
|
||||
when(psiClass.getProject()).thenReturn(project);
|
||||
when(psiFile.getProject()).thenReturn(project);
|
||||
when(psiClass.getContainingFile()).thenReturn(psiFile);
|
||||
when(psiFile.getOriginalFile()).thenReturn(psiFile);
|
||||
when(psiFile.getVirtualFile()).thenReturn(virtualFile);
|
||||
when(virtualFile.getParent()).thenReturn(parentVirtualFile);
|
||||
when(parentVirtualFile.getParent()).thenReturn(parentParVirtualFile);
|
||||
@@ -113,13 +124,8 @@ public class ConfigDiscoveryTest {
|
||||
when(fileBasedIndex.getValues(eq(LombokConfigIndex.NAME), eq(configKey), any(GlobalSearchScope.class)))
|
||||
.thenReturn(makeValue("+_d;"), Collections.emptyList(), makeValue("-a;+cc"), makeValue("+a;+b"));
|
||||
|
||||
final String[] properties = discovery.getMultipleValueLombokConfigProperty(configKey, psiClass);
|
||||
assertNotNull(properties);
|
||||
assertEquals(3, properties.length);
|
||||
final ArrayList<String> list = new ArrayList<>(Arrays.asList(properties));
|
||||
assertTrue(list.contains("b"));
|
||||
assertTrue(list.contains("cc"));
|
||||
assertTrue(list.contains("_d"));
|
||||
final Collection<String> properties = discovery.getMultipleValueLombokConfigProperty(configKey, psiClass);
|
||||
assertThat(properties, hasItems("b", "cc", "_d"));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -133,10 +139,7 @@ public class ConfigDiscoveryTest {
|
||||
when(fileBasedIndex.getValues(eq(LombokConfigIndex.NAME), eq(configKey), isA(GlobalSearchScope.class)))
|
||||
.thenReturn(makeValue("+_d;"));
|
||||
|
||||
final String[] properties = discovery.getMultipleValueLombokConfigProperty(configKey, psiClass);
|
||||
assertNotNull(properties);
|
||||
assertEquals(1, properties.length);
|
||||
final ArrayList<String> list = new ArrayList<>(Arrays.asList(properties));
|
||||
assertTrue(list.contains("_d"));
|
||||
final Collection<String> properties = discovery.getMultipleValueLombokConfigProperty(configKey, psiClass);
|
||||
assertThat(properties, hasItems("_d"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user