use of org.eclipse.text.edits.TextEditProcessor in project che by eclipse.
the class SourceProvider method getCodeBlocks.
public String[] getCodeBlocks(CallContext context, ImportRewrite importRewrite) throws CoreException {
final ASTRewrite rewriter = ASTRewrite.create(fDeclaration.getAST());
replaceParameterWithExpression(rewriter, context, importRewrite);
updateImplicitReceivers(rewriter, context);
makeNamesUnique(rewriter, context.scope);
updateTypeReferences(rewriter, context);
updateStaticReferences(rewriter, context);
updateTypeVariables(rewriter, context);
updateMethodTypeVariable(rewriter, context);
List<IRegion> ranges = null;
if (hasReturnValue()) {
if (context.callMode == ASTNode.RETURN_STATEMENT) {
ranges = getStatementRanges();
} else {
ranges = getExpressionRanges();
}
} else {
ASTNode last = getLastStatement();
if (last != null && last.getNodeType() == ASTNode.RETURN_STATEMENT) {
ranges = getReturnStatementRanges();
} else {
ranges = getStatementRanges();
}
}
final TextEdit dummy = rewriter.rewriteAST(fDocument, fTypeRoot.getJavaProject().getOptions(true));
int size = ranges.size();
RangeMarker[] markers = new RangeMarker[size];
for (int i = 0; i < markers.length; i++) {
IRegion range = ranges.get(i);
markers[i] = new RangeMarker(range.getOffset(), range.getLength());
}
int split;
if (size <= 1) {
split = Integer.MAX_VALUE;
} else {
IRegion region = ranges.get(0);
split = region.getOffset() + region.getLength();
}
TextEdit[] edits = dummy.removeChildren();
for (int i = 0; i < edits.length; i++) {
TextEdit edit = edits[i];
int pos = edit.getOffset() >= split ? 1 : 0;
markers[pos].addChild(edit);
}
MultiTextEdit root = new MultiTextEdit(0, fDocument.getLength());
root.addChildren(markers);
try {
TextEditProcessor processor = new TextEditProcessor(fDocument, root, TextEdit.CREATE_UNDO | TextEdit.UPDATE_REGIONS);
UndoEdit undo = processor.performEdits();
String[] result = getBlocks(markers);
// It is faster to undo the changes than coping the buffer over and over again.
processor = new TextEditProcessor(fDocument, undo, TextEdit.UPDATE_REGIONS);
processor.performEdits();
return result;
} catch (MalformedTreeException exception) {
JavaPlugin.log(exception);
} catch (BadLocationException exception) {
JavaPlugin.log(exception);
}
return new String[] {};
}
use of org.eclipse.text.edits.TextEditProcessor 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();
}
use of org.eclipse.text.edits.TextEditProcessor 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;
}
}
use of org.eclipse.text.edits.TextEditProcessor in project che by eclipse.
the class TextChange method createTextEditProcessor.
private TextEditProcessor createTextEditProcessor(IDocument document, int flags, TextEditBasedChangeGroup[] changes) {
if (fEdit == null)
return new TextEditProcessor(document, new MultiTextEdit(0, 0), flags);
List includes = new ArrayList(0);
for (int c = 0; c < changes.length; c++) {
TextEditBasedChangeGroup change = changes[c];
Assert.isTrue(change.getTextEditChange() == this);
if (change.isEnabled()) {
includes.addAll(Arrays.asList(change.getTextEditGroup().getTextEdits()));
}
}
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.setIncludes(mapEdits((TextEdit[]) includes.toArray(new TextEdit[includes.size()]), fCopier));
if (!keep)
fCopier = null;
return result;
}
use of org.eclipse.text.edits.TextEditProcessor in project che by eclipse.
the class TextChange method performEdits.
/**
* Executes the text edits on the given document.
* Subclasses that override this method should call <code>super.performEdits(document)</code>.
*
* @param document the document
* @return an object representing the undo of the executed edits
* @exception MalformedTreeException is thrown if the edit tree isn't
* in a valid state. This exception is thrown before any edit is executed.
* So the document is still in its original state.
* @exception BadLocationException is thrown if one of the edits in the
* tree can't be executed. The state of the document is undefined if this
* exception is thrown.
* @since 3.5
*/
protected UndoEdit performEdits(IDocument document) throws BadLocationException, MalformedTreeException {
DocumentRewriteSession session = null;
try {
if (document instanceof IDocumentExtension4) {
session = ((IDocumentExtension4) document).startRewriteSession(DocumentRewriteSessionType.UNRESTRICTED);
}
LinkedModeModel.closeAllModels(document);
TextEditProcessor processor = createTextEditProcessor(document, TextEdit.CREATE_UNDO, false);
return processor.performEdits();
} finally {
if (session != null) {
((IDocumentExtension4) document).stopRewriteSession(session);
}
}
}
Aggregations