don't hold strong references to dom file elements, rewrite their computation for the side effects to be visible

This commit is contained in:
peter
2011-01-19 15:52:42 +01:00
parent b61c0c6f2a
commit 927f651a98
2 changed files with 29 additions and 20 deletions
@@ -45,6 +45,7 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.ref.WeakReference;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.List;
@@ -55,8 +56,8 @@ import java.util.Set;
*/
public final class DomManagerImpl extends DomManager {
private static final Key<Object> MOCK = Key.create("MockElement");
public static final Key<DomFileElementImpl> CACHED_FILE_ELEMENT = Key.create("CACHED_FILE_ELEMENT");
static final Key<DomFileDescription> MOCK_DESCIPRTION = Key.create("MockDescription");
static final Key<WeakReference<DomFileElementImpl>> CACHED_FILE_ELEMENT = Key.create("CACHED_FILE_ELEMENT");
static final Key<DomFileDescription> MOCK_DESCRIPTION = Key.create("MockDescription");
static final Key<DomInvocationHandler> CACHED_DOM_HANDLER = Key.create("CACHED_DOM_HANDLER");
static final SemKey<FileDescriptionCachedValueProvider> FILE_DESCRIPTION_KEY = SemKey.createKey("FILE_DESCRIPTION_KEY");
@@ -294,8 +295,8 @@ public final class DomManagerImpl extends DomManager {
@NotNull
public final <T extends DomElement> DomFileElementImpl<T> getFileElement(final XmlFile file, final Class<T> aClass, String rootTagName) {
//noinspection unchecked
if (file.getUserData(MOCK_DESCIPRTION) == null) {
file.putUserData(MOCK_DESCIPRTION, new MockDomFileDescription<T>(aClass, rootTagName, file));
if (file.getUserData(MOCK_DESCRIPTION) == null) {
file.putUserData(MOCK_DESCRIPTION, new MockDomFileDescription<T>(aClass, rootTagName, file));
mySemService.clearCache();
}
final DomFileElementImpl<T> fileElement = getFileElement(file);
@@ -354,7 +355,8 @@ public final class DomManagerImpl extends DomManager {
@Nullable
static <T extends DomElement> DomFileElementImpl<T> getCachedFileElement(XmlFile file) {
return file.getUserData(CACHED_FILE_ELEMENT);
WeakReference<DomFileElementImpl> ref = file.getUserData(CACHED_FILE_ELEMENT);
return ref == null ? null : ref.get();
}
@Nullable
@@ -31,6 +31,7 @@ import com.intellij.util.xml.*;
import com.intellij.util.xml.events.DomEvent;
import org.jetbrains.annotations.Nullable;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -67,20 +68,27 @@ class FileDescriptionCachedValueProvider<T extends DomElement> implements SemEle
public final DomFileElementImpl<T> getFileElement() {
if (myComputed) return myLastResult;
_computeFileElement(false, getRootTag(), null);
myXmlFile.putUserData(DomManagerImpl.CACHED_FILE_ELEMENT, myLastResult);
myComputed = true;
return myLastResult;
DomFileElementImpl<T> result = _computeFileElement(false, getRootTag(), null);
synchronized (myCondition) {
if (myComputed) return myLastResult;
myLastResult = result;
WeakReference<DomFileElementImpl> ref = result != null ? new WeakReference<DomFileElementImpl>(result) : null;
myXmlFile.putUserData(DomManagerImpl.CACHED_FILE_ELEMENT, ref);
myComputed = true;
return result;
}
}
private void _computeFileElement(final boolean fireEvents, final XmlFileHeader rootTagName, @Nullable StringBuilder sb) {
@Nullable
private DomFileElementImpl<T> _computeFileElement(final boolean fireEvents, final XmlFileHeader rootTagName, @Nullable StringBuilder sb) {
if (sb != null) {
sb.append(rootTagName).append("\n");
}
if (!myXmlFile.isValid()) {
myLastResult = null;
return;
return null;
}
if (sb != null) {
sb.append("File is valid\n");
@@ -100,28 +108,27 @@ class FileDescriptionCachedValueProvider<T extends DomElement> implements SemEle
}
if (description == null) {
myLastResult = null;
return;
return null;
}
final Class<T> rootElementClass = description.getRootElementClass();
final XmlName xmlName = DomImplUtil.createXmlName(description.getRootTagName(), rootElementClass, null);
assert xmlName != null;
final EvaluatedXmlNameImpl rootTagName1 = EvaluatedXmlNameImpl.createEvaluatedXmlName(xmlName, xmlName.getNamespaceKey(), false);
myLastResult = new DomFileElementImpl<T>(myXmlFile, rootElementClass, rootTagName1, myDomManager, description);
DomFileElementImpl<T> result = new DomFileElementImpl<T>(myXmlFile, rootElementClass, rootTagName1, myDomManager, description);
if (sb != null) {
sb.append("success " + myLastResult + "\n");
sb.append("success " + result + "\n");
}
if (fireEvents) {
final DomElement element = myLastResult;
events.add(new DomEvent(element, true));
events.add(new DomEvent(result, true));
}
return result;
}
@Nullable
private DomFileDescription<T> findFileDescription(final XmlFileHeader rootTagName, @Nullable StringBuilder sb) {
final DomFileDescription<T> mockDescription = myXmlFile.getUserData(DomManagerImpl.MOCK_DESCIPRTION);
final DomFileDescription<T> mockDescription = myXmlFile.getUserData(DomManagerImpl.MOCK_DESCRIPTION);
if (mockDescription != null) return mockDescription;
if (sb != null) {
@@ -170,7 +177,7 @@ class FileDescriptionCachedValueProvider<T extends DomElement> implements SemEle
public String getFileElementWithLogging() {
final XmlFileHeader rootTagName = getRootTag();
final StringBuilder log = new StringBuilder();
_computeFileElement(false, rootTagName, log);
myLastResult = _computeFileElement(false, rootTagName, log);
return log.toString();
}