diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/DomFileElementImpl.java b/xml/dom-impl/src/com/intellij/util/xml/impl/DomFileElementImpl.java index 3babbc2ed85a..e7bb233e5977 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/DomFileElementImpl.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/DomFileElementImpl.java @@ -17,15 +17,16 @@ package com.intellij.util.xml.impl; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.module.ModuleUtilCore; -import com.intellij.openapi.util.Factory; import com.intellij.openapi.util.Key; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiManager; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.xml.XmlDocument; import com.intellij.psi.xml.XmlElement; import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; +import com.intellij.util.ObjectUtils; import com.intellij.util.xml.*; import com.intellij.util.xml.reflect.*; import com.intellij.util.xml.stubs.FileStub; @@ -286,7 +287,10 @@ public class DomFileElementImpl implements DomFileElement< @Override public final T createStableCopy() { - return myManager.createStableValue(() -> (T)myManager.getFileElement(myFile)); + PsiManager psiManager = myFile.getManager(); + VirtualFile vFile = myFile.getViewProvider().getVirtualFile(); + //noinspection unchecked + return myManager.createStableValue(() -> (T)myManager.getFileElement(ObjectUtils.tryCast(psiManager.findFile(vFile), XmlFile.class))); } @Override diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java b/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java index 9e66096935ff..715a517e1b92 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java @@ -335,7 +335,7 @@ public final class DomManagerImpl extends DomManager { @Override @Nullable - public final DomFileElementImpl getFileElement(XmlFile file) { + public final DomFileElementImpl getFileElement(@Nullable XmlFile file) { if (file == null) return null; if (!(file.getFileType() instanceof DomSupportEnabled)) return null; final VirtualFile virtualFile = file.getVirtualFile(); diff --git a/xml/dom-tests/tests/com/intellij/util/xml/DomBasicsTest.java b/xml/dom-tests/tests/com/intellij/util/xml/DomBasicsTest.java index e11462ab14d0..19b40b9dbe54 100644 --- a/xml/dom-tests/tests/com/intellij/util/xml/DomBasicsTest.java +++ b/xml/dom-tests/tests/com/intellij/util/xml/DomBasicsTest.java @@ -15,11 +15,17 @@ */ package com.intellij.util.xml; +import com.intellij.lang.xml.XMLLanguage; import com.intellij.mock.MockModule; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.Result; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.module.Module; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFileFactory; +import com.intellij.psi.impl.PsiManagerEx; +import com.intellij.psi.impl.file.impl.FileManagerImpl; import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.util.IncorrectOperationException; @@ -534,6 +540,22 @@ public class DomBasicsTest extends DomTestCase { assertTrue(copy.isValid()); } + public void testStableCopySurvivesPsiFileInvalidation() { + XmlFile xmlFile = (XmlFile)PsiFileFactory.getInstance(getProject()) + .createFileFromText(XMLLanguage.INSTANCE, ""); + VirtualFile file = xmlFile.getViewProvider().getVirtualFile(); + + getDomManager().registerFileDescription(new MockDomFileDescription<>(MyElement.class, "a", file), getTestRootDisposable()); + + MyElement element = getDomManager().getFileElement(xmlFile, MyElement.class).getRootElement().getChildElements().get(1); + MyElement copy = element.createStableCopy(); + + ApplicationManager.getApplication().runWriteAction(() -> ((FileManagerImpl)PsiManagerEx.getInstanceEx(getProject()).getFileManager()).forceReload(file)); + + assertFalse(element.isValid()); + assertTrue(copy.isValid()); + } + @Implementation(Impl.class) public interface MyElement extends DomElement { GenericAttributeValue getAttr();