Search in sources :

Example 6 with MultiTextEdit

use of org.eclipse.text.edits.MultiTextEdit in project che by eclipse.

the class MultiStateTextFileChange method getPreviewContent.

/*
	 * @see org.eclipse.ltk.core.refactoring.TextEditBasedChange#getPreviewContent(org.eclipse.ltk.core.refactoring.TextEditBasedChangeGroup[],org.eclipse.jface.text.IRegion,boolean,int,org.eclipse.core.runtime.IProgressMonitor)
	 */
public final String getPreviewContent(final TextEditBasedChangeGroup[] groups, final IRegion region, final boolean expand, final int surround, final IProgressMonitor monitor) throws CoreException {
    final Set cachedGroups = new HashSet(Arrays.asList(groups));
    final IDocument document = new Document(getCurrentDocument(monitor).get());
    // Marks the region in the document to be previewed
    final Position range = new Position(region.getOffset(), region.getLength());
    try {
        ComposableBufferChange change = null;
        final TextEditBasedChangeGroup[] changedGroups = getChangeGroups();
        LinkedList compositeUndo = new LinkedList();
        for (int index = 0; index < fChanges.size(); index++) {
            change = (ComposableBufferChange) fChanges.get(index);
            TextEdit copy = null;
            try {
                // Have to use a copy
                fCopier = new TextEditCopier(change.getEdit());
                copy = fCopier.perform();
                // Create a mapping from the copied edits to its originals
                final Map originalMap = new HashMap();
                for (final Iterator outer = change.getGroups().iterator(); outer.hasNext(); ) {
                    final ComposableBufferChangeGroup group = (ComposableBufferChangeGroup) outer.next();
                    for (final Iterator inner = group.getCachedEdits().iterator(); inner.hasNext(); ) {
                        final TextEdit originalEdit = (TextEdit) inner.next();
                        final TextEdit copiedEdit = fCopier.getCopy(originalEdit);
                        if (copiedEdit != null)
                            originalMap.put(copiedEdit, originalEdit);
                        else
                            //$NON-NLS-1$
                            RefactoringCorePlugin.logErrorMessage("Could not find a copy for the indexed text edit " + originalEdit.toString());
                    }
                }
                final ComposableBufferChangeGroup[] currentGroup = { null };
                final TextEdit[] currentEdit = { null };
                // Text edit processor which sets the change group and
                // current edit when processing
                final TextEditProcessor processor = new TextEditProcessor(document, copy, TextEdit.NONE) {

                    protected final boolean considerEdit(final TextEdit edit) {
                        final TextEdit originalEdit = (TextEdit) originalMap.get(edit);
                        if (originalEdit != null) {
                            currentEdit[0] = originalEdit;
                            boolean found = false;
                            for (int offset = 0; offset < changedGroups.length && !found; offset++) {
                                final ComposableBufferChangeGroup group = (ComposableBufferChangeGroup) changedGroups[offset];
                                if (group.containsEdit(originalEdit)) {
                                    currentGroup[0] = group;
                                    found = true;
                                }
                            }
                            if (!found)
                                currentGroup[0] = null;
                        } else if (!(edit instanceof MultiTextEdit)) {
                            //$NON-NLS-1$
                            RefactoringCorePlugin.logErrorMessage("Could not find the original of the copied text edit " + edit.toString());
                        }
                        return true;
                    }
                };
                final LinkedList eventUndos = new LinkedList();
                // Listener to record the undos on the document (offsets
                // relative to the document event)
                final IDocumentListener listener = new IDocumentListener() {

                    public final void documentAboutToBeChanged(final DocumentEvent event) {
                        final ComposableUndoEdit edit = new ComposableUndoEdit();
                        edit.setGroup(currentGroup[0]);
                        edit.setOriginal(currentEdit[0]);
                        edit.setUndo(createUndoEdit(document, event.getOffset(), event.getLength(), event.getText()));
                        eventUndos.addFirst(edit);
                    }

                    public final void documentChanged(final DocumentEvent event) {
                    // Do nothing
                    }
                };
                try {
                    // Record undos in LIFO order
                    document.addDocumentListener(listener);
                    processor.performEdits();
                } finally {
                    document.removeDocumentListener(listener);
                }
                compositeUndo.addFirst(eventUndos);
            } finally {
                fCopier = null;
            }
        }
        final IPositionUpdater positionUpdater = new IPositionUpdater() {

            public final void update(final DocumentEvent event) {
                final int eventOffset = event.getOffset();
                final int eventLength = event.getLength();
                final int eventOldEndOffset = eventOffset + eventLength;
                final String eventText = event.getText();
                final int eventNewLength = eventText == null ? 0 : eventText.length();
                final int eventNewEndOffset = eventOffset + eventNewLength;
                final int deltaLength = eventNewLength - eventLength;
                try {
                    final Position[] positions = event.getDocument().getPositions(COMPOSABLE_POSITION_CATEGORY);
                    for (int index = 0; index < positions.length; index++) {
                        final Position position = positions[index];
                        if (position.isDeleted())
                            continue;
                        final int offset = position.getOffset();
                        final int length = position.getLength();
                        final int end = offset + length;
                        if (offset > eventOldEndOffset) {
                            // position comes way after change - shift
                            position.setOffset(offset + deltaLength);
                        } else if (end < eventOffset) {
                        // position comes way before change - leave
                        // alone
                        } else if (offset == eventOffset) {
                        // leave alone, since the edits are overlapping
                        } else if (offset <= eventOffset && end >= eventOldEndOffset) {
                            // event completely internal to the position
                            // -
                            // adjust length
                            position.setLength(length + deltaLength);
                        } else if (offset < eventOffset) {
                            // event extends over end of position - include
                            // the
                            // replacement text into the position
                            position.setLength(eventNewEndOffset - offset);
                        } else if (end > eventOldEndOffset) {
                            // event extends from before position into it -
                            // adjust
                            // offset and length, including the replacement
                            // text into
                            // the position
                            position.setOffset(eventOffset);
                            int deleted = eventOldEndOffset - offset;
                            position.setLength(length - deleted + eventNewLength);
                        } else {
                            // event comprises the position - keep it at the
                            // same
                            // position, but always inside the replacement
                            // text
                            int newOffset = Math.min(offset, eventNewEndOffset);
                            int newEndOffset = Math.min(end, eventNewEndOffset);
                            position.setOffset(newOffset);
                            position.setLength(newEndOffset - newOffset);
                        }
                    }
                } catch (BadPositionCategoryException exception) {
                // ignore and return
                }
            }
        };
        try {
            document.addPositionCategory(COMPOSABLE_POSITION_CATEGORY);
            document.addPositionUpdater(positionUpdater);
            // Apply undos in LIFO order to get to the original document
            // Track the undos of edits which are in change groups to be
            // previewed and insert
            // Undo edits for them (corresponding to the linearized net
            // effect on the original document)
            final LinkedList undoQueue = new LinkedList();
            for (final Iterator outer = compositeUndo.iterator(); outer.hasNext(); ) {
                for (final Iterator inner = ((List) outer.next()).iterator(); inner.hasNext(); ) {
                    final ComposableUndoEdit edit = (ComposableUndoEdit) inner.next();
                    final ReplaceEdit undo = edit.getUndo();
                    final int offset = undo.getOffset();
                    final int length = undo.getLength();
                    final String text = undo.getText();
                    ComposableEditPosition position = new ComposableEditPosition();
                    if (cachedGroups.contains(edit.getGroup())) {
                        if (text == null || text.equals("")) {
                            //$NON-NLS-1$
                            position.offset = offset;
                            if (length != 0) {
                                // Undo is a delete, create final insert
                                // edit
                                position.length = 0;
                                position.setText(edit.getOriginalText());
                            } else
                                //$NON-NLS-1$
                                RefactoringCorePlugin.logErrorMessage("Dubious undo edit found: " + undo.toString());
                        } else if (length == 0) {
                            position.offset = offset;
                            // Undo is an insert, create final delete
                            // edit
                            //$NON-NLS-1$
                            position.setText("");
                            position.length = text.length();
                        } else {
                            // Undo is a replace, create final replace edit
                            position.offset = offset;
                            position.length = length;
                            position.setText(edit.getOriginalText());
                        }
                        document.addPosition(COMPOSABLE_POSITION_CATEGORY, position);
                    }
                    position = new ComposableEditPosition();
                    position.offset = undo.getOffset();
                    position.length = undo.getLength();
                    position.setText(undo.getText());
                    undoQueue.add(position);
                }
                for (final Iterator iterator = undoQueue.iterator(); iterator.hasNext(); ) {
                    final ComposableEditPosition position = (ComposableEditPosition) iterator.next();
                    document.replace(position.offset, position.length, position.getText());
                    iterator.remove();
                }
            }
            // Use a simple non deleting position updater for the range
            final IPositionUpdater markerUpdater = new NonDeletingPositionUpdater(MARKER_POSITION_CATEGORY);
            try {
                final Position[] positions = document.getPositions(COMPOSABLE_POSITION_CATEGORY);
                document.addPositionCategory(MARKER_POSITION_CATEGORY);
                document.addPositionUpdater(markerUpdater);
                document.addPosition(MARKER_POSITION_CATEGORY, range);
                for (int index = 0; index < positions.length; index++) {
                    final ComposableEditPosition position = (ComposableEditPosition) positions[index];
                    //$NON-NLS-1$
                    document.replace(position.offset, position.length, position.getText() != null ? position.getText() : "");
                }
            } catch (BadPositionCategoryException exception) {
                RefactoringCorePlugin.log(exception);
            } finally {
                document.removePositionUpdater(markerUpdater);
                try {
                    document.removePosition(MARKER_POSITION_CATEGORY, range);
                    document.removePositionCategory(MARKER_POSITION_CATEGORY);
                } catch (BadPositionCategoryException exception) {
                // Cannot happen
                }
            }
        } catch (BadPositionCategoryException exception) {
            RefactoringCorePlugin.log(exception);
        } finally {
            document.removePositionUpdater(positionUpdater);
            try {
                document.removePositionCategory(COMPOSABLE_POSITION_CATEGORY);
            } catch (BadPositionCategoryException exception) {
                RefactoringCorePlugin.log(exception);
            }
        }
        return getContent(document, new Region(range.offset, range.length), expand, surround);
    } catch (MalformedTreeException exception) {
        RefactoringCorePlugin.log(exception);
    } catch (BadLocationException exception) {
        RefactoringCorePlugin.log(exception);
    }
    return getPreviewDocument(monitor).get();
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) HashMap(java.util.HashMap) TextEditProcessor(org.eclipse.text.edits.TextEditProcessor) Document(org.eclipse.jface.text.Document) IDocument(org.eclipse.jface.text.IDocument) TextEditCopier(org.eclipse.text.edits.TextEditCopier) NonDeletingPositionUpdater(org.eclipse.ltk.internal.core.refactoring.NonDeletingPositionUpdater) Iterator(java.util.Iterator) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) HashSet(java.util.HashSet) Position(org.eclipse.jface.text.Position) IDocumentListener(org.eclipse.jface.text.IDocumentListener) MalformedTreeException(org.eclipse.text.edits.MalformedTreeException) DocumentEvent(org.eclipse.jface.text.DocumentEvent) LinkedList(java.util.LinkedList) IPositionUpdater(org.eclipse.jface.text.IPositionUpdater) MultiTextEdit(org.eclipse.text.edits.MultiTextEdit) TextEdit(org.eclipse.text.edits.TextEdit) BadPositionCategoryException(org.eclipse.jface.text.BadPositionCategoryException) ReplaceEdit(org.eclipse.text.edits.ReplaceEdit) IRegion(org.eclipse.jface.text.IRegion) Region(org.eclipse.jface.text.Region) Map(java.util.Map) HashMap(java.util.HashMap) IDocument(org.eclipse.jface.text.IDocument) MultiTextEdit(org.eclipse.text.edits.MultiTextEdit) BadLocationException(org.eclipse.jface.text.BadLocationException)

Example 7 with MultiTextEdit

use of org.eclipse.text.edits.MultiTextEdit in project che by eclipse.

the class CUCorrectionProposal method createTextChange.

/**
	 * Creates the text change for this proposal.
	 * This method is only called once and only when no text change has been passed in
	 * {@link #CUCorrectionProposal(String, ICompilationUnit, TextChange, int, Image)}.
	 *
	 * @return the created text change
	 * @throws CoreException if the creation of the text change failed
	 */
protected TextChange createTextChange() throws CoreException {
    ICompilationUnit cu = getCompilationUnit();
    String name = getName();
    TextChange change;
    if (!cu.getResource().exists()) {
        String source;
        try {
            source = cu.getSource();
        } catch (JavaModelException e) {
            JavaPlugin.log(e);
            // empty
            source = new String();
        }
        Document document = new Document(source);
        document.setInitialLineDelimiter(StubUtility.getLineDelimiterUsed(cu));
        change = new DocumentChange(name, document);
    } else {
        CompilationUnitChange cuChange = new CompilationUnitChange(name, cu);
        cuChange.setSaveMode(TextFileChange.LEAVE_DIRTY);
        change = cuChange;
    }
    TextEdit rootEdit = new MultiTextEdit();
    change.setEdit(rootEdit);
    // initialize text change
    IDocument document = change.getCurrentDocument(new NullProgressMonitor());
    addEdits(document, rootEdit);
    return change;
}
Also used : ICompilationUnit(org.eclipse.jdt.core.ICompilationUnit) NullProgressMonitor(org.eclipse.core.runtime.NullProgressMonitor) JavaModelException(org.eclipse.jdt.core.JavaModelException) MultiTextEdit(org.eclipse.text.edits.MultiTextEdit) TextEdit(org.eclipse.text.edits.TextEdit) TextChange(org.eclipse.ltk.core.refactoring.TextChange) Document(org.eclipse.jface.text.Document) IDocument(org.eclipse.jface.text.IDocument) DocumentChange(org.eclipse.ltk.core.refactoring.DocumentChange) MultiTextEdit(org.eclipse.text.edits.MultiTextEdit) IDocument(org.eclipse.jface.text.IDocument) CompilationUnitChange(org.eclipse.jdt.core.refactoring.CompilationUnitChange)

Example 8 with MultiTextEdit

use of org.eclipse.text.edits.MultiTextEdit in project che by eclipse.

the class TextChange method createTextEditProcessor.

private TextEditProcessor createTextEditProcessor(IDocument document, int flags, boolean preview) {
    if (fEdit == null)
        return new TextEditProcessor(document, new MultiTextEdit(0, 0), flags);
    List excludes = new ArrayList(0);
    TextEditBasedChangeGroup[] groups = getChangeGroups();
    for (int index = 0; index < groups.length; index++) {
        TextEditBasedChangeGroup edit = groups[index];
        if (!edit.isEnabled()) {
            excludes.addAll(Arrays.asList(edit.getTextEditGroup().getTextEdits()));
        }
    }
    if (preview) {
        fCopier = new TextEditCopier(fEdit);
        TextEdit copiedEdit = fCopier.perform();
        boolean keep = getKeepPreviewEdits();
        if (keep)
            flags = flags | TextEdit.UPDATE_REGIONS;
        LocalTextEditProcessor result = new LocalTextEditProcessor(document, copiedEdit, flags);
        result.setExcludes(mapEdits((TextEdit[]) excludes.toArray(new TextEdit[excludes.size()]), fCopier));
        if (!keep)
            fCopier = null;
        return result;
    } else {
        LocalTextEditProcessor result = new LocalTextEditProcessor(document, fEdit, flags | TextEdit.UPDATE_REGIONS);
        result.setExcludes((TextEdit[]) excludes.toArray(new TextEdit[excludes.size()]));
        return result;
    }
}
Also used : TextEditCopier(org.eclipse.text.edits.TextEditCopier) TextEditProcessor(org.eclipse.text.edits.TextEditProcessor) MultiTextEdit(org.eclipse.text.edits.MultiTextEdit) TextEdit(org.eclipse.text.edits.TextEdit) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) MultiTextEdit(org.eclipse.text.edits.MultiTextEdit)

Example 9 with MultiTextEdit

use of org.eclipse.text.edits.MultiTextEdit in project che by eclipse.

the class TextChangeCompatibility method addTextEdit.

public static void addTextEdit(TextChange change, String name, TextEdit edit) throws MalformedTreeException {
    Assert.isNotNull(change);
    Assert.isNotNull(name);
    Assert.isNotNull(edit);
    TextEdit root = change.getEdit();
    if (root == null) {
        root = new MultiTextEdit();
        change.setEdit(root);
    }
    insert(root, edit);
    change.addTextEditGroup(new TextEditGroup(name, edit));
}
Also used : MultiTextEdit(org.eclipse.text.edits.MultiTextEdit) TextEdit(org.eclipse.text.edits.TextEdit) TextEditGroup(org.eclipse.text.edits.TextEditGroup) CategorizedTextEditGroup(org.eclipse.ltk.core.refactoring.CategorizedTextEditGroup) MultiTextEdit(org.eclipse.text.edits.MultiTextEdit)

Example 10 with MultiTextEdit

use of org.eclipse.text.edits.MultiTextEdit in project che by eclipse.

the class SurroundWithTryCatchRefactoring method createChange.

/* non Java-doc
	 * @see IRefactoring#createChange(IProgressMonitor)
	 */
@Override
public Change createChange(IProgressMonitor pm) throws CoreException {
    //$NON-NLS-1$
    final String NN = "";
    if (pm == null)
        pm = new NullProgressMonitor();
    pm.beginTask(NN, 2);
    try {
        final CompilationUnitChange result = new CompilationUnitChange(getName(), fCUnit);
        if (fLeaveDirty)
            result.setSaveMode(TextFileChange.LEAVE_DIRTY);
        MultiTextEdit root = new MultiTextEdit();
        result.setEdit(root);
        fRewriter = ASTRewrite.create(fAnalyzer.getEnclosingBodyDeclaration().getAST());
        fRewriter.setTargetSourceRangeComputer(new SelectionAwareSourceRangeComputer(fAnalyzer.getSelectedNodes(), fCUnit.getBuffer(), fSelection.getOffset(), fSelection.getLength()));
        fImportRewrite = StubUtility.createImportRewrite(fRootNode, true);
        fLinkedProposalModel = new LinkedProposalModel();
        fScope = CodeScopeBuilder.perform(fAnalyzer.getEnclosingBodyDeclaration(), fSelection).findScope(fSelection.getOffset(), fSelection.getLength());
        fScope.setCursor(fSelection.getOffset());
        fSelectedNodes = fAnalyzer.getSelectedNodes();
        createTryCatchStatement(fCUnit.getBuffer(), fCUnit.findRecommendedLineSeparator());
        if (fImportRewrite.hasRecordedChanges()) {
            TextEdit edit = fImportRewrite.rewriteImports(null);
            root.addChild(edit);
            result.addTextEditGroup(new TextEditGroup(NN, new TextEdit[] { edit }));
        }
        TextEdit change = fRewriter.rewriteAST();
        root.addChild(change);
        result.addTextEditGroup(new TextEditGroup(NN, new TextEdit[] { change }));
        return result;
    } finally {
        pm.done();
    }
}
Also used : SelectionAwareSourceRangeComputer(org.eclipse.jdt.internal.corext.refactoring.util.SelectionAwareSourceRangeComputer) NullProgressMonitor(org.eclipse.core.runtime.NullProgressMonitor) LinkedProposalModel(org.eclipse.jdt.internal.corext.fix.LinkedProposalModel) MultiTextEdit(org.eclipse.text.edits.MultiTextEdit) TextEdit(org.eclipse.text.edits.TextEdit) TextEditGroup(org.eclipse.text.edits.TextEditGroup) MultiTextEdit(org.eclipse.text.edits.MultiTextEdit) CompilationUnitChange(org.eclipse.jdt.core.refactoring.CompilationUnitChange)

Aggregations

MultiTextEdit (org.eclipse.text.edits.MultiTextEdit)51 TextEdit (org.eclipse.text.edits.TextEdit)33 Test (org.junit.Test)18 IDocument (org.eclipse.jface.text.IDocument)13 ReplaceEdit (org.eclipse.text.edits.ReplaceEdit)13 Document (org.eclipse.jface.text.Document)11 TextEditGroup (org.eclipse.text.edits.TextEditGroup)10 CompilationUnitChange (org.eclipse.jdt.core.refactoring.CompilationUnitChange)9 DeleteEdit (org.eclipse.text.edits.DeleteEdit)7 ICompilationUnit (org.eclipse.jdt.core.ICompilationUnit)6 ArrayList (java.util.ArrayList)5 MalformedTreeException (org.eclipse.text.edits.MalformedTreeException)5 HashSet (java.util.HashSet)4 List (java.util.List)4 NullProgressMonitor (org.eclipse.core.runtime.NullProgressMonitor)4 OperationCanceledException (org.eclipse.core.runtime.OperationCanceledException)4 ASTNode (org.eclipse.jdt.core.dom.ASTNode)4 TextChange (org.eclipse.ltk.core.refactoring.TextChange)4 CopySourceEdit (org.eclipse.text.edits.CopySourceEdit)4 TextEditCopier (org.eclipse.text.edits.TextEditCopier)4