diff --git a/platform/lang-impl/src/com/intellij/pom/wrappers/PsiEventWrapperAspect.java b/platform/lang-impl/src/com/intellij/pom/wrappers/PsiEventWrapperAspect.java index c30280439874..363c62248b61 100644 --- a/platform/lang-impl/src/com/intellij/pom/wrappers/PsiEventWrapperAspect.java +++ b/platform/lang-impl/src/com/intellij/pom/wrappers/PsiEventWrapperAspect.java @@ -32,6 +32,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.impl.PsiManagerImpl; import com.intellij.psi.impl.PsiTreeChangeEventImpl; import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.CompositeElement; import java.util.Collections; @@ -104,10 +105,10 @@ public class PsiEventWrapperAspect implements PomModelAspect{ break; case ChangeInfo.CONTENTS_CHANGED: psiEvent.setOffset(treeElement.getStartOffset()); - psiEvent.setOldChild(psiChild); - psiEvent.setNewChild(psiChild); + psiEvent.setParent(psiChild); psiEvent.setOldLength(changeByChild.getOldLength()); - manager.childReplaced(psiEvent); + psiEvent.setGeneric(treeElement instanceof CompositeElement); + manager.childrenChanged(psiEvent); break; case ChangeInfo.REMOVED: psiEvent.setOffset(changesByElement.getChildOffsetInNewTree(treeElement)); diff --git a/xml/tests/src/com/intellij/codeInsight/XmlEventsTest.java b/xml/tests/src/com/intellij/codeInsight/XmlEventsTest.java index 5ccbdba311a2..457a949f2fc3 100644 --- a/xml/tests/src/com/intellij/codeInsight/XmlEventsTest.java +++ b/xml/tests/src/com/intellij/codeInsight/XmlEventsTest.java @@ -15,16 +15,12 @@ import com.intellij.pom.event.PomChangeSet; import com.intellij.pom.event.PomModelEvent; import com.intellij.pom.event.PomModelListener; import com.intellij.pom.xml.XmlAspect; -import com.intellij.psi.PsiDocumentManager; -import com.intellij.psi.PsiFile; -import com.intellij.psi.XmlElementFactory; +import com.intellij.psi.*; import com.intellij.psi.impl.source.PsiFileImpl; -import com.intellij.psi.xml.XmlAttribute; -import com.intellij.psi.xml.XmlFile; -import com.intellij.psi.xml.XmlTag; -import com.intellij.psi.xml.XmlText; +import com.intellij.psi.xml.*; import com.intellij.testFramework.LightCodeInsightTestCase; import com.intellij.testFramework.PlatformTestUtil; +import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.FileNotFoundException; @@ -235,4 +231,64 @@ public class XmlEventsTest extends LightCodeInsightTestCase { text = StringUtil.convertLineSeparators(text); return text; } + + public void testDocumentChange() throws Exception { + final String xml = "" + + "\n" + + "\n" + + " \n" + + "\n" + + "\n" + + " \n" + + " \n" + + "\n" + + "\n"; + PsiFile file = createFile("file.xml", xml); + assertTrue(file instanceof XmlFile); + XmlDocument xmlDocument = ((XmlFile)file).getDocument(); + assertNotNull(xmlDocument); + final XmlTag tagFromText = xmlDocument.getRootTag(); + assertNotNull(tagFromText); + final PsiFileImpl containingFile = (PsiFileImpl)tagFromText.getContainingFile(); + final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject()); + final Document document = documentManager.getDocument(containingFile); + assertNotNull(document); + + final TestListener listener = new TestListener(); + PsiManager.getInstance(getProject()).addPsiTreeChangeListener(listener); + + CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + int positionToInsert = xml.indexOf(" \n"; + document.insertString(positionToInsert, stringToInsert); + documentManager.commitDocument(document); + } + }); + } + }, "", null); + + PsiManager.getInstance(getProject()).removePsiTreeChangeListener(listener); + } + + private static class TestListener extends PsiTreeChangeAdapter { + @Override + public void childReplaced(@NotNull PsiTreeChangeEvent event) { + if (event.getNewChild() != null) { + assertNotSame("Received identical before and after children in childReplaced;", event.getOldChild(), event.getNewChild()); + } + } + } }