}
boolean insertNew = currPos == -1;
if (insertNew) { // only inserts
if (keyword.length() > 0) { // creating a new list -> insert keyword first (e.g. " throws ")
TextEditGroup editGroup= getEditGroup(this.list[0]); // first node is insert
doTextInsert(offset, keyword, editGroup);
}
currPos= offset;
}
if (lastNonDelete == -1) { // all removed, set back to start so the keyword is removed as well
currPos= offset;
}
int prevEnd= currPos;
int prevMark= RewriteEvent.UNCHANGED;
final int NONE= 0, NEW= 1, EXISTING= 2;
int separatorState= NEW;
for (int i= 0; i < total; i++) {
RewriteEvent currEvent= this.list[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)) {
if (separatorState == EXISTING) {
updateIndent(prevMark, currPos, i, editGroup);
}
doTextInsert(currPos, node, getNodeIndent(i), true, editGroup); // insert node
separatorState= NEW;
if (i != lastNonDelete) {
if (this.list[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);
}
if (insertNew) {
if (endKeyword != null && endKeyword.length() > 0) {
doTextInsert(currPos, endKeyword, editGroup);
}
}
} else if (currMark == RewriteEvent.REMOVED) {
ASTNode node= (ASTNode) currEvent.getOriginalValue();
TextEditGroup editGroup= getEditGroup(currEvent);
int currEnd= getEndOfNode(node);
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=306524
// Check for leading comments that are not part of extended range, and prevent them
// from getting removed.
try {
TokenScanner scanner = getScanner();
int newOffset = prevEnd;
int extendedOffset = getExtendedOffset(node);
// Try to find the end of the last comment which is not part of extended source
// range of the node.
while (TokenScanner.isComment(scanner.readNext(newOffset, false))) {
int tempOffset = scanner.getNextEndOffset(newOffset, false);
// check whether the comment is part of extended source range of the node.
// If it is then we need to stop.
if (tempOffset < extendedOffset) {
newOffset = tempOffset;
} else {
break;
}
}
if (currPos < newOffset) {
currPos = extendedOffset;
}
prevEnd = newOffset;
} catch (CoreException e) {
// ignore
}
if (i > lastNonDelete && separatorState == EXISTING) {
// is last, remove previous separator: split delete to allow range copies
doTextRemove(prevEnd, currPos - prevEnd, editGroup); // remove separator
doTextRemoveAndVisit(currPos, currEnd - currPos, node, editGroup); // remove node
currPos= currEnd;
prevEnd= currEnd;
} else {
if (i < lastNonDelete) {
updateIndent(prevMark, currPos, i, editGroup);
}
// remove element and next separator
int end= getStartOfNextNode(nextIndex, currEnd); // start of next
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=306524
// Check for trailing comments that are not part of extended range, and prevent them
// from getting removed.
try {
TokenScanner scanner = getScanner();
int nextToken= scanner.readNext(currEnd, false);
if (TokenScanner.isComment(nextToken)) {
// the separator also has comments that are not part of extended
// source range of this node or the next node. So dont remove the separator
if (end != scanner.getNextStartOffset(currEnd, false)) {
// If this condition were true, comments just found as part of the separator would've basically been
// part of the extended source range of the next node. So 'end' wud've safely been set to the correct position
// and no change is needed.
end = currEnd;
}
}
} catch (CoreException e) {
// ignore
}
doTextRemoveAndVisit(currPos, currEnd - currPos, node, getEditGroup(currEvent)); // remove node
if (mustRemoveSeparator(currPos, i)) {
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();
updateIndent(prevMark, currPos, i, editGroup);
// make sure that comments between last modified source position and extended starting position of
// node to be replaced are not touched