migrate xml namespace stuff to CachedValue since it depends not only on AST descendants, so using clearCaches for it is incorrect

This commit is contained in:
peter
2016-04-21 21:38:10 +02:00
parent 7edaae6c76
commit 9e668a91d2
@@ -25,6 +25,7 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.PomManager;
@@ -106,14 +107,7 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag, HintedReferenc
private volatile TextRange[] myTextElements = null;
private volatile Map<String, String> myAttributeValueMap = null;
private volatile XmlTagValue myValue = null;
private volatile Map<String, CachedValue<XmlNSDescriptor>> myNSDescriptorsMap = null;
private volatile String myCachedNamespace;
private volatile long myModCount;
private volatile XmlElementDescriptor myCachedDescriptor;
private volatile long myDescriptorModCount = -1;
private volatile long myExtResourcesModCount = -1;
private volatile boolean myHasNamespaceDeclarations = false;
private volatile BidirectionalMap<String, String> myNamespaceMap = null;
public XmlTagImpl() {
this(XmlElementType.XML_TAG);
@@ -154,16 +148,11 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag, HintedReferenc
public void clearCaches() {
myName = null;
myLocalName = null;
myNamespaceMap = null;
myCachedNamespace = null;
myCachedDescriptor = null;
myDescriptorModCount = -1;
myAttributes = null;
myTextElements = null;
myAttributeValueMap = null;
myHasNamespaceDeclarations = false;
myValue = null;
myNSDescriptorsMap = null;
super.clearCaches();
}
@@ -267,7 +256,7 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag, HintedReferenc
}
}
Map<String, CachedValue<XmlNSDescriptor>> map = initNSDescriptorsMap();
Map<String, CachedValue<XmlNSDescriptor>> map = getNSDescriptorsMap();
final CachedValue<XmlNSDescriptor> descriptor = map.get(namespace);
if (descriptor != null) {
final XmlNSDescriptor value = descriptor.getValue();
@@ -334,16 +323,10 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag, HintedReferenc
return tag.getValue().getText();
}
protected final Map<String, CachedValue<XmlNSDescriptor>> initNSDescriptorsMap() {
Map<String, CachedValue<XmlNSDescriptor>> map = myNSDescriptorsMap;
if (map == null) {
RecursionGuard.StackStamp stamp = ourGuard.markStack();
map = computeNsDescriptorMap();
if (stamp.mayCacheNow()) {
myNSDescriptorsMap = map;
}
}
return map;
protected final Map<String, CachedValue<XmlNSDescriptor>> getNSDescriptorsMap() {
return CachedValuesManager.getCachedValue(this, () ->
CachedValueProvider.Result.create(computeNsDescriptorMap(),
PsiModificationTracker.MODIFICATION_COUNT, externalResourceModificationTracker()));
}
@NotNull
@@ -487,23 +470,15 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag, HintedReferenc
@Override
public XmlElementDescriptor getDescriptor() {
final long curModCount = getManager().getModificationTracker().getModificationCount();
long curExtResourcesModCount = ExternalResourceManagerEx.getInstanceEx().getModificationCount(getProject());
if (myDescriptorModCount != curModCount || myExtResourcesModCount != curExtResourcesModCount) {
if (myExtResourcesModCount != curExtResourcesModCount) {
myNSDescriptorsMap = null;
}
RecursionGuard.StackStamp stamp = ourGuard.markStack();
XmlElementDescriptor descriptor = computeElementDescriptor();
if (!stamp.mayCacheNow()) {
return descriptor;
}
return CachedValuesManager.getCachedValue(this, () ->
CachedValueProvider.Result.create(computeElementDescriptor(),
PsiModificationTracker.MODIFICATION_COUNT, externalResourceModificationTracker()));
}
myCachedDescriptor = descriptor;
myDescriptorModCount = curModCount;
myExtResourcesModCount = curExtResourcesModCount;
}
return myCachedDescriptor;
private ModificationTracker externalResourceModificationTracker() {
Project project = getProject();
ExternalResourceManagerEx manager = ExternalResourceManagerEx.getInstanceEx();
return () -> manager.getModificationCount(project);
}
@Nullable
@@ -671,10 +646,8 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag, HintedReferenc
}
XmlTagImpl current = this;
PsiElement parent = getParent();
while (current != null) {
BidirectionalMap<String, String> map = current.initNamespaceMaps(parent);
while (true) {
BidirectionalMap<String, String> map = current.getNamespaceMap();
if (map != null) {
List<String> keysByValue = map.getKeysByValue(namespace);
if (keysByValue != null && !keysByValue.isEmpty()) {
@@ -688,8 +661,11 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag, HintedReferenc
}
}
current = parent instanceof XmlTag ? (XmlTagImpl)parent : null;
parent = parent.getParent();
PsiElement parent = current.getParent();
if (!(parent instanceof XmlTag)) {
break;
}
current = (XmlTagImpl)parent;
}
if (namespace.isEmpty() || getNamespace().equals(namespace)) {
@@ -787,20 +763,8 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag, HintedReferenc
@Override
@NotNull
public String getNamespace() {
String cachedNamespace = myCachedNamespace;
final long curModCount = getManager().getModificationTracker().getModificationCount();
if (cachedNamespace != null && myModCount == curModCount) {
return cachedNamespace;
}
RecursionGuard.StackStamp stamp = ourGuard.markStack();
cachedNamespace = getNamespaceByPrefix(getNamespacePrefix());
if (!stamp.mayCacheNow()) {
return cachedNamespace;
}
myCachedNamespace = cachedNamespace;
myModCount = curModCount;
return cachedNamespace;
return CachedValuesManager.getCachedValue(this, () ->
CachedValueProvider.Result.create(getNamespaceByPrefix(getNamespacePrefix()), PsiModificationTracker.MODIFICATION_COUNT));
}
@Override
@@ -812,11 +776,7 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag, HintedReferenc
@Override
@NotNull
public String getNamespaceByPrefix(String prefix) {
final PsiElement parent = getParent();
if (!parent.isValid()) {
LOG.error(this.isValid());
}
BidirectionalMap<String, String> map = initNamespaceMaps(parent);
BidirectionalMap<String, String> map = getNamespaceMap();
if (map != null) {
final String ns = map.get(prefix);
if (ns != null) return ns;
@@ -855,8 +815,7 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag, HintedReferenc
@Override
public String getPrefixByNamespace(String namespace) {
final PsiElement parent = getParent();
BidirectionalMap<String, String> map = initNamespaceMaps(parent);
BidirectionalMap<String, String> map = getNamespaceMap();
if (map != null) {
List<String> keysByValue = map.getKeysByValue(namespace);
final String ns = keysByValue == null || keysByValue.isEmpty() ? null : keysByValue.get(0);
@@ -872,7 +831,7 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag, HintedReferenc
@Override
public String[] knownNamespaces() {
final PsiElement parentElement = getParent();
BidirectionalMap<String, String> map = initNamespaceMaps(parentElement);
BidirectionalMap<String, String> map = getNamespaceMap();
Set<String> known = Collections.emptySet();
if (map != null) {
known = new HashSet<String>(map.values());
@@ -898,18 +857,9 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag, HintedReferenc
}
@Nullable
private BidirectionalMap<String, String> initNamespaceMaps(PsiElement parent) {
BidirectionalMap<String, String> map = myNamespaceMap;
if (map == null) {
RecursionGuard.StackStamp stamp = ourGuard.markStack();
map = computeNamespaceMap(parent);
if (stamp.mayCacheNow()) {
myNamespaceMap = map;
}
}
return map;
private BidirectionalMap<String, String> getNamespaceMap() {
return CachedValuesManager.getCachedValue(this, () ->
CachedValueProvider.Result.create(computeNamespaceMap(getParent()), PsiModificationTracker.MODIFICATION_COUNT));
}
@Nullable