fix DOM stub index inconsistency with xincludes present (hopefully EA-89230, EA-210672, EA-210382, EA-139275, EA-208992)

GitOrigin-RevId: 36c4db63dd4dd30d896013cf152b947afa6eafd2
This commit is contained in:
peter
2019-08-26 20:02:30 +03:00
committed by intellij-monorepo-bot
parent 6db9f52b92
commit d65fbe402d
3 changed files with 26 additions and 5 deletions
@@ -19,8 +19,8 @@ import com.intellij.psi.stubs.StubTreeLoader;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.JBIterable;
import com.intellij.util.indexing.FileBasedIndex;
import com.intellij.util.xml.*;
import com.intellij.util.xml.reflect.CustomDomChildrenDescription;
@@ -30,6 +30,7 @@ import com.intellij.util.xml.reflect.DomFixedChildDescription;
import com.intellij.util.xml.stubs.DomStub;
import com.intellij.util.xml.stubs.ElementStub;
import com.intellij.util.xml.stubs.FileStub;
import com.intellij.xml.util.IncludedXmlTag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -123,7 +124,10 @@ final class DomCreator {
XmlTag parentTag) {
DomStub parentStub = parent.getStub();
if (parentStub != null) {
int index = ArrayUtil.indexOf(parentTag.findSubTags(tag.getName(), tag.getNamespace()), tag);
int index = JBIterable
.of(parentTag.findSubTags(tag.getName(), tag.getNamespace()))
.filter(t -> !(t instanceof IncludedXmlTag))
.indexOf(t -> t == tag);
ElementStub stub = parentStub.getElementStub(tag.getLocalName(), index);
if (stub != null) {
XmlName name = description.getXmlName();
@@ -349,7 +349,13 @@ public final class DomManagerImpl extends DomManager {
public DomInvocationHandler getDomHandler(@Nullable XmlElement xml) {
if (xml instanceof XmlTag) {
return CachedValuesManager.getCachedValue(xml, chooseKey(HANDLER_KEY, HANDLER_KEY_FOR_INDEX), () ->
CachedValueProvider.Result.create(DomCreator.createTagHandler((XmlTag)xml), PsiModificationTracker.MODIFICATION_COUNT, this));
{
DomInvocationHandler handler = DomCreator.createTagHandler((XmlTag)xml);
if (handler != null && handler.getXmlTag() != xml) {
throw new AssertionError("Inconsistent dom, stub=" + handler.getStub());
}
return CachedValueProvider.Result.create(handler, PsiModificationTracker.MODIFICATION_COUNT, this);
});
}
if (xml instanceof XmlAttribute) {
return CachedValuesManager.getCachedValue(xml, chooseKey(HANDLER_KEY, HANDLER_KEY_FOR_INDEX), () ->
@@ -24,6 +24,7 @@ import com.intellij.psi.stubs.ObjectStubTree;
import com.intellij.psi.stubs.Stub;
import com.intellij.psi.stubs.StubTreeLoader;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ref.GCWatcher;
@@ -106,8 +107,11 @@ public class DomStubBuilderTest extends DomStubTest {
assertNotNull(stubTree);
}
public void testInclusion() {
public void testInclusionOnStubs() {
doInclusionTest(true);
}
public void testInclusionOnAST() {
doInclusionTest(false);
}
@@ -128,7 +132,8 @@ public class DomStubBuilderTest extends DomStubTest {
}
assertEquals(!onStubs, ((PsiFileImpl) file).isContentsLoaded());
DomFileElement<Foo> element = DomManager.getDomManager(getProject()).getFileElement((XmlFile)file, Foo.class);
DomManager domManager = DomManager.getDomManager(getProject());
DomFileElement<Foo> element = domManager.getFileElement((XmlFile)file, Foo.class);
assert element != null;
List<Bar> bars = element.getRootElement().getBars();
assertEquals(3, bars.size());
@@ -139,6 +144,12 @@ public class DomStubBuilderTest extends DomStubTest {
Bar lastBar = bars.get(2);
assertEquals("included2", assertOneElement(lastBar.getBars()).getString().getStringValue());
XmlTag[] barTags = ((XmlFile)file).getRootTag().findSubTags("bar");
assertSize(3, barTags);
for (int i = 1; i < barTags.length; i++) {
assertEquals(String.valueOf(i), bars.get(i), domManager.getDomElement(barTags[i]));
}
}
public static class TestExtender extends DomExtender<Bar> {