cleanup, synchronize fields properly

This commit is contained in:
Alexey Kudravtsev
2017-10-11 18:06:09 +03:00
parent 70ce590e37
commit 079dca595c
3 changed files with 21 additions and 39 deletions
@@ -39,14 +39,14 @@ import java.util.concurrent.ConcurrentMap;
public class KeyedExtensionCollector<T, KeyT> {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.util.KeyedExtensionCollector");
private final Map<String, List<T>> myExplicitExtensions = new THashMap<>();
private final Map<String, List<T>> myExplicitExtensions = new THashMap<>(); // guarded by lock
private final ConcurrentMap<String, List<T>> myCache = ContainerUtil.newConcurrentMap();
@NonNls private final String lock;
private ExtensionPoint<KeyedLazyInstance<T>> myPoint;
private ExtensionPoint<KeyedLazyInstance<T>> myPoint; // guarded by lock
private final String myEpName;
private ExtensionPointAndAreaListener<KeyedLazyInstance<T>> myListener;
private ExtensionPointAndAreaListener<KeyedLazyInstance<T>> myListener; // guarded by lock
private final List<ExtensionPointListener<T>> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
public KeyedExtensionCollector(@NonNls @NotNull String epName) {
@@ -70,11 +70,7 @@ public class KeyedExtensionCollector<T, KeyT> {
public void addExplicitExtension(@NotNull KeyT key, @NotNull T t) {
synchronized (lock) {
final String skey = keyToString(key);
List<T> list = myExplicitExtensions.get(skey);
if (list == null) {
list = new ArrayList<>();
myExplicitExtensions.put(skey, list);
}
List<T> list = myExplicitExtensions.computeIfAbsent(skey, __ -> new ArrayList<>());
list.add(t);
myCache.remove(skey);
for (ExtensionPointListener<T> listener : myListeners) {
@@ -109,12 +105,11 @@ public class KeyedExtensionCollector<T, KeyT> {
public List<T> forKey(@NotNull KeyT key) {
final String stringKey = keyToString(key);
boolean rebuild = myPoint == null && Extensions.getRootArea().hasExtensionPoint(myEpName);
List<T> cached = rebuild ? null : myCache.get(stringKey);
if (cached != null) return cached;
cached = buildExtensions(stringKey, key);
cached = ConcurrencyUtil.cacheOrGet(myCache, stringKey, Collections.unmodifiableList(cached));
List<T> cached = myCache.get(stringKey);
if (cached == null) {
cached = Collections.unmodifiableList(buildExtensions(stringKey, key));
cached = ConcurrencyUtil.cacheOrGet(myCache, stringKey, cached);
}
return cached;
}
@@ -157,11 +152,7 @@ public class KeyedExtensionCollector<T, KeyT> {
catch (ProcessCanceledException e) {
throw e;
}
catch (Exception e) {
LOG.error(e);
continue;
}
catch (LinkageError e) {
catch (Exception | LinkageError e) {
LOG.error(e);
continue;
}
@@ -178,8 +169,7 @@ public class KeyedExtensionCollector<T, KeyT> {
private ExtensionPoint<KeyedLazyInstance<T>> getPoint() {
ExtensionPoint<KeyedLazyInstance<T>> point = myPoint;
if (point == null && Extensions.getRootArea().hasExtensionPoint(myEpName)) {
ExtensionPointName<KeyedLazyInstance<T>> typesafe = ExtensionPointName.create(myEpName);
myPoint = point = Extensions.getRootArea().getExtensionPoint(typesafe);
myPoint = point = Extensions.getRootArea().getExtensionPoint(myEpName);
myListener = new ExtensionPointAndAreaListener<KeyedLazyInstance<T>>() {
@Override
public void extensionAdded(@NotNull final KeyedLazyInstance<T> bean, @Nullable final PluginDescriptor pluginDescriptor) {
@@ -228,20 +218,13 @@ public class KeyedExtensionCollector<T, KeyT> {
}
}
public void addListener(@NotNull ExtensionPointListener<T> listener) {
myListeners.add(listener);
}
public void addListener(@NotNull final ExtensionPointListener<T> listener, @NotNull Disposable parent) {
myListeners.add(listener);
Disposer.register(parent, new Disposable() {
@Override
public void dispose() {
myListeners.remove(listener);
}
});
Disposer.register(parent, () -> myListeners.remove(listener));
}
public void removeListener(@NotNull ExtensionPointListener<T> listener) {
myListeners.remove(listener);
@NotNull
public String getName() {
return myEpName;
}
}
@@ -21,6 +21,7 @@ import com.intellij.lang.refactoring.RefactoringSupportProvider;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.extensions.ExtensionPointListener;
import com.intellij.openapi.extensions.PluginDescriptor;
@@ -39,7 +40,7 @@ import java.util.List;
* @author yole
*/
public abstract class BasePlatformRefactoringAction extends BaseRefactoringAction {
private Boolean myHidden = null;
private Boolean myHidden;
private final Condition<RefactoringSupportProvider> myCondition = provider -> getRefactoringHandler(provider) != null;
public BasePlatformRefactoringAction() {
@@ -53,7 +54,7 @@ public abstract class BasePlatformRefactoringAction extends BaseRefactoringActio
public void extensionRemoved(@NotNull RefactoringSupportProvider extension, @Nullable PluginDescriptor pluginDescriptor) {
myHidden = null;
}
});
}, ApplicationManager.getApplication());
}
@Override
@@ -17,7 +17,6 @@ package com.intellij.psi.tree;
import com.intellij.lang.*;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.ElementManipulators;
@@ -45,7 +44,7 @@ public class IElementTypeTest extends LightPlatformCodeInsightFixtureTestCase {
public void testCount() {
int count = IElementType.getAllocatedTypesCount();
LOG.debug("Preloaded: " + count +" element types");
LanguageExtensionPoint[] extensions = Extensions.getExtensions(new ExtensionPointName<LanguageExtensionPoint>("com.intellij.lang.parserDefinition"));
LanguageExtensionPoint[] extensions = Extensions.getExtensions(LanguageParserDefinitions.INSTANCE.getName(), null);
LOG.debug("ParserDefinitions: " + extensions.length);
THashMap<Language, String> languageMap = new THashMap<>();
@@ -65,7 +64,7 @@ public class IElementTypeTest extends LightPlatformCodeInsightFixtureTestCase {
Lexer lexer = definition.createLexer(getProject());
PsiParser parser = definition.createParser(getProject());
}
catch (UnsupportedOperationException e1) {
catch (UnsupportedOperationException ignored) {
}
// language-based calculation: per-class-loading stuff commented
@@ -120,8 +119,7 @@ public class IElementTypeTest extends LightPlatformCodeInsightFixtureTestCase {
}
public void testManipulatorRegistered() {
LanguageExtensionPoint[] extensions =
Extensions.getExtensions(new ExtensionPointName<LanguageExtensionPoint>("com.intellij.lang.parserDefinition"));
LanguageExtensionPoint[] extensions = Extensions.getExtensions(LanguageParserDefinitions.INSTANCE.getName(), null);
Set<String> classes = new HashSet<>();
List<String> failures = new ArrayList<>();
int total = 0;