/eclipse-cdt-8.1.0/org.eclipse.cdt-CDT_8_1_0/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/TextEditUtil.java
Java | 219 lines | 163 code | 21 blank | 35 comment | 47 complexity | 4dbd35fe15757e1e38f4276b56b69d19 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.1
- /*******************************************************************************
- * Copyright (c) 2007, 2012 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- * Sergey Prigogin (Google)
- *******************************************************************************/
- package org.eclipse.cdt.internal.core.dom.rewrite.changegenerator;
- import org.eclipse.text.edits.CopyTargetEdit;
- import org.eclipse.text.edits.DeleteEdit;
- import org.eclipse.text.edits.InsertEdit;
- import org.eclipse.text.edits.MalformedTreeException;
- import org.eclipse.text.edits.MoveSourceEdit;
- import org.eclipse.text.edits.MoveTargetEdit;
- import org.eclipse.text.edits.MultiTextEdit;
- import org.eclipse.text.edits.ReplaceEdit;
- import org.eclipse.text.edits.TextEdit;
- public class TextEditUtil {
- // Do not instantiate. All methods are static.
- private TextEditUtil() {
- }
-
- /**
- * Degenerates the given edit tree into a list.<br>
- * All nodes of the result are leafs.<br>
- * <strong>The given edit is modified and can no longer be used.</strong>
- *
- * @param edit the edit tree to flatten
- * @return a MultiTextEdit containing the list of edits
- */
- public static MultiTextEdit flatten(TextEdit edit) {
- MultiTextEdit result= new MultiTextEdit();
- flatten(edit, result);
- return result;
- }
- private static void flatten(TextEdit edit, MultiTextEdit result) {
- if (edit.hasChildren()) {
- TextEdit[] children= edit.getChildren();
- for (int i= 0; i < children.length; i++) {
- TextEdit child= children[i];
- child.getParent().removeChild(0);
- flatten(child, result);
- }
- } else if (!(edit instanceof MultiTextEdit)) {
- result.addChild(edit);
- }
- }
- /**
- * Create an edit which contains <code>edit1</code> and <code>edit2</code>
- * <p><strong>The given edits are modified and they can no longer be used.</strong></p>
- *
- * @param edit1 the edit to merge with edit2
- * @param edit2 the edit to merge with edit1
- * @return the merged tree
- * @throws MalformedTreeException if the two edits ovelap
- */
- public static TextEdit merge(TextEdit edit1, TextEdit edit2) {
- if (edit1 instanceof MultiTextEdit && !edit1.hasChildren()) {
- return edit2;
- }
- if (edit2 instanceof MultiTextEdit && !edit2.hasChildren()) {
- return edit1;
- }
- MultiTextEdit result= new MultiTextEdit();
- merge(edit1, edit2, result);
- return result;
- }
- private static void merge(TextEdit edit1, TextEdit edit2, MultiTextEdit result) {
- if (edit1 instanceof MultiTextEdit && edit2 instanceof MultiTextEdit) {
- MultiTextEdit multiTextEdit1= (MultiTextEdit) edit1;
- if (!multiTextEdit1.hasChildren()) {
- result.addChild(edit2);
- return;
- }
- MultiTextEdit multiTextEdit2= (MultiTextEdit) edit2;
- if (!multiTextEdit2.hasChildren()) {
- result.addChild(edit1);
- return;
- }
- TextEdit[] children1= multiTextEdit1.getChildren();
- TextEdit[] children2= multiTextEdit2.getChildren();
- int i1= 0;
- int i2= 0;
- while (i1 < children1.length && i2 < children2.length) {
- while (i1 < children1.length && children1[i1].getExclusiveEnd() < children2[i2].getOffset()) {
- edit1.removeChild(0);
- result.addChild(children1[i1]);
- i1++;
- }
- if (i1 >= children1.length)
- break;
- while (i2 < children2.length && children2[i2].getExclusiveEnd() < children1[i1].getOffset()) {
- edit2.removeChild(0);
- result.addChild(children2[i2]);
- i2++;
- }
- if (i2 >= children2.length)
- break;
- if (children1[i1].getExclusiveEnd() < children2[i2].getOffset())
- continue;
- edit1.removeChild(0);
- edit2.removeChild(0);
- merge(children1[i1], children2[i2], result);
- i1++;
- i2++;
- }
- while (i1 < children1.length) {
- edit1.removeChild(0);
- result.addChild(children1[i1]);
- i1++;
- }
- while (i2 < children2.length) {
- edit2.removeChild(0);
- result.addChild(children2[i2]);
- i2++;
- }
- } else if (edit1 instanceof MultiTextEdit) {
- TextEdit[] children= edit1.getChildren();
- int i= 0;
- while (children[i].getExclusiveEnd() < edit2.getOffset()) {
- edit1.removeChild(0);
- result.addChild(children[i]);
- i++;
- if (i >= children.length) {
- result.addChild(edit2);
- return;
- }
- }
- edit1.removeChild(0);
- merge(children[i], edit2, result);
- i++;
- while (i < children.length) {
- edit1.removeChild(0);
- result.addChild(children[i]);
- i++;
- }
- } else if (edit2 instanceof MultiTextEdit) {
- TextEdit[] children= edit2.getChildren();
- int i= 0;
- while (children[i].getExclusiveEnd() < edit1.getOffset()) {
- edit2.removeChild(0);
- result.addChild(children[i]);
- i++;
- if (i >= children.length) {
- result.addChild(edit1);
- return;
- }
- }
- edit2.removeChild(0);
- merge(edit1, children[i], result);
- i++;
- while (i < children.length) {
- edit2.removeChild(0);
- result.addChild(children[i]);
- i++;
- }
- } else {
- if (edit1.getExclusiveEnd() < edit2.getOffset()) {
- result.addChild(edit1);
- result.addChild(edit2);
- } else {
- result.addChild(edit2);
- result.addChild(edit1);
- }
- }
- }
- /**
- * Returns the difference in the document length caused by the edit. {@code InsertEdit}s have
- * positive delta, {@code DeleteEdit}s have negative one.
- * @param edit the edit to determine delta for.
- * @return the delta
- */
- public static int delta(TextEdit edit) {
- int delta = 0;
- for (TextEdit child : edit.getChildren()) {
- delta += delta(child);
- }
- delta += ownDelta(edit);
- return delta;
- }
- private static int ownDelta(TextEdit edit) {
- if (edit instanceof DeleteEdit || edit instanceof MoveSourceEdit) {
- return -edit.getLength();
- } else if (edit instanceof InsertEdit) {
- return ((InsertEdit) edit).getText().length();
- } else if (edit instanceof ReplaceEdit) {
- return ((ReplaceEdit) edit).getText().length() - edit.getLength();
- } else if (edit instanceof CopyTargetEdit) {
- return ((CopyTargetEdit) edit).getSourceEdit().getLength();
- } else if (edit instanceof MoveTargetEdit) {
- return ((MoveTargetEdit) edit).getSourceEdit().getLength();
- }
- return 0;
- }
- }