From 8b31bf2debcc1b154eaf0c8109081516693a622f Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 18 Nov 2009 15:29:28 +0300 Subject: [PATCH] LAHT test fixed: added extension listener to KeyedExtensionCollector --- .../codeInsight/daemon/impl/PerThreadMap.java | 22 ++++++++++++---- .../impl/analysis/DefaultHighlightVisitor.java | 30 ++++++++++++++++++++++ .../openapi/util/KeyedExtensionCollector.java | 21 +++++++++++++++ 3 files changed, 68 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PerThreadMap.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PerThreadMap.java index 5891a4b11c..74c6e3234e 100755 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PerThreadMap.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PerThreadMap.java @@ -16,6 +16,7 @@ package com.intellij.codeInsight.daemon.impl; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.UserDataHolder; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; @@ -31,14 +32,15 @@ import java.util.Map; * User: cdr */ public abstract class PerThreadMap { - + private volatile int version; @NotNull public abstract Collection initialValue(@NotNull KeyT key); - private final ThreadLocal>> CACHE = new ThreadLocal>>(){ + // pair(version, map) + private final ThreadLocal>>> CACHE = new ThreadLocal>>>(){ @Override - protected Map> initialValue() { - return new THashMap>(); + protected Pair>> initialValue() { + return Pair.>>create(version, new THashMap>()); } }; @@ -55,7 +57,13 @@ public abstract class PerThreadMap { @NotNull public List get(@NotNull KeyT key) { - Map> map = CACHE.get(); + Pair>> pair = CACHE.get(); + Integer mapVersion = pair.getFirst(); + if (version != mapVersion) { + CACHE.remove(); + pair = CACHE.get(); + } + Map> map = pair.getSecond(); List cached = map.get(key); if (cached == null) { Collection templates = initialValue(key); @@ -64,4 +72,8 @@ public abstract class PerThreadMap { } return cached; } + + public void clear() { + version++; //we don't care about atomicity here + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/DefaultHighlightVisitor.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/DefaultHighlightVisitor.java index 79b10a407b..1ab591cee1 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/DefaultHighlightVisitor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/DefaultHighlightVisitor.java @@ -22,8 +22,10 @@ import com.intellij.lang.Language; import com.intellij.lang.LanguageAnnotators; import com.intellij.lang.annotation.Annotation; import com.intellij.lang.annotation.Annotator; +import com.intellij.openapi.extensions.ExtensionPointListener; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.extensions.PluginDescriptor; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; @@ -31,6 +33,7 @@ import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.List; @@ -91,6 +94,33 @@ public class DefaultHighlightVisitor extends PsiElementVisitor implements Highli return LanguageAnnotators.INSTANCE.allForLanguage(key); } }; + + static { + LanguageAnnotators.INSTANCE.addListener(new ExtensionPointListener() { + public void extensionAdded(Annotator extension, @Nullable PluginDescriptor pluginDescriptor) { + cachedAnnotators.clear(); + } + + public void extensionRemoved(Annotator extension, @Nullable PluginDescriptor pluginDescriptor) { + cachedAnnotators.clear(); + } + }); + + //final ExtensionPoint> point = Extensions.getRootArea().getExtensionPoint(LanguageAnnotators.EP_NAME); + //point.addExtensionPointListener(new ExtensionPointAndAreaListener>() { + // public void areaReplaced(ExtensionsArea area) { + // cachedAnnotators.clear(); + // } + // + // public void extensionAdded(LanguageExtensionPoint extension, @Nullable PluginDescriptor pluginDescriptor) { + // cachedAnnotators.clear(); + // } + // + // public void extensionRemoved(LanguageExtensionPoint extension, @Nullable PluginDescriptor pluginDescriptor) { + // cachedAnnotators.clear(); + // } + //}); + } private void runAnnotators(final PsiElement element) { List annotators = cachedAnnotators.get(element.getLanguage()); diff --git a/platform/platform-api/src/com/intellij/openapi/util/KeyedExtensionCollector.java b/platform/platform-api/src/com/intellij/openapi/util/KeyedExtensionCollector.java index ae8c0325f9..a9066a920b 100644 --- a/platform/platform-api/src/com/intellij/openapi/util/KeyedExtensionCollector.java +++ b/platform/platform-api/src/com/intellij/openapi/util/KeyedExtensionCollector.java @@ -22,6 +22,7 @@ package com.intellij.openapi.util; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.*; import com.intellij.util.KeyedLazyInstance; +import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashMap; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -38,6 +39,7 @@ public abstract class KeyedExtensionCollector { private ExtensionPoint> myPoint; private final String myEpName; private ExtensionPointAndAreaListener> myListener; + private final List> myListeners = ContainerUtil.createEmptyCOWList(); public KeyedExtensionCollector(@NonNls String epName) { myEpName = epName; @@ -66,6 +68,9 @@ public abstract class KeyedExtensionCollector { } list.add(t); myCache.remove(skey); + for (ExtensionPointListener listener : myListeners) { + listener.extensionAdded(t, null); + } } } @@ -77,6 +82,9 @@ public abstract class KeyedExtensionCollector { list.remove(t); myCache.remove(skey); } + for (ExtensionPointListener listener : myListeners) { + listener.extensionRemoved(t, null); + } } } @@ -141,12 +149,18 @@ public abstract class KeyedExtensionCollector { public void extensionAdded(final KeyedLazyInstance bean, @Nullable final PluginDescriptor pluginDescriptor) { synchronized (lock) { myCache.remove(bean.getKey()); + for (ExtensionPointListener listener : myListeners) { + listener.extensionAdded(bean.getInstance(), null); + } } } public void extensionRemoved(final KeyedLazyInstance bean, @Nullable final PluginDescriptor pluginDescriptor) { synchronized (lock) { myCache.remove(bean.getKey()); + for (ExtensionPointListener listener : myListeners) { + listener.extensionRemoved(bean.getInstance(), null); + } } } @@ -169,4 +183,11 @@ public abstract class KeyedExtensionCollector { return point != null && point.hasAnyExtensions(); } } + + public void addListener(@NotNull ExtensionPointListener listener) { + myListeners.add(listener); + } + public void removeListener(@NotNull ExtensionPointListener listener) { + myListeners.remove(listener); + } } \ No newline at end of file -- 2.11.4.GIT