blob: f0d9358dc0b03bc679b2d504cf98a20572e758cd [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.core.dom.rewrite;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import org.eclipse.text.edits.CopySourceEdit;
import org.eclipse.text.edits.CopyTargetEdit;
import org.eclipse.text.edits.DeleteEdit;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.MoveSourceEdit;
import org.eclipse.text.edits.MoveTargetEdit;
import org.eclipse.text.edits.RangeMarker;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.text.edits.TextEditGroup;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.text.Assert;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jdt.core.ToolFactory;
import org.eclipse.jdt.core.compiler.IScanner;
import org.eclipse.jdt.core.compiler.ITerminalSymbols;
import org.eclipse.jdt.core.dom.*;
import org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteFormatter.BlockContext;
import org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteFormatter.NodeMarker;
import org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteFormatter.Prefix;
import org.eclipse.jdt.internal.core.dom.rewrite.NodeInfoStore.CopyPlaceholderData;
import org.eclipse.jdt.internal.core.dom.rewrite.NodeInfoStore.StringPlaceholderData;
import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.CopySourceInfo;
import org.eclipse.jdt.internal.core.util.Util;
/**
* Infrastructure to support code modifications. Existing code must stay untouched, new code
* added with correct formatting, moved code left with the users formattings / comments.
* Idea:
* - Get the AST for existing code
* - Describe changes
* - This visitor analyses the changes or annotations and generates text edits
* (text manipulation API) that describe the required code changes. See test
* cases in org.eclipse.jdt.ui.tests / package org.eclipse.jdt.ui.tests.
* astrewrite for examples
*/
public final class ASTRewriteAnalyzer extends ASTVisitor {
TextEdit fCurrentEdit;
private TokenScanner fTokenScanner; // shared scanner
private Map fSourceCopyInfoToEdit;
private Stack fSourceCopyEndNodes;
final IDocument fDocument; // used from inner classes
private final ASTRewriteFormatter fFormatter;
RewriteEventStore fEventStore;
private NodeInfoStore fNodeInfos;
private CompilationUnit fAstRoot;
/*
* Constructor for ASTRewriteAnalyzer.
*/
public ASTRewriteAnalyzer(IDocument document, CompilationUnit astRoot, TextEdit rootEdit, RewriteEventStore eventStore, NodeInfoStore nodeInfos, Map options) {
fAstRoot= astRoot;
fEventStore= eventStore;
fDocument= document;
fNodeInfos= nodeInfos;
fTokenScanner= null;
fCurrentEdit= rootEdit;
fSourceCopyInfoToEdit= new IdentityHashMap();
fSourceCopyEndNodes= new Stack();
fFormatter= new ASTRewriteFormatter(nodeInfos, eventStore, options, getLineDelimiter());
}
public final TokenScanner getScanner() {
if (fTokenScanner == null) {
IScanner scanner= ToolFactory.createScanner(true, false, false, false);
scanner.setSource(fDocument.get().toCharArray());
fTokenScanner= new TokenScanner(scanner, fDocument);
}
return fTokenScanner;
}
final int getExtendedOffset(ASTNode node) {
return fAstRoot.getExtendedStartPosition(node);
}
final int getExtendedLength(ASTNode node) {
return fAstRoot.getExtendedLength(node);
}
final int getExtendedEnd(ASTNode node) {
return fAstRoot.getExtendedStartPosition(node) + fAstRoot.getExtendedLength(node);
}
final TextEdit getCopySourceEdit(CopySourceInfo info) {
TextEdit edit= (TextEdit) fSourceCopyInfoToEdit.get(info);
if (edit == null) {
int start= getExtendedOffset(info.getStartNode());
int end= getExtendedEnd(info.getEndNode());
if (info.isMove) {
MoveSourceEdit moveSourceEdit= new MoveSourceEdit(start, end - start);
moveSourceEdit.setTargetEdit(new MoveTargetEdit(0));
edit= moveSourceEdit;
} else {
CopySourceEdit copySourceEdit= new CopySourceEdit(start, end - start);
copySourceEdit.setTargetEdit(new CopyTargetEdit(0));
edit= copySourceEdit;
}
fSourceCopyInfoToEdit.put(info, edit);
}
return edit;
}
private final int getChangeKind(ASTNode node, StructuralPropertyDescriptor property) {
RewriteEvent event= getEvent(node, property);
if (event != null) {
return event.getChangeKind();
}
return RewriteEvent.UNCHANGED;
}
private final boolean hasChildrenChanges(ASTNode node) {
return fEventStore.hasChangedProperties(node);
}
private final boolean isChanged(ASTNode node, StructuralPropertyDescriptor property) {
RewriteEvent event= getEvent(node, property);
if (event != null) {
return event.getChangeKind() != RewriteEvent.UNCHANGED;
}
return false;
}
private final boolean isCollapsed(ASTNode node) {
return fNodeInfos.isCollapsed(node);
}
final boolean isInsertBoundToPrevious(ASTNode node) {
return fEventStore.isInsertBoundToPrevious(node);
}
private final TextEditGroup getEditGroup(ASTNode parent, StructuralPropertyDescriptor property) {
RewriteEvent event= getEvent(parent, property);
if (event != null) {
return getEditGroup(event);
}
return null;
}
final RewriteEvent getEvent(ASTNode parent, StructuralPropertyDescriptor property) {
return fEventStore.getEvent(parent, property);
}
final TextEditGroup getEditGroup(RewriteEvent change) {
return fEventStore.getEventEditGroup(change);
}
private final Object getOriginalValue(ASTNode parent, StructuralPropertyDescriptor property) {
return fEventStore.getOriginalValue(parent, property);
}
private final Object getNewValue(ASTNode parent, StructuralPropertyDescriptor property) {
return fEventStore.getNewValue(parent, property);
}
final void addEdit(TextEdit edit) {
fCurrentEdit.addChild(edit);
}
final String getLineDelimiter() {
return TextUtilities.getDefaultLineDelimiter(fDocument);
}
final void doTextInsert(int offset, String insertString, TextEditGroup editGroup) {
if (insertString.length() > 0) {
TextEdit edit= new InsertEdit(offset, insertString);
addEdit(edit);
if (editGroup != null) {
addEditGroup(editGroup, edit);
}
}
}
final void addEditGroup(TextEditGroup editGroup, TextEdit edit) {
editGroup.addTextEdit(edit);
}
final TextEdit doTextRemove(int offset, int len, TextEditGroup editGroup) {
if (len == 0) {
return null;
}
TextEdit edit= new DeleteEdit(offset, len);
addEdit(edit);
if (editGroup != null) {
addEditGroup(editGroup, edit);
}
return edit;
}
final void doTextRemoveAndVisit(int offset, int len, ASTNode node, TextEditGroup editGroup) {
TextEdit edit= doTextRemove(offset, len, editGroup);
if (edit != null) {
fCurrentEdit= edit;
doVisit(node);
fCurrentEdit= edit.getParent();
} else {
doVisit(node);
}
}
final int doVisit(ASTNode node) {
node.accept(this);
return node.getStartPosition() + node.getLength();
}
private final int doVisit(ASTNode parent, StructuralPropertyDescriptor property, int offset) {
Object node= getOriginalValue(parent, property);
if (property.isChildProperty() && node != null) {
return doVisit((ASTNode) node);
} else if (property.isChildListProperty()) {
boolean hasRangeCopySources= fEventStore.hasRangeCopySources(parent, property);
return doVisitList((List) node, offset, hasRangeCopySources);
}
return offset;
}
private int doVisitList(List list, int offset, boolean hasRangeCopySources) {
if (hasRangeCopySources) {
// list with copy source ranges
Stack nodeRangeEndStack= new Stack();
int endPos= offset;
for (Iterator iter= list.iterator(); iter.hasNext();) {
ASTNode curr= ((ASTNode) iter.next());
doCopySourcePreVisit(fEventStore.getRangeCopySources(curr), nodeRangeEndStack);
endPos= doVisit(curr);
doCopySourcePostVisit(curr, nodeRangeEndStack);
}
return endPos;
} else {
int endPos= offset;
for (Iterator iter= list.iterator(); iter.hasNext();) {
ASTNode curr= ((ASTNode) iter.next());
endPos= doVisit(curr);
}
return endPos;
}
}
private final boolean doVisitUnchangedChildren(ASTNode parent) {
List properties= parent.structuralPropertiesForType();
for (int i= 0; i < properties.size(); i++) {
StructuralPropertyDescriptor property= (StructuralPropertyDescriptor) properties.get(i);
if (property.isChildProperty()) {
ASTNode child= (ASTNode) parent.getStructuralProperty(property);
if (child != null) {
doVisit(child);
}
} else if (property.isChildListProperty()) {
List list= (List) parent.getStructuralProperty(property);
boolean hasRangeCopySources= fEventStore.hasRangeCopySources(parent, property);
doVisitList(list, 0, hasRangeCopySources);
}
}
return false;
}
private final void doTextReplace(int offset, int len, String insertString, TextEditGroup editGroup) {
if (len > 0 || insertString.length() > 0) {
TextEdit edit= new ReplaceEdit(offset, len, insertString);
addEdit(edit);
if (editGroup != null) {
addEditGroup(editGroup, edit);
}
}
}
private final TextEdit doTextCopy(TextEdit sourceEdit, int destOffset, int sourceIndentLevel, String destIndentString, int tabWidth, TextEditGroup editGroup) {
TextEdit targetEdit;
if (sourceEdit instanceof MoveSourceEdit) {
MoveSourceEdit moveEdit= (MoveSourceEdit) sourceEdit;
moveEdit.setSourceModifier(SourceModifier.createMoveModifier(sourceIndentLevel, destIndentString, tabWidth));
targetEdit= new MoveTargetEdit(destOffset, moveEdit);
addEdit(targetEdit);
} else {
CopySourceEdit copyEdit= (CopySourceEdit) sourceEdit;
copyEdit.setSourceModifier(SourceModifier.createMoveModifier(sourceIndentLevel, destIndentString, tabWidth));
targetEdit= new CopyTargetEdit(destOffset, copyEdit);
addEdit(targetEdit);
}
if (editGroup != null) {
addEditGroup(editGroup, targetEdit);
addEditGroup(editGroup, targetEdit);
}
return targetEdit;
}
private void changeNotSupported(ASTNode node) {
Assert.isTrue(false, "Change not supported in " + node.getClass().getName()); //$NON-NLS-1$
}
private class ListRewriter {
protected String fContantSeparator;
protected int fStartPos;
protected RewriteEvent[] fList;
private Stack fCopyRangeEndStack;
protected final ASTNode getOriginalNode(int index) {
return (ASTNode) fList[index].getOriginalValue();
}
protected String getSeparatorString(int nodeIndex) {
return fContantSeparator;
}
protected int getInitialIndent() {
return getIndent(fStartPos);
}
protected int getNodeIndent(int nodeIndex) {
ASTNode node= getOriginalNode(nodeIndex);
if (node == null) {
for (int i= nodeIndex - 1; i>= 0; i--) {
ASTNode curr= getOriginalNode(i);
if (curr != null) {
return getIndent(curr.getStartPosition());
}
}
return getInitialIndent();
}
return getIndent(node.getStartPosition());
}
protected int getStartOfNextNode(int nextIndex, int defaultPos) {
for (int i= nextIndex; i < fList.length; i++) {
RewriteEvent elem= fList[i];
if (elem.getChangeKind() != RewriteEvent.INSERTED) {
ASTNode node= (ASTNode) elem.getOriginalValue();
return getExtendedOffset(node);
}
}
return defaultPos;
}
protected int getEndOfNode(ASTNode node) {
return getExtendedEnd(node);
}
public final int rewriteList(ASTNode parent, StructuralPropertyDescriptor property, int startPos, String keyword, String separator) {
fContantSeparator= separator;
return rewriteList(parent, property, startPos, keyword);
}
private boolean insertAfterSeparator(ASTNode node) {
return !isInsertBoundToPrevious(node);
}
public final int rewriteList(ASTNode parent, StructuralPropertyDescriptor property, int startPos, String keyword) {
fStartPos= startPos;
fList= getEvent(parent, property).getChildren();
initCopyRangeChecks(parent, property);
int total= fList.length;
if (total == 0) {
return fStartPos;
}
int currPos= -1;
int lastNonInsert= -1;
int lastNonDelete= -1;
for (int i= 0; i < total; i++) {
int currMark= fList[i].getChangeKind();
if (currMark != RewriteEvent.INSERTED) {
lastNonInsert= i;
if (currPos == -1) {
ASTNode elem= (ASTNode) fList[i].getOriginalValue();
currPos= getExtendedOffset(elem);
}
}
if (currMark != RewriteEvent.REMOVED) {
lastNonDelete= i;
}
}
if (currPos == -1) { // only inserts
if (keyword.length() > 0) { // creating a new list -> insert keyword first (e.g. " throws ")
TextEditGroup editGroup= getEditGroup(fList[0]); // first node is insert
doTextInsert(startPos, keyword, editGroup);
}
currPos= startPos;
}
if (lastNonDelete == -1) { // all removed, set back to start so the keyword is removed as well
currPos= startPos;
}
int prevEnd= currPos;
final int NONE= 0, NEW= 1, EXISTING= 2;
int separatorState= NEW;
for (int i= 0; i < total; i++) {
RewriteEvent currEvent= fList[i];
int currMark= currEvent.getChangeKind();
int nextIndex= i + 1;
if (currMark == RewriteEvent.INSERTED) {
TextEditGroup editGroup= getEditGroup(currEvent);
ASTNode node= (ASTNode) currEvent.getNewValue();
if (separatorState == NONE) { // element after last existing element (but not first)
doTextInsert(currPos, getSeparatorString(i - 1), editGroup); // insert separator
separatorState= NEW;
}
if (separatorState == NEW || insertAfterSeparator(node)) {
doTextInsert(currPos, node, getNodeIndent(i), true, editGroup); // insert node
separatorState= NEW;
if (i != lastNonDelete) {
if (fList[nextIndex].getChangeKind() != RewriteEvent.INSERTED) {
doTextInsert(currPos, getSeparatorString(i), editGroup); // insert separator
} else {
separatorState= NONE;
}
}
} else { // EXISTING && insert before separator
doTextInsert(prevEnd, getSeparatorString(i - 1), editGroup);
doTextInsert(prevEnd, node, getNodeIndent(i), true, editGroup);
}
} else if (currMark == RewriteEvent.REMOVED) {
ASTNode node= (ASTNode) currEvent.getOriginalValue();
TextEditGroup editGroup= getEditGroup(currEvent);
int currEnd= getEndOfNode(node);
if (i > lastNonDelete && separatorState == EXISTING) {
// is last, remove previous separator: split delete to allow range copies
doTextRemove(prevEnd, currPos - prevEnd, editGroup); // remove separator
checkForRangeStart(node);
doTextRemoveAndVisit(currPos, currEnd - currPos, node, editGroup); // remove node
checkForRangeEnd(node);
currPos= currEnd;
prevEnd= currEnd;
} else {
// remove element and next separator
int end= getStartOfNextNode(nextIndex, currEnd); // start of next
checkForRangeStart(node);
doTextRemoveAndVisit(currPos, currEnd - currPos, node, getEditGroup(currEvent)); // remove node
checkForRangeEnd(node);
doTextRemove(currEnd, end - currEnd, editGroup); // remove separator
currPos= end;
prevEnd= currEnd;
separatorState= NEW;
}
} else { // replaced or unchanged
if (currMark == RewriteEvent.REPLACED) {
ASTNode node= (ASTNode) currEvent.getOriginalValue();
int currEnd= getEndOfNode(node);
TextEditGroup editGroup= getEditGroup(currEvent);
ASTNode changed= (ASTNode) currEvent.getNewValue();
checkForRangeStart(node);
doTextRemoveAndVisit(currPos, currEnd - currPos, node, editGroup);
doTextInsert(currPos, changed, getNodeIndent(i), true, editGroup);
checkForRangeEnd(node);
prevEnd= currEnd;
} else { // is unchanged
ASTNode node= (ASTNode) currEvent.getOriginalValue();
checkForRangeStart(node);
doVisit(node);
checkForRangeEnd(node);
}
if (i == lastNonInsert) { // last node or next nodes are all inserts
separatorState= NONE;
if (currMark == RewriteEvent.UNCHANGED) {
ASTNode node= (ASTNode) currEvent.getOriginalValue();
prevEnd= getEndOfNode(node);
}
currPos= prevEnd;
} else if (fList[nextIndex].getChangeKind() != RewriteEvent.UNCHANGED) {
// no updates needed while nodes are unchanged
if (currMark == RewriteEvent.UNCHANGED) {
ASTNode node= (ASTNode) currEvent.getOriginalValue();
prevEnd= getEndOfNode(node);
}
currPos= getStartOfNextNode(nextIndex, prevEnd); // start of next
separatorState= EXISTING;
}
}
}
return currPos;
}
private void initCopyRangeChecks(ASTNode parent, StructuralPropertyDescriptor property) {
if (fEventStore.hasRangeCopySources(parent, property)) {
fCopyRangeEndStack= new Stack();
}
}
private void checkForRangeStart(ASTNode node) {
if (fCopyRangeEndStack != null) {
doCopySourcePreVisit(fEventStore.getRangeCopySources(node), fCopyRangeEndStack);
}
}
private void checkForRangeEnd(ASTNode node) {
if (fCopyRangeEndStack != null) {
doCopySourcePostVisit(node, fCopyRangeEndStack);
}
}
}
private int rewriteRequiredNode(ASTNode parent, StructuralPropertyDescriptor property) {
RewriteEvent event= getEvent(parent, property);
if (event != null && event.getChangeKind() == RewriteEvent.REPLACED) {
ASTNode node= (ASTNode) event.getOriginalValue();
TextEditGroup editGroup= getEditGroup(event);
int offset= getExtendedOffset(node);
int length= getExtendedLength(node);
doTextRemoveAndVisit(offset, length, node, editGroup);
doTextInsert(offset, (ASTNode) event.getNewValue(), getIndent(offset), true, editGroup);
return offset + length;
}
return doVisit(parent, property, 0);
}
private int rewriteNode(ASTNode parent, StructuralPropertyDescriptor property, int offset, Prefix prefix) {
RewriteEvent event= getEvent(parent, property);
if (event != null) {
switch (event.getChangeKind()) {
case RewriteEvent.INSERTED: {
ASTNode node= (ASTNode) event.getNewValue();
TextEditGroup editGroup= getEditGroup(event);
int indent= getIndent(offset);
doTextInsert(offset, prefix.getPrefix(indent, getLineDelimiter()), editGroup);
doTextInsert(offset, node, indent, true, editGroup);
return offset;
}
case RewriteEvent.REMOVED: {
ASTNode node= (ASTNode) event.getOriginalValue();
TextEditGroup editGroup= getEditGroup(event);
int nodeEnd= getExtendedEnd(node);
// if there is a prefix, remove the prefix as well
int len= nodeEnd - offset;
doTextRemoveAndVisit(offset, len, node, editGroup);
return nodeEnd;
}
case RewriteEvent.REPLACED: {
ASTNode node= (ASTNode) event.getOriginalValue();
TextEditGroup editGroup= getEditGroup(event);
int nodeOffset= getExtendedOffset(node);
int nodeLen= getExtendedLength(node);
doTextRemoveAndVisit(nodeOffset, nodeLen, node, editGroup);
doTextInsert(nodeOffset, (ASTNode) event.getNewValue(), getIndent(offset), true, editGroup);
return nodeOffset + nodeLen;
}
}
}
return doVisit(parent, property, offset);
}
final String getIndentString(int pos) {
try {
IRegion line= fDocument.getLineInformationOfOffset(pos);
String str= fDocument.get(line.getOffset(), line.getLength());
return Strings.getIndentString(str, CodeFormatterUtil.getTabWidth());
} catch (BadLocationException e) {
return ""; //$NON-NLS-1$
}
}
private int rewriteJavadoc(ASTNode node, StructuralPropertyDescriptor property) {
int pos= rewriteNode(node, property, node.getStartPosition(), ASTRewriteFormatter.NONE);
int changeKind= getChangeKind(node, property);
if (changeKind == RewriteEvent.INSERTED) {
String indent= getLineDelimiter() + getIndentString(pos);
doTextInsert(pos, indent, getEditGroup(node, property));
} else if (changeKind == RewriteEvent.REMOVED) {
try {
getScanner().readNext(pos, false);
doTextRemove(pos, getScanner().getCurrentStartOffset() - pos, getEditGroup(node, property));
pos= getScanner().getCurrentStartOffset();
} catch (CoreException e) {
handleException(e);
}
}
return pos;
}
/*
* endpos can be -1 -> use the end pos of the body
*/
private int rewriteBodyNode(ASTNode parent, StructuralPropertyDescriptor property, int offset, int endPos, int indent, BlockContext context) {
RewriteEvent event= getEvent(parent, property);
if (event != null) {
switch (event.getChangeKind()) {
case RewriteEvent.INSERTED: {
ASTNode node= (ASTNode) event.getNewValue();
TextEditGroup editGroup= getEditGroup(event);
String[] strings= context.getPrefixAndSuffix(indent, getLineDelimiter(), node, fEventStore);
doTextInsert(offset, strings[0], editGroup);
doTextInsert(offset, node, indent, true, editGroup);
doTextInsert(offset, strings[1], editGroup);
return offset;
}
case RewriteEvent.REMOVED: {
ASTNode node= (ASTNode) event.getOriginalValue();
if (endPos == -1) {
endPos= getExtendedEnd(node);
}
TextEditGroup editGroup= getEditGroup(event);
// if there is a prefix, remove the prefix as well
int len= endPos - offset;
doTextRemoveAndVisit(offset, len, node, editGroup);
return endPos;
}
case RewriteEvent.REPLACED: {
ASTNode node= (ASTNode) event.getOriginalValue();
if (endPos == -1) {
endPos= getExtendedEnd(node);
}
TextEditGroup editGroup= getEditGroup(event);
int nodeLen= endPos - offset;
ASTNode replacingNode= (ASTNode) event.getNewValue();
String[] strings= context.getPrefixAndSuffix(indent, getLineDelimiter(), replacingNode, fEventStore);
doTextRemoveAndVisit(offset, nodeLen, node, editGroup);
String prefix= strings[0];
doTextInsert(offset, prefix, editGroup);
String lineInPrefix= getCurrentLine(prefix, prefix.length());
if (prefix.length() != lineInPrefix.length()) {
// prefix contains a new line: update the indent to the one used in the prefix
indent= Strings.computeIndent(lineInPrefix, CodeFormatterUtil.getTabWidth());
}
doTextInsert(offset, replacingNode, indent, true, editGroup);
doTextInsert(offset, strings[1], editGroup);
return endPos;
}
}
}
return doVisit(parent, property, offset);
}
private int rewriteOptionalQualifier(ASTNode parent, StructuralPropertyDescriptor property, int startPos) {
RewriteEvent event= getEvent(parent, property);
if (event != null) {
switch (event.getChangeKind()) {
case RewriteEvent.INSERTED: {
ASTNode node= (ASTNode) event.getNewValue();
TextEditGroup editGroup= getEditGroup(event);
doTextInsert(startPos, node, getIndent(startPos), true, editGroup);
doTextInsert(startPos, ".", editGroup); //$NON-NLS-1$
return startPos;
}
case RewriteEvent.REMOVED: {
try {
ASTNode node= (ASTNode) event.getOriginalValue();
TextEditGroup editGroup= getEditGroup(event);
int dotEnd= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameDOT, node.getStartPosition() + node.getLength());
doTextRemoveAndVisit(startPos, dotEnd - startPos, node, editGroup);
return dotEnd;
} catch (CoreException e) {
handleException(e);
}
break;
}
case RewriteEvent.REPLACED: {
ASTNode node= (ASTNode) event.getOriginalValue();
TextEditGroup editGroup= getEditGroup(event);
int offset= getExtendedOffset(node);
int length= getExtendedLength(node);
doTextRemoveAndVisit(offset, length, node, editGroup);
doTextInsert(offset, (ASTNode) event.getNewValue(), getIndent(startPos), true, editGroup);
return offset + length;
}
}
}
return doVisit(parent, property, startPos);
}
private class ParagraphListRewriter extends ListRewriter {
public final int DEFAULT_SPACING= 1;
private int fInitialIndent;
private int fSeparatorLines;
public ParagraphListRewriter(int initialIndent, int separator) {
fInitialIndent= initialIndent;
fSeparatorLines= separator;
}
protected int getInitialIndent() {
return fInitialIndent;
}
protected String getSeparatorString(int nodeIndex) {
int newLines= fSeparatorLines == -1 ? getNewLines(nodeIndex) : fSeparatorLines;
String lineDelim= getLineDelimiter();
StringBuffer buf= new StringBuffer(lineDelim);
for (int i= 0; i < newLines; i++) {
buf.append(lineDelim);
}
buf.append(CodeFormatterUtil.createIndentString(getNodeIndent(nodeIndex + 1)));
return buf.toString();
}
private ASTNode getNode(int nodeIndex) {
ASTNode elem= (ASTNode) fList[nodeIndex].getOriginalValue();
if (elem == null) {
elem= (ASTNode) fList[nodeIndex].getNewValue();
}
return elem;
}
private int getNewLines(int nodeIndex) {
ASTNode curr= getNode(nodeIndex);
ASTNode next= getNode(nodeIndex + 1);
int currKind= curr.getNodeType();
int nextKind= next.getNodeType();
ASTNode last= null;
ASTNode secondLast= null;
for (int i= 0; i < fList.length; i++) {
ASTNode elem= (ASTNode) fList[i].getOriginalValue();
if (elem != null) {
if (last != null) {
if (elem.getNodeType() == nextKind && last.getNodeType() == currKind) {
return countEmptyLines(last);
}
secondLast= last;
}
last= elem;
}
}
if (currKind == ASTNode.FIELD_DECLARATION && nextKind == ASTNode.FIELD_DECLARATION ) {
return 0;
}
if (secondLast != null) {
return countEmptyLines(secondLast);
}
return DEFAULT_SPACING;
}
private int countEmptyLines(ASTNode last) {
IDocument doc= fDocument;
try {
int lastLine= doc.getLineOfOffset(last.getStartPosition() + last.getLength());
int scanLine= lastLine + 1;
int numLines= doc.getNumberOfLines();
while(scanLine < numLines && containsOnlyWhitespaces(doc, scanLine)) {
scanLine++;
}
return scanLine - lastLine - 1;
} catch (BadLocationException e) {
handleException(e);
return 0;
}
}
private boolean containsOnlyWhitespaces(IDocument doc, int line) throws BadLocationException {
int offset= doc.getLineOffset(line);
int end= offset + doc.getLineLength(line);
while (offset < end && Character.isWhitespace(doc.getChar(offset))) {
offset++;
}
return offset == end;
}
}
private int rewriteParagraphList(ASTNode parent, StructuralPropertyDescriptor property, int insertPos, int insertIndent, int separator, int lead) {
RewriteEvent event= getEvent(parent, property);
if (event == null || event.getChangeKind() == RewriteEvent.UNCHANGED) {
return doVisit(parent, property, insertPos);
}
RewriteEvent[] events= event.getChildren();
boolean hasExisting= false;
for (int i= 0; i < events.length; i++) {
int changeKind= events[i].getChangeKind();
hasExisting |= (changeKind != RewriteEvent.INSERTED);
}
ParagraphListRewriter listRewriter= new ParagraphListRewriter(insertIndent, separator);
StringBuffer leadString= new StringBuffer();
if (!hasExisting) {
for (int i= 0; i < lead; i++) {
leadString.append(getLineDelimiter());
}
leadString.append(CodeFormatterUtil.createIndentString(insertIndent));
}
return listRewriter.rewriteList(parent, property, insertPos, leadString.toString());
}
private int rewriteNodeList(ASTNode parent, StructuralPropertyDescriptor property, int pos, String keyword, String separator) {
RewriteEvent event= getEvent(parent, property);
if (event != null && event.getChangeKind() != RewriteEvent.UNCHANGED) {
return new ListRewriter().rewriteList(parent, property, pos, keyword, separator);
}
return doVisit(parent, property, pos);
}
private void rewriteMethodBody(MethodDeclaration parent, int startPos) {
RewriteEvent event= getEvent(parent, MethodDeclaration.BODY_PROPERTY);
if (event != null) {
switch (event.getChangeKind()) {
case RewriteEvent.INSERTED: {
int endPos= parent.getStartPosition() + parent.getLength();
TextEditGroup editGroup= getEditGroup(event);
ASTNode body= (ASTNode) event.getNewValue();
doTextRemove(startPos, endPos - startPos, editGroup);
int indent= getIndent(parent.getStartPosition());
String prefix= fFormatter.METHOD_BODY.getPrefix(indent, getLineDelimiter());
doTextInsert(startPos, prefix, editGroup);
doTextInsert(startPos, body, indent, true, editGroup);
return;
}
case RewriteEvent.REMOVED: {
TextEditGroup editGroup= getEditGroup(event);
ASTNode body= (ASTNode) event.getOriginalValue();
int endPos= parent.getStartPosition() + parent.getLength();
doTextRemoveAndVisit(startPos, endPos - startPos, body, editGroup);
doTextInsert(startPos, ";", editGroup); //$NON-NLS-1$
return;
}
case RewriteEvent.REPLACED: {
TextEditGroup editGroup= getEditGroup(event);
ASTNode body= (ASTNode) event.getOriginalValue();
doTextRemoveAndVisit(body.getStartPosition(), body.getLength(), body, editGroup);
doTextInsert(body.getStartPosition(), (ASTNode) event.getNewValue(), getIndent(body.getStartPosition()), true, editGroup);
return;
}
}
}
doVisit(parent, MethodDeclaration.BODY_PROPERTY, startPos);
}
private int rewriteExtraDimensions(ASTNode parent, StructuralPropertyDescriptor property, int pos) {
RewriteEvent event= getEvent(parent, property);
if (event == null || event.getChangeKind() == RewriteEvent.UNCHANGED) {
return ((Integer) getOriginalValue(parent, property)).intValue();
}
int oldDim= ((Integer) event.getOriginalValue()).intValue();
int newDim= ((Integer) event.getNewValue()).intValue();
if (oldDim != newDim) {
TextEditGroup editGroup= getEditGroup(event);
rewriteExtraDimensions(oldDim, newDim, pos, editGroup);
}
return oldDim;
}
private void rewriteExtraDimensions(int oldDim, int newDim, int pos, TextEditGroup editGroup) {
if (oldDim < newDim) {
for (int i= oldDim; i < newDim; i++) {
doTextInsert(pos, "[]", editGroup); //$NON-NLS-1$
}
} else if (newDim < oldDim) {
try {
getScanner().setOffset(pos);
for (int i= newDim; i < oldDim; i++) {
getScanner().readToToken(ITerminalSymbols.TokenNameRBRACKET);
}
doTextRemove(pos, getScanner().getCurrentEndOffset() - pos, editGroup);
} catch (CoreException e) {
handleException(e);
}
}
}
/*
* Next token is a left brace. Returns the offset after the brace. For incomplete code, return the start offset.
*/
private int getPosAfterLeftBrace(int pos) {
try {
int nextToken= getScanner().readNext(pos, true);
if (nextToken == ITerminalSymbols.TokenNameLBRACE) {
return getScanner().getCurrentEndOffset();
}
} catch (CoreException e) {
handleException(e);
}
return pos;
}
final int getIndent(int pos) {
try {
IRegion line= fDocument.getLineInformationOfOffset(pos);
String str= fDocument.get(line.getOffset(), line.getLength());
return Strings.computeIndent(str, CodeFormatterUtil.getTabWidth());
} catch (BadLocationException e) {
return 0;
}
}
final void doTextInsert(int insertOffset, ASTNode node, int initialIndentLevel, boolean removeLeadingIndent, TextEditGroup editGroup) {
ArrayList markers= new ArrayList();
String formatted= fFormatter.getFormattedResult(node, initialIndentLevel, markers);
int tabWidth= CodeFormatterUtil.getTabWidth();
int currPos= 0;
if (removeLeadingIndent) {
while (currPos < formatted.length() && Character.isWhitespace(formatted.charAt(currPos))) {
currPos++;
}
}
for (int i= 0; i < markers.size(); i++) { // markers.size can change!
NodeMarker curr= (NodeMarker) markers.get(i);
int offset= curr.offset;
if (offset != currPos) {
String insertStr= formatted.substring(currPos, offset);
doTextInsert(insertOffset, insertStr, editGroup); // insert until the marker's begin
}
Object data= curr.data;
if (data instanceof TextEditGroup) { // tracking a node
// need to split and create 2 edits as tracking node can surround replaced node.
TextEdit edit= new RangeMarker(insertOffset, 0);
addEditGroup((TextEditGroup) data, edit);
addEdit(edit);
if (curr.length != 0) {
int end= offset + curr.length;
int k= i + 1;
while (k < markers.size() && ((NodeMarker) markers.get(k)).offset < end) {
k++;
}
curr.offset= end;
curr.length= 0;
markers.add(k, curr); // add again for end position
}
currPos= offset;
} else {
String destIndentString= Strings.getIndentString(getCurrentLine(formatted, offset), tabWidth);
if (data instanceof CopyPlaceholderData) { // replace with a copy/move target
CopySourceInfo copySource= ((CopyPlaceholderData) data).copySource;
int srcIndentLevel= getIndent(copySource.getStartNode().getStartPosition());
TextEdit sourceEdit= getCopySourceEdit(copySource);
doTextCopy(sourceEdit, insertOffset, srcIndentLevel, destIndentString, tabWidth, editGroup);
currPos= offset + curr.length; // continue to insert after the replaced string
} else if (data instanceof StringPlaceholderData) { // replace with a placeholder
String code= ((StringPlaceholderData) data).code;
String str= Strings.changeIndent(code, 0, tabWidth, destIndentString, getLineDelimiter());
doTextInsert(insertOffset, str, editGroup);
currPos= offset + curr.length; // continue to insert after the replaced string
}
}
}
if (currPos < formatted.length()) {
String insertStr= formatted.substring(currPos);
doTextInsert(insertOffset, insertStr, editGroup);
}
}
private String getCurrentLine(String str, int pos) {
for (int i= pos - 1; i>= 0; i--) {
char ch= str.charAt(i);
if (Strings.isLineDelimiterChar(ch)) {
return str.substring(i + 1, pos);
}
}
return str.substring(0, pos);
}
private void rewriteModifiers(ASTNode parent, StructuralPropertyDescriptor property, int offset) {
RewriteEvent event= getEvent(parent, property);
if (event == null || event.getChangeKind() != RewriteEvent.REPLACED) {
return;
}
int oldModifiers= ((Integer) event.getOriginalValue()).intValue();
int newModifiers= ((Integer) event.getNewValue()).intValue();
TextEditGroup editGroup= getEditGroup(event);
try {
int tok= getScanner().readNext(offset, true);
int startPos= getScanner().getCurrentStartOffset();
int endPos= startPos;
loop: while (true) {
boolean keep= true;
switch (tok) {
case ITerminalSymbols.TokenNamepublic: keep= Modifier.isPublic(newModifiers); break;
case ITerminalSymbols.TokenNameprotected: keep= Modifier.isProtected(newModifiers); break;
case ITerminalSymbols.TokenNameprivate: keep= Modifier.isPrivate(newModifiers); break;
case ITerminalSymbols.TokenNamestatic: keep= Modifier.isStatic(newModifiers); break;
case ITerminalSymbols.TokenNamefinal: keep= Modifier.isFinal(newModifiers); break;
case ITerminalSymbols.TokenNameabstract: keep= Modifier.isAbstract(newModifiers); break;
case ITerminalSymbols.TokenNamenative: keep= Modifier.isNative(newModifiers); break;
case ITerminalSymbols.TokenNamevolatile: keep= Modifier.isVolatile(newModifiers); break;
case ITerminalSymbols.TokenNamestrictfp: keep= Modifier.isStrictfp(newModifiers); break;
case ITerminalSymbols.TokenNametransient: keep= Modifier.isTransient(newModifiers); break;
case ITerminalSymbols.TokenNamesynchronized: keep= Modifier.isSynchronized(newModifiers); break;
default:
break loop;
}
tok= getScanner().readNext(true);
int currPos= endPos;
endPos= getScanner().getCurrentStartOffset();
if (!keep) {
doTextRemove(currPos, endPos - currPos, editGroup);
}
}
int addedModifiers= newModifiers & ~oldModifiers;
if (addedModifiers != 0) {
if (startPos != endPos) {
int visibilityModifiers= addedModifiers & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED);
if (visibilityModifiers != 0) {
StringBuffer buf= new StringBuffer();
ASTRewriteFlattener.printModifiers(visibilityModifiers, buf);
doTextInsert(startPos, buf.toString(), editGroup);
addedModifiers &= ~visibilityModifiers;
}
}
StringBuffer buf= new StringBuffer();
ASTRewriteFlattener.printModifiers(addedModifiers, buf);
doTextInsert(endPos, buf.toString(), editGroup);
}
} catch (CoreException e) {
// ignore
}
}
private void replaceOperation(int posBeforeOperation, String newOperation, TextEditGroup editGroup) {
try {
getScanner().readNext(posBeforeOperation, true);
doTextReplace(getScanner().getCurrentStartOffset(), getScanner().getCurrentLength(), newOperation, editGroup);
} catch (CoreException e) {
handleException(e);
}
}
private void rewriteOperation(ASTNode parent, StructuralPropertyDescriptor property, int posBeforeOperation) {
RewriteEvent event= getEvent(parent, property);
if (event != null && event.getChangeKind() != RewriteEvent.UNCHANGED) {
try {
String newOperation= event.getNewValue().toString();
TextEditGroup editGroup= getEditGroup(event);
getScanner().readNext(posBeforeOperation, true);
doTextReplace(getScanner().getCurrentStartOffset(), getScanner().getCurrentLength(), newOperation, editGroup);
} catch (CoreException e) {
handleException(e);
}
}
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#postVisit(ASTNode)
*/
public void postVisit(ASTNode node) {
TextEditGroup editGroup= fEventStore.getTrackedNodeData(node);
if (editGroup != null) {
fCurrentEdit= fCurrentEdit.getParent();
}
// remove copy source edits
doCopySourcePostVisit(node, fSourceCopyEndNodes);
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#preVisit(ASTNode)
*/
public void preVisit(ASTNode node) {
// copies, then range marker
CopySourceInfo[] infos= fEventStore.getNodeCopySources(node);
doCopySourcePreVisit(infos, fSourceCopyEndNodes);
TextEditGroup editGroup= fEventStore.getTrackedNodeData(node);
if (editGroup != null) {
int offset= getExtendedOffset(node);
int length= getExtendedLength(node);
TextEdit edit= new RangeMarker(offset, length);
addEditGroup(editGroup, edit);
addEdit(edit);
fCurrentEdit= edit;
}
}
final void doCopySourcePreVisit(CopySourceInfo[] infos, Stack nodeEndStack) {
if (infos != null) {
for (int i= 0; i < infos.length; i++) {
CopySourceInfo curr= infos[i];
TextEdit edit= getCopySourceEdit(curr);
addEdit(edit);
fCurrentEdit= edit;
nodeEndStack.push(curr.getEndNode());
}
}
}
final void doCopySourcePostVisit(ASTNode node, Stack nodeEndStack) {
while (!nodeEndStack.isEmpty() && nodeEndStack.peek() == node) {
nodeEndStack.pop();
fCurrentEdit= fCurrentEdit.getParent();
}
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(CompilationUnit)
*/
public boolean visit(CompilationUnit node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int startPos= rewriteNode(node, CompilationUnit.PACKAGE_PROPERTY, 0, ASTRewriteFormatter.NONE); //$NON-NLS-1$
if (getChangeKind(node, CompilationUnit.PACKAGE_PROPERTY) == RewriteEvent.INSERTED) {
doTextInsert(0, getLineDelimiter(), getEditGroup(node, CompilationUnit.PACKAGE_PROPERTY));
}
startPos= rewriteParagraphList(node, CompilationUnit.IMPORTS_PROPERTY, startPos, 0, 0, 2);
rewriteParagraphList(node, CompilationUnit.TYPES_PROPERTY, startPos, 0, -1, 2);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(TypeDeclaration)
*/
public boolean visit(TypeDeclaration node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int pos= rewriteJavadoc(node, TypeDeclaration.JAVADOC_PROPERTY);
rewriteModifiers(node, TypeDeclaration.MODIFIERS_PROPERTY, pos);
boolean isInterface= ((Boolean) getOriginalValue(node, TypeDeclaration.INTERFACE_PROPERTY)).booleanValue();
// modifiers & class/interface
boolean invertType= isChanged(node, TypeDeclaration.INTERFACE_PROPERTY);
if (invertType) {
try {
int typeToken= isInterface ? ITerminalSymbols.TokenNameinterface : ITerminalSymbols.TokenNameclass;
getScanner().readToToken(typeToken, node.getStartPosition());
String str= isInterface ? "class" : "interface"; //$NON-NLS-1$ //$NON-NLS-2$
int start= getScanner().getCurrentStartOffset();
int end= getScanner().getCurrentEndOffset();
doTextReplace(start, end - start, str, getEditGroup(node, TypeDeclaration.INTERFACE_PROPERTY));
} catch (CoreException e) {
// ignore
}
}
// name
pos= rewriteRequiredNode(node, TypeDeclaration.NAME_PROPERTY);
// superclass
if (!isInterface || invertType) {
RewriteEvent superClassEvent= getEvent(node, TypeDeclaration.SUPERCLASS_PROPERTY);
int changeKind= superClassEvent != null ? superClassEvent.getChangeKind() : RewriteEvent.UNCHANGED;
switch (changeKind) {
case RewriteEvent.INSERTED: {
doTextInsert(pos, " extends ", getEditGroup(superClassEvent)); //$NON-NLS-1$
doTextInsert(pos, (ASTNode) superClassEvent.getNewValue(), 0, false, getEditGroup(superClassEvent));
break;
}
case RewriteEvent.REMOVED: {
ASTNode superClass= (ASTNode) superClassEvent.getOriginalValue();
int endPos= getExtendedEnd(superClass);
doTextRemoveAndVisit(pos, endPos - pos, superClass, getEditGroup(superClassEvent));
pos= endPos;
break;
}
case RewriteEvent.REPLACED: {
ASTNode superClass= (ASTNode) superClassEvent.getOriginalValue();
int offset= getExtendedOffset(superClass);
int length= getExtendedLength(superClass);
doTextRemoveAndVisit(offset, length, superClass, getEditGroup(superClassEvent));
doTextInsert(offset, (ASTNode) superClassEvent.getNewValue(), 0, false, getEditGroup(superClassEvent));
pos= offset + length;
break;
}
case RewriteEvent.UNCHANGED: {
pos= doVisit(node, TypeDeclaration.SUPERCLASS_PROPERTY, pos);
}
}
}
// extended interfaces
RewriteEvent interfaceEvent= getEvent(node, TypeDeclaration.SUPER_INTERFACES_PROPERTY);
if (interfaceEvent == null || interfaceEvent.getChangeKind() == RewriteEvent.UNCHANGED) {
if (invertType) {
List originalNodes= (List) getOriginalValue(node, TypeDeclaration.SUPER_INTERFACES_PROPERTY);
if (!originalNodes.isEmpty()) {
String keyword= isInterface ? " implements " : " extends "; //$NON-NLS-1$ //$NON-NLS-2$
ASTNode firstNode= (ASTNode) originalNodes.get(0);
doTextReplace(pos, firstNode.getStartPosition() - pos, keyword, getEditGroup(node, TypeDeclaration.INTERFACE_PROPERTY));
}
}
pos= doVisit(node, TypeDeclaration.SUPER_INTERFACES_PROPERTY, pos);
} else {
String keyword= (isInterface == invertType) ? " implements " : " extends "; //$NON-NLS-1$ //$NON-NLS-2$
if (invertType) {
List newNodes= (List) getNewValue(node, TypeDeclaration.SUPER_INTERFACES_PROPERTY);
if (!newNodes.isEmpty()) {
List origNodes= (List) getOriginalValue(node, TypeDeclaration.SUPER_INTERFACES_PROPERTY);
int firstStart= pos;
if (!origNodes.isEmpty()) {
firstStart= ((ASTNode) origNodes.get(0)).getStartPosition();
}
doTextReplace(pos, firstStart - pos, keyword, getEditGroup(node, TypeDeclaration.INTERFACE_PROPERTY));
keyword= ""; //$NON-NLS-1$
pos= firstStart;
}
}
pos= rewriteNodeList(node, TypeDeclaration.SUPER_INTERFACES_PROPERTY, pos, keyword, ", "); //$NON-NLS-1$
}
// type members
// startPos : find position after left brace of type, be aware that bracket might be missing
int startIndent= getIndent(node.getStartPosition()) + 1;
int startPos= getPosAfterLeftBrace(pos);
rewriteParagraphList(node, TypeDeclaration.BODY_DECLARATIONS_PROPERTY, startPos, startIndent, -1, 2);
return false;
}
private void rewriteReturnType(MethodDeclaration node, boolean isConstructor, boolean isConstructorChange) {
// weakness in the AST: return type always exists, even if missing in source
ASTNode originalReturnType= (ASTNode) getOriginalValue(node, MethodDeclaration.RETURN_TYPE_PROPERTY);
boolean returnTypeExists= originalReturnType != null && originalReturnType.getStartPosition() != -1;
if (!isConstructorChange && returnTypeExists) {
rewriteRequiredNode(node, MethodDeclaration.RETURN_TYPE_PROPERTY);
return;
}
ASTNode newReturnType= (ASTNode) getNewValue(node, MethodDeclaration.RETURN_TYPE_PROPERTY);
if (isConstructorChange || !returnTypeExists && newReturnType != originalReturnType) {
try {
int startPos= node.getStartPosition();
getScanner().setOffset(startPos);
int token= getScanner().readNext(true);
while (TokenScanner.isModifier(token)) {
startPos= getScanner().getCurrentEndOffset();
token= getScanner().readNext(true);
}
TextEditGroup editGroup= getEditGroup(node, MethodDeclaration.RETURN_TYPE_PROPERTY);
if (isConstructor || !returnTypeExists) { // insert
doTextInsert(startPos, " ", editGroup); //$NON-NLS-1$
doTextInsert(startPos, newReturnType, getIndent(startPos), true, editGroup);
} else { // remove
int len= getExtendedEnd(originalReturnType) - startPos;
doTextRemoveAndVisit(startPos, len, originalReturnType, editGroup);
}
} catch (CoreException e) {
handleException(e);
}
}
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(MethodDeclaration)
*/
public boolean visit(MethodDeclaration node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int pos= rewriteJavadoc(node, MethodDeclaration.JAVADOC_PROPERTY);
rewriteModifiers(node, MethodDeclaration.MODIFIERS_PROPERTY, pos);
boolean isConstructorChange= isChanged(node, MethodDeclaration.CONSTRUCTOR_PROPERTY);
boolean isConstructor= ((Boolean) getOriginalValue(node, MethodDeclaration.CONSTRUCTOR_PROPERTY)).booleanValue();
if (!isConstructor || isConstructorChange) {
rewriteReturnType(node, isConstructor, isConstructorChange);
}
// method name
pos= rewriteRequiredNode(node, MethodDeclaration.NAME_PROPERTY);
// parameters
try {
if (isChanged(node, MethodDeclaration.PARAMETERS_PROPERTY)) {
pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLPAREN, pos);
pos= rewriteNodeList(node, MethodDeclaration.PARAMETERS_PROPERTY, pos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$
} else {
pos= doVisit(node, MethodDeclaration.PARAMETERS_PROPERTY, pos);
}
pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameRPAREN, pos);
int extraDims= rewriteExtraDimensions(node, MethodDeclaration.EXTRA_DIMENSIONS_PROPERTY, pos);
boolean hasExceptionChanges= isChanged(node, MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY);
int bodyChangeKind= getChangeKind(node, MethodDeclaration.BODY_PROPERTY);
if ((extraDims > 0) && (hasExceptionChanges || bodyChangeKind == RewriteEvent.INSERTED || bodyChangeKind == RewriteEvent.REMOVED)) {
int dim= ((Integer) getOriginalValue(node, MethodDeclaration.EXTRA_DIMENSIONS_PROPERTY)).intValue();
while (dim > 0) {
pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameRBRACKET, pos);
dim--;
}
}
pos= rewriteNodeList(node, MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY, pos, " throws ", ", "); //$NON-NLS-1$ //$NON-NLS-2$
rewriteMethodBody(node, pos);
} catch (CoreException e) {
// ignore
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(Block)
*/
public boolean visit(Block node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int startPos;
if (isCollapsed(node)) {
startPos= node.getStartPosition();
} else {
startPos= getPosAfterLeftBrace(node.getStartPosition());
}
int startIndent= getIndent(node.getStartPosition()) + 1;
rewriteParagraphList(node, Block.STATEMENTS_PROPERTY, startPos, startIndent, 0, 1);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ReturnStatement)
*/
public boolean visit(ReturnStatement node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
try {
int offset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNamereturn, node.getStartPosition());
rewriteNode(node, ReturnStatement.EXPRESSION_PROPERTY, offset, ASTRewriteFormatter.SPACE); //$NON-NLS-1$
} catch (CoreException e) {
handleException(e);
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(AnonymousClassDeclaration)
*/
public boolean visit(AnonymousClassDeclaration node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int startPos= getPosAfterLeftBrace(node.getStartPosition());
int startIndent= getIndent(node.getStartPosition()) + 1;
rewriteParagraphList(node, AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY, startPos, startIndent, -1, 2);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ArrayAccess)
*/
public boolean visit(ArrayAccess node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteRequiredNode(node, ArrayAccess.ARRAY_PROPERTY);
rewriteRequiredNode(node, ArrayAccess.INDEX_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ArrayCreation)
*/
public boolean visit(ArrayCreation node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
ArrayType arrayType= (ArrayType) getOriginalValue(node, ArrayCreation.TYPE_PROPERTY);
int nOldBrackets= getDimensions(arrayType); // number of total brackets
int nNewBrackets= nOldBrackets;
TextEditGroup editGroup= null;
RewriteEvent typeEvent= getEvent(node, ArrayCreation.TYPE_PROPERTY);
if (typeEvent != null && typeEvent.getChangeKind() == RewriteEvent.REPLACED) { // changed arraytype can have different dimension or type name
ArrayType replacingType= (ArrayType) typeEvent.getNewValue();
editGroup= getEditGroup(typeEvent);
Type newType= replacingType.getElementType();
Type oldType= getElementType(arrayType);
if (!newType.equals(oldType)) {
int offset= getExtendedOffset(oldType);
int length= getExtendedLength(oldType);
doTextRemove(offset, length, editGroup);
doTextInsert(offset, newType, 0, false, editGroup);
}
nNewBrackets= replacingType.getDimensions(); // is replaced type
}
doVisit(arrayType);
try {
int offset= getScanner().getTokenStartOffset(ITerminalSymbols.TokenNameLBRACKET, arrayType.getStartPosition());
// dimension node with expressions
RewriteEvent dimEvent= getEvent(node, ArrayCreation.DIMENSIONS_PROPERTY);
boolean hasDimensionChanges= (dimEvent != null && dimEvent.getChangeKind() != RewriteEvent.UNCHANGED);
if (hasDimensionChanges) {
RewriteEvent[] events= dimEvent.getChildren();
// offset on first opening brace
for (int i= 0; i < events.length; i++) {
RewriteEvent event= events[i];
int changeKind= event.getChangeKind();
if (changeKind == RewriteEvent.INSERTED) { // insert new dimension
editGroup= getEditGroup(event);
doTextInsert(offset, "[", editGroup); //$NON-NLS-1$
doTextInsert(offset, (ASTNode) event.getNewValue(), 0, false, editGroup);
doTextInsert(offset, "]", editGroup); //$NON-NLS-1$
nNewBrackets--;
} else {
ASTNode elem= (ASTNode) event.getOriginalValue();
int elemEnd= elem.getStartPosition() + elem.getLength();
int endPos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameRBRACKET, elemEnd);
if (changeKind == RewriteEvent.REMOVED) {
editGroup= getEditGroup(event);
doTextRemoveAndVisit(offset, endPos - offset, elem, editGroup);
} else if (changeKind == RewriteEvent.REPLACED) {
editGroup= getEditGroup(event);
int elemOffset= getExtendedOffset(elem);
int elemLength= getExtendedLength(elem);
doTextRemoveAndVisit(elemOffset, elemLength, elem, editGroup);
doTextInsert(elemOffset, (ASTNode) event.getNewValue(), 0, false, editGroup);
nNewBrackets--;
} else {
doVisit(elem);
nNewBrackets--;
}
offset= endPos;
nOldBrackets--;
}
}
} else {
offset= doVisit(node, ArrayCreation.DIMENSIONS_PROPERTY, offset);
}
if (nOldBrackets != nNewBrackets) {
if (!hasDimensionChanges) {
offset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameRBRACKET, offset);
}
rewriteExtraDimensions(nOldBrackets, nNewBrackets, offset, editGroup);
}
int kind= getChangeKind(node, ArrayCreation.INITIALIZER_PROPERTY);
if (kind == RewriteEvent.REMOVED) {
offset= getScanner().getPreviousTokenEndOffset(ITerminalSymbols.TokenNameLBRACE, offset);
} else {
offset= node.getStartPosition() + node.getLength(); // insert pos
}
rewriteNode(node, ArrayCreation.INITIALIZER_PROPERTY, offset, ASTRewriteFormatter.SPACE); //$NON-NLS-1$
} catch (CoreException e) {
handleException(e);
}
return false;
}
private Type getElementType(ArrayType parent) {
Type t = (Type) getOriginalValue(parent, ArrayType.COMPONENT_TYPE_PROPERTY);
while (t.isArrayType()) {
t = (Type) getOriginalValue(t, ArrayType.COMPONENT_TYPE_PROPERTY);
}
return t;
}
private int getDimensions(ArrayType parent) {
Type t = (Type) getOriginalValue(parent, ArrayType.COMPONENT_TYPE_PROPERTY);
int dimensions = 1; // always include this array type
while (t.isArrayType()) {
dimensions++;
t = (Type) getOriginalValue(t, ArrayType.COMPONENT_TYPE_PROPERTY);
}
return dimensions;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ArrayInitializer)
*/
public boolean visit(ArrayInitializer node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int startPos= getPosAfterLeftBrace(node.getStartPosition());
rewriteNodeList(node, ArrayInitializer.EXPRESSIONS_PROPERTY, startPos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ArrayType)
*/
public boolean visit(ArrayType node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteRequiredNode(node, ArrayType.COMPONENT_TYPE_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(AssertStatement)
*/
public boolean visit(AssertStatement node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int offset= rewriteRequiredNode(node, AssertStatement.EXPRESSION_PROPERTY);
rewriteNode(node, AssertStatement.MESSAGE_PROPERTY, offset, ASTRewriteFormatter.ASSERT_COMMENT);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(Assignment)
*/
public boolean visit(Assignment node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int pos= rewriteRequiredNode(node, Assignment.LEFT_HAND_SIDE_PROPERTY);
rewriteOperation(node, Assignment.OPERATOR_PROPERTY, pos);
rewriteRequiredNode(node, Assignment.RIGHT_HAND_SIDE_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(BooleanLiteral)
*/
public boolean visit(BooleanLiteral node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
changeNotSupported(node); // no modification possible
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(BreakStatement)
*/
public boolean visit(BreakStatement node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
try {
int offset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNamebreak, node.getStartPosition());
rewriteNode(node, BreakStatement.LABEL_PROPERTY, offset, ASTRewriteFormatter.SPACE); // space between break and label //$NON-NLS-1$
} catch (CoreException e) {
handleException(e);
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(CastExpression)
*/
public boolean visit(CastExpression node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteRequiredNode(node, CastExpression.TYPE_PROPERTY);
rewriteRequiredNode(node, CastExpression.EXPRESSION_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(CatchClause)
*/
public boolean visit(CatchClause node) { // catch (Exception) Block
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteRequiredNode(node, CatchClause.EXCEPTION_PROPERTY);
rewriteRequiredNode(node, CatchClause.BODY_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(CharacterLiteral)
*/
public boolean visit(CharacterLiteral node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
changeNotSupported(node); // no modification possible
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ClassInstanceCreation)
*/
public boolean visit(ClassInstanceCreation node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteOptionalQualifier(node, ClassInstanceCreation.EXPRESSION_PROPERTY, node.getStartPosition());
int pos= rewriteRequiredNode(node, ClassInstanceCreation.NAME_PROPERTY);
if (isChanged(node, ClassInstanceCreation.ARGUMENTS_PROPERTY)) {
try {
int startpos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLPAREN, pos);
rewriteNodeList(node, ClassInstanceCreation.ARGUMENTS_PROPERTY, startpos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$
} catch (CoreException e) {
handleException(e);
}
} else {
doVisit(node, ClassInstanceCreation.ARGUMENTS_PROPERTY, 0);
}
int kind= getChangeKind(node, ClassInstanceCreation.ANONYMOUS_CLASS_DECLARATION_PROPERTY);
if (kind == RewriteEvent.REMOVED) {
try {
pos= getScanner().getPreviousTokenEndOffset(ITerminalSymbols.TokenNameLBRACE, pos);
} catch (CoreException e) {
handleException(e);
}
} else {
pos= node.getStartPosition() + node.getLength(); // insert pos
}
rewriteNode(node, ClassInstanceCreation.ANONYMOUS_CLASS_DECLARATION_PROPERTY, pos, ASTRewriteFormatter.SPACE); //$NON-NLS-1$
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ConditionalExpression)
*/
public boolean visit(ConditionalExpression node) { // expression ? thenExpression : elseExpression
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteRequiredNode(node, ConditionalExpression.EXPRESSION_PROPERTY);
rewriteRequiredNode(node, ConditionalExpression.THEN_EXPRESSION_PROPERTY);
rewriteRequiredNode(node, ConditionalExpression.ELSE_EXPRESSION_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ConstructorInvocation)
*/
public boolean visit(ConstructorInvocation node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
try {
int startpos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLPAREN, node.getStartPosition());
rewriteNodeList(node, ConstructorInvocation.ARGUMENTS_PROPERTY, startpos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$
} catch (CoreException e) {
handleException(e);
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ContinueStatement)
*/
public boolean visit(ContinueStatement node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
try {
int offset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNamecontinue, node.getStartPosition());
rewriteNode(node, ContinueStatement.LABEL_PROPERTY, offset, ASTRewriteFormatter.SPACE); // space between continue and label //$NON-NLS-1$
} catch (CoreException e) {
handleException(e);
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(DoStatement)
*/
public boolean visit(DoStatement node) { // do statement while expression
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int pos= node.getStartPosition();
try {
RewriteEvent event= getEvent(node, DoStatement.BODY_PROPERTY);
if (event != null && event.getChangeKind() == RewriteEvent.REPLACED) {
int startOffset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNamedo, pos);
ASTNode body= (ASTNode) event.getOriginalValue();
int bodyEnd= body.getStartPosition() + body.getLength();
int endPos= getScanner().getTokenStartOffset(ITerminalSymbols.TokenNamewhile, bodyEnd);
rewriteBodyNode(node, DoStatement.BODY_PROPERTY, startOffset, endPos, getIndent(node.getStartPosition()), fFormatter.DO_BLOCK); // body
} else {
doVisit(node, DoStatement.BODY_PROPERTY, pos);
}
} catch (CoreException e) {
handleException(e);
}
rewriteRequiredNode(node, DoStatement.EXPRESSION_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(EmptyStatement)
*/
public boolean visit(EmptyStatement node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
changeNotSupported(node); // no modification possible
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ExpressionStatement)
*/
public boolean visit(ExpressionStatement node) { // expression
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteRequiredNode(node, ExpressionStatement.EXPRESSION_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(FieldAccess)
*/
public boolean visit(FieldAccess node) { // expression.name
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteRequiredNode(node, FieldAccess.EXPRESSION_PROPERTY); // expression
rewriteRequiredNode(node, FieldAccess.NAME_PROPERTY); // name
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(FieldDeclaration)
*/
public boolean visit(FieldDeclaration node) { //{ Modifier } Type VariableDeclarationFragment { ',' VariableDeclarationFragment } ';'
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int pos= rewriteJavadoc(node, FieldDeclaration.JAVADOC_PROPERTY);
rewriteModifiers(node, FieldDeclaration.MODIFIERS_PROPERTY, pos);
pos= rewriteRequiredNode(node, FieldDeclaration.TYPE_PROPERTY);
rewriteNodeList(node, FieldDeclaration.FRAGMENTS_PROPERTY, pos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ForStatement)
*/
public boolean visit(ForStatement node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
try {
int pos= node.getStartPosition();
if (isChanged(node, ForStatement.INITIALIZERS_PROPERTY)) {
// position after opening parent
int startOffset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLPAREN, pos);
pos= rewriteNodeList(node, ForStatement.INITIALIZERS_PROPERTY, startOffset, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$
} else {
pos= doVisit(node, ForStatement.INITIALIZERS_PROPERTY, pos);
}
// position after first semicolon
pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameSEMICOLON, pos);
pos= rewriteNode(node, ForStatement.EXPRESSION_PROPERTY, pos, ASTRewriteFormatter.NONE);
if (isChanged(node, ForStatement.UPDATERS_PROPERTY)) {
int startOffset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameSEMICOLON, pos);
pos= rewriteNodeList(node, ForStatement.UPDATERS_PROPERTY, startOffset, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$
} else {
pos= doVisit(node, ForStatement.UPDATERS_PROPERTY, pos);
}
RewriteEvent bodyEvent= getEvent(node, ForStatement.BODY_PROPERTY);
if (bodyEvent != null && bodyEvent.getChangeKind() == RewriteEvent.REPLACED) {
int startOffset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameRPAREN, pos);
rewriteBodyNode(node, ForStatement.BODY_PROPERTY, startOffset, -1, getIndent(node.getStartPosition()), fFormatter.FOR_BLOCK); // body
} else {
doVisit(node, ForStatement.BODY_PROPERTY, 0);
}
} catch (CoreException e) {
handleException(e);
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(IfStatement)
*/
public boolean visit(IfStatement node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int pos= rewriteRequiredNode(node, IfStatement.EXPRESSION_PROPERTY); // statement
RewriteEvent thenEvent= getEvent(node, IfStatement.THEN_STATEMENT_PROPERTY);
int elseChange= getChangeKind(node, IfStatement.ELSE_STATEMENT_PROPERTY);
if (thenEvent != null && thenEvent.getChangeKind() != RewriteEvent.UNCHANGED) {
try {
pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameRPAREN, pos); // after the closing parent
int indent= getIndent(node.getStartPosition());
int endPos= -1;
Object elseStatement= getOriginalValue(node, IfStatement.ELSE_STATEMENT_PROPERTY);
if (elseStatement != null) {
ASTNode thenStatement = (ASTNode) thenEvent.getOriginalValue();
endPos= getScanner().getTokenStartOffset(ITerminalSymbols.TokenNameelse, thenStatement.getStartPosition() + thenStatement.getLength()); // else keyword
}
if (elseStatement == null || elseChange != RewriteEvent.UNCHANGED) {
pos= rewriteBodyNode(node, IfStatement.THEN_STATEMENT_PROPERTY, pos, endPos, indent, fFormatter.IF_BLOCK_NO_ELSE);
} else {
pos= rewriteBodyNode(node, IfStatement.THEN_STATEMENT_PROPERTY, pos, endPos, indent, fFormatter.IF_BLOCK_WITH_ELSE);
}
} catch (CoreException e) {
handleException(e);
}
} else {
pos= doVisit(node, IfStatement.THEN_STATEMENT_PROPERTY, pos);
}
if (elseChange != RewriteEvent.UNCHANGED) {
int indent= getIndent(node.getStartPosition());
Object newThen= getNewValue(node, IfStatement.THEN_STATEMENT_PROPERTY);
if (newThen instanceof Block) {
rewriteBodyNode(node, IfStatement.ELSE_STATEMENT_PROPERTY, pos, -1, indent, fFormatter.ELSE_AFTER_BLOCK);
} else {
rewriteBodyNode(node, IfStatement.ELSE_STATEMENT_PROPERTY, pos, -1, indent, fFormatter.ELSE_AFTER_STATEMENT);
}
} else {
pos= doVisit(node, IfStatement.ELSE_STATEMENT_PROPERTY, pos);
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ImportDeclaration)
*/
public boolean visit(ImportDeclaration node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int pos= rewriteRequiredNode(node, ImportDeclaration.NAME_PROPERTY);
RewriteEvent event= getEvent(node, ImportDeclaration.ON_DEMAND_PROPERTY);
if (event != null && event.getChangeKind() != RewriteEvent.UNCHANGED) {
boolean isOnDemand= ((Boolean) event.getOriginalValue()).booleanValue();
if (!isOnDemand) {
doTextInsert(pos, ".*", getEditGroup(event)); //$NON-NLS-1$
} else {
try {
int endPos= getScanner().getTokenStartOffset(ITerminalSymbols.TokenNameSEMICOLON, pos);
doTextRemove(pos, endPos - pos, getEditGroup(event));
} catch (CoreException e) {
handleException(e);
}
}
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(InfixExpression)
*/
public boolean visit(InfixExpression node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int pos= rewriteRequiredNode(node, InfixExpression.LEFT_OPERAND_PROPERTY);
boolean needsNewOperation= isChanged(node, InfixExpression.OPERATOR_PROPERTY);
String operation= getNewValue(node, InfixExpression.OPERATOR_PROPERTY).toString();
if (needsNewOperation) {
replaceOperation(pos, operation, getEditGroup(node, InfixExpression.OPERATOR_PROPERTY));
}
pos= rewriteRequiredNode(node, InfixExpression.RIGHT_OPERAND_PROPERTY);
RewriteEvent event= getEvent(node, InfixExpression.EXTENDED_OPERANDS_PROPERTY);
String prefixString= ' ' + operation + ' ';
if (needsNewOperation) {
int startPos= pos;
TextEditGroup editGroup= getEditGroup(node, InfixExpression.OPERATOR_PROPERTY);
if (event != null && event.getChangeKind() != RewriteEvent.UNCHANGED) {
RewriteEvent[] extendedOperands= event.getChildren();
for (int i= 0; i < extendedOperands.length; i++) {
RewriteEvent curr= extendedOperands[i];
ASTNode elem= (ASTNode) curr.getOriginalValue();
if (elem != null) {
if (curr.getChangeKind() != RewriteEvent.REPLACED) {
replaceOperation(startPos, operation, editGroup);
}
startPos= elem.getStartPosition() + elem.getLength();
}
}
} else {
List extendedOperands= (List) getOriginalValue(node, InfixExpression.EXTENDED_OPERANDS_PROPERTY);
for (int i= 0; i < extendedOperands.size(); i++) {
ASTNode elem= (ASTNode) extendedOperands.get(i);
replaceOperation(startPos, operation, editGroup);
startPos= elem.getStartPosition() + elem.getLength();
}
}
}
rewriteNodeList(node, InfixExpression.EXTENDED_OPERANDS_PROPERTY, pos, prefixString, prefixString);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(Initializer)
*/
public boolean visit(Initializer node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int pos= rewriteJavadoc(node, Initializer.JAVADOC_PROPERTY);
rewriteModifiers(node, Initializer.MODIFIERS_PROPERTY, pos);
rewriteRequiredNode(node, Initializer.BODY_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(InstanceofExpression)
*/
public boolean visit(InstanceofExpression node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteRequiredNode(node, InstanceofExpression.LEFT_OPERAND_PROPERTY);
rewriteRequiredNode(node, InstanceofExpression.RIGHT_OPERAND_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(Javadoc)
*/
public boolean visit(Javadoc node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int startPos= node.getStartPosition() + 3;
String separator= getLineDelimiter() + getIndentString(node.getStartPosition()) + " * "; //$NON-NLS-1$
rewriteNodeList(node, Javadoc.TAGS_PROPERTY, startPos, separator, separator);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(LabeledStatement)
*/
public boolean visit(LabeledStatement node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteRequiredNode(node, LabeledStatement.LABEL_PROPERTY);
rewriteRequiredNode(node, LabeledStatement.BODY_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(MethodInvocation)
*/
public boolean visit(MethodInvocation node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteOptionalQualifier(node, MethodInvocation.EXPRESSION_PROPERTY, node.getStartPosition());
int pos= rewriteRequiredNode(node, MethodInvocation.NAME_PROPERTY);
if (isChanged(node, MethodInvocation.ARGUMENTS_PROPERTY)) {
// eval position after opening parent
try {
int startOffset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLPAREN, pos);
rewriteNodeList(node, MethodInvocation.ARGUMENTS_PROPERTY, startOffset, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$
} catch (CoreException e) {
handleException(e);
}
} else {
doVisit(node, MethodInvocation.ARGUMENTS_PROPERTY, 0);
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(NullLiteral)
*/
public boolean visit(NullLiteral node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
changeNotSupported(node); // no modification possible
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(NumberLiteral)
*/
public boolean visit(NumberLiteral node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
changeNotSupported(node); // no modification possible
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(PackageDeclaration)
*/
public boolean visit(PackageDeclaration node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteRequiredNode(node, PackageDeclaration.NAME_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ParenthesizedExpression)
*/
public boolean visit(ParenthesizedExpression node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteRequiredNode(node, ParenthesizedExpression.EXPRESSION_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(PostfixExpression)
*/
public boolean visit(PostfixExpression node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int pos= rewriteRequiredNode(node, PostfixExpression.OPERAND_PROPERTY);
rewriteOperation(node, PostfixExpression.OPERATOR_PROPERTY, pos);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(PrefixExpression)
*/
public boolean visit(PrefixExpression node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteOperation(node, PrefixExpression.OPERATOR_PROPERTY, node.getStartPosition());
rewriteRequiredNode(node, PrefixExpression.OPERAND_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(PrimitiveType)
*/
public boolean visit(PrimitiveType node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
changeNotSupported(node); // no modification possible
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(QualifiedName)
*/
public boolean visit(QualifiedName node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteRequiredNode(node, QualifiedName.QUALIFIER_PROPERTY);
rewriteRequiredNode(node, QualifiedName.NAME_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(SimpleName)
*/
public boolean visit(SimpleName node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
changeNotSupported(node); // no modification possible
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(SimpleType)
*/
public boolean visit(SimpleType node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteRequiredNode(node, SimpleType.NAME_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(SingleVariableDeclaration)
*/
public boolean visit(SingleVariableDeclaration node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteModifiers(node, SingleVariableDeclaration.MODIFIERS_PROPERTY, node.getStartPosition());
rewriteRequiredNode(node, SingleVariableDeclaration.TYPE_PROPERTY);
int pos= rewriteRequiredNode(node, SingleVariableDeclaration.NAME_PROPERTY);
int extraDims= rewriteExtraDimensions(node, SingleVariableDeclaration.EXTRA_DIMENSIONS_PROPERTY, pos);
if (extraDims > 0) {
int kind= getChangeKind(node, SingleVariableDeclaration.INITIALIZER_PROPERTY);
if (kind == RewriteEvent.REMOVED) {
try {
pos= getScanner().getPreviousTokenEndOffset(ITerminalSymbols.TokenNameEQUAL, pos);
} catch (CoreException e) {
handleException(e);
}
} else {
pos= node.getStartPosition() + node.getLength(); // insert pos
}
}
rewriteNode(node, SingleVariableDeclaration.INITIALIZER_PROPERTY, pos, fFormatter.VAR_INITIALIZER);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(StringLiteral)
*/
public boolean visit(StringLiteral node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
changeNotSupported(node); // no modification possible
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(SuperConstructorInvocation)
*/
public boolean visit(SuperConstructorInvocation node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int pos= rewriteOptionalQualifier(node, SuperConstructorInvocation.EXPRESSION_PROPERTY, node.getStartPosition());
if (isChanged(node, SuperConstructorInvocation.ARGUMENTS_PROPERTY)) {
// eval position after opening parent
try {
pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLPAREN, pos);
rewriteNodeList(node, SuperConstructorInvocation.ARGUMENTS_PROPERTY, pos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$
} catch (CoreException e) {
handleException(e);
}
} else {
doVisit(node, SuperConstructorInvocation.ARGUMENTS_PROPERTY, 0);
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(SuperFieldAccess)
*/
public boolean visit(SuperFieldAccess node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteOptionalQualifier(node, SuperFieldAccess.QUALIFIER_PROPERTY, node.getStartPosition());
rewriteRequiredNode(node, SuperFieldAccess.NAME_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(SuperMethodInvocation)
*/
public boolean visit(SuperMethodInvocation node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteOptionalQualifier(node, SuperMethodInvocation.QUALIFIER_PROPERTY, node.getStartPosition());
int pos= rewriteRequiredNode(node, SuperMethodInvocation.NAME_PROPERTY);
if (isChanged(node, SuperMethodInvocation.ARGUMENTS_PROPERTY)) {
// eval position after opening parent
try {
pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLPAREN, pos);
rewriteNodeList(node, SuperMethodInvocation.ARGUMENTS_PROPERTY, pos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$
} catch (CoreException e) {
handleException(e);
}
} else {
doVisit(node, SuperMethodInvocation.ARGUMENTS_PROPERTY, 0);
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(SwitchCase)
*/
public boolean visit(SwitchCase node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
// dont allow switching from case to default or back. New statements should be created.
rewriteRequiredNode(node, SwitchCase.EXPRESSION_PROPERTY);
return false;
}
private class SwitchListRewriter extends ParagraphListRewriter {
public SwitchListRewriter(int initialIndent) {
super(initialIndent, 0);
}
protected int getNodeIndent(int nodeIndex) {
int indent= getInitialIndent();
ASTNode node= (ASTNode) fList[nodeIndex].getOriginalValue();
if (node == null) {
node= (ASTNode) fList[nodeIndex].getNewValue();
}
if (node.getNodeType() != ASTNode.SWITCH_CASE) {
indent++;
}
return indent;
}
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(SwitchStatement)
*/
public boolean visit(SwitchStatement node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int pos= rewriteRequiredNode(node, SwitchStatement.EXPRESSION_PROPERTY);
ChildListPropertyDescriptor property= SwitchStatement.STATEMENTS_PROPERTY;
if (getChangeKind(node, property) != RewriteEvent.UNCHANGED) {
try {
pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLBRACE, pos);
int insertIndent= getIndent(node.getStartPosition()) + 1;
ParagraphListRewriter listRewriter= new SwitchListRewriter(insertIndent);
StringBuffer leadString= new StringBuffer();
leadString.append(getLineDelimiter());
leadString.append(CodeFormatterUtil.createIndentString(insertIndent));
listRewriter.rewriteList(node, property, pos, leadString.toString());
} catch (CoreException e) {
handleException(e);
}
} else {
doVisit(node, SwitchStatement.STATEMENTS_PROPERTY, 0);
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(SynchronizedStatement)
*/
public boolean visit(SynchronizedStatement node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteRequiredNode(node, SynchronizedStatement.EXPRESSION_PROPERTY);
rewriteRequiredNode(node, SynchronizedStatement.BODY_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ThisExpression)
*/
public boolean visit(ThisExpression node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteOptionalQualifier(node, ThisExpression.QUALIFIER_PROPERTY, node.getStartPosition());
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ThrowStatement)
*/
public boolean visit(ThrowStatement node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteRequiredNode(node, ThrowStatement.EXPRESSION_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(TryStatement)
*/
public boolean visit(TryStatement node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int pos= rewriteRequiredNode(node, TryStatement.BODY_PROPERTY);
if (isChanged(node, TryStatement.CATCH_CLAUSES_PROPERTY)) {
int indent= getIndent(node.getStartPosition());
String prefix= fFormatter.CATCH_BLOCK.getPrefix(indent, getLineDelimiter());
pos= rewriteNodeList(node, TryStatement.CATCH_CLAUSES_PROPERTY, pos, prefix, prefix);
} else {
pos= doVisit(node, TryStatement.CATCH_CLAUSES_PROPERTY, pos);
}
rewriteNode(node, TryStatement.FINALLY_PROPERTY, pos, fFormatter.FINALLY_BLOCK);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(TypeDeclarationStatement)
*/
public boolean visit(TypeDeclarationStatement node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteRequiredNode(node, TypeDeclarationStatement.TYPE_DECLARATION_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(TypeLiteral)
*/
public boolean visit(TypeLiteral node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteRequiredNode(node, TypeLiteral.TYPE_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(VariableDeclarationExpression)
*/
public boolean visit(VariableDeclarationExpression node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
// same code as FieldDeclaration
rewriteModifiers(node, VariableDeclarationExpression.MODIFIERS_PROPERTY, node.getStartPosition());
int pos= rewriteRequiredNode(node, VariableDeclarationExpression.TYPE_PROPERTY);
rewriteNodeList(node, VariableDeclarationExpression.FRAGMENTS_PROPERTY, pos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(VariableDeclarationFragment)
*/
public boolean visit(VariableDeclarationFragment node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int pos= rewriteRequiredNode(node, VariableDeclarationFragment.NAME_PROPERTY);
int extraDims= rewriteExtraDimensions(node, VariableDeclarationFragment.EXTRA_DIMENSIONS_PROPERTY, pos);
if (extraDims > 0) {
int kind= getChangeKind(node, VariableDeclarationFragment.INITIALIZER_PROPERTY);
if (kind == RewriteEvent.REMOVED) {
try {
pos= getScanner().getPreviousTokenEndOffset(ITerminalSymbols.TokenNameEQUAL, pos);
} catch (CoreException e) {
handleException(e);
}
} else {
pos= node.getStartPosition() + node.getLength(); // insert pos
}
}
rewriteNode(node, VariableDeclarationFragment.INITIALIZER_PROPERTY, pos, fFormatter.VAR_INITIALIZER);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(VariableDeclarationStatement)
*/
public boolean visit(VariableDeclarationStatement node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
// same code as FieldDeclaration
rewriteModifiers(node, VariableDeclarationStatement.MODIFIERS_PROPERTY, node.getStartPosition());
int pos= rewriteRequiredNode(node, VariableDeclarationStatement.TYPE_PROPERTY);
rewriteNodeList(node, VariableDeclarationStatement.FRAGMENTS_PROPERTY, pos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(WhileStatement)
*/
public boolean visit(WhileStatement node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int pos= rewriteRequiredNode(node, WhileStatement.EXPRESSION_PROPERTY);
try {
if (isChanged(node, WhileStatement.BODY_PROPERTY)) {
int startOffset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameRPAREN, pos);
rewriteBodyNode(node, WhileStatement.BODY_PROPERTY, startOffset, -1, getIndent(node.getStartPosition()), fFormatter.WHILE_BLOCK); // body
} else {
doVisit(node, WhileStatement.BODY_PROPERTY, 0);
}
} catch (CoreException e) {
handleException(e);
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MemberRef)
*/
public boolean visit(MemberRef node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteNode(node, MemberRef.QUALIFIER_PROPERTY, node.getStartPosition(), ASTRewriteFormatter.NONE); //$NON-NLS-1$
rewriteRequiredNode(node, MemberRef.NAME_PROPERTY);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodRef)
*/
public boolean visit(MethodRef node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
rewriteNode(node, MethodRef.QUALIFIER_PROPERTY, node.getStartPosition(), ASTRewriteFormatter.NONE); //$NON-NLS-1$
int pos= rewriteRequiredNode(node, MethodRef.NAME_PROPERTY);
if (isChanged(node, MethodRef.PARAMETERS_PROPERTY)) {
// eval position after opening parent
try {
int startOffset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLPAREN, pos);
rewriteNodeList(node, MethodRef.PARAMETERS_PROPERTY, startOffset, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$
} catch (CoreException e) {
handleException(e);
}
} else {
doVisit(node, MethodRef.PARAMETERS_PROPERTY, 0);
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodRefParameter)
*/
public boolean visit(MethodRefParameter node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
int pos= rewriteRequiredNode(node, MethodRefParameter.TYPE_PROPERTY);
rewriteNode(node, MethodRefParameter.NAME_PROPERTY, pos, ASTRewriteFormatter.SPACE); //$NON-NLS-1$
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TagElement)
*/
public boolean visit(TagElement node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
if (isChanged(node, TagElement.FRAGMENTS_PROPERTY)) {
// eval position after opening parent
try {
int startOffset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameIdentifier, node.getStartPosition());
rewriteNodeList(node, TagElement.FRAGMENTS_PROPERTY, startOffset, " ", ", "); //$NON-NLS-1$ //$NON-NLS-2$
} catch (CoreException e) {
handleException(e);
}
} else {
doVisit(node, TagElement.FRAGMENTS_PROPERTY, 0);
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TextElement)
*/
public boolean visit(TextElement node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
changeNotSupported(node); // no modification possible
return true;
}
void handleException(Throwable e) {
Util.log(e, e.getMessage());
throw new RewriteRuntimeException(e);
}
}