diff options
author | aclement <aclement> | 2005-09-23 15:50:34 +0000 |
---|---|---|
committer | aclement <aclement> | 2005-09-23 15:50:34 +0000 |
commit | d9fe366566e2d3e1b301692650e9657fbc52e407 (patch) | |
tree | fd51b7bd7a93d4b21f164bf9a5bd67d97d249f11 /org.aspectj.ajdt.core | |
parent | d0ae646468f33d52522cc324e5d7db112c0fd534 (diff) | |
download | aspectj-d9fe366566e2d3e1b301692650e9657fbc52e407.tar.gz aspectj-d9fe366566e2d3e1b301692650e9657fbc52e407.zip |
ast support ! (and testcase)
Diffstat (limited to 'org.aspectj.ajdt.core')
3 files changed, 4161 insertions, 0 deletions
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/org/eclipse/jdt/internal/core/dom/rewrite/AjASTRewriteAnalyzer.java b/org.aspectj.ajdt.core/src/org/aspectj/org/eclipse/jdt/internal/core/dom/rewrite/AjASTRewriteAnalyzer.java new file mode 100644 index 000000000..fb1167b38 --- /dev/null +++ b/org.aspectj.ajdt.core/src/org/aspectj/org/eclipse/jdt/internal/core/dom/rewrite/AjASTRewriteAnalyzer.java @@ -0,0 +1,3621 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.aspectj.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.aspectj.org.eclipse.jdt.core.ToolFactory; +import org.aspectj.org.eclipse.jdt.core.compiler.IScanner; +import org.aspectj.org.eclipse.jdt.core.compiler.ITerminalSymbols; + +import org.aspectj.org.eclipse.jdt.core.dom.*; +import org.aspectj.org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer; +import org.aspectj.org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer.SourceRange; + +import org.aspectj.org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteFormatter.BlockContext; +import org.aspectj.org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteFormatter.NodeMarker; +import org.aspectj.org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteFormatter.Prefix; +import org.aspectj.org.eclipse.jdt.internal.core.dom.rewrite.NodeInfoStore.CopyPlaceholderData; +import org.aspectj.org.eclipse.jdt.internal.core.dom.rewrite.NodeInfoStore.StringPlaceholderData; +import org.aspectj.org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.CopySourceInfo; + + +/** + * Infrastructure to support code modifications. Existing code must stay untouched, new code + * added with correct formatting, moved code left with the user's formatting / 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. + */ +public final class AjASTRewriteAnalyzer extends AjASTVisitor { + + /** + * Internal synonynm for deprecated constant AST.JLS2 + * to alleviate deprecation warnings. + * @deprecated + */ + /*package*/ static final int JLS2_INTERNAL = AST.JLS2; + + TextEdit currentEdit; + final RewriteEventStore eventStore; // used from inner classes + + private TokenScanner tokenScanner; // shared scanner + + private final Map sourceCopyInfoToEdit; + private final Stack sourceCopyEndNodes; + + private final IDocument document; + private final ASTRewriteFormatter formatter; + private final NodeInfoStore nodeInfos; + private final TargetSourceRangeComputer extendedSourceRangeComputer; + + /* + * Constructor for ASTRewriteAnalyzer. + */ + public AjASTRewriteAnalyzer(IDocument document, TextEdit rootEdit, RewriteEventStore eventStore, NodeInfoStore nodeInfos, Map options, TargetSourceRangeComputer extendedSourceRangeComputer) { + this.eventStore= eventStore; + this.document= document; + this.nodeInfos= nodeInfos; + this.tokenScanner= null; + this.currentEdit= rootEdit; + this.sourceCopyInfoToEdit= new IdentityHashMap(); + this.sourceCopyEndNodes= new Stack(); + + this.formatter= new ASTRewriteFormatter(nodeInfos, eventStore, options, TextUtilities.getDefaultLineDelimiter(document)); + + this.extendedSourceRangeComputer = extendedSourceRangeComputer; + } + + final TokenScanner getScanner() { + if (this.tokenScanner == null) { + IScanner scanner= ToolFactory.createScanner(true, false, false, false); + scanner.setSource(getDocument().get().toCharArray()); + this.tokenScanner= new TokenScanner(scanner, getDocument()); + } + return this.tokenScanner; + } + + final IDocument getDocument() { + return this.document; + } + + /** + * Returns the extended source range for a node. + * + * @return an extended source range (never null) + * @since 3.1 + */ + final SourceRange getExtendedRange(ASTNode node) { + if (this.eventStore.isRangeCopyPlaceholder(node)) { + return new SourceRange(node.getStartPosition(), node.getLength()); + } + return this.extendedSourceRangeComputer.computeSourceRange(node); + } + + final int getExtendedOffset(ASTNode node) { + return getExtendedRange(node).getStartPosition(); + } + + final int getExtendedEnd(ASTNode node) { + TargetSourceRangeComputer.SourceRange range= getExtendedRange(node); + return range.getStartPosition() + range.getLength(); + } + + final TextEdit getCopySourceEdit(CopySourceInfo info) { + TextEdit edit= (TextEdit) this.sourceCopyInfoToEdit.get(info); + if (edit == null) { + SourceRange range= getExtendedRange(info.getNode()); + int start= range.getStartPosition(); + int end= start + range.getLength(); + 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; + } + this.sourceCopyInfoToEdit.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 this.eventStore.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 this.nodeInfos.isCollapsed(node); + } + + final boolean isInsertBoundToPrevious(ASTNode node) { + return this.eventStore.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 this.eventStore.getEvent(parent, property); + } + + final TextEditGroup getEditGroup(RewriteEvent change) { + return this.eventStore.getEventEditGroup(change); + } + + private final Object getOriginalValue(ASTNode parent, StructuralPropertyDescriptor property) { + return this.eventStore.getOriginalValue(parent, property); + } + + private final Object getNewValue(ASTNode parent, StructuralPropertyDescriptor property) { + return this.eventStore.getNewValue(parent, property); + } + + final void addEdit(TextEdit edit) { + this.currentEdit.addChild(edit); + } + + final String getLineDelimiter() { + return this.formatter.lineDelimiter; + } + + final String createIndentString(int indent) { + return this.formatter.createIndentString(indent); + } + + final String getIndentAtOffset(int pos) { + try { + IRegion line= getDocument().getLineInformationOfOffset(pos); + String str= getDocument().get(line.getOffset(), line.getLength()); + return this.formatter.getIndentString(str); + } catch (BadLocationException e) { + return ""; //$NON-NLS-1$ + } + } + + 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) { + this.currentEdit= edit; + voidVisit(node); + this.currentEdit= edit.getParent(); + } else { + voidVisit(node); + } + } + + final int doVisit(ASTNode node) { + node.accept(this); + return getExtendedEnd(node); + } + + 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()) { + return doVisitList((List) node, offset); + } + return offset; + } + + private int doVisitList(List list, int offset) { + int endPos= offset; + for (Iterator iter= list.iterator(); iter.hasNext();) { + ASTNode curr= ((ASTNode) iter.next()); + endPos= doVisit(curr); + } + return endPos; + } + + final void voidVisit(ASTNode node) { + node.accept(this); + } + + private final void voidVisit(ASTNode parent, StructuralPropertyDescriptor property) { + Object node= getOriginalValue(parent, property); + if (property.isChildProperty() && node != null) { + voidVisit((ASTNode) node); + } else if (property.isChildListProperty()) { + voidVisitList((List) node); + } + } + + private void voidVisitList(List list) { + for (Iterator iter= list.iterator(); iter.hasNext();) { + doVisit(((ASTNode) iter.next())); + } + } + + private final boolean doVisitUnchangedChildren(ASTNode parent) { + List properties= parent.structuralPropertiesForType(); + for (int i= 0; i < properties.size(); i++) { + voidVisit(parent, (StructuralPropertyDescriptor) properties.get(i)); + } + 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, TextEditGroup editGroup) { + TextEdit targetEdit; + SourceModifier modifier= new SourceModifier(sourceIndentLevel, destIndentString, this.formatter.tabWidth, this.formatter.indentWidth); + + if (sourceEdit instanceof MoveSourceEdit) { + MoveSourceEdit moveEdit= (MoveSourceEdit) sourceEdit; + moveEdit.setSourceModifier(modifier); + + targetEdit= new MoveTargetEdit(destOffset, moveEdit); + addEdit(targetEdit); + } else { + CopySourceEdit copyEdit= (CopySourceEdit) sourceEdit; + copyEdit.setSourceModifier(modifier); + + targetEdit= new CopyTargetEdit(destOffset, copyEdit); + addEdit(targetEdit); + } + + if (editGroup != null) { + addEditGroup(editGroup, sourceEdit); + 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 contantSeparator; + protected int startPos; + + protected RewriteEvent[] list; + + protected final ASTNode getOriginalNode(int index) { + return (ASTNode) this.list[index].getOriginalValue(); + } + + protected final ASTNode getNewNode(int index) { + return (ASTNode) this.list[index].getNewValue(); + } + + protected String getSeparatorString(int nodeIndex) { + return this.contantSeparator; + } + + protected int getInitialIndent() { + return getIndent(this.startPos); + } + + 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 < this.list.length; i++) { + RewriteEvent elem= this.list[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 offset, String keyword, String separator) { + this.contantSeparator= separator; + return rewriteList(parent, property, offset, keyword); + } + + private boolean insertAfterSeparator(ASTNode node) { + return !isInsertBoundToPrevious(node); + } + + public final int rewriteList(ASTNode parent, StructuralPropertyDescriptor property, int offset, String keyword) { + this.startPos= offset; + this.list= getEvent(parent, property).getChildren(); + + int total= this.list.length; + if (total == 0) { + return this.startPos; + } + + int currPos= -1; + + int lastNonInsert= -1; + int lastNonDelete= -1; + + for (int i= 0; i < total; i++) { + int currMark= this.list[i].getChangeKind(); + + if (currMark != RewriteEvent.INSERTED) { + lastNonInsert= i; + if (currPos == -1) { + ASTNode elem= (ASTNode) this.list[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(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; + + 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)) { + 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); + } + } 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 + doTextRemoveAndVisit(currPos, currEnd - currPos, node, editGroup); // remove node + currPos= currEnd; + prevEnd= currEnd; + } else { + // remove element and next separator + int end= getStartOfNextNode(nextIndex, currEnd); // start of next + doTextRemoveAndVisit(currPos, currEnd - currPos, node, getEditGroup(currEvent)); // remove 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(); + doTextRemoveAndVisit(currPos, currEnd - currPos, node, editGroup); + doTextInsert(currPos, changed, getNodeIndent(i), true, editGroup); + + prevEnd= currEnd; + } else { // is unchanged + ASTNode node= (ASTNode) currEvent.getOriginalValue(); + voidVisit(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 (this.list[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 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); + SourceRange range= getExtendedRange(node); + int offset= range.getStartPosition(); + int length= range.getLength(); + 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), 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); + SourceRange range= getExtendedRange(node); + int nodeOffset= range.getStartPosition(); + int nodeLen= range.getLength(); + doTextRemoveAndVisit(nodeOffset, nodeLen, node, editGroup); + doTextInsert(nodeOffset, (ASTNode) event.getNewValue(), getIndent(offset), true, editGroup); + return nodeOffset + nodeLen; + } + } + } + return doVisit(parent, property, offset); + } + + 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() + getIndentAtOffset(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, node, this.eventStore); + + 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, replacingNode, this.eventStore); + 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= this.formatter.computeIndentUnits(lineInPrefix); + } + doTextInsert(offset, replacingNode, indent, true, editGroup); + doTextInsert(offset, strings[1], editGroup); + return endPos; + } + } + } + int pos= doVisit(parent, property, offset); + if (endPos != -1) { + return endPos; + } + return pos; + } + + 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); + SourceRange range= getExtendedRange(node); + int offset= range.getStartPosition(); + int length= range.getLength(); + + doTextRemoveAndVisit(offset, length, node, editGroup); + doTextInsert(offset, (ASTNode) event.getNewValue(), getIndent(startPos), true, editGroup); + try { + return getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameDOT, offset + length); + } catch (CoreException e) { + handleException(e); + } + break; + } + } + } + Object node= getOriginalValue(parent, property); + if (node == null) { + return startPos; + } + int pos= doVisit((ASTNode) node); + try { + return getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameDOT, pos); + } catch (CoreException e) { + handleException(e); + } + return pos; + } + + private class ParagraphListRewriter extends ListRewriter { + + public final static int DEFAULT_SPACING= 1; + + private int initialIndent; + private int separatorLines; + + public ParagraphListRewriter(int initialIndent, int separator) { + this.initialIndent= initialIndent; + this.separatorLines= separator; + } + + protected int getInitialIndent() { + return this.initialIndent; + } + + protected String getSeparatorString(int nodeIndex) { + int newLines= this.separatorLines == -1 ? getNewLines(nodeIndex) : this.separatorLines; + + String lineDelim= getLineDelimiter(); + StringBuffer buf= new StringBuffer(lineDelim); + for (int i= 0; i < newLines; i++) { + buf.append(lineDelim); + } + buf.append(createIndentString(getNodeIndent(nodeIndex + 1))); + return buf.toString(); + } + + private ASTNode getNode(int nodeIndex) { + ASTNode elem= (ASTNode) this.list[nodeIndex].getOriginalValue(); + if (elem == null) { + elem= (ASTNode) this.list[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 < this.list.length; i++) { + ASTNode elem= (ASTNode) this.list[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= getDocument(); + 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(); + ParagraphListRewriter listRewriter= new ParagraphListRewriter(insertIndent, separator); + StringBuffer leadString= new StringBuffer(); + if (isAllOfKind(events, RewriteEvent.INSERTED)) { + for (int i= 0; i < lead; i++) { + leadString.append(getLineDelimiter()); + } + leadString.append(createIndentString(insertIndent)); + } + return listRewriter.rewriteList(parent, property, insertPos, leadString.toString()); + } + + private int rewriteOptionalTypeParameters(ASTNode parent, StructuralPropertyDescriptor property, int offset, String keyword, boolean adjustOnNext, boolean needsSpaceOnRemoveAll) { + int pos= offset; + RewriteEvent event= getEvent(parent, property); + if (event != null && event.getChangeKind() != RewriteEvent.UNCHANGED) { + RewriteEvent[] children= event.getChildren(); + try { + boolean isAllInserted= isAllOfKind(children, RewriteEvent.INSERTED); + if (isAllInserted && adjustOnNext) { + pos= getScanner().getNextStartOffset(pos, false); // adjust on next element + } + boolean isAllRemoved= !isAllInserted && isAllOfKind(children, RewriteEvent.REMOVED); + if (isAllRemoved) { // all removed: set start to left bracket + int posBeforeOpenBracket= getScanner().getTokenStartOffset(ITerminalSymbols.TokenNameLESS, pos); + if (posBeforeOpenBracket != pos) { + needsSpaceOnRemoveAll= false; + } + pos= posBeforeOpenBracket; + } + pos= new ListRewriter().rewriteList(parent, property, pos, String.valueOf('<'), ", "); //$NON-NLS-1$ //$NON-NLS-2$ + if (isAllRemoved) { // all removed: remove right and space up to next element + int endPos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameGREATER, pos); // set pos to '>' + endPos= getScanner().getNextStartOffset(endPos, false); + String replacement= needsSpaceOnRemoveAll ? String.valueOf(' ') : new String(); + doTextReplace(pos, endPos - pos, replacement, getEditGroup(children[children.length - 1])); + return endPos; + } else if (isAllInserted) { + doTextInsert(pos, String.valueOf('>' + keyword), getEditGroup(children[children.length - 1])); + return pos; + } + } catch (CoreException e) { + handleException(e); + } + } else { + pos= doVisit(parent, property, pos); + } + if (pos != offset) { // list contained some type -> parse after closing bracket + try { + return getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameGREATER, pos); + } catch (CoreException e) { + handleException(e); + } + } + return pos; + } + + private boolean isAllOfKind(RewriteEvent[] children, int kind) { + for (int i= 0; i < children.length; i++) { + if (children[i].getChangeKind() != kind) { + return false; + } + } + return true; + } + + 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 rewriteAdviceBody(AdviceDeclaration parent, int startPos) { + //ajh02: method added, forked from rewriteMethodBody + RewriteEvent event= getEvent(parent, AdviceDeclaration.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= this.formatter.METHOD_BODY.getPrefix(indent); + 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; + } + } + } + voidVisit(parent, AdviceDeclaration.BODY_PROPERTY); + } + + 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= this.formatter.METHOD_BODY.getPrefix(indent); + 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; + } + } + } + voidVisit(parent, MethodDeclaration.BODY_PROPERTY); + } + + 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= getDocument().getLineInformationOfOffset(pos); + String str= getDocument().get(line.getOffset(), line.getLength()); + return this.formatter.computeIndentUnits(str); + } catch (BadLocationException e) { + return 0; + } + } + + final void doTextInsert(int insertOffset, ASTNode node, int initialIndentLevel, boolean removeLeadingIndent, TextEditGroup editGroup) { + ArrayList markers= new ArrayList(); + String formatted= this.formatter.getFormattedResult(node, initialIndentLevel, markers); + + + 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= this.formatter.getIndentString(getCurrentLine(formatted, offset)); + if (data instanceof CopyPlaceholderData) { // replace with a copy/move target + CopySourceInfo copySource= ((CopyPlaceholderData) data).copySource; + int srcIndentLevel= getIndent(copySource.getNode().getStartPosition()); + TextEdit sourceEdit= getCopySourceEdit(copySource); + doTextCopy(sourceEdit, insertOffset, srcIndentLevel, destIndentString, 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= this.formatter.changeIndent(code, 0, destIndentString); + 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 (Indents.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; + } + try { + int oldModifiers= ((Integer) event.getOriginalValue()).intValue(); + int newModifiers= ((Integer) event.getNewValue()).intValue(); + TextEditGroup editGroup= getEditGroup(event); + + TokenScanner scanner= getScanner(); + + int tok= scanner.readNext(offset, false); + int startPos= scanner.getCurrentStartOffset(); + int nextStart= startPos; + loop: while (true) { + if (TokenScanner.isComment(tok)) { + tok= scanner.readNext(true); // next non-comment token + } + 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(false); // include comments + int currPos= nextStart; + nextStart= getScanner().getCurrentStartOffset(); + if (!keep) { + doTextRemove(currPos, nextStart - currPos, editGroup); + } + } + int addedModifiers= newModifiers & ~oldModifiers; + if (addedModifiers != 0) { + if (startPos != nextStart) { + 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(nextStart, buf.toString(), editGroup); + } + } catch (CoreException e) { + handleException(e); + } + } + + private class ModifierRewriter extends ListRewriter { + + private final Prefix annotationSeparation; + + public ModifierRewriter(Prefix annotationSeparation) { + this.annotationSeparation= annotationSeparation; + } + + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer.ListRewriter#getSeparatorString(int) + */ + protected String getSeparatorString(int nodeIndex) { + ASTNode curr= getNewNode(nodeIndex); + if (curr instanceof Annotation) { + return this.annotationSeparation.getPrefix(getNodeIndent(nodeIndex + 1)); + } + return super.getSeparatorString(nodeIndex); + } + } + + + private int rewriteModifiers2(ASTNode node, ChildListPropertyDescriptor property, int pos) { + RewriteEvent event= getEvent(node, property); + if (event == null || event.getChangeKind() == RewriteEvent.UNCHANGED) { + return doVisit(node, property, pos); + } + RewriteEvent[] children= event.getChildren(); + boolean isAllInsert= isAllOfKind(children, RewriteEvent.INSERTED); + boolean isAllRemove= isAllOfKind(children, RewriteEvent.REMOVED); + if (isAllInsert || isAllRemove) { + // update pos + try { + pos= getScanner().getNextStartOffset(pos, false); + } catch (CoreException e) { + handleException(e); + } + } + + int endPos= new ModifierRewriter(this.formatter.ANNOTATION_SEPARATION).rewriteList(node, property, pos, "", " "); //$NON-NLS-1$ //$NON-NLS-2$ + + if (isAllInsert) { + doTextInsert(endPos, " ", getEditGroup(children[children.length - 1])); //$NON-NLS-1$ + } else if (isAllRemove) { + try { + int nextPos= getScanner().getNextStartOffset(endPos, false); // to the next token + doTextRemove(endPos, nextPos - endPos, getEditGroup(children[children.length - 1])); + return nextPos; + } catch (CoreException e) { + handleException(e); + } + } + return endPos; + } + + + 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.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#postVisit(ASTNode) + */ + public void postVisit(ASTNode node) { + TextEditGroup editGroup= this.eventStore.getTrackedNodeData(node); + if (editGroup != null) { + this.currentEdit= this.currentEdit.getParent(); + } + // remove copy source edits + doCopySourcePostVisit(node, this.sourceCopyEndNodes); + } + + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#preVisit(ASTNode) + */ + public void preVisit(ASTNode node) { + // copies, then range marker + + CopySourceInfo[] infos= this.eventStore.getNodeCopySources(node); + doCopySourcePreVisit(infos, this.sourceCopyEndNodes); + + TextEditGroup editGroup= this.eventStore.getTrackedNodeData(node); + if (editGroup != null) { + SourceRange range= getExtendedRange(node); + int offset= range.getStartPosition(); + int length= range.getLength(); + TextEdit edit= new RangeMarker(offset, length); + addEditGroup(editGroup, edit); + addEdit(edit); + this.currentEdit= 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); + this.currentEdit= edit; + nodeEndStack.push(curr.getNode()); + } + } + } + + final void doCopySourcePostVisit(ASTNode node, Stack nodeEndStack) { + while (!nodeEndStack.isEmpty() && nodeEndStack.peek() == node) { + nodeEndStack.pop(); + this.currentEdit= this.currentEdit.getParent(); + } + } + + /* (non-Javadoc) + * @see org.aspectj.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; + } + + + public boolean visit(AspectDeclaration node) { + // ajh02: method added + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + int apiLevel= node.getAST().apiLevel(); + + int pos= rewriteJavadoc(node, AspectDeclaration.JAVADOC_PROPERTY); + + if (apiLevel == JLS2_INTERNAL) { + rewriteModifiers(node, AspectDeclaration.MODIFIERS_PROPERTY, pos); + } else { + rewriteModifiers2(node, AspectDeclaration.MODIFIERS2_PROPERTY, pos); + } + + boolean isInterface= ((Boolean) getOriginalValue(node, AspectDeclaration.INTERFACE_PROPERTY)).booleanValue(); + // modifiers & class/interface + boolean invertType= isChanged(node, AspectDeclaration.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, AspectDeclaration.INTERFACE_PROPERTY)); + } catch (CoreException e) { + // ignore + } + } + + // name + pos= rewriteRequiredNode(node, AspectDeclaration.NAME_PROPERTY); + pos = rewriteRequiredNode(node, AspectDeclaration.PERCLAUSE_PROPERTY); + + if (apiLevel >= AST.JLS3) { + pos= rewriteOptionalTypeParameters(node, AspectDeclaration.TYPE_PARAMETERS_PROPERTY, pos, "", false, true); //$NON-NLS-1$ + } + + // superclass + if (!isInterface || invertType) { + ChildPropertyDescriptor superClassProperty= (apiLevel == JLS2_INTERNAL) ? AspectDeclaration.SUPERCLASS_PROPERTY : AspectDeclaration.SUPERCLASS_TYPE_PROPERTY; + + RewriteEvent superClassEvent= getEvent(node, superClassProperty); + + 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(); + SourceRange range= getExtendedRange(superClass); + int offset= range.getStartPosition(); + int length= range.getLength(); + 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, superClassProperty, pos); + } + } + } + // extended interfaces + ChildListPropertyDescriptor superInterfaceProperty= (apiLevel == JLS2_INTERNAL) ? AspectDeclaration.SUPER_INTERFACES_PROPERTY : AspectDeclaration.SUPER_INTERFACE_TYPES_PROPERTY; + + RewriteEvent interfaceEvent= getEvent(node, superInterfaceProperty); + if (interfaceEvent == null || interfaceEvent.getChangeKind() == RewriteEvent.UNCHANGED) { + if (invertType) { + List originalNodes= (List) getOriginalValue(node, superInterfaceProperty); + 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, AspectDeclaration.INTERFACE_PROPERTY)); + } + } + pos= doVisit(node, superInterfaceProperty, pos); + } else { + String keyword= (isInterface == invertType) ? " implements " : " extends "; //$NON-NLS-1$ //$NON-NLS-2$ + if (invertType) { + List newNodes= (List) interfaceEvent.getNewValue(); + if (!newNodes.isEmpty()) { + List origNodes= (List) interfaceEvent.getOriginalValue(); + int firstStart= pos; + if (!origNodes.isEmpty()) { + firstStart= ((ASTNode) origNodes.get(0)).getStartPosition(); + } + doTextReplace(pos, firstStart - pos, keyword, getEditGroup(node, AspectDeclaration.INTERFACE_PROPERTY)); + keyword= ""; //$NON-NLS-1$ + pos= firstStart; + } + } + pos= rewriteNodeList(node, superInterfaceProperty, 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, AspectDeclaration.BODY_DECLARATIONS_PROPERTY, startPos, startIndent, -1, 2); + return false; + } + + + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(TypeDeclaration) + */ + public boolean visit(TypeDeclaration node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + int apiLevel= node.getAST().apiLevel(); + + int pos= rewriteJavadoc(node, TypeDeclaration.JAVADOC_PROPERTY); + + if (apiLevel == JLS2_INTERNAL) { + rewriteModifiers(node, TypeDeclaration.MODIFIERS_PROPERTY, pos); + } else { + rewriteModifiers2(node, TypeDeclaration.MODIFIERS2_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); + + if (apiLevel >= AST.JLS3) { + pos= rewriteOptionalTypeParameters(node, TypeDeclaration.TYPE_PARAMETERS_PROPERTY, pos, "", false, true); //$NON-NLS-1$ + } + + // superclass + if (!isInterface || invertType) { + ChildPropertyDescriptor superClassProperty= (apiLevel == JLS2_INTERNAL) ? TypeDeclaration.SUPERCLASS_PROPERTY : TypeDeclaration.SUPERCLASS_TYPE_PROPERTY; + + RewriteEvent superClassEvent= getEvent(node, superClassProperty); + + 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(); + SourceRange range= getExtendedRange(superClass); + int offset= range.getStartPosition(); + int length= range.getLength(); + 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, superClassProperty, pos); + } + } + } + // extended interfaces + ChildListPropertyDescriptor superInterfaceProperty= (apiLevel == JLS2_INTERNAL) ? TypeDeclaration.SUPER_INTERFACES_PROPERTY : TypeDeclaration.SUPER_INTERFACE_TYPES_PROPERTY; + + RewriteEvent interfaceEvent= getEvent(node, superInterfaceProperty); + if (interfaceEvent == null || interfaceEvent.getChangeKind() == RewriteEvent.UNCHANGED) { + if (invertType) { + List originalNodes= (List) getOriginalValue(node, superInterfaceProperty); + 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, superInterfaceProperty, pos); + } else { + String keyword= (isInterface == invertType) ? " implements " : " extends "; //$NON-NLS-1$ //$NON-NLS-2$ + if (invertType) { + List newNodes= (List) interfaceEvent.getNewValue(); + if (!newNodes.isEmpty()) { + List origNodes= (List) interfaceEvent.getOriginalValue(); + 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, superInterfaceProperty, 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(AroundAdviceDeclaration node) { + // ajh02: method added + ChildPropertyDescriptor property= (node.getAST().apiLevel() == JLS2_INTERNAL) ? AroundAdviceDeclaration.aroundRETURN_TYPE_PROPERTY : AroundAdviceDeclaration.aroundRETURN_TYPE2_PROPERTY; + + // weakness in the AST: return type can exist, even if missing in source + ASTNode originalReturnType= (ASTNode) getOriginalValue(node, property); + boolean returnTypeExists= originalReturnType != null && originalReturnType.getStartPosition() != -1; + if (returnTypeExists) { + rewriteRequiredNode(node, property); + return; + } + // difficult cases: return type insert or remove + ASTNode newReturnType= (ASTNode) getNewValue(node, property); + } + + private void rewriteReturnType(MethodDeclaration node, boolean isConstructor, boolean isConstructorChange) { + ChildPropertyDescriptor property= (node.getAST().apiLevel() == JLS2_INTERNAL) ? MethodDeclaration.RETURN_TYPE_PROPERTY : MethodDeclaration.RETURN_TYPE2_PROPERTY; + + // weakness in the AST: return type can exist, even if missing in source + ASTNode originalReturnType= (ASTNode) getOriginalValue(node, property); + boolean returnTypeExists= originalReturnType != null && originalReturnType.getStartPosition() != -1; + if (!isConstructorChange && returnTypeExists) { + rewriteRequiredNode(node, property); + return; + } + // difficult cases: return type insert or remove + ASTNode newReturnType= (ASTNode) getNewValue(node, property); + if (isConstructorChange || !returnTypeExists && newReturnType != originalReturnType) { + // use the start offset of the method name to insert + ASTNode originalMethodName= (ASTNode) getOriginalValue(node, MethodDeclaration.NAME_PROPERTY); + int nextStart= originalMethodName.getStartPosition(); // see bug 84049: can't use extended offset + TextEditGroup editGroup= getEditGroup(node, property); + if (isConstructor || !returnTypeExists) { // insert + doTextInsert(nextStart, newReturnType, getIndent(nextStart), true, editGroup); + doTextInsert(nextStart, " ", editGroup); //$NON-NLS-1$ + } else { // remove up to the method name + int offset= getExtendedOffset(originalReturnType); + doTextRemoveAndVisit(offset, nextStart - offset, originalReturnType, editGroup); + } + } + } + + public boolean visit(PointcutDeclaration node) { + // ajh02: method added + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + int pos= rewriteJavadoc(node, PointcutDeclaration.JAVADOC_PROPERTY); + if (node.getAST().apiLevel() == JLS2_INTERNAL) { + rewriteModifiers(node, PointcutDeclaration.MODIFIERS_PROPERTY, pos); + } else { + pos= rewriteModifiers2(node, PointcutDeclaration.MODIFIERS2_PROPERTY, pos); + } + // pointcut name + pos= rewriteRequiredNode(node, PointcutDeclaration.NAME_PROPERTY); + return false; + } + public boolean visit(ReferencePointcut node) { + // ajh02: method added + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + // pointcut name + rewriteRequiredNode(node, ReferencePointcut.NAME_PROPERTY); + return false; + } + public boolean visit(NotPointcut node) { + // ajh02: method added + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + // body + rewriteRequiredNode(node, NotPointcut.BODY_PROPERTY); + return false; + } + public boolean visit(PerObject node) { + // ajh02: method added + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + // body + rewriteRequiredNode(node, PerObject.BODY_PROPERTY); + return false; + } + public boolean visit(PerCflow node) { + // ajh02: method added + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + // body + rewriteRequiredNode(node, PerCflow.BODY_PROPERTY); + return false; + } + public boolean visit(PerTypeWithin node) { + // ajh02: method added + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + // ajh02: should visit the typepattern too.. + return false; + } + public boolean visit(CflowPointcut node) { + // ajh02: method added + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + // body + rewriteRequiredNode(node, CflowPointcut.BODY_PROPERTY); + return false; + } + public boolean visit(AndPointcut node) { + // ajh02: method added + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + // left + rewriteRequiredNode(node, AndPointcut.LEFT_PROPERTY); + // right + rewriteRequiredNode(node, AndPointcut.RIGHT_PROPERTY); + return false; + } + public boolean visit(OrPointcut node) { + // ajh02: method added + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + // left + rewriteRequiredNode(node, OrPointcut.LEFT_PROPERTY); + // right + rewriteRequiredNode(node, OrPointcut.RIGHT_PROPERTY); + return false; + } + + + /* (non-Javadoc) + * @see org.aspectj.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); + if (node.getAST().apiLevel() == JLS2_INTERNAL) { + rewriteModifiers(node, MethodDeclaration.MODIFIERS_PROPERTY, pos); + } else { + pos= rewriteModifiers2(node, MethodDeclaration.MODIFIERS2_PROPERTY, pos); + pos= rewriteOptionalTypeParameters(node, MethodDeclaration.TYPE_PARAMETERS_PROPERTY, pos, " ", true, pos != node.getStartPosition()); //$NON-NLS-1$ + } + + 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; + } + + public boolean commonVisitStuff(AdviceDeclaration node) { + // ajh02: method added + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + int pos= rewriteJavadoc(node, AdviceDeclaration.JAVADOC_PROPERTY); + // pointcut + pos= rewriteRequiredNode(node, AdviceDeclaration.POINTCUT_PROPERTY); + // parameters + try { + if (isChanged(node, AdviceDeclaration.PARAMETERS_PROPERTY)) { + pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLPAREN, pos); + pos= rewriteNodeList(node, AdviceDeclaration.PARAMETERS_PROPERTY, pos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + pos= doVisit(node, AdviceDeclaration.PARAMETERS_PROPERTY, pos); + } + pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameRPAREN, pos); + boolean hasExceptionChanges= isChanged(node, AdviceDeclaration.THROWN_EXCEPTIONS_PROPERTY); + int bodyChangeKind= getChangeKind(node, AdviceDeclaration.BODY_PROPERTY); + pos= rewriteNodeList(node, AdviceDeclaration.THROWN_EXCEPTIONS_PROPERTY, pos, " throws ", ", "); //$NON-NLS-1$ //$NON-NLS-2$ + rewriteAdviceBody(node, pos); + } catch (CoreException e) { + // ignore + } + return false; + } + public boolean visit(BeforeAdviceDeclaration node) { + // ajh02: method added + return commonVisitStuff(node); + } + public boolean visit(AfterAdviceDeclaration node) { + // ajh02: method added + return commonVisitStuff(node); + } + public boolean visit(AfterReturningAdviceDeclaration node) { + // ajh02: method added + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + int pos= rewriteJavadoc(node, AfterReturningAdviceDeclaration.returningJAVADOC_PROPERTY); + // pointcut + pos= rewriteRequiredNode(node, AfterReturningAdviceDeclaration.returningPOINTCUT_PROPERTY); + // parameters + try { + if (isChanged(node, AfterReturningAdviceDeclaration.returningPARAMETERS_PROPERTY)) { + pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLPAREN, pos); + pos= rewriteNodeList(node, AfterReturningAdviceDeclaration.returningPARAMETERS_PROPERTY, pos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + pos= doVisit(node, AfterReturningAdviceDeclaration.returningPARAMETERS_PROPERTY, pos); + } + pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameRPAREN, pos); + if (node.getReturning() != null){ + pos= rewriteRequiredNode(node, AfterReturningAdviceDeclaration.returningRETURNING_PROPERTY); + } + + boolean hasExceptionChanges= isChanged(node, AfterReturningAdviceDeclaration.returningTHROWN_EXCEPTIONS_PROPERTY); + int bodyChangeKind= getChangeKind(node, AfterReturningAdviceDeclaration.returningBODY_PROPERTY); + pos= rewriteNodeList(node, AfterReturningAdviceDeclaration.returningTHROWN_EXCEPTIONS_PROPERTY, pos, " throws ", ", "); //$NON-NLS-1$ //$NON-NLS-2$ + rewriteAdviceBody(node, pos); + } catch (CoreException e) { + // ignore + } + return false; + } + public boolean visit(AfterThrowingAdviceDeclaration node) { +// ajh02: method added + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + int pos= rewriteJavadoc(node, AfterThrowingAdviceDeclaration.throwingJAVADOC_PROPERTY); + // pointcut + pos= rewriteRequiredNode(node, AfterThrowingAdviceDeclaration.throwingPOINTCUT_PROPERTY); + // parameters + try { + if (isChanged(node, AfterThrowingAdviceDeclaration.throwingPARAMETERS_PROPERTY)) { + pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLPAREN, pos); + pos= rewriteNodeList(node, AfterThrowingAdviceDeclaration.throwingPARAMETERS_PROPERTY, pos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + pos= doVisit(node, AfterThrowingAdviceDeclaration.throwingPARAMETERS_PROPERTY, pos); + } + pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameRPAREN, pos); + if (node.getThrowing() != null){ + pos= rewriteRequiredNode(node, AfterThrowingAdviceDeclaration.throwingTHROWING_PROPERTY); + } + + boolean hasExceptionChanges= isChanged(node, AfterThrowingAdviceDeclaration.throwingTHROWN_EXCEPTIONS_PROPERTY); + int bodyChangeKind= getChangeKind(node, AfterThrowingAdviceDeclaration.throwingBODY_PROPERTY); + pos= rewriteNodeList(node, AfterThrowingAdviceDeclaration.throwingTHROWN_EXCEPTIONS_PROPERTY, pos, " throws ", ", "); //$NON-NLS-1$ //$NON-NLS-2$ + rewriteAdviceBody(node, pos); + } catch (CoreException e) { + // ignore + } + return false; + } + public boolean visit(AroundAdviceDeclaration node) { + // ajh02: method added + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + int pos= rewriteJavadoc(node, AroundAdviceDeclaration.aroundJAVADOC_PROPERTY); + if (node.getAST().apiLevel() == JLS2_INTERNAL) { + pos= rewriteOptionalTypeParameters(node, AroundAdviceDeclaration.aroundTYPE_PARAMETERS_PROPERTY, pos, " ", true, pos != node.getStartPosition()); //$NON-NLS-1$ + } + + rewriteReturnType(node); + + // parameters + try { + if (isChanged(node, AroundAdviceDeclaration.aroundPARAMETERS_PROPERTY)) { + pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLPAREN, pos); + pos= rewriteNodeList(node, AroundAdviceDeclaration.aroundPARAMETERS_PROPERTY, pos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + pos= doVisit(node, AroundAdviceDeclaration.aroundPARAMETERS_PROPERTY, pos); + } + + pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameRPAREN, pos); + + boolean hasExceptionChanges= isChanged(node, AroundAdviceDeclaration.aroundTHROWN_EXCEPTIONS_PROPERTY); + + int bodyChangeKind= getChangeKind(node, AroundAdviceDeclaration.aroundBODY_PROPERTY); + + pos= rewriteNodeList(node, AroundAdviceDeclaration.aroundTHROWN_EXCEPTIONS_PROPERTY, pos, " throws ", ", "); //$NON-NLS-1$ //$NON-NLS-2$ + rewriteAdviceBody(node, pos); + } catch (CoreException e) { + // ignore + } + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.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.aspectj.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.aspectj.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.aspectj.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.aspectj.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)) { + SourceRange range= getExtendedRange(oldType); + int offset= range.getStartPosition(); + int length= range.getLength(); + doTextRemove(offset, length, editGroup); + doTextInsert(offset, newType, 0, false, editGroup); + } + nNewBrackets= replacingType.getDimensions(); // is replaced type + } + voidVisit(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); + SourceRange range= getExtendedRange(elem); + int elemOffset= range.getStartPosition(); + int elemLength= range.getLength(); + doTextRemoveAndVisit(elemOffset, elemLength, elem, editGroup); + doTextInsert(elemOffset, (ASTNode) event.getNewValue(), 0, false, editGroup); + nNewBrackets--; + } else { + voidVisit(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.aspectj.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.aspectj.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.aspectj.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.aspectj.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.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(BooleanLiteral) + */ + public boolean visit(BooleanLiteral node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + + Boolean newLiteral= (Boolean) getNewValue(node, BooleanLiteral.BOOLEAN_VALUE_PROPERTY); + TextEditGroup group = getEditGroup(node, BooleanLiteral.BOOLEAN_VALUE_PROPERTY); + doTextReplace(node.getStartPosition(), node.getLength(), newLiteral.toString(), group); + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.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.aspectj.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.aspectj.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.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(CharacterLiteral) + */ + public boolean visit(CharacterLiteral node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + + String escapedSeq= (String) getNewValue(node, CharacterLiteral.ESCAPED_VALUE_PROPERTY); + TextEditGroup group = getEditGroup(node, CharacterLiteral.ESCAPED_VALUE_PROPERTY); + doTextReplace(node.getStartPosition(), node.getLength(), escapedSeq, group); + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(ClassInstanceCreation) + */ + public boolean visit(ClassInstanceCreation node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + + int pos= rewriteOptionalQualifier(node, ClassInstanceCreation.EXPRESSION_PROPERTY, node.getStartPosition()); + if (node.getAST().apiLevel() == JLS2_INTERNAL) { + pos= rewriteRequiredNode(node, ClassInstanceCreation.NAME_PROPERTY); + } else { + if (isChanged(node, ClassInstanceCreation.TYPE_ARGUMENTS_PROPERTY)) { + try { + pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNamenew, pos); //after 'new' + rewriteOptionalTypeParameters(node, ClassInstanceCreation.TYPE_ARGUMENTS_PROPERTY, pos, " ", true, true); //$NON-NLS-1$ + } catch (CoreException e) { + handleException(e); + } + } else { + voidVisit(node, ClassInstanceCreation.TYPE_ARGUMENTS_PROPERTY); + } + pos= rewriteRequiredNode(node, ClassInstanceCreation.TYPE_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 { + voidVisit(node, ClassInstanceCreation.ARGUMENTS_PROPERTY); + } + + 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.aspectj.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.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(ConstructorInvocation) + */ + public boolean visit(ConstructorInvocation node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + int pos= node.getStartPosition(); + if (node.getAST().apiLevel() >= AST.JLS3) { + pos= rewriteOptionalTypeParameters(node, ConstructorInvocation.TYPE_ARGUMENTS_PROPERTY, pos, "", false, false); //$NON-NLS-1$ + } + try { + pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLPAREN, pos); + rewriteNodeList(node, ConstructorInvocation.ARGUMENTS_PROPERTY, pos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$ + } catch (CoreException e) { + handleException(e); + } + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.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.aspectj.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()), this.formatter.DO_BLOCK); // body + } else { + voidVisit(node, DoStatement.BODY_PROPERTY); + } + } catch (CoreException e) { + handleException(e); + } + + rewriteRequiredNode(node, DoStatement.EXPRESSION_PROPERTY); + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.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.aspectj.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.aspectj.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.aspectj.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); + + if (node.getAST().apiLevel() == JLS2_INTERNAL) { + rewriteModifiers(node, FieldDeclaration.MODIFIERS_PROPERTY, pos); + } else { + rewriteModifiers2(node, FieldDeclaration.MODIFIERS2_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.aspectj.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()), this.formatter.FOR_BLOCK); // body + } else { + voidVisit(node, ForStatement.BODY_PROPERTY); + } + + } catch (CoreException e) { + handleException(e); + } + + + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.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, this.formatter.IF_BLOCK_NO_ELSE); + } else { + pos= rewriteBodyNode(node, IfStatement.THEN_STATEMENT_PROPERTY, pos, endPos, indent, this.formatter.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, this.formatter.ELSE_AFTER_BLOCK); + } else { + rewriteBodyNode(node, IfStatement.ELSE_STATEMENT_PROPERTY, pos, -1, indent, this.formatter.ELSE_AFTER_STATEMENT); + } + } else { + pos= doVisit(node, IfStatement.ELSE_STATEMENT_PROPERTY, pos); + } + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(ImportDeclaration) + */ + public boolean visit(ImportDeclaration node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + if (node.getAST().apiLevel() >= AST.JLS3) { + RewriteEvent event= getEvent(node, ImportDeclaration.STATIC_PROPERTY); + if (event != null && event.getChangeKind() != RewriteEvent.UNCHANGED) { + boolean wasStatic= ((Boolean) event.getOriginalValue()).booleanValue(); + int pos= node.getStartPosition(); + if (wasStatic) { + try { + int endPos= getScanner().getTokenStartOffset(ITerminalSymbols.TokenNameimport, pos); + doTextRemove(pos, endPos - pos, getEditGroup(event)); + } catch (CoreException e) { + handleException(e); + } + } else { + doTextInsert(pos, "static ", getEditGroup(event)); //$NON-NLS-1$ + } + } + } + + 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.aspectj.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.aspectj.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); + if (node.getAST().apiLevel() == JLS2_INTERNAL) { + rewriteModifiers(node, Initializer.MODIFIERS_PROPERTY, pos); + } else { + rewriteModifiers2(node, Initializer.MODIFIERS2_PROPERTY, pos); + } + rewriteRequiredNode(node, Initializer.BODY_PROPERTY); + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.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.aspectj.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() + getIndentAtOffset(node.getStartPosition()) + " * "; //$NON-NLS-1$ + + rewriteNodeList(node, Javadoc.TAGS_PROPERTY, startPos, separator, separator); + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.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.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(MethodInvocation) + */ + public boolean visit(MethodInvocation node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + + int pos= rewriteOptionalQualifier(node, MethodInvocation.EXPRESSION_PROPERTY, node.getStartPosition()); + if (node.getAST().apiLevel() >= AST.JLS3) { + pos= rewriteOptionalTypeParameters(node, MethodInvocation.TYPE_ARGUMENTS_PROPERTY, pos, "", false, false); //$NON-NLS-1$ + } + + 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 { + voidVisit(node, MethodInvocation.ARGUMENTS_PROPERTY); + } + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.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.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(NumberLiteral) + */ + public boolean visit(NumberLiteral node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + String newLiteral= (String) getNewValue(node, NumberLiteral.TOKEN_PROPERTY); + TextEditGroup group = getEditGroup(node, NumberLiteral.TOKEN_PROPERTY); + doTextReplace(node.getStartPosition(), node.getLength(), newLiteral, group); + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(PackageDeclaration) + */ + public boolean visit(PackageDeclaration node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + if (node.getAST().apiLevel() >= AST.JLS3) { + int pos= rewriteJavadoc(node, PackageDeclaration.JAVADOC_PROPERTY); + rewriteNodeList(node, PackageDeclaration.ANNOTATIONS_PROPERTY, pos, "", " "); //$NON-NLS-1$ //$NON-NLS-2$ + } + + rewriteRequiredNode(node, PackageDeclaration.NAME_PROPERTY); + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.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.aspectj.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.aspectj.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.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(PrimitiveType) + */ + public boolean visit(PrimitiveType node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + PrimitiveType.Code newCode= (PrimitiveType.Code) getNewValue(node, PrimitiveType.PRIMITIVE_TYPE_CODE_PROPERTY); + TextEditGroup group = getEditGroup(node, PrimitiveType.PRIMITIVE_TYPE_CODE_PROPERTY); + doTextReplace(node.getStartPosition(), node.getLength(), newCode.toString(), group); + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.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.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(SimpleName) + */ + public boolean visit(SimpleName node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + String newString= (String) getNewValue(node, SimpleName.IDENTIFIER_PROPERTY); + TextEditGroup group = getEditGroup(node, SimpleName.IDENTIFIER_PROPERTY); + doTextReplace(node.getStartPosition(), node.getLength(), newString, group); + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.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.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(SingleVariableDeclaration) + */ + public boolean visit(SingleVariableDeclaration node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + int pos= node.getStartPosition(); + if (node.getAST().apiLevel() == JLS2_INTERNAL) { + rewriteModifiers(node, SingleVariableDeclaration.MODIFIERS_PROPERTY, pos); + } else { + rewriteModifiers2(node, SingleVariableDeclaration.MODIFIERS2_PROPERTY, pos); + } + pos= rewriteRequiredNode(node, SingleVariableDeclaration.TYPE_PROPERTY); + if (node.getAST().apiLevel() >= AST.JLS3) { + if (isChanged(node, SingleVariableDeclaration.VARARGS_PROPERTY)) { + if (getNewValue(node, SingleVariableDeclaration.VARARGS_PROPERTY).equals(Boolean.TRUE)) { + doTextInsert(pos, "...", getEditGroup(node, SingleVariableDeclaration.VARARGS_PROPERTY)); //$NON-NLS-1$ + } else { + try { + int ellipsisEnd= getScanner().getNextEndOffset(pos, true); + doTextRemove(pos, ellipsisEnd - pos, getEditGroup(node, SingleVariableDeclaration.VARARGS_PROPERTY)); //$NON-NLS-1$ + } catch (CoreException e) { + handleException(e); + } + } + } + } + + 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, this.formatter.VAR_INITIALIZER); + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(StringLiteral) + */ + public boolean visit(StringLiteral node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + String escapedSeq= (String) getNewValue(node, StringLiteral.ESCAPED_VALUE_PROPERTY); + TextEditGroup group = getEditGroup(node, StringLiteral.ESCAPED_VALUE_PROPERTY); + doTextReplace(node.getStartPosition(), node.getLength(), escapedSeq, group); + + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.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 (node.getAST().apiLevel() >= AST.JLS3) { + pos= rewriteOptionalTypeParameters(node, SuperConstructorInvocation.TYPE_ARGUMENTS_PROPERTY, pos, "", false, false); //$NON-NLS-1$ + } + + 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 { + voidVisit(node, SuperConstructorInvocation.ARGUMENTS_PROPERTY); + } + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.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.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(SuperMethodInvocation) + */ + public boolean visit(SuperMethodInvocation node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + + int pos= rewriteOptionalQualifier(node, SuperMethodInvocation.QUALIFIER_PROPERTY, node.getStartPosition()); + + if (node.getAST().apiLevel() >= AST.JLS3) { + if (isChanged(node, SuperMethodInvocation.TYPE_ARGUMENTS_PROPERTY)) { + try { + pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameDOT, pos); + rewriteOptionalTypeParameters(node, SuperMethodInvocation.TYPE_ARGUMENTS_PROPERTY, pos, "", false, false); //$NON-NLS-1$ + } catch (CoreException e) { + handleException(e); + } + } + } + + 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 { + voidVisit(node, SuperMethodInvocation.ARGUMENTS_PROPERTY); + } + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.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) this.list[nodeIndex].getOriginalValue(); + if (node == null) { + node= (ASTNode) this.list[nodeIndex].getNewValue(); + } + if (node.getNodeType() != ASTNode.SWITCH_CASE) { + indent++; + } + return indent; + } + } + + /* (non-Javadoc) + * @see org.aspectj.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(createIndentString(insertIndent)); + listRewriter.rewriteList(node, property, pos, leadString.toString()); + } catch (CoreException e) { + handleException(e); + } + } else { + voidVisit(node, SwitchStatement.STATEMENTS_PROPERTY); + } + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.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.aspectj.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.aspectj.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.aspectj.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= this.formatter.CATCH_BLOCK.getPrefix(indent); + 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, this.formatter.FINALLY_BLOCK); + return false; + } + + + + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(TypeDeclarationStatement) + */ + public boolean visit(TypeDeclarationStatement node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + if (node.getAST().apiLevel() == JLS2_INTERNAL) { + rewriteRequiredNode(node, TypeDeclarationStatement.TYPE_DECLARATION_PROPERTY); + } else { + rewriteRequiredNode(node, TypeDeclarationStatement.DECLARATION_PROPERTY); + } + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.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.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(VariableDeclarationExpression) + */ + public boolean visit(VariableDeclarationExpression node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + + // same code as FieldDeclaration + int pos= node.getStartPosition(); + if (node.getAST().apiLevel() == JLS2_INTERNAL) { + rewriteModifiers(node, VariableDeclarationExpression.MODIFIERS_PROPERTY, pos); + } else { + rewriteModifiers2(node, VariableDeclarationExpression.MODIFIERS2_PROPERTY, pos); + } + pos= rewriteRequiredNode(node, VariableDeclarationExpression.TYPE_PROPERTY); + rewriteNodeList(node, VariableDeclarationExpression.FRAGMENTS_PROPERTY, pos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$ + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.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, this.formatter.VAR_INITIALIZER); + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(VariableDeclarationStatement) + */ + public boolean visit(VariableDeclarationStatement node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + + // same code as FieldDeclaration + int pos= node.getStartPosition(); + if (node.getAST().apiLevel() == JLS2_INTERNAL) { + rewriteModifiers(node, VariableDeclarationStatement.MODIFIERS_PROPERTY, pos); + } else { + rewriteModifiers2(node, VariableDeclarationStatement.MODIFIERS2_PROPERTY, pos); + } + pos= rewriteRequiredNode(node, VariableDeclarationStatement.TYPE_PROPERTY); + + rewriteNodeList(node, VariableDeclarationStatement.FRAGMENTS_PROPERTY, pos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$ + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.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()), this.formatter.WHILE_BLOCK); // body + } else { + voidVisit(node, WhileStatement.BODY_PROPERTY); + } + } catch (CoreException e) { + handleException(e); + } + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(org.aspectj.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.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(org.aspectj.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 { + voidVisit(node, MethodRef.PARAMETERS_PROPERTY); + } + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(org.aspectj.org.eclipse.jdt.core.dom.MethodRefParameter) + */ + public boolean visit(MethodRefParameter node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + int pos= rewriteRequiredNode(node, MethodRefParameter.TYPE_PROPERTY); + if (node.getAST().apiLevel() >= AST.JLS3) { + if (isChanged(node, MethodRefParameter.VARARGS_PROPERTY)) { + if (getNewValue(node, MethodRefParameter.VARARGS_PROPERTY).equals(Boolean.TRUE)) { + doTextInsert(pos, "...", getEditGroup(node, MethodRefParameter.VARARGS_PROPERTY)); //$NON-NLS-1$ + } else { + try { + int ellipsisEnd= getScanner().getNextEndOffset(pos, true); + doTextRemove(pos, ellipsisEnd - pos, getEditGroup(node, MethodRefParameter.VARARGS_PROPERTY)); //$NON-NLS-1$ + } catch (CoreException e) { + handleException(e); + } + } + } + } + rewriteNode(node, MethodRefParameter.NAME_PROPERTY, pos, ASTRewriteFormatter.SPACE); //$NON-NLS-1$ + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(org.aspectj.org.eclipse.jdt.core.dom.TagElement) + */ + public boolean visit(TagElement node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + + int changeKind= getChangeKind(node, TagElement.TAG_NAME_PROPERTY); + switch (changeKind) { + case RewriteEvent.INSERTED: { + String newTagName= (String) getNewValue(node, TagElement.TAG_NAME_PROPERTY); + doTextInsert(node.getStartPosition(), newTagName, getEditGroup(node, TagElement.TAG_NAME_PROPERTY)); + break; + } + case RewriteEvent.REMOVED: { + doTextRemove(node.getStartPosition(), findTagNameEnd(node) - node.getStartPosition(), getEditGroup(node, TagElement.TAG_NAME_PROPERTY)); + break; + } + case RewriteEvent.REPLACED: { + String newTagName= (String) getNewValue(node, TagElement.TAG_NAME_PROPERTY); + doTextReplace(node.getStartPosition(), findTagNameEnd(node) - node.getStartPosition(), newTagName, getEditGroup(node, TagElement.TAG_NAME_PROPERTY)); + break; + } + } + + if (isChanged(node, TagElement.FRAGMENTS_PROPERTY)) { + // eval position after name + int endOffset= findTagNameEnd(node); + rewriteNodeList(node, TagElement.FRAGMENTS_PROPERTY, endOffset, " ", " "); //$NON-NLS-1$//$NON-NLS-2$ + } else { + voidVisit(node, TagElement.FRAGMENTS_PROPERTY); + } + return false; + } + + private int findTagNameEnd(TagElement tagNode) { + if (tagNode.getTagName() != null) { + try { + IDocument doc = getDocument(); + int len= doc.getLength(); + int i= tagNode.getStartPosition(); + while (i < len && !Indents.isIndentChar(doc.getChar(i))) { + i++; + } + return i; + } catch (BadLocationException e) { + handleException(e); + } + } + return tagNode.getStartPosition(); + } + + + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(org.aspectj.org.eclipse.jdt.core.dom.TextElement) + */ + public boolean visit(TextElement node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + String newText= (String) getNewValue(node, TextElement.TEXT_PROPERTY); + TextEditGroup group = getEditGroup(node, TextElement.TEXT_PROPERTY); + doTextReplace(node.getStartPosition(), node.getLength(), newText, group); + return false; + } + + + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(org.aspectj.org.eclipse.jdt.core.dom.AnnotationTypeDeclaration) + */ + public boolean visit(AnnotationTypeDeclaration node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + int pos= rewriteJavadoc(node, AnnotationTypeDeclaration.JAVADOC_PROPERTY); + rewriteModifiers2(node, AnnotationTypeDeclaration.MODIFIERS2_PROPERTY, pos); + pos= rewriteRequiredNode(node, AnnotationTypeDeclaration.NAME_PROPERTY); + + int startIndent= getIndent(node.getStartPosition()) + 1; + int startPos= getPosAfterLeftBrace(pos); + rewriteParagraphList(node, AnnotationTypeDeclaration.BODY_DECLARATIONS_PROPERTY, startPos, startIndent, -1, 2); + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(org.aspectj.org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration) + */ + public boolean visit(AnnotationTypeMemberDeclaration node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + int pos= rewriteJavadoc(node, AnnotationTypeMemberDeclaration.JAVADOC_PROPERTY); + rewriteModifiers2(node, AnnotationTypeMemberDeclaration.MODIFIERS2_PROPERTY, pos); + rewriteRequiredNode(node, AnnotationTypeMemberDeclaration.TYPE_PROPERTY); + pos= rewriteRequiredNode(node, AnnotationTypeMemberDeclaration.NAME_PROPERTY); + + try { + int changeKind= getChangeKind(node, AnnotationTypeMemberDeclaration.DEFAULT_PROPERTY); + if (changeKind == RewriteEvent.INSERTED || changeKind == RewriteEvent.REMOVED) { + pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameRPAREN, pos); + } + rewriteNode(node, AnnotationTypeMemberDeclaration.DEFAULT_PROPERTY, pos, this.formatter.ANNOT_MEMBER_DEFAULT); + } catch (CoreException e) { + handleException(e); + } + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(org.aspectj.org.eclipse.jdt.core.dom.EnhancedForStatement) + */ + public boolean visit(EnhancedForStatement node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + rewriteRequiredNode(node, EnhancedForStatement.PARAMETER_PROPERTY); + int pos= rewriteRequiredNode(node, EnhancedForStatement.EXPRESSION_PROPERTY); + + RewriteEvent bodyEvent= getEvent(node, EnhancedForStatement.BODY_PROPERTY); + if (bodyEvent != null && bodyEvent.getChangeKind() == RewriteEvent.REPLACED) { + int startOffset; + try { + startOffset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameRPAREN, pos); + rewriteBodyNode(node, EnhancedForStatement.BODY_PROPERTY, startOffset, -1, getIndent(node.getStartPosition()), this.formatter.FOR_BLOCK); // body + } catch (CoreException e) { + handleException(e); + } + } else { + voidVisit(node, EnhancedForStatement.BODY_PROPERTY); + } + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(org.aspectj.org.eclipse.jdt.core.dom.EnumConstantDeclaration) + */ + public boolean visit(EnumConstantDeclaration node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + int pos= rewriteJavadoc(node, EnumConstantDeclaration.JAVADOC_PROPERTY); + rewriteModifiers2(node, EnumConstantDeclaration.MODIFIERS2_PROPERTY, pos); + pos= rewriteRequiredNode(node, EnumConstantDeclaration.NAME_PROPERTY); + RewriteEvent argsEvent= getEvent(node, EnumConstantDeclaration.ARGUMENTS_PROPERTY); + if (argsEvent != null && argsEvent.getChangeKind() != RewriteEvent.UNCHANGED) { + RewriteEvent[] children= argsEvent.getChildren(); + try { + int nextTok= getScanner().readNext(pos, true); + boolean hasParents= (nextTok == ITerminalSymbols.TokenNameLPAREN); + boolean isAllRemoved= hasParents && isAllOfKind(children, RewriteEvent.REMOVED); + String prefix= ""; //$NON-NLS-1$ + if (!hasParents) { + prefix= "("; //$NON-NLS-1$ + } else if (!isAllRemoved) { + pos= getScanner().getCurrentEndOffset(); + } + pos= rewriteNodeList(node, EnumConstantDeclaration.ARGUMENTS_PROPERTY, pos, prefix, ", "); //$NON-NLS-1$ //$NON-NLS-2$ + + if (!hasParents) { + doTextInsert(pos, ")", getEditGroup(children[children.length - 1])); //$NON-NLS-1$ + } else if (isAllRemoved) { + int afterClosing= getScanner().getNextEndOffset(pos, true); + doTextRemove(pos, afterClosing - pos, getEditGroup(children[children.length - 1])); + pos= afterClosing; + } + } catch (CoreException e) { + handleException(e); + } + } else { + pos= doVisit(node, EnumConstantDeclaration.ARGUMENTS_PROPERTY, 0); + } + + if (isChanged(node, EnumConstantDeclaration.ANONYMOUS_CLASS_DECLARATION_PROPERTY)) { + int kind= getChangeKind(node, EnumConstantDeclaration.ANONYMOUS_CLASS_DECLARATION_PROPERTY); + if (kind == RewriteEvent.REMOVED) { + try { + // 'pos' can be before brace + pos= getScanner().getPreviousTokenEndOffset(ITerminalSymbols.TokenNameLBRACE, pos); + } catch (CoreException e) { + handleException(e); + } + } else { + pos= node.getStartPosition() + node.getLength(); // insert pos + } + rewriteNode(node, EnumConstantDeclaration.ANONYMOUS_CLASS_DECLARATION_PROPERTY, pos, ASTRewriteFormatter.SPACE); //$NON-NLS-1$ + } + return false; + } + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(org.aspectj.org.eclipse.jdt.core.dom.EnumDeclaration) + */ + public boolean visit(EnumDeclaration node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + int pos= rewriteJavadoc(node, EnumDeclaration.JAVADOC_PROPERTY); + rewriteModifiers2(node, EnumDeclaration.MODIFIERS2_PROPERTY, pos); + pos= rewriteRequiredNode(node, EnumDeclaration.NAME_PROPERTY); + pos= rewriteNodeList(node, EnumDeclaration.SUPER_INTERFACE_TYPES_PROPERTY, pos, " implements ", ", "); //$NON-NLS-1$ //$NON-NLS-2$ + + pos= getPosAfterLeftBrace(pos); + + String leadString= ""; //$NON-NLS-1$ + RewriteEvent constEvent= getEvent(node, EnumDeclaration.ENUM_CONSTANTS_PROPERTY); + + if (constEvent != null && constEvent.getChangeKind() != RewriteEvent.UNCHANGED) { + RewriteEvent[] events= constEvent.getChildren(); + if (isAllOfKind(events, RewriteEvent.INSERTED)) { + leadString= this.formatter.FIRST_ENUM_CONST.getPrefix(getIndent(node.getStartPosition())); + } + } + pos= rewriteNodeList(node, EnumDeclaration.ENUM_CONSTANTS_PROPERTY, pos, leadString, ", "); //$NON-NLS-1$ //$NON-NLS-2$ + + RewriteEvent bodyEvent= getEvent(node, EnumDeclaration.BODY_DECLARATIONS_PROPERTY); + int indent= 0; + if (bodyEvent != null && bodyEvent.getChangeKind() != RewriteEvent.UNCHANGED) { + boolean hasConstants= !((List) getNewValue(node, EnumDeclaration.ENUM_CONSTANTS_PROPERTY)).isEmpty(); + + RewriteEvent[] children= bodyEvent.getChildren(); + try { + if (hasConstants) { + indent= getIndent(pos); + } else { + indent= getIndent(node.getStartPosition()) + 1; + } + int token= getScanner().readNext(pos, true); + boolean hasSemicolon= token == ITerminalSymbols.TokenNameSEMICOLON; + if (!hasSemicolon && isAllOfKind(children, RewriteEvent.INSERTED)) { + if (!hasConstants) { + String str= this.formatter.FIRST_ENUM_CONST.getPrefix(indent - 1); + doTextInsert(pos, str, getEditGroup(children[0])); //$NON-NLS-1$ + } + doTextInsert(pos, ";", getEditGroup(children[0])); //$NON-NLS-1$ + } else if (hasSemicolon) { + int endPos= getScanner().getCurrentEndOffset(); + if (isAllOfKind(children, RewriteEvent.REMOVED)) { + doTextRemove(pos, endPos - pos, getEditGroup(children[0])); //$NON-NLS-1$ + } + pos= endPos; + } + } catch (CoreException e) { + handleException(e); + } + } + rewriteParagraphList(node, EnumDeclaration.BODY_DECLARATIONS_PROPERTY, pos, indent, -1, 2); + return false; + } + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(org.aspectj.org.eclipse.jdt.core.dom.MarkerAnnotation) + */ + public boolean visit(MarkerAnnotation node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + rewriteRequiredNode(node, MarkerAnnotation.TYPE_NAME_PROPERTY); + return false; + } + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(org.aspectj.org.eclipse.jdt.core.dom.MemberValuePair) + */ + public boolean visit(MemberValuePair node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + rewriteRequiredNode(node, MemberValuePair.NAME_PROPERTY); + rewriteRequiredNode(node, MemberValuePair.VALUE_PROPERTY); + + return false; + } + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(org.aspectj.org.eclipse.jdt.core.dom.Modifier) + */ + public boolean visit(Modifier node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + String newText= getNewValue(node, Modifier.KEYWORD_PROPERTY).toString(); // type Modifier.ModifierKeyword + TextEditGroup group = getEditGroup(node, Modifier.KEYWORD_PROPERTY); + doTextReplace(node.getStartPosition(), node.getLength(), newText, group); + return false; + } + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(org.aspectj.org.eclipse.jdt.core.dom.NormalAnnotation) + */ + public boolean visit(NormalAnnotation node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + int pos= rewriteRequiredNode(node, NormalAnnotation.TYPE_NAME_PROPERTY); + if (isChanged(node, NormalAnnotation.VALUES_PROPERTY)) { + // eval position after opening parent + try { + int startOffset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLPAREN, pos); + rewriteNodeList(node, NormalAnnotation.VALUES_PROPERTY, startOffset, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$ + } catch (CoreException e) { + handleException(e); + } + } else { + voidVisit(node, NormalAnnotation.VALUES_PROPERTY); + } + return false; + } + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(org.aspectj.org.eclipse.jdt.core.dom.ParameterizedType) + */ + public boolean visit(ParameterizedType node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + int pos= rewriteRequiredNode(node, ParameterizedType.TYPE_PROPERTY); + if (isChanged(node, ParameterizedType.TYPE_ARGUMENTS_PROPERTY)) { + // eval position after opening parent + try { + int startOffset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLESS, pos); + rewriteNodeList(node, ParameterizedType.TYPE_ARGUMENTS_PROPERTY, startOffset, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$ + } catch (CoreException e) { + handleException(e); + } + } else { + voidVisit(node, ParameterizedType.TYPE_ARGUMENTS_PROPERTY); + } + return false; + } + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(org.aspectj.org.eclipse.jdt.core.dom.QualifiedType) + */ + public boolean visit(QualifiedType node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + rewriteRequiredNode(node, QualifiedType.QUALIFIER_PROPERTY); + rewriteRequiredNode(node, QualifiedType.NAME_PROPERTY); + return false; + } + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(org.aspectj.org.eclipse.jdt.core.dom.SingleMemberAnnotation) + */ + public boolean visit(SingleMemberAnnotation node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + rewriteRequiredNode(node, SingleMemberAnnotation.TYPE_NAME_PROPERTY); + rewriteRequiredNode(node, SingleMemberAnnotation.VALUE_PROPERTY); + return false; + } + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(org.aspectj.org.eclipse.jdt.core.dom.TypeParameter) + */ + public boolean visit(TypeParameter node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + int pos= rewriteRequiredNode(node, TypeParameter.NAME_PROPERTY); + if (isChanged(node, TypeParameter.TYPE_BOUNDS_PROPERTY)) { + rewriteNodeList(node, TypeParameter.TYPE_BOUNDS_PROPERTY, pos, " extends ", " & "); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + voidVisit(node, TypeParameter.TYPE_BOUNDS_PROPERTY); + } + return false; + } + /* (non-Javadoc) + * @see org.aspectj.org.eclipse.jdt.core.dom.ASTVisitor#visit(org.aspectj.org.eclipse.jdt.core.dom.WildcardType) + */ + public boolean visit(WildcardType node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + try { + int pos= getScanner().getNextEndOffset(node.getStartPosition(), true); // pos after question mark + + Prefix prefix; + if (Boolean.TRUE.equals(getNewValue(node, WildcardType.UPPER_BOUND_PROPERTY))) { + prefix= this.formatter.WILDCARD_EXTENDS; + } else { + prefix= this.formatter.WILDCARD_SUPER; + } + + int boundKindChange= getChangeKind(node, WildcardType.UPPER_BOUND_PROPERTY); + if (boundKindChange != RewriteEvent.UNCHANGED) { + int boundTypeChange= getChangeKind(node, WildcardType.BOUND_PROPERTY); + if (boundTypeChange != RewriteEvent.INSERTED && boundTypeChange != RewriteEvent.REMOVED) { + ASTNode type= (ASTNode) getOriginalValue(node, WildcardType.BOUND_PROPERTY); + String str= prefix.getPrefix(0); + doTextReplace(pos, type.getStartPosition() - pos, str, getEditGroup(node, WildcardType.BOUND_PROPERTY)); + } + } + rewriteNode(node, WildcardType.BOUND_PROPERTY, pos, prefix); + } catch (CoreException e) { + handleException(e); + } + return false; + } + + final void handleException(Throwable e) { + IllegalArgumentException runtimeException= new IllegalArgumentException("Document does not match the AST"); //$NON-NLS-1$ + runtimeException.initCause(e); + throw runtimeException; + } +} diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/tools/ajc/ASTVisitorTest.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/tools/ajc/ASTVisitorTest.java new file mode 100644 index 000000000..785c7f3ec --- /dev/null +++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/tools/ajc/ASTVisitorTest.java @@ -0,0 +1,539 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.aspectj.tools.ajc; + +import java.util.HashMap; + +import junit.framework.TestCase; + +import org.aspectj.org.eclipse.jdt.core.dom.AST; +import org.aspectj.org.eclipse.jdt.core.dom.ASTParser; +import org.aspectj.org.eclipse.jdt.core.dom.AfterAdviceDeclaration; +import org.aspectj.org.eclipse.jdt.core.dom.AfterReturningAdviceDeclaration; +import org.aspectj.org.eclipse.jdt.core.dom.AfterThrowingAdviceDeclaration; +import org.aspectj.org.eclipse.jdt.core.dom.AjASTVisitor; +import org.aspectj.org.eclipse.jdt.core.dom.AjTypeDeclaration; +import org.aspectj.org.eclipse.jdt.core.dom.AroundAdviceDeclaration; +import org.aspectj.org.eclipse.jdt.core.dom.Assignment; +import org.aspectj.org.eclipse.jdt.core.dom.BeforeAdviceDeclaration; +import org.aspectj.org.eclipse.jdt.core.dom.Block; +import org.aspectj.org.eclipse.jdt.core.dom.BodyDeclaration; +import org.aspectj.org.eclipse.jdt.core.dom.CompilationUnit; +import org.aspectj.org.eclipse.jdt.core.dom.DeclareDeclaration; +import org.aspectj.org.eclipse.jdt.core.dom.ExpressionStatement; +import org.aspectj.org.eclipse.jdt.core.dom.FieldAccess; +import org.aspectj.org.eclipse.jdt.core.dom.FieldDeclaration; +import org.aspectj.org.eclipse.jdt.core.dom.InfixExpression; +import org.aspectj.org.eclipse.jdt.core.dom.Initializer; +import org.aspectj.org.eclipse.jdt.core.dom.InterTypeFieldDeclaration; +import org.aspectj.org.eclipse.jdt.core.dom.InterTypeMethodDeclaration; +import org.aspectj.org.eclipse.jdt.core.dom.MethodDeclaration; +import org.aspectj.org.eclipse.jdt.core.dom.MethodInvocation; +import org.aspectj.org.eclipse.jdt.core.dom.NumberLiteral; +import org.aspectj.org.eclipse.jdt.core.dom.PointcutDeclaration; +import org.aspectj.org.eclipse.jdt.core.dom.PrimitiveType; +import org.aspectj.org.eclipse.jdt.core.dom.QualifiedName; +import org.aspectj.org.eclipse.jdt.core.dom.SimpleName; +import org.aspectj.org.eclipse.jdt.core.dom.StringLiteral; +import org.aspectj.org.eclipse.jdt.core.dom.TypeDeclaration; +import org.aspectj.org.eclipse.jdt.core.dom.VariableDeclaration; +import org.aspectj.org.eclipse.jdt.core.dom.VariableDeclarationStatement; +import org.aspectj.weaver.patterns.DeclareAnnotation; +import org.aspectj.weaver.patterns.DeclareErrorOrWarning; +import org.aspectj.weaver.patterns.DeclareParents; +import org.aspectj.weaver.patterns.DeclarePrecedence; +import org.aspectj.weaver.patterns.DeclareSoft; + +public class ASTVisitorTest extends TestCase { + + public void testAnInterface() { + check("interface AnInterface{}","(compilationUnit(interface(simpleName)))"); + } + public void testAnAspect() { + check("aspect AnAspect{}","(compilationUnit(aspect(simpleName)))"); + } + public void testPointcutInClass() { + check("class A {pointcut a();}", + "(compilationUnit(class(simpleName)(pointcut(simpleName))))"); + } + public void testPointcutInAspect() { + check("aspect A {pointcut a();}","(compilationUnit(aspect(simpleName)(pointcut(simpleName))))"); + } + public void testAroundAdvice() { + check("aspect A {pointcut a();void around():a(){}}", + "(compilationUnit(aspect(simpleName)(pointcut(simpleName))(aroundAdvice(primitiveType)(simpleName)(block))))"); + } + public void testAroundAdviceWithProceed() { + // ajh02: currently proceed calls are just normal method calls + // could add a special AST node for them if anyone would like + check("aspect A {pointcut a();void around():a(){proceed();}}", + "(compilationUnit(aspect(simpleName)(pointcut(simpleName))(aroundAdvice(primitiveType)(simpleName)(block(expressionStatement(methodInvocation(simpleName)))))))"); + } + public void testBeforeAdvice() { + check("aspect A {pointcut a();before():a(){}}", + "(compilationUnit(aspect(simpleName)(pointcut(simpleName))(beforeAdvice(simpleName)(block))))"); + } + public void testAfterAdvice() { + check("aspect A {pointcut a();after():a(){}}", + "(compilationUnit(aspect(simpleName)(pointcut(simpleName))(afterAdvice(simpleName)(block))))"); + } + public void testAfterThrowingAdvice() { + check("aspect A {pointcut a();after()throwing(Exception e):a(){} }", + "(compilationUnit(aspect(simpleName)(pointcut(simpleName))(afterThrowingAdvice(simpleName)(simpleName)(simpleName)(block))))"); + } + public void testAfterReturningAdvice() { + check("aspect A {pointcut a();after()returning(Object o):a(){}}", + "(compilationUnit(aspect(simpleName)(pointcut(simpleName))(afterReturningAdvice(simpleName)(simpleName)(simpleName)(block))))"); + } + public void testMethodWithStatements() { + check("class A {void a(){System.out.println(\"a\");}}", + "(compilationUnit(class(simpleName)(method(primitiveType)(simpleName)(block(expressionStatement(methodInvocation(qualifiedName(simpleName)(simpleName))(simpleName)(stringLiteral)))))))"); + } + public void testAdviceWithStatements() { + check("aspect A {pointcut a();before():a(){System.out.println(\"a\");}}", + "(compilationUnit(aspect(simpleName)(pointcut(simpleName))(beforeAdvice(simpleName)(block(expressionStatement(methodInvocation(qualifiedName(simpleName)(simpleName))(simpleName)(stringLiteral)))))))"); + } + public void testPointcutInAPointcut() { + check("aspect A {pointcut a();pointcut b();pointcut c(): a() && b();}", + "(compilationUnit(aspect(simpleName)(pointcut(simpleName))(pointcut(simpleName))(pointcut(simpleName)(simpleName)(simpleName))))"); + } + + public void testCallPointcut(){ + check("aspect A {pointcut a(): call(* *.*(..));}", + "(compilationUnit(aspect(simpleName)(pointcut(simpleName))))"); + } + public void testExecutionPointcut(){ + check("aspect A {pointcut a(): execution(* *.*(..));}", + "(compilationUnit(aspect(simpleName)(pointcut(simpleName))))"); + } + public void testGetPointcut(){ + check("aspect A {pointcut a(): get(* *.*);}", + "(compilationUnit(aspect(simpleName)(pointcut(simpleName))))"); + } + public void testSetPointcut(){ + check("aspect A {pointcut a(): set(* *.*);}", + "(compilationUnit(aspect(simpleName)(pointcut(simpleName))))"); + } + public void testHandlerPointcut(){ + check("aspect A {pointcut a(): handler(Exception+);}", + "(compilationUnit(aspect(simpleName)(pointcut(simpleName))))"); + } + public void testStaticInitializationPointcut(){ + check("aspect A {pointcut a(): staticinitialization(Object+);}", + "(compilationUnit(aspect(simpleName)(pointcut(simpleName))))"); + } + public void testInitializationPointcut(){ + check("aspect A {pointcut a(): initialization(public Object+.new());}", + "(compilationUnit(aspect(simpleName)(pointcut(simpleName))))"); + } + public void testPreInitializationPointcut(){ + check("aspect A {pointcut a(): preinitialization(public Object+.new());}", + "(compilationUnit(aspect(simpleName)(pointcut(simpleName))))"); + } + public void testAdviceExecutionPointcut(){ + check("aspect A {pointcut a(): adviceexecution();}", + "(compilationUnit(aspect(simpleName)(pointcut(simpleName))))"); + } + + public void testFieldITD(){ + check("class A {}aspect B {int A.a;}", + "(compilationUnit(class(simpleName))(aspect(simpleName)(fieldITD(primitiveType)(simpleName))))"); + } + public void testMethodITD(){ + check("class A {}aspect B {void A.a(){}}", + "(compilationUnit(class(simpleName))(aspect(simpleName)(methodITD(primitiveType)(simpleName)(block))))"); + } + public void testConstructorITD(){ + check("class A {}aspect B {A.new(){}}", + "(compilationUnit(class(simpleName))(aspect(simpleName)(constructorITD(primitiveType)(simpleName)(block))))"); + } + + public void testInitializedField(){ + check("class A{int a = 1;}", + "(compilationUnit(class(simpleName)(field(primitiveType)(simpleName)(numberLiteral))))"); + } + public void testMethodITDWithStatements(){ + check("class A {}aspect B {void A.a(){System.out.println(\"a\");}}", + "(compilationUnit(class(simpleName))(aspect(simpleName)(methodITD(primitiveType)(simpleName)(block(expressionStatement(methodInvocation(qualifiedName(simpleName)(simpleName))(simpleName)(stringLiteral)))))))"); + } + public void testConstructorITDWithStatements(){ + check("class A {}aspect B {A.new(){System.out.println(\"a\");}}", + "(compilationUnit(class(simpleName))(aspect(simpleName)(constructorITD(primitiveType)(simpleName)(block(expressionStatement(methodInvocation(qualifiedName(simpleName)(simpleName))(simpleName)(stringLiteral)))))))"); + } + public void testInitializedFieldITD(){ + check("class A {}aspect B {int A.a = 1;}", + "(compilationUnit(class(simpleName))(aspect(simpleName)(fieldITD(primitiveType)(simpleName)(numberLiteral))))"); + } + + public void testMethodBeingCalled(){ + check("class A {void a(){}void b(){a();}}", + "(compilationUnit(class(simpleName)(method(primitiveType)(simpleName)(block))(method(primitiveType)(simpleName)(block(expressionStatement(methodInvocation(simpleName)))))))"); + } + public void testFieldBeingCalled(){ + check("class A {int a;void b(){int c = a;a = c;}}", + "(compilationUnit(class(simpleName)(field(primitiveType)(simpleName))(method(primitiveType)(simpleName)(block(variableDeclarationStatement(primitiveType)(simpleName)(simpleName))(expressionStatement(assignment(simpleName)(simpleName)))))))"); + } + public void testConstructorBeingCalled(){ + check("class A {A(){}void b(){A();}}", + "(compilationUnit(class(simpleName)(constructor(primitiveType)(simpleName)(block))(method(primitiveType)(simpleName)(block(expressionStatement(methodInvocation(simpleName)))))))"); + } + public void testMethodITDBeingCalled(){ + check("class A {void b(){a();}}aspect B {void A.a(){}}", + "(compilationUnit(class(simpleName)(method(primitiveType)(simpleName)(block(expressionStatement(methodInvocation(simpleName))))))(aspect(simpleName)(methodITD(primitiveType)(simpleName)(block))))"); + } + public void testFieldITDBeingCalled(){ + check("class A {void b(){int c = a;a = c;}}aspect B {int A.a;}", + "(compilationUnit(class(simpleName)(method(primitiveType)(simpleName)(block(variableDeclarationStatement(primitiveType)(simpleName)(simpleName))(expressionStatement(assignment(simpleName)(simpleName))))))(aspect(simpleName)(fieldITD(primitiveType)(simpleName))))"); + } + public void testConstructorITDBeingCalled(){ + check("class A {void b(){A();}}aspect B {A.new(){}}", + "(compilationUnit(class(simpleName)(method(primitiveType)(simpleName)(block(expressionStatement(methodInvocation(simpleName))))))(aspect(simpleName)(constructorITD(primitiveType)(simpleName)(block))))"); + } + + public void testDeclareParents(){ + check("class A{}class B{}aspect C {declare parents : A extends B;}", + "(compilationUnit(class(simpleName))(class(simpleName))(aspect(simpleName)(declareParents)))"); + } + public void testDeclareWarning(){ + check("aspect A {pointcut a();declare warning: a(): \"warning\";}", + "(compilationUnit(aspect(simpleName)(pointcut(simpleName))(declareWarning)))"); + } + public void testDeclareError(){ + check("aspect A {pointcut a();declare error: a(): \"error\";}", + "(compilationUnit(aspect(simpleName)(pointcut(simpleName))(declareError)))"); + } + public void testDeclareSoft(){ + check("aspect A {pointcut a();declare soft: Exception+: a();}", + "(compilationUnit(aspect(simpleName)(pointcut(simpleName))(declareSoft)))"); + } + public void testDeclarePrecedence(){ + check("aspect A{}aspect B{declare precedence: B,A;}", + "(compilationUnit(aspect(simpleName))(aspect(simpleName)(declarePrecedence)))"); + } + + public void testPerThis(){ + check("aspect A perthis(a()) {pointcut a();}", + "(compilationUnit(aspect(simpleName)(simpleName)(pointcut(simpleName))))"); + } + public void testPerTarget(){ + check("aspect A pertarget(a()) {pointcut a();}", + "(compilationUnit(aspect(simpleName)(simpleName)(pointcut(simpleName))))"); + } + public void testPerCFlow(){ + check("aspect A percflow(a()) {pointcut a();}", + "(compilationUnit(aspect(simpleName)(simpleName)(pointcut(simpleName))))"); + } + public void testPerCFlowBelow(){ + check("aspect A percflowbelow(a()) {pointcut a();}", + "(compilationUnit(aspect(simpleName)(simpleName)(pointcut(simpleName))))"); + } + + private void check(String source, String expectedOutput){ + ASTParser parser = ASTParser.newParser(AST.JLS2); // ajh02: need to use 2 for returnType - in 3 it has "returnType2" + parser.setCompilerOptions(new HashMap());//JavaCore.getOptions()); + parser.setSource(source.toCharArray()); + CompilationUnit cu2 = (CompilationUnit) parser.createAST(null); + TestVisitor visitor = new TestVisitor(); + cu2.accept(visitor); + String result = visitor.toString(); + System.err.println("actual:\n" + result); + assertTrue("Expected:\n"+ expectedOutput + "====Actual:\n" + result, + expectedOutput.equals(result)); + } + + /** @deprecated using deprecated code */ + private static final int AST_INTERNAL_JLS2 = AST.JLS2; + + + /** + * @deprecated (not really - just suppressing the warnings + * that come from testing Javadoc.getComment()) + * + */ + protected void setUp() throws Exception { + super.setUp(); + } + + + protected void tearDown() throws Exception { + super.tearDown(); + } + + protected CompilationUnit createAST(char[] source) { + ASTParser parser= ASTParser.newParser(AST_INTERNAL_JLS2); + parser.setSource(source); + parser.setResolveBindings(false); + return (CompilationUnit) parser.createAST(null); + } +} + +class TestVisitor extends AjASTVisitor { + + StringBuffer b = new StringBuffer(); + boolean visitTheKids = true; + + boolean visitDocTags; + + TestVisitor() { + this(false); + } + + public String toString(){ + return b.toString(); + } + + TestVisitor(boolean visitDocTags) { + super(visitDocTags); + this.visitDocTags = visitDocTags; + } + + public boolean isVisitingChildren() { + return visitTheKids; + } + + public void setVisitingChildren(boolean visitChildren) { + visitTheKids = visitChildren; + } + + public boolean visit(TypeDeclaration node) { + if (((AjTypeDeclaration)node).isAspect()) { + b.append("(aspect"); //$NON-NLS-1$ + //if (((AspectDeclaration)node).getPerClause() != null){ + // b.append("{" + ((AspectDeclaration)node).getPerClause() + "}"); + //} + } else if (node.isInterface()){ + b.append("(interface"); // $NON-NLS-1$ + } else { + b.append("(class"); //$NON-NLS-1$ + } + return isVisitingChildren(); + } + public void endVisit(TypeDeclaration node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(PointcutDeclaration node) { + b.append("(pointcut"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public void endVisit(PointcutDeclaration node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(BeforeAdviceDeclaration node) { + b.append("(beforeAdvice"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public boolean visit(AroundAdviceDeclaration node) { + b.append("(aroundAdvice"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public boolean visit(AfterAdviceDeclaration node) { + b.append("(afterAdvice"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public boolean visit(AfterThrowingAdviceDeclaration node) { + b.append("(afterThrowingAdvice"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public boolean visit(AfterReturningAdviceDeclaration node) { + b.append("(afterReturningAdvice"); //$NON-NLS-1$ + return isVisitingChildren(); + } + + public void endVisit(BeforeAdviceDeclaration node) { + b.append(")"); //$NON-NLS-1$ + } + public void endVisit(AroundAdviceDeclaration node) { + b.append(")"); //$NON-NLS-1$ + } + public void endVisit(AfterAdviceDeclaration node) { + b.append(")"); //$NON-NLS-1$ + } + public void endVisit(AfterThrowingAdviceDeclaration node) { + b.append(")"); //$NON-NLS-1$ + } + public void endVisit(AfterReturningAdviceDeclaration node) { + b.append(")"); //$NON-NLS-1$ + } + + public boolean visit(MethodDeclaration node) { + if (node.isConstructor()){ + b.append("(constructor"); + } else { + b.append("(method"); //$NON-NLS-1$ + } + return isVisitingChildren(); + } + public void endVisit(MethodDeclaration node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(InterTypeFieldDeclaration node) { + b.append("(fieldITD"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public void endVisit(InterTypeFieldDeclaration node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(InterTypeMethodDeclaration node) { + if (node.isConstructor()){ + b.append("(constructorITD"); + } else { + b.append("(methodITD"); //$NON-NLS-1$ + } + return isVisitingChildren(); + } + public void endVisit(InterTypeMethodDeclaration node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(MethodInvocation node) { + b.append("(methodInvocation"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public void endVisit(MethodInvocation node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(BodyDeclaration node) { + b.append("(methodInvocation"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public void endVisit(BodyDeclaration node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(FieldDeclaration node) { + b.append("(field"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public void endVisit(FieldDeclaration node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(FieldAccess node) { + b.append("(fieldAccess"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public void endVisit(FieldAccess node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(Assignment node) { + b.append("(assignment"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public void endVisit(Assignment node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(Block node) { + b.append("(block"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public void endVisit(Block node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(CompilationUnit node) { + b.append("(compilationUnit"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public void endVisit(CompilationUnit node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(ExpressionStatement node) { + b.append("(expressionStatement"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public void endVisit(ExpressionStatement node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(InfixExpression node) { + b.append("(infixExpression"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public void endVisit(InfixExpression node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(Initializer node) { + b.append("(initializer"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public void endVisit(Initializer node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(NumberLiteral node) { + b.append("(numberLiteral"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public void endVisit(NumberLiteral node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(PrimitiveType node) { + b.append("(primitiveType"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public void endVisit(PrimitiveType node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(QualifiedName node) { + b.append("(qualifiedName"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public void endVisit(QualifiedName node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(SimpleName node) { + b.append("(simpleName"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public void endVisit(SimpleName node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(StringLiteral node) { + b.append("(stringLiteral"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public void endVisit(StringLiteral node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(VariableDeclaration node) { + b.append("(variableDeclaration"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public void endVisit(VariableDeclaration node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(VariableDeclarationStatement node) { + b.append("(variableDeclarationStatement"); //$NON-NLS-1$ + return isVisitingChildren(); + } + public void endVisit(VariableDeclarationStatement node) { + b.append(")"); //$NON-NLS-1$ + } + public boolean visit(DeclareDeclaration node) { + System.err.println("visiting a DeclareDeclaration"); + if (node.declareDecl instanceof DeclareAnnotation){ + b.append("(declareAnnotation"); + } else if (node.declareDecl instanceof DeclareErrorOrWarning){ + if (((DeclareErrorOrWarning)node.declareDecl).isError()){ + b.append("(declareError"); + } else { + b.append("(declareWarning"); + } + } else if (node.declareDecl instanceof DeclareParents){ + b.append("(declareParents"); + } else if (node.declareDecl instanceof DeclarePrecedence){ + b.append("(declarePrecedence"); + } else if (node.declareDecl instanceof DeclareSoft){ + b.append("(declareSoft"); + } else { + // node.declareDecl is null... weird + b.append("(declareErrorOrWarning"); + } + return isVisitingChildren(); + } + public void endVisit(DeclareDeclaration node) { + b.append(")"); //$NON-NLS-1$ + } +} diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/tools/ajc/AjcTests.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/tools/ajc/AjcTests.java index cb721c841..86e0e3b6c 100644 --- a/org.aspectj.ajdt.core/testsrc/org/aspectj/tools/ajc/AjcTests.java +++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/tools/ajc/AjcTests.java @@ -26,6 +26,7 @@ public class AjcTests extends TestCase { public static Test suite() { TestSuite suite = new TestSuite(AjcTests.class.getName()); suite.addTestSuite(org.aspectj.tools.ajc.MainTest.class); + suite.addTestSuite(ASTVisitorTest.class); return suite; } |