Search in sources :

Example 1 with TreeChangeImpl

use of com.intellij.pom.tree.events.impl.TreeChangeImpl in project intellij-community by JetBrains.

the class XmlAspectImpl method update.

@Override
public void update(PomModelEvent event) {
    if (!event.getChangedAspects().contains(myTreeAspect))
        return;
    final TreeChangeEvent changeSet = (TreeChangeEvent) event.getChangeSet(myTreeAspect);
    if (changeSet == null)
        return;
    final ASTNode rootElement = changeSet.getRootElement();
    final PsiFile file = (PsiFile) rootElement.getPsi();
    if (!(file instanceof XmlFile))
        return;
    final XmlAspectChangeSetImpl xmlChangeSet = event.registerChangeSetIfAbsent(this, new XmlAspectChangeSetImpl(myModel));
    xmlChangeSet.addChangedFile((XmlFile) file);
    final ASTNode[] changedElements = changeSet.getChangedElements();
    final CharTable table = ((FileElement) changeSet.getRootElement()).getCharTable();
    for (ASTNode changedElement : changedElements) {
        TreeChange changesByElement = changeSet.getChangesByElement(changedElement);
        PsiElement psiElement = null;
        while (changedElement != null && (psiElement = changedElement.getPsi()) == null) {
            final ASTNode parent = changedElement.getTreeParent();
            final ChangeInfoImpl changeInfo = ChangeInfoImpl.create(ChangeInfo.CONTENTS_CHANGED, changedElement);
            changeInfo.compactChange(changesByElement);
            changesByElement = new TreeChangeImpl(parent);
            changesByElement.addChange(changedElement, changeInfo);
            changedElement = parent;
        }
        if (changedElement == null)
            continue;
        final TreeChange finalChangedElement = changesByElement;
        psiElement.accept(new XmlElementVisitor() {

            TreeChange myChange = finalChangedElement;

            @Override
            public void visitElement(PsiElement element) {
                final ASTNode child = element.getNode();
                final ASTNode treeParent = child.getTreeParent();
                if (treeParent == null)
                    return;
                final PsiElement parent = treeParent.getPsi();
                final ChangeInfoImpl changeInfo = ChangeInfoImpl.create(ChangeInfo.CONTENTS_CHANGED, child);
                changeInfo.compactChange(myChange);
                myChange = new TreeChangeImpl(treeParent);
                myChange.addChange(child, changeInfo);
                parent.accept(this);
            }

            @Override
            public void visitXmlAttribute(XmlAttribute attribute) {
                final ASTNode[] affectedChildren = myChange.getAffectedChildren();
                String oldName = null;
                String oldValue = null;
                for (final ASTNode treeElement : affectedChildren) {
                    final ChangeInfo changeByChild = myChange.getChangeByChild(treeElement);
                    final int changeType = changeByChild.getChangeType();
                    if (treeElement.getElementType() == XmlTokenType.XML_NAME) {
                        if (changeType == ChangeInfo.REMOVED) {
                            oldName = treeElement.getText();
                        } else if (changeType == ChangeInfo.REPLACE) {
                            oldName = ((ReplaceChangeInfo) changeByChild).getReplaced().getText();
                        }
                    }
                    if (treeElement.getElementType() == XmlElementType.XML_ATTRIBUTE_VALUE) {
                        if (changeType == ChangeInfo.REMOVED) {
                            oldValue = treeElement.getText();
                        } else if (changeType == ChangeInfo.REPLACE) {
                            oldValue = ((ReplaceChangeInfo) changeByChild).getReplaced().getText();
                        }
                    }
                }
                if (oldName != null && !oldName.equals(attribute.getName())) {
                    xmlChangeSet.add(new XmlAttributeSetImpl(attribute.getParent(), oldName, null));
                    xmlChangeSet.add(new XmlAttributeSetImpl(attribute.getParent(), attribute.getName(), attribute.getValue()));
                } else if (oldValue != null) {
                    xmlChangeSet.add(new XmlAttributeSetImpl(attribute.getParent(), attribute.getName(), attribute.getValue()));
                } else {
                    xmlChangeSet.add(new XmlElementChangedImpl(attribute));
                }
            }

            @Override
            public void visitXmlTag(XmlTag tag) {
                ASTNode[] affectedChildren = shortenChange(myChange.getAffectedChildren(), changeSet);
                for (final ASTNode treeElement : affectedChildren) {
                    if (!(treeElement.getPsi() instanceof XmlTagChild)) {
                        visitElement(tag);
                        return;
                    }
                }
                for (final ASTNode treeElement : affectedChildren) {
                    final ChangeInfo changeByChild = myChange.getChangeByChild(treeElement);
                    final int changeType = changeByChild.getChangeType();
                    final IElementType type = treeElement.getElementType();
                    if (type == TokenType.WHITE_SPACE)
                        continue;
                    /*
            if (type == ElementType.XML_NAME) {
              final XmlToken xmlToken = (XmlToken)((ReplaceChangeInfo)changeByChild).getReplaced();
              xmlChangeSet.add(new XmlTagNameChangedImpl(tag, xmlToken.getText()));
              continue;
            }
            */
                    final PsiElement element = treeElement.getPsi();
                    switch(changeType) {
                        case ChangeInfo.ADD:
                            xmlChangeSet.add(new XmlTagChildAddImpl(tag, (XmlTagChild) element));
                            break;
                        case ChangeInfo.REMOVED:
                            treeElement.putUserData(CharTable.CHAR_TABLE_KEY, table);
                            xmlChangeSet.add(new XmlTagChildRemovedImpl(tag, (XmlTagChild) element));
                            break;
                        case ChangeInfo.CONTENTS_CHANGED:
                            xmlChangeSet.add(new XmlTagChildChangedImpl(tag, (XmlTagChild) element));
                            break;
                        case ChangeInfo.REPLACE:
                            final PsiElement psi = ((ReplaceChangeInfo) changeByChild).getReplaced().getPsi();
                            if (psi instanceof XmlTagChild) {
                                final XmlTagChild replaced = (XmlTagChild) psi;
                                replaced.putUserData(CharTable.CHAR_TABLE_KEY, table);
                                xmlChangeSet.add(new XmlTagChildRemovedImpl(tag, replaced));
                                xmlChangeSet.add(new XmlTagChildAddImpl(tag, (XmlTagChild) element));
                            }
                            break;
                    }
                }
            }

            @Override
            public void visitXmlDocument(XmlDocument document) {
                xmlChangeSet.clear();
                xmlChangeSet.add(new XmlDocumentChangedImpl(document));
            }

            @Override
            public void visitFile(PsiFile file) {
                final XmlDocument document = ((XmlFile) file).getDocument();
                if (document != null) {
                    xmlChangeSet.clear();
                    xmlChangeSet.add(new XmlDocumentChangedImpl(document));
                }
            }
        });
    }
}
Also used : TreeChangeEvent(com.intellij.pom.tree.events.TreeChangeEvent) ChangeInfoImpl(com.intellij.pom.tree.events.impl.ChangeInfoImpl) CharTable(com.intellij.util.CharTable) ASTNode(com.intellij.lang.ASTNode) PsiFile(com.intellij.psi.PsiFile) PsiElement(com.intellij.psi.PsiElement) XmlElementVisitor(com.intellij.psi.XmlElementVisitor) ReplaceChangeInfo(com.intellij.pom.tree.events.ReplaceChangeInfo) TreeChangeImpl(com.intellij.pom.tree.events.impl.TreeChangeImpl) ReplaceChangeInfo(com.intellij.pom.tree.events.ReplaceChangeInfo) ChangeInfo(com.intellij.pom.tree.events.ChangeInfo) IElementType(com.intellij.psi.tree.IElementType) TreeChange(com.intellij.pom.tree.events.TreeChange) FileElement(com.intellij.psi.impl.source.tree.FileElement)

Example 2 with TreeChangeImpl

use of com.intellij.pom.tree.events.impl.TreeChangeImpl in project intellij-community by JetBrains.

the class PsiEventWrapperAspect method sendAfterEvents.

private static void sendAfterEvents(TreeChangeEvent changeSet) {
    ASTNode rootElement = changeSet.getRootElement();
    final PsiFile file = (PsiFile) SourceTreeToPsiMap.treeElementToPsi(rootElement);
    final PsiManagerImpl manager = (PsiManagerImpl) file.getManager();
    if (manager == null)
        return;
    if (!file.isPhysical()) {
        manager.afterChange(false);
        return;
    }
    final ASTNode[] changedElements = changeSet.getChangedElements();
    for (ASTNode changedElement : changedElements) {
        TreeChange changesByElement = changeSet.getChangesByElement(changedElement);
        PsiElement psiParent = null;
        while (changedElement != null && ((psiParent = changedElement.getPsi()) == null || !checkPsiForChildren(changesByElement.getAffectedChildren()))) {
            final ASTNode parent = changedElement.getTreeParent();
            final ChangeInfoImpl changeInfo = ChangeInfoImpl.create(ChangeInfo.CONTENTS_CHANGED, changedElement);
            changeInfo.compactChange(changesByElement);
            changesByElement = new TreeChangeImpl(parent);
            changesByElement.addChange(changedElement, changeInfo);
            changedElement = parent;
        }
        if (changedElement == null)
            continue;
        final ASTNode[] affectedChildren = changesByElement.getAffectedChildren();
        for (final ASTNode treeElement : affectedChildren) {
            PsiTreeChangeEventImpl psiEvent = new PsiTreeChangeEventImpl(manager);
            psiEvent.setParent(psiParent);
            psiEvent.setFile(file);
            final PsiElement psiChild = treeElement.getPsi();
            psiEvent.setChild(psiChild);
            final ChangeInfo changeByChild = changesByElement.getChangeByChild(treeElement);
            switch(changeByChild.getChangeType()) {
                case ChangeInfo.ADD:
                    psiEvent.setOffset(treeElement.getStartOffset());
                    psiEvent.setOldLength(0);
                    manager.childAdded(psiEvent);
                    break;
                case ChangeInfo.REPLACE:
                    final ReplaceChangeInfo change = (ReplaceChangeInfo) changeByChild;
                    psiEvent.setOffset(treeElement.getStartOffset());
                    final ASTNode replaced = change.getReplaced();
                    psiEvent.setOldChild(replaced.getPsi());
                    psiEvent.setNewChild(psiChild);
                    psiEvent.setOldLength(replaced.getTextLength());
                    manager.childReplaced(psiEvent);
                    break;
                case ChangeInfo.CONTENTS_CHANGED:
                    psiEvent.setOffset(treeElement.getStartOffset());
                    psiEvent.setParent(psiChild);
                    psiEvent.setOldLength(changeByChild.getOldLength());
                    manager.childrenChanged(psiEvent);
                    break;
                case ChangeInfo.REMOVED:
                    psiEvent.setOffset(changesByElement.getChildOffsetInNewTree(treeElement));
                    psiEvent.setOldParent(psiParent);
                    psiEvent.setOldChild(psiChild);
                    psiEvent.setOldLength(changeByChild.getOldLength());
                    manager.childRemoved(psiEvent);
                    break;
            }
        }
    }
}
Also used : ReplaceChangeInfo(com.intellij.pom.tree.events.ReplaceChangeInfo) PsiManagerImpl(com.intellij.psi.impl.PsiManagerImpl) TreeChange(com.intellij.pom.tree.events.TreeChange) TreeChangeImpl(com.intellij.pom.tree.events.impl.TreeChangeImpl) ReplaceChangeInfo(com.intellij.pom.tree.events.ReplaceChangeInfo) ChangeInfo(com.intellij.pom.tree.events.ChangeInfo) ASTNode(com.intellij.lang.ASTNode) ChangeInfoImpl(com.intellij.pom.tree.events.impl.ChangeInfoImpl) PsiFile(com.intellij.psi.PsiFile) PsiTreeChangeEventImpl(com.intellij.psi.impl.PsiTreeChangeEventImpl) PsiElement(com.intellij.psi.PsiElement)

Aggregations

ASTNode (com.intellij.lang.ASTNode)2 ChangeInfo (com.intellij.pom.tree.events.ChangeInfo)2 ReplaceChangeInfo (com.intellij.pom.tree.events.ReplaceChangeInfo)2 TreeChange (com.intellij.pom.tree.events.TreeChange)2 ChangeInfoImpl (com.intellij.pom.tree.events.impl.ChangeInfoImpl)2 TreeChangeImpl (com.intellij.pom.tree.events.impl.TreeChangeImpl)2 PsiElement (com.intellij.psi.PsiElement)2 PsiFile (com.intellij.psi.PsiFile)2 TreeChangeEvent (com.intellij.pom.tree.events.TreeChangeEvent)1 XmlElementVisitor (com.intellij.psi.XmlElementVisitor)1 PsiManagerImpl (com.intellij.psi.impl.PsiManagerImpl)1 PsiTreeChangeEventImpl (com.intellij.psi.impl.PsiTreeChangeEventImpl)1 FileElement (com.intellij.psi.impl.source.tree.FileElement)1 IElementType (com.intellij.psi.tree.IElementType)1 CharTable (com.intellij.util.CharTable)1