fix flaky flex tests after psi events rewrite

let xml tag value change be one event, as this results in better range marker survival
This commit is contained in:
peter
2017-11-06 21:23:01 +01:00
parent 02659d9f8d
commit 36f225e27a
2 changed files with 34 additions and 15 deletions
@@ -673,23 +673,23 @@ public class CompositeElement extends TreeElement {
TreeUtil.ensureParsed(getFirstChildNode());
TreeUtil.ensureParsed(anotherParent.getFirstChildNode());
final ASTNode firstChild = anotherParent.getFirstChildNode();
ChangeUtil.prepareAndRunChangeAction(new ChangeUtil.ChangeAction(){
@Override
public void makeChange(TreeChangeEvent destinationTreeChange) {
remove((TreeChangeEventImpl)destinationTreeChange, (TreeElement)anotherParent.getFirstChildNode(), null);
}
}, (TreeElement)anotherParent);
ChangeUtil.prepareAndRunChangeAction(
event -> remove((TreeChangeEventImpl)event, (TreeElement)anotherParent.getFirstChildNode(), null),
(TreeElement)anotherParent);
if (firstChild != null) {
ChangeUtil.prepareAndRunChangeAction(new ChangeUtil.ChangeAction(){
@Override
public void makeChange(TreeChangeEvent destinationTreeChange) {
TreeElement first = getFirstChildNode();
remove((TreeChangeEventImpl)destinationTreeChange, first, null);
add((TreeChangeEventImpl)destinationTreeChange, CompositeElement.this, (TreeElement)firstChild);
if(getTreeParent() != null){
repairRemovedElement(CompositeElement.this, first);
}
ChangeUtil.prepareAndRunChangeAction(destinationTreeChange -> {
TreeElement first = getFirstChildNode();
TreeChangeEventImpl event = (TreeChangeEventImpl)destinationTreeChange;
CompositeElement parent = getTreeParent();
if (parent != null) {
// treat all replacements as one big childrenChanged to simplify resulting PSI/document events
event.addElementaryChange(parent);
}
remove(event, first, null);
add(event, this, (TreeElement)firstChild);
if(parent != null) {
repairRemovedElement(this, first);
}
}, this);
}
@@ -15,11 +15,13 @@
*/
package com.intellij.codeInsight;
import com.intellij.lang.xml.XMLLanguage;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.util.TextRange;
import com.intellij.pom.PomManager;
import com.intellij.pom.PomModel;
@@ -30,6 +32,7 @@ import com.intellij.pom.event.PomModelListener;
import com.intellij.pom.xml.XmlAspect;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiFileImpl;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.*;
import com.intellij.testFramework.LightCodeInsightTestCase;
import com.intellij.util.DocumentUtil;
@@ -256,6 +259,22 @@ public class XmlEventsTest extends LightCodeInsightTestCase {
PsiManager.getInstance(getProject()).removePsiTreeChangeListener(listener);
}
public void testRangeMarkersShouldSurviveOnSmallTagValueModification() {
String text = "<tag>x y z a b c d</tag>";
PsiFile file = PsiFileFactory.getInstance(getProject()).createFileFromText("a.xml", XMLLanguage.INSTANCE, text);
Document document = file.getViewProvider().getDocument();
RangeMarker marker = document.createRangeMarker(TextRange.from(text.indexOf("a b"), 3));
XmlTag tag = PsiTreeUtil.findElementOfClassAtOffset(file, 0, XmlTag.class, false);
WriteCommandAction.runWriteCommandAction(null, () -> tag.getValue().setText("x a b c d"));
assertEquals("<tag>x a b c d</tag>", document.getText());
assertTrue(marker.isValid());
assertEquals("a b", document.getText(TextRange.create(marker)));
}
private static class TestListener extends PsiTreeChangeAdapter {
@Override
public void childReplaced(@NotNull PsiTreeChangeEvent event) {