X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEditNode.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEditNode.java index 7cfaa70..b8e11fb 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEditNode.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEditNode.java @@ -13,35 +13,40 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.text.DocumentEvent; import org.eclipse.jface.text.IDocumentListener; - /** - * A helper class to arrange TextEdits into a tree to optimize their - * execution. + * A helper class to arrange TextEdits into a tree to optimize + * their execution. */ -/* package */ abstract class TextEditNode { +/* package */abstract class TextEditNode { + + /* package */TextEditNode fParent; + + /* package */List fChildren; - /* package */ TextEditNode fParent; - /* package */ List fChildren; - /* package */ TextEdit fEdit; - - /* package */ static class DefaultNode extends TextEditNode { + /* package */TextEdit fEdit; + + /* package */static class DefaultNode extends TextEditNode { public DefaultNode(TextEdit edit) { super(edit); } } - - /* package */ static class RootNode extends TextEditNode { + + /* package */static class RootNode extends TextEditNode { private int fUndoIndex; + public RootNode(int length) { super(new NopTextEdit(new TextRange(0, length))); - fEdit.isSynthetic= true; + fEdit.isSynthetic = true; } + public boolean covers(TextEditNode node) { return true; } - public UndoMemento performDo(TextBuffer buffer, IProgressMonitor pm) throws CoreException { - DoRangeUpdater updater= new DoRangeUpdater(); - UndoMemento undo= new UndoMemento(TextBufferEditor.UNDO); + + public UndoMemento performDo(TextBuffer buffer, IProgressMonitor pm) + throws CoreException { + DoRangeUpdater updater = new DoRangeUpdater(); + UndoMemento undo = new UndoMemento(TextBufferEditor.UNDO); try { buffer.registerUpdater(updater); performDo(buffer, updater, undo, pm); @@ -51,9 +56,11 @@ import org.eclipse.jface.text.IDocumentListener; } return undo; } - public UndoMemento performUndo(TextBuffer buffer, IProgressMonitor pm) throws CoreException { - UndoRangeUpdater updater= new UndoRangeUpdater(this); - UndoMemento undo= new UndoMemento(TextBufferEditor.REDO); + + public UndoMemento performUndo(TextBuffer buffer, IProgressMonitor pm) + throws CoreException { + UndoRangeUpdater updater = new UndoRangeUpdater(this); + UndoMemento undo = new UndoMemento(TextBufferEditor.REDO); try { buffer.registerUpdater(updater); performUndo(buffer, updater, undo, pm); @@ -63,239 +70,286 @@ import org.eclipse.jface.text.IDocumentListener; } return undo; } - + protected void setUndoIndex(int index) { - fUndoIndex= index; + fUndoIndex = index; } - + protected int getUndoIndex() { return fUndoIndex; } } - - /* package */ abstract static class AbstractMoveNode extends TextEditNode { - private int state; - + + /* package */abstract static class AbstractMoveNode extends TextEditNode { + private int state; + private int fTargetIndex; + private int fSourceIndex; - + private List fAffectedChildren; - + public AbstractMoveNode(TextEdit edit) { super(edit); reset(); } + protected abstract TextRange getSourceRange(); + protected abstract TextRange getTargetRange(); + protected abstract boolean isUpMove(); + protected boolean isDownMove() { return !isUpMove(); } + public boolean isMove() { return true; } + protected void checkRange(DocumentEvent event) { - TextRange range= getChildRange(); - int eventOffset= event.getOffset(); - int eventLength= event.getLength(); + TextRange range = getChildRange(); + int eventOffset = event.getOffset(); + int eventLength = event.getLength(); int eventEnd = eventOffset + eventLength - 1; // "Edit changes text that lies outside its defined range" - // Assert.isTrue(range.fOffset <= eventOffset && eventEnd <= range.getInclusiveEnd()); + // Assert.isTrue(range.fOffset <= eventOffset && eventEnd <= + // range.getInclusiveEnd()); } + protected boolean activeNodeChanged(int delta) { - TextRange targetRange= getTargetRange(); - TextRange sourceRange= getSourceRange(); + TextRange targetRange = getTargetRange(); + TextRange sourceRange = getSourceRange(); switch (state) { - case 0: // the move delete - init(); - // Assert.isTrue(Math.abs(delta) == sourceRange.fLength); - if (isUpMove()) { - updateOffset(fAffectedChildren, delta); - targetRange.fOffset+= delta; - } - sourceRange.fLength= 0; - state= 1; - break; - case 1: - TextEditNode target= (TextEditNode)fParent.fChildren.get(fTargetIndex); - TextEditNode source= (TextEditNode)fParent.fChildren.get(fSourceIndex); - updateOffset(source.fChildren, targetRange.fOffset - sourceRange.fOffset); - target.fChildren= source.fChildren; - if (target.fChildren != null) { - for (Iterator iter= target.fChildren.iterator(); iter.hasNext();) { - ((TextEditNode)iter.next()).fParent= target; - } - } - source.fChildren= null; - if (isDownMove()) { - updateOffset(fAffectedChildren, delta); - sourceRange.fOffset+= delta; + case 0: // the move delete + init(); + // Assert.isTrue(Math.abs(delta) == sourceRange.fLength); + if (isUpMove()) { + updateOffset(fAffectedChildren, delta); + targetRange.fOffset += delta; + } + sourceRange.fLength = 0; + state = 1; + break; + case 1: + TextEditNode target = (TextEditNode) fParent.fChildren + .get(fTargetIndex); + TextEditNode source = (TextEditNode) fParent.fChildren + .get(fSourceIndex); + updateOffset(source.fChildren, targetRange.fOffset + - sourceRange.fOffset); + target.fChildren = source.fChildren; + if (target.fChildren != null) { + for (Iterator iter = target.fChildren.iterator(); iter + .hasNext();) { + ((TextEditNode) iter.next()).fParent = target; } - targetRange.fLength= delta; - reset(); - break; + } + source.fChildren = null; + if (isDownMove()) { + updateOffset(fAffectedChildren, delta); + sourceRange.fOffset += delta; + } + targetRange.fLength = delta; + reset(); + break; } return true; } + private static void updateOffset(List nodes, int delta) { if (nodes == null) return; - for (int i= nodes.size() - 1; i >= 0; i--) { - TextEditNode node= (TextEditNode)nodes.get(i); - TextRange range= node.getTextRange(); - range.fOffset+= delta; + for (int i = nodes.size() - 1; i >= 0; i--) { + TextEditNode node = (TextEditNode) nodes.get(i); + TextRange range = node.getTextRange(); + range.fOffset += delta; updateOffset(node.fChildren, delta); } } + private void init() { - TextRange source= getSourceRange(); - TextRange target= getTargetRange(); - List children= fParent.fChildren; - for (int i= children.size() - 1; i >= 0; i--) { - TextEditNode child= (TextEditNode)children.get(i); - TextRange range= child.fEdit.getTextRange(); + TextRange source = getSourceRange(); + TextRange target = getTargetRange(); + List children = fParent.fChildren; + for (int i = children.size() - 1; i >= 0; i--) { + TextEditNode child = (TextEditNode) children.get(i); + TextRange range = child.fEdit.getTextRange(); if (range == source) - fSourceIndex= i; + fSourceIndex = i; else if (range == target) - fTargetIndex= i; + fTargetIndex = i; } - int start= Math.min(fTargetIndex, fSourceIndex); - int end= Math.max(fTargetIndex, fSourceIndex); - fAffectedChildren= new ArrayList(3); - for (int i= start + 1; i < end; i++) { + int start = Math.min(fTargetIndex, fSourceIndex); + int end = Math.max(fTargetIndex, fSourceIndex); + fAffectedChildren = new ArrayList(3); + for (int i = start + 1; i < end; i++) { fAffectedChildren.add(children.get(i)); } } + private void reset() { - state= 0; - fSourceIndex= -1; - fTargetIndex= -1; + state = 0; + fSourceIndex = -1; + fTargetIndex = -1; } } - - /* package */ static class MoveNode extends AbstractMoveNode { + + /* package */static class MoveNode extends AbstractMoveNode { public MoveNode(TextEdit edit) { super(edit); } + protected TextRange getChildRange() { - return ((MoveTextEdit)fEdit).getChildRange(); + return ((MoveTextEdit) fEdit).getChildRange(); } + protected TextRange getSourceRange() { - return ((MoveTextEdit)fEdit).getSourceRange(); + return ((MoveTextEdit) fEdit).getSourceRange(); } + protected TextRange getTargetRange() { - return ((MoveTextEdit)fEdit).getTargetRange(); + return ((MoveTextEdit) fEdit).getTargetRange(); } + protected boolean isUpMove() { - return ((MoveTextEdit)fEdit).isUpMove(); + return ((MoveTextEdit) fEdit).isUpMove(); } + public boolean isMovePartner(TextEditNode other) { if (!(other instanceof TargetMarkNode)) return false; - return fEdit == ((MoveTextEdit.TargetMark)other.fEdit).getMoveTextEdit(); + return fEdit == ((MoveTextEdit.TargetMark) other.fEdit) + .getMoveTextEdit(); } + public boolean covers(TextEditNode node) { if (node instanceof TargetMarkNode) { - MoveTextEdit.TargetMark edit= (MoveTextEdit.TargetMark)node.fEdit; + MoveTextEdit.TargetMark edit = (MoveTextEdit.TargetMark) node.fEdit; if (edit.getMoveTextEdit() == fEdit) return false; } return getParentRange().covers(node.getChildRange()); } } - - /* package */ static class TargetMarkNode extends AbstractMoveNode { + + /* package */static class TargetMarkNode extends AbstractMoveNode { public TargetMarkNode(TextEdit edit) { super(edit); } + protected TextRange getChildRange() { - return ((MoveTextEdit.TargetMark)fEdit).getMoveTextEdit().getChildRange(); + return ((MoveTextEdit.TargetMark) fEdit).getMoveTextEdit() + .getChildRange(); } + protected TextRange getSourceRange() { - return ((MoveTextEdit.TargetMark)fEdit).getMoveTextEdit().getSourceRange(); + return ((MoveTextEdit.TargetMark) fEdit).getMoveTextEdit() + .getSourceRange(); } + protected TextRange getTargetRange() { - return ((MoveTextEdit.TargetMark)fEdit).getMoveTextEdit().getTargetRange(); + return ((MoveTextEdit.TargetMark) fEdit).getMoveTextEdit() + .getTargetRange(); } + protected boolean isUpMove() { - return ((MoveTextEdit.TargetMark)fEdit).getMoveTextEdit().isUpMove(); + return ((MoveTextEdit.TargetMark) fEdit).getMoveTextEdit() + .isUpMove(); } + public boolean isMovePartner(TextEditNode other) { - return ((MoveTextEdit.TargetMark)fEdit).getMoveTextEdit() == other.fEdit; + return ((MoveTextEdit.TargetMark) fEdit).getMoveTextEdit() == other.fEdit; } } - //---- Range updating --------------------------------------------------------------------------- + // ---- Range updating + // --------------------------------------------------------------------------- private static abstract class RangeUpdater implements IDocumentListener { protected TextEditNode fActiveNode; + public void documentAboutToBeChanged(DocumentEvent event) { } + public void setActiveNode(TextEditNode node) { - fActiveNode= node; + fActiveNode = node; } + public void updateParents(int delta) { - TextEditNode node= fActiveNode.fParent; + TextEditNode node = fActiveNode.fParent; while (node != null) { node.childNodeChanged(delta); - node= node.fParent; + node = node.fParent; } } + public static int getDelta(DocumentEvent event) { - return (event.getText() == null ? 0 : event.getText().length()) - event.getLength(); + return (event.getText() == null ? 0 : event.getText().length()) + - event.getLength(); } } + private static class DoRangeUpdater extends RangeUpdater { - private List fProcessedNodes= new ArrayList(10); + private List fProcessedNodes = new ArrayList(10); + public void setActiveNode(TextEditNode node) { if (fActiveNode != null) fProcessedNodes.add(fActiveNode); super.setActiveNode(node); } + public void documentChanged(DocumentEvent event) { fActiveNode.checkRange(event); - int delta= getDelta(event); + int delta = getDelta(event); if (!fActiveNode.activeNodeChanged(delta)) { - for (Iterator iter= fProcessedNodes.iterator(); iter.hasNext();) { - ((TextEditNode)iter.next()).previousNodeChanged(delta); + for (Iterator iter = fProcessedNodes.iterator(); iter.hasNext();) { + ((TextEditNode) iter.next()).previousNodeChanged(delta); } } updateParents(delta); } } - private static class UndoRangeUpdater extends RangeUpdater { + + private static class UndoRangeUpdater extends RangeUpdater { private RootNode fRootNode; + public UndoRangeUpdater(RootNode root) { - fRootNode= root; + fRootNode = root; } + public void setActiveNode(TextEditNode node) { super.setActiveNode(node); } + public void documentChanged(DocumentEvent event) { fActiveNode.checkRange(event); - int delta= getDelta(event); + int delta = getDelta(event); if (!fActiveNode.activeNodeChanged(delta)) { - int start= fRootNode.getUndoIndex() + 1; - List children= fRootNode.fChildren; - int size= children != null ? children.size() : 0; - for (int i= start; i < size; i++) { - updateUndo((TextEditNode)children.get(i), delta); + int start = fRootNode.getUndoIndex() + 1; + List children = fRootNode.fChildren; + int size = children != null ? children.size() : 0; + for (int i = start; i < size; i++) { + updateUndo((TextEditNode) children.get(i), delta); } } updateParents(delta); } + private void updateUndo(TextEditNode node, int delta) { node.previousNodeChanged(delta); - List children= node.fChildren; - int size= children != null ? children.size() : 0; - for (int i= 0; i < size; i++) { - updateUndo((TextEditNode)children.get(i), delta); + List children = node.fChildren; + int size = children != null ? children.size() : 0; + for (int i = 0; i < size; i++) { + updateUndo((TextEditNode) children.get(i), delta); } } } - - //---- Creating instances --------------------------------------------------------------------------- - + + // ---- Creating instances + // --------------------------------------------------------------------------- + static TextEditNode create(TextEdit edit) { if (edit instanceof MoveTextEdit) return new MoveNode(edit); @@ -303,34 +357,35 @@ import org.eclipse.jface.text.IDocumentListener; return new TargetMarkNode(edit); return new DefaultNode(edit); } - + static RootNode createRoot(int length) { return new RootNode(length); } - + private TextEditNode(TextEdit edit) { - fEdit= edit; + fEdit = edit; } - - //---- Adding children --------------------------------------------------------------------------- - + + // ---- Adding children + // --------------------------------------------------------------------------- + protected void add(TextEditNode node) { if (fChildren == null) { - fChildren= new ArrayList(1); - node.fParent= this; + fChildren = new ArrayList(1); + node.fParent = this; fChildren.add(node); return; } // Optimize using binary search - for (Iterator iter= fChildren.iterator(); iter.hasNext();) { - TextEditNode child= (TextEditNode)iter.next(); + for (Iterator iter = fChildren.iterator(); iter.hasNext();) { + TextEditNode child = (TextEditNode) iter.next(); if (child.covers(node)) { child.add(node); return; } } - for (int i= 0; i < fChildren.size(); ) { - TextEditNode child= (TextEditNode)fChildren.get(i); + for (int i = 0; i < fChildren.size();) { + TextEditNode child = (TextEditNode) fChildren.get(i); if (node.covers(child)) { fChildren.remove(i); node.add(child); @@ -338,101 +393,111 @@ import org.eclipse.jface.text.IDocumentListener; i++; } } - node.fParent= this; + node.fParent = this; fChildren.add(node); } - + public boolean covers(TextEditNode node) { - return false; + return false; } - - //---- Accessing -------------------------------------------------------------------------------------- - + + // ---- Accessing + // -------------------------------------------------------------------------------------- + protected RootNode getRoot() { - TextEditNode candidate= this; - while(candidate.fParent != null) - candidate= candidate.fParent; - return (RootNode)candidate; + TextEditNode candidate = this; + while (candidate.fParent != null) + candidate = candidate.fParent; + return (RootNode) candidate; } - - //---- Query interface -------------------------------------------------------------------------------- - + + // ---- Query interface + // -------------------------------------------------------------------------------- + protected boolean isSynthetic() { return fEdit.isSynthetic; } - + public boolean isMove() { return false; } - - //---- Accessing Ranges ------------------------------------------------------------------------------ - + + // ---- Accessing Ranges + // ------------------------------------------------------------------------------ + protected void checkRange(DocumentEvent event) { - TextRange range= getTextRange(); - int eventOffset= event.getOffset(); - int eventLength= event.getLength(); + TextRange range = getTextRange(); + int eventOffset = event.getOffset(); + int eventLength = event.getLength(); int eventEnd = eventOffset + eventLength - 1; // "Edit changes text that lies outside its defined range" - // Assert.isTrue(range.fOffset <= eventOffset && eventEnd <= range.getInclusiveEnd()); + // Assert.isTrue(range.fOffset <= eventOffset && eventEnd <= + // range.getInclusiveEnd()); } - + protected TextRange getTextRange() { return fEdit.getTextRange(); } - + protected TextRange getChildRange() { return getTextRange(); } - + protected TextRange getParentRange() { return getTextRange(); } - + public boolean validate(int bufferLength) { if (fChildren == null) return true; - // Only Moves and Nops can be parents + // Only Moves and Nops can be parents if (!(fEdit instanceof MoveTextEdit || fEdit instanceof NopTextEdit)) return false; - TextRange lastRange= null; - for (Iterator iter= fChildren.iterator(); iter.hasNext(); ) { - TextEditNode node= (TextEditNode)iter.next(); + TextRange lastRange = null; + for (Iterator iter = fChildren.iterator(); iter.hasNext();) { + TextEditNode node = (TextEditNode) iter.next(); if (!node.validate(bufferLength)) return false; - TextRange range= node.fEdit.getTextRange(); - if (!range.isValid() || range.fOffset + range.fLength > bufferLength) + TextRange range = node.fEdit.getTextRange(); + if (!range.isValid() + || range.fOffset + range.fLength > bufferLength) return false; - if (lastRange != null && !(range.isInsertionPointAt(lastRange.fOffset) || range.liesBehind(lastRange))) + if (lastRange != null + && !(range.isInsertionPointAt(lastRange.fOffset) || range + .liesBehind(lastRange))) return false; - lastRange= range; + lastRange = range; } return true; } - //---- Updating ---------------------------------------------------------------------------------------- - + // ---- Updating + // ---------------------------------------------------------------------------------------- + protected boolean activeNodeChanged(int delta) { - TextRange range= getTextRange(); - range.fLength+= delta; + TextRange range = getTextRange(); + range.fLength += delta; // we didn't adjust any processed nodes. return false; } - + protected void previousNodeChanged(int delta) { - TextRange range= getTextRange(); - range.fOffset+= delta; + TextRange range = getTextRange(); + range.fOffset += delta; } - + protected void childNodeChanged(int delta) { - getTextRange().fLength+= delta; + getTextRange().fLength += delta; } - //---- Do it --------------------------------------------------------------------------------------------- - - protected void performDo(TextBuffer buffer, RangeUpdater updater, UndoMemento undo, IProgressMonitor pm) throws CoreException { - int size= fChildren != null ? fChildren.size() : 0; - for (int i= size - 1; i >= 0; i--) { - TextEditNode child= (TextEditNode)fChildren.get(i); + // ---- Do it + // --------------------------------------------------------------------------------------------- + + protected void performDo(TextBuffer buffer, RangeUpdater updater, + UndoMemento undo, IProgressMonitor pm) throws CoreException { + int size = fChildren != null ? fChildren.size() : 0; + for (int i = size - 1; i >= 0; i--) { + TextEditNode child = (TextEditNode) fChildren.get(i); child.performDo(buffer, updater, undo, pm); } updater.setActiveNode(this); @@ -442,23 +507,25 @@ import org.eclipse.jface.text.IDocumentListener; undo.add(fEdit.perform(buffer)); pm.worked(1); } - - public void performedDo() { - int size= fChildren != null ? fChildren.size() : 0; - for (int i= size - 1; i >= 0; i--) { - TextEditNode child= (TextEditNode)fChildren.get(i); + + public void performedDo() { + int size = fChildren != null ? fChildren.size() : 0; + for (int i = size - 1; i >= 0; i--) { + TextEditNode child = (TextEditNode) fChildren.get(i); child.performedDo(); } fEdit.performed(); } - - //---- Undo it ------------------------------------------------------------------------------------------- - - protected void performUndo(TextBuffer buffer, RangeUpdater updater, UndoMemento undo, IProgressMonitor pm) throws CoreException { - int size= fChildren != null ? fChildren.size() : 0; - for (int i= 0; i < size; i++) { + + // ---- Undo it + // ------------------------------------------------------------------------------------------- + + protected void performUndo(TextBuffer buffer, RangeUpdater updater, + UndoMemento undo, IProgressMonitor pm) throws CoreException { + int size = fChildren != null ? fChildren.size() : 0; + for (int i = 0; i < size; i++) { setUndoIndex(i); - TextEditNode child= (TextEditNode)fChildren.get(i); + TextEditNode child = (TextEditNode) fChildren.get(i); child.performUndo(buffer, updater, undo, pm); } updater.setActiveNode(this); @@ -468,26 +535,25 @@ import org.eclipse.jface.text.IDocumentListener; undo.add(fEdit.perform(buffer)); pm.worked(1); } - + protected void setUndoIndex(int index) { } - - public void performedUndo() { - int size= fChildren != null ? fChildren.size() : 0; - for (int i= 0; i < size; i++) { - TextEditNode child= (TextEditNode)fChildren.get(i); + + public void performedUndo() { + int size = fChildren != null ? fChildren.size() : 0; + for (int i = 0; i < size; i++) { + TextEditNode child = (TextEditNode) fChildren.get(i); child.performedUndo(); } fEdit.performed(); } - -// protected void createUndoList(List list) { -// int size= fChildren != null ? fChildren.size() : 0; -// for (int i= 0; i < size; i++) { -// TextEditNode child= (TextEditNode)fChildren.get(i); -// child.createUndoList(list); -// } -// list.add(this); -// } -} + // protected void createUndoList(List list) { + // int size= fChildren != null ? fChildren.size() : 0; + // for (int i= 0; i < size; i++) { + // TextEditNode child= (TextEditNode)fChildren.get(i); + // child.createUndoList(list); + // } + // list.add(this); + // } +}