| /******************************************************************************* |
| * Copyright (c) 2000, 2008 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.eclipse.wst.jsdt.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.core.runtime.Assert; |
| import org.eclipse.core.runtime.CoreException; |
| 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.wst.jsdt.core.ToolFactory; |
| import org.eclipse.wst.jsdt.core.compiler.IScanner; |
| import org.eclipse.wst.jsdt.core.compiler.ITerminalSymbols; |
| import org.eclipse.wst.jsdt.core.dom.AST; |
| import org.eclipse.wst.jsdt.core.dom.ASTNode; |
| import org.eclipse.wst.jsdt.core.dom.ASTVisitor; |
| import org.eclipse.wst.jsdt.core.dom.Annotation; |
| import org.eclipse.wst.jsdt.core.dom.AnnotationTypeDeclaration; |
| import org.eclipse.wst.jsdt.core.dom.AnnotationTypeMemberDeclaration; |
| import org.eclipse.wst.jsdt.core.dom.AnonymousClassDeclaration; |
| import org.eclipse.wst.jsdt.core.dom.ArrayAccess; |
| import org.eclipse.wst.jsdt.core.dom.ArrayCreation; |
| import org.eclipse.wst.jsdt.core.dom.ArrayInitializer; |
| import org.eclipse.wst.jsdt.core.dom.ArrayType; |
| import org.eclipse.wst.jsdt.core.dom.AssertStatement; |
| import org.eclipse.wst.jsdt.core.dom.Assignment; |
| import org.eclipse.wst.jsdt.core.dom.Block; |
| import org.eclipse.wst.jsdt.core.dom.BooleanLiteral; |
| import org.eclipse.wst.jsdt.core.dom.BreakStatement; |
| import org.eclipse.wst.jsdt.core.dom.CastExpression; |
| import org.eclipse.wst.jsdt.core.dom.CatchClause; |
| import org.eclipse.wst.jsdt.core.dom.CharacterLiteral; |
| import org.eclipse.wst.jsdt.core.dom.ChildListPropertyDescriptor; |
| import org.eclipse.wst.jsdt.core.dom.ChildPropertyDescriptor; |
| import org.eclipse.wst.jsdt.core.dom.ClassInstanceCreation; |
| import org.eclipse.wst.jsdt.core.dom.JavaScriptUnit; |
| import org.eclipse.wst.jsdt.core.dom.ConditionalExpression; |
| import org.eclipse.wst.jsdt.core.dom.ConstructorInvocation; |
| import org.eclipse.wst.jsdt.core.dom.ContinueStatement; |
| import org.eclipse.wst.jsdt.core.dom.DoStatement; |
| import org.eclipse.wst.jsdt.core.dom.EmptyStatement; |
| import org.eclipse.wst.jsdt.core.dom.EnhancedForStatement; |
| import org.eclipse.wst.jsdt.core.dom.EnumConstantDeclaration; |
| import org.eclipse.wst.jsdt.core.dom.EnumDeclaration; |
| import org.eclipse.wst.jsdt.core.dom.ExpressionStatement; |
| import org.eclipse.wst.jsdt.core.dom.FieldAccess; |
| import org.eclipse.wst.jsdt.core.dom.FieldDeclaration; |
| import org.eclipse.wst.jsdt.core.dom.ForInStatement; |
| import org.eclipse.wst.jsdt.core.dom.ForStatement; |
| import org.eclipse.wst.jsdt.core.dom.FunctionExpression; |
| import org.eclipse.wst.jsdt.core.dom.IfStatement; |
| import org.eclipse.wst.jsdt.core.dom.ImportDeclaration; |
| import org.eclipse.wst.jsdt.core.dom.InfixExpression; |
| import org.eclipse.wst.jsdt.core.dom.Initializer; |
| import org.eclipse.wst.jsdt.core.dom.InstanceofExpression; |
| import org.eclipse.wst.jsdt.core.dom.JSdoc; |
| import org.eclipse.wst.jsdt.core.dom.LabeledStatement; |
| import org.eclipse.wst.jsdt.core.dom.ListExpression; |
| import org.eclipse.wst.jsdt.core.dom.MarkerAnnotation; |
| import org.eclipse.wst.jsdt.core.dom.MemberRef; |
| import org.eclipse.wst.jsdt.core.dom.MemberValuePair; |
| import org.eclipse.wst.jsdt.core.dom.FunctionDeclaration; |
| import org.eclipse.wst.jsdt.core.dom.FunctionInvocation; |
| import org.eclipse.wst.jsdt.core.dom.FunctionRef; |
| import org.eclipse.wst.jsdt.core.dom.FunctionRefParameter; |
| import org.eclipse.wst.jsdt.core.dom.Modifier; |
| import org.eclipse.wst.jsdt.core.dom.NormalAnnotation; |
| import org.eclipse.wst.jsdt.core.dom.NullLiteral; |
| import org.eclipse.wst.jsdt.core.dom.NumberLiteral; |
| import org.eclipse.wst.jsdt.core.dom.ObjectLiteral; |
| import org.eclipse.wst.jsdt.core.dom.ObjectLiteralField; |
| import org.eclipse.wst.jsdt.core.dom.PackageDeclaration; |
| import org.eclipse.wst.jsdt.core.dom.ParameterizedType; |
| import org.eclipse.wst.jsdt.core.dom.ParenthesizedExpression; |
| import org.eclipse.wst.jsdt.core.dom.PostfixExpression; |
| import org.eclipse.wst.jsdt.core.dom.PrefixExpression; |
| import org.eclipse.wst.jsdt.core.dom.PrimitiveType; |
| import org.eclipse.wst.jsdt.core.dom.QualifiedName; |
| import org.eclipse.wst.jsdt.core.dom.QualifiedType; |
| import org.eclipse.wst.jsdt.core.dom.RegularExpressionLiteral; |
| import org.eclipse.wst.jsdt.core.dom.ReturnStatement; |
| import org.eclipse.wst.jsdt.core.dom.SimpleName; |
| import org.eclipse.wst.jsdt.core.dom.SimpleType; |
| import org.eclipse.wst.jsdt.core.dom.SingleMemberAnnotation; |
| import org.eclipse.wst.jsdt.core.dom.SingleVariableDeclaration; |
| import org.eclipse.wst.jsdt.core.dom.StringLiteral; |
| import org.eclipse.wst.jsdt.core.dom.StructuralPropertyDescriptor; |
| import org.eclipse.wst.jsdt.core.dom.SuperConstructorInvocation; |
| import org.eclipse.wst.jsdt.core.dom.SuperFieldAccess; |
| import org.eclipse.wst.jsdt.core.dom.SuperMethodInvocation; |
| import org.eclipse.wst.jsdt.core.dom.SwitchCase; |
| import org.eclipse.wst.jsdt.core.dom.SwitchStatement; |
| import org.eclipse.wst.jsdt.core.dom.TagElement; |
| import org.eclipse.wst.jsdt.core.dom.TextElement; |
| import org.eclipse.wst.jsdt.core.dom.ThisExpression; |
| import org.eclipse.wst.jsdt.core.dom.ThrowStatement; |
| import org.eclipse.wst.jsdt.core.dom.TryStatement; |
| import org.eclipse.wst.jsdt.core.dom.Type; |
| import org.eclipse.wst.jsdt.core.dom.TypeDeclaration; |
| import org.eclipse.wst.jsdt.core.dom.TypeDeclarationStatement; |
| import org.eclipse.wst.jsdt.core.dom.TypeLiteral; |
| import org.eclipse.wst.jsdt.core.dom.TypeParameter; |
| import org.eclipse.wst.jsdt.core.dom.UndefinedLiteral; |
| import org.eclipse.wst.jsdt.core.dom.VariableDeclarationExpression; |
| import org.eclipse.wst.jsdt.core.dom.VariableDeclarationFragment; |
| import org.eclipse.wst.jsdt.core.dom.VariableDeclarationStatement; |
| import org.eclipse.wst.jsdt.core.dom.WhileStatement; |
| import org.eclipse.wst.jsdt.core.dom.WildcardType; |
| import org.eclipse.wst.jsdt.core.dom.WithStatement; |
| import org.eclipse.wst.jsdt.core.dom.rewrite.TargetSourceRangeComputer; |
| import org.eclipse.wst.jsdt.core.dom.rewrite.TargetSourceRangeComputer.SourceRange; |
| import org.eclipse.wst.jsdt.core.formatter.IndentManipulation; |
| import org.eclipse.wst.jsdt.internal.compiler.parser.ScannerHelper; |
| import org.eclipse.wst.jsdt.internal.core.dom.rewrite.ASTRewriteFormatter.BlockContext; |
| import org.eclipse.wst.jsdt.internal.core.dom.rewrite.ASTRewriteFormatter.NodeMarker; |
| import org.eclipse.wst.jsdt.internal.core.dom.rewrite.ASTRewriteFormatter.Prefix; |
| import org.eclipse.wst.jsdt.internal.core.dom.rewrite.NodeInfoStore.CopyPlaceholderData; |
| import org.eclipse.wst.jsdt.internal.core.dom.rewrite.NodeInfoStore.StringPlaceholderData; |
| import org.eclipse.wst.jsdt.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 analyzes the changes or annotations and generates text edits |
| * (text manipulation API) that describe the required code changes. |
| */ |
| public final class ASTRewriteAnalyzer extends ASTVisitor { |
| |
| /** |
| * Internal synonym for deprecated constant AST.JLS2 |
| * to alleviate deprecated 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 char[] content; |
| private final LineInformation lineInfo; |
| private final ASTRewriteFormatter formatter; |
| private final NodeInfoStore nodeInfos; |
| private final TargetSourceRangeComputer extendedSourceRangeComputer; |
| private final LineCommentEndOffsets lineCommentEndOffsets; |
| |
| /** |
| * Constructor for ASTRewriteAnalyzer. |
| * @param content the content of the compilation unit to rewrite. |
| * @param lineInfo line information for the content of the compilation unit to rewrite. |
| * @param rootEdit the edit to add all generated edits to |
| * @param eventStore the event store containing the description of changes |
| * @param nodeInfos annotations to nodes, such as if a node is a string placeholder or a copy target |
| * @param comments list of comments of the compilation unit to rewrite (elements of type <code>Comment</code>) or <code>null</code>. |
| * @param options the current jdt.core options (formatting/compliance) or <code>null</code>. |
| * @param extendedSourceRangeComputer the source range computer to use |
| */ |
| public ASTRewriteAnalyzer(char[] content, LineInformation lineInfo, String lineDelim, TextEdit rootEdit, RewriteEventStore eventStore, NodeInfoStore nodeInfos, List comments, Map options, TargetSourceRangeComputer extendedSourceRangeComputer) { |
| this.eventStore= eventStore; |
| this.content= content; |
| this.lineInfo= lineInfo; |
| this.nodeInfos= nodeInfos; |
| this.tokenScanner= null; |
| this.currentEdit= rootEdit; |
| this.sourceCopyInfoToEdit= new IdentityHashMap(); |
| this.sourceCopyEndNodes= new Stack(); |
| |
| this.formatter= new ASTRewriteFormatter(nodeInfos, eventStore, options, lineDelim); |
| |
| this.extendedSourceRangeComputer = extendedSourceRangeComputer; |
| this.lineCommentEndOffsets= new LineCommentEndOffsets(comments); |
| } |
| |
| final TokenScanner getScanner() { |
| if (this.tokenScanner == null) { |
| IScanner scanner= ToolFactory.createScanner(true, false, false, false); |
| scanner.setSource(this.content); |
| this.tokenScanner= new TokenScanner(scanner); |
| } |
| return this.tokenScanner; |
| } |
| |
| final char[] getContent() { |
| return this.content; |
| } |
| |
| final LineInformation getLineInformation() { |
| return this.lineInfo; |
| } |
| |
| /** |
| * 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.getLineDelimiter(); |
| } |
| |
| final String createIndentString(int indent) { |
| return this.formatter.createIndentString(indent); |
| } |
| |
| final private String getIndentOfLine(int pos) { |
| int line= getLineInformation().getLineOfOffset(pos); |
| if (line >= 0) { |
| char[] cont= getContent(); |
| int lineStart= getLineInformation().getLineOffset(line); |
| int i= lineStart; |
| while (i < cont.length && IndentManipulation.isIndentChar(content[i])) { |
| i++; |
| } |
| return new String(cont, lineStart, i - lineStart); |
| } |
| return new String(); |
| } |
| |
| |
| final String getIndentAtOffset(int pos) { |
| return this.formatter.getIndentString(getIndentOfLine(pos)); |
| } |
| |
| final void doTextInsert(int offset, String insertString, TextEditGroup editGroup) { |
| if (insertString.length() > 0) { |
| // bug fix for 95839: problem with inserting at the end of a line comment |
| if (this.lineCommentEndOffsets.isEndOfLineComment(offset, this.content)) { |
| if (!insertString.startsWith(getLineDelimiter())) { |
| TextEdit edit= new InsertEdit(offset, getLineDelimiter()); // add a line delimiter |
| addEdit(edit); |
| if (editGroup != null) { |
| addEditGroup(editGroup, edit); |
| } |
| } |
| this.lineCommentEndOffsets.remove(offset); // only one line delimiter per line comment required |
| } |
| 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.getTabWidth(), this.formatter.getIndentWidth()); |
| |
| 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$ |
| } |
| |
| |
| 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; |
| } |
| |
| 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) { |
| LineInformation lineInformation= getLineInformation(); |
| int lastLine= lineInformation.getLineOfOffset(getExtendedEnd(last)); |
| if (lastLine >= 0) { |
| int startLine= lastLine + 1; |
| int start= lineInformation.getLineOffset(startLine); |
| if (start < 0) { |
| return 0; |
| } |
| char[] cont= getContent(); |
| int i= start; |
| while (i < cont.length && ScannerHelper.isWhitespace(cont[i])) { |
| i++; |
| } |
| if (i > start) { |
| lastLine= lineInformation.getLineOfOffset(i); |
| if (lastLine > startLine) { |
| return lastLine - startLine; |
| } |
| } |
| } |
| return 0; |
| } |
| } |
| |
| 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$ |
| 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 rewriteMethodBody(FunctionDeclaration parent, int startPos) { |
| RewriteEvent event= getEvent(parent, FunctionDeclaration.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, FunctionDeclaration.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 offset) { |
| return this.formatter.computeIndentUnits(getIndentOfLine(offset)); |
| } |
| |
| 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() && ScannerHelper.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 |
| if (needsNewLineForLineComment(copySource.getNode(), formatted, currPos)) { |
| doTextInsert(insertOffset, getLineDelimiter(), editGroup); |
| } |
| } 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 boolean needsNewLineForLineComment(ASTNode node, String formatted, int offset) { |
| if (!this.lineCommentEndOffsets.isEndOfLineComment(getExtendedEnd(node), this.content)) { |
| return false; |
| } |
| // copied code ends with a line comment, but doesn't contain the new line |
| return offset < formatted.length() && !IndentManipulation.isLineDelimiterChar(formatted.charAt(offset)); |
| } |
| |
| private String getCurrentLine(String str, int pos) { |
| for (int i= pos - 1; i>= 0; i--) { |
| char ch= str.charAt(i); |
| if (IndentManipulation.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); |
| // } |
| } |
| |
| class ModifierRewriter extends ListRewriter { |
| |
| private final Prefix annotationSeparation; |
| |
| public ModifierRewriter(Prefix annotationSeparation) { |
| this.annotationSeparation= annotationSeparation; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.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$ |
| // |
| // try { |
| // int nextPos= getScanner().getNextStartOffset(endPos, false); |
| // |
| // boolean lastUnchanged= children[children.length - 1].getChangeKind() != RewriteEvent.UNCHANGED; |
| // |
| // if (isAllRemove) { |
| // doTextRemove(endPos, nextPos - endPos, getEditGroup(children[children.length - 1])); |
| // return nextPos; |
| // } else if (isAllInsert || (nextPos == endPos && lastUnchanged)) { // see bug 165654 |
| // RewriteEvent lastChild= children[children.length - 1]; |
| // String separator; |
| // if (lastChild.getNewValue() instanceof Annotation) { |
| // separator= this.formatter.ANNOTATION_SEPARATION.getPrefix(getIndent(pos)); |
| // } else { |
| // separator= String.valueOf(' '); |
| // } |
| // doTextInsert(endPos, separator, getEditGroup(lastChild)); |
| // } |
| // } 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.eclipse.wst.jsdt.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.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(JavaScriptUnit) |
| */ |
| public boolean visit(JavaScriptUnit node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| int startPos= rewriteNode(node, JavaScriptUnit.PACKAGE_PROPERTY, 0, ASTRewriteFormatter.NONE); |
| |
| if (getChangeKind(node, JavaScriptUnit.PACKAGE_PROPERTY) == RewriteEvent.INSERTED) { |
| doTextInsert(0, getLineDelimiter(), getEditGroup(node, JavaScriptUnit.PACKAGE_PROPERTY)); |
| } |
| |
| startPos= rewriteParagraphList(node, JavaScriptUnit.IMPORTS_PROPERTY, startPos, 0, 0, 2); |
| // startPos= rewriteParagraphList(node, JavaScriptUnit.TYPES_PROPERTY, startPos, 0, -1, 2); |
| rewriteParagraphList(node, JavaScriptUnit.STATEMENTS_PROPERTY, startPos, 0, -1, 1); |
| return false; |
| } |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.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(FunctionDeclaration node, boolean isConstructor, boolean isConstructorChange) { |
| ChildPropertyDescriptor property= (node.getAST().apiLevel() == JLS2_INTERNAL) ? FunctionDeclaration.RETURN_TYPE_PROPERTY : FunctionDeclaration.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, FunctionDeclaration.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); |
| } |
| } |
| } |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(FunctionDeclaration) |
| */ |
| public boolean visit(FunctionDeclaration node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| int pos= rewriteJavadoc(node, FunctionDeclaration.JAVADOC_PROPERTY); |
| // if (node.getAST().apiLevel() == JLS2_INTERNAL) { |
| // rewriteModifiers(node, FunctionDeclaration.MODIFIERS_PROPERTY, pos); |
| // } else { |
| // pos= rewriteModifiers2(node, FunctionDeclaration.MODIFIERS2_PROPERTY, pos); |
| // pos= rewriteOptionalTypeParameters(node, FunctionDeclaration.TYPE_PARAMETERS_PROPERTY, pos, " ", true, pos != node.getStartPosition()); //$NON-NLS-1$ |
| // } |
| |
| boolean isConstructorChange= isChanged(node, FunctionDeclaration.CONSTRUCTOR_PROPERTY); |
| boolean isConstructor= ((Boolean) getOriginalValue(node, FunctionDeclaration.CONSTRUCTOR_PROPERTY)).booleanValue(); |
| if (!isConstructor || isConstructorChange) { |
| rewriteReturnType(node, isConstructor, isConstructorChange); |
| } |
| |
| try { |
| // method name |
| pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNamefunction, pos); |
| |
| pos= rewriteNode(node, FunctionDeclaration.NAME_PROPERTY, pos, ASTRewriteFormatter.NONE); |
| |
| // parameters |
| if (isChanged(node, FunctionDeclaration.PARAMETERS_PROPERTY)) { |
| pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLPAREN, pos); |
| pos= rewriteNodeList(node, FunctionDeclaration.PARAMETERS_PROPERTY, pos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$ |
| } else { |
| pos= doVisit(node, FunctionDeclaration.PARAMETERS_PROPERTY, pos); |
| } |
| |
| pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameRPAREN, pos); |
| |
| int extraDims= rewriteExtraDimensions(node, FunctionDeclaration.EXTRA_DIMENSIONS_PROPERTY, pos); |
| |
| boolean hasExceptionChanges= isChanged(node, FunctionDeclaration.THROWN_EXCEPTIONS_PROPERTY); |
| |
| int bodyChangeKind= getChangeKind(node, FunctionDeclaration.BODY_PROPERTY); |
| |
| if ((extraDims > 0) && (hasExceptionChanges || bodyChangeKind == RewriteEvent.INSERTED || bodyChangeKind == RewriteEvent.REMOVED)) { |
| int dim= ((Integer) getOriginalValue(node, FunctionDeclaration.EXTRA_DIMENSIONS_PROPERTY)).intValue(); |
| while (dim > 0) { |
| pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameRBRACKET, pos); |
| dim--; |
| } |
| } |
| |
| pos= rewriteNodeList(node, FunctionDeclaration.THROWN_EXCEPTIONS_PROPERTY, pos, " throws ", ", "); //$NON-NLS-1$ //$NON-NLS-2$ |
| rewriteMethodBody(node, pos); |
| } catch (CoreException e) { |
| // ignore |
| } |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jsdt.core.dom.ASTVisitor#visit(CastExpression) |
| */ |
| public boolean visit(FunctionExpression node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| rewriteRequiredNode(node, FunctionExpression.METHOD_PROPERTY); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jsdt.core.dom.ASTVisitor#visit(CastExpression) |
| */ |
| public boolean visit(ObjectLiteralField node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| rewriteRequiredNode(node, ObjectLiteralField.FIELD_NAME_PROPERTY); |
| |
| rewriteRequiredNode(node, ObjectLiteralField.INITIALIZER_PROPERTY); |
| return false; |
| } |
| |
| public boolean visit(RegularExpressionLiteral node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| String escapedSeq= (String) getNewValue(node, RegularExpressionLiteral.REGULAR_EXPRESSION_PROPERTY); |
| TextEditGroup group = getEditGroup(node, RegularExpressionLiteral.REGULAR_EXPRESSION_PROPERTY); |
| doTextReplace(node.getStartPosition(), node.getLength(), escapedSeq, group); |
| return false; |
| } |
| |
| |
| |
| public boolean visit(ObjectLiteral node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| int pos= node.getStartPosition(); |
| |
| try { |
| if (isChanged(node, ObjectLiteral.FIELDS_PROPERTY)) { |
| pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLBRACE, pos); |
| pos= rewriteNodeList(node, ObjectLiteral.FIELDS_PROPERTY, pos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$ |
| } else { |
| pos= doVisit(node, ObjectLiteral.FIELDS_PROPERTY, pos); |
| } |
| } catch (CoreException e) { |
| handleException(e); |
| } |
| return false; |
| } |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(Block) |
| */ |
| public boolean visit(Block node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| int startPos; |
| if (isCollapsed(node)) { |
| startPos= node.getStartPosition(); |
| } else { |
| startPos= getPosAfterLeftBrace(node.getStartPosition()); |
| } |
| int startIndent= getIndent(node.getStartPosition()) + 1; |
| rewriteParagraphList(node, Block.STATEMENTS_PROPERTY, startPos, startIndent, 0, 1); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.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()); |
| ensureSpaceBeforeReplace(node, ReturnStatement.EXPRESSION_PROPERTY, offset, 0); |
| |
| rewriteNode(node, ReturnStatement.EXPRESSION_PROPERTY, offset, ASTRewriteFormatter.SPACE); |
| } catch (CoreException e) { |
| handleException(e); |
| } |
| return false; |
| } |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(AnonymousClassDeclaration) |
| */ |
| public boolean visit(AnonymousClassDeclaration node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| int startPos= getPosAfterLeftBrace(node.getStartPosition()); |
| int startIndent= getIndent(node.getStartPosition()) + 1; |
| rewriteParagraphList(node, AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY, startPos, startIndent, -1, 2); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(ArrayAccess) |
| */ |
| public boolean visit(ArrayAccess node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| rewriteRequiredNode(node, ArrayAccess.ARRAY_PROPERTY); |
| rewriteRequiredNode(node, ArrayAccess.INDEX_PROPERTY); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.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); |
| } catch (CoreException e) { |
| handleException(e); |
| } |
| return false; |
| } |
| |
| private Type getElementType(ArrayType parent) { |
| Type t = (Type) getOriginalValue(parent, ArrayType.COMPONENT_TYPE_PROPERTY); |
| while (t.isArrayType()) { |
| t = (Type) getOriginalValue(t, ArrayType.COMPONENT_TYPE_PROPERTY); |
| } |
| return t; |
| } |
| |
| private int getDimensions(ArrayType parent) { |
| Type t = (Type) getOriginalValue(parent, ArrayType.COMPONENT_TYPE_PROPERTY); |
| int dimensions = 1; // always include this array type |
| while (t.isArrayType()) { |
| dimensions++; |
| t = (Type) getOriginalValue(t, ArrayType.COMPONENT_TYPE_PROPERTY); |
| } |
| return dimensions; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(ArrayInitializer) |
| */ |
| public boolean visit(ArrayInitializer node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| int startPos= getPosAfterLeftBrace(node.getStartPosition()); |
| rewriteNodeList(node, ArrayInitializer.EXPRESSIONS_PROPERTY, startPos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$ |
| return false; |
| } |
| |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(ArrayType) |
| */ |
| public boolean visit(ArrayType node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| rewriteRequiredNode(node, ArrayType.COMPONENT_TYPE_PROPERTY); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(AssertStatement) |
| */ |
| public boolean visit(AssertStatement node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| ensureSpaceBeforeReplace(node, AssertStatement.EXPRESSION_PROPERTY, node.getStartPosition(), 1); |
| int offset= rewriteRequiredNode(node, AssertStatement.EXPRESSION_PROPERTY); |
| rewriteNode(node, AssertStatement.MESSAGE_PROPERTY, offset, ASTRewriteFormatter.ASSERT_COMMENT); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(Assignment) |
| */ |
| public boolean visit(Assignment node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| int pos= rewriteRequiredNode(node, Assignment.LEFT_HAND_SIDE_PROPERTY); |
| rewriteOperation(node, Assignment.OPERATOR_PROPERTY, pos); |
| rewriteRequiredNode(node, Assignment.RIGHT_HAND_SIDE_PROPERTY); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.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 |
| } catch (CoreException e) { |
| handleException(e); |
| } |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(CastExpression) |
| */ |
| public boolean visit(CastExpression node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| rewriteRequiredNode(node, CastExpression.TYPE_PROPERTY); |
| rewriteRequiredNode(node, CastExpression.EXPRESSION_PROPERTY); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(CatchClause) |
| */ |
| public boolean visit(CatchClause node) { // catch (Exception) Block |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| rewriteRequiredNode(node, CatchClause.EXCEPTION_PROPERTY); |
| rewriteRequiredNode(node, CatchClause.BODY_PROPERTY); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.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()); |
| pos= rewriteRequiredNode(node, ClassInstanceCreation.MEMBER_PROPERTY); |
| // 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); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(ConditionalExpression) |
| */ |
| public boolean visit(ConditionalExpression node) { // expression ? thenExpression : elseExpression |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| rewriteRequiredNode(node, ConditionalExpression.EXPRESSION_PROPERTY); |
| rewriteRequiredNode(node, ConditionalExpression.THEN_EXPRESSION_PROPERTY); |
| rewriteRequiredNode(node, ConditionalExpression.ELSE_EXPRESSION_PROPERTY); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.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 |
| } catch (CoreException e) { |
| handleException(e); |
| } |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(EmptyStatement) |
| */ |
| public boolean visit(EmptyStatement node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| changeNotSupported(node); // no modification possible |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(ExpressionStatement) |
| */ |
| public boolean visit(ExpressionStatement node) { // expression |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| rewriteRequiredNode(node, ExpressionStatement.EXPRESSION_PROPERTY); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(FieldAccess) |
| */ |
| public boolean visit(FieldAccess node) { // expression.name |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| rewriteRequiredNode(node, FieldAccess.EXPRESSION_PROPERTY); // expression |
| rewriteRequiredNode(node, FieldAccess.NAME_PROPERTY); // name |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.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; |
| } |
| |
| |
| public boolean visit(ForInStatement node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| try { |
| int pos= node.getStartPosition(); |
| |
| pos= rewriteNode(node, ForInStatement.ITERATION_VARIABLE_PROPERTY, pos, ASTRewriteFormatter.NONE); |
| |
| // position after first semicolon |
| pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNamein, pos); |
| |
| pos= rewriteNode(node, ForInStatement.COLLECTION_PROPERTY, pos, ASTRewriteFormatter.NONE); |
| |
| |
| RewriteEvent bodyEvent= getEvent(node, ForInStatement.BODY_PROPERTY); |
| if (bodyEvent != null && bodyEvent.getChangeKind() == RewriteEvent.REPLACED) { |
| int startOffset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameRPAREN, pos); |
| rewriteBodyNode(node, ForInStatement.BODY_PROPERTY, startOffset, -1, getIndent(node.getStartPosition()), this.formatter.FOR_BLOCK); // body |
| } else { |
| voidVisit(node, ForInStatement.BODY_PROPERTY); |
| } |
| |
| } catch (CoreException e) { |
| handleException(e); |
| } |
| |
| |
| return false; |
| } |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(ImportDeclaration) |
| */ |
| public boolean visit(ImportDeclaration node) { |
| if (node.isFileImport()) |
| return false; |
| 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) { |
| try { |
| int pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameimport, node.getStartPosition()); |
| boolean wasStatic= ((Boolean) event.getOriginalValue()).booleanValue(); |
| if (wasStatic) { |
| int endPos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNamestatic, pos); |
| doTextRemove(pos, endPos - pos, getEditGroup(event)); |
| } else { |
| doTextInsert(pos, " static", getEditGroup(event)); //$NON-NLS-1$ |
| } |
| } catch (CoreException e) { |
| handleException(e); |
| } |
| } |
| } |
| |
| int pos= rewriteRequiredNode(node, ImportDeclaration.NAME_PROPERTY); |
| |
| RewriteEvent event= getEvent(node, ImportDeclaration.ON_DEMAND_PROPERTY); |
| if (event != null && event.getChangeKind() != RewriteEvent.UNCHANGED) { |
| boolean isOnDemand= ((Boolean) event.getOriginalValue()).booleanValue(); |
| if (!isOnDemand) { |
| doTextInsert(pos, ".*", getEditGroup(event)); //$NON-NLS-1$ |
| } else { |
| try { |
| int endPos= getScanner().getTokenStartOffset(ITerminalSymbols.TokenNameSEMICOLON, pos); |
| doTextRemove(pos, endPos - pos, getEditGroup(event)); |
| } catch (CoreException e) { |
| handleException(e); |
| } |
| } |
| } |
| return false; |
| } |
| |
| |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(InfixExpression) |
| */ |
| public boolean visit(InfixExpression node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| int pos= rewriteRequiredNode(node, InfixExpression.LEFT_OPERAND_PROPERTY); |
| |
| boolean needsNewOperation= isChanged(node, InfixExpression.OPERATOR_PROPERTY); |
| String operation= getNewValue(node, InfixExpression.OPERATOR_PROPERTY).toString(); |
| if (needsNewOperation) { |
| replaceOperation(pos, operation, getEditGroup(node, InfixExpression.OPERATOR_PROPERTY)); |
| } |
| |
| pos= rewriteRequiredNode(node, InfixExpression.RIGHT_OPERAND_PROPERTY); |
| |
| RewriteEvent event= getEvent(node, InfixExpression.EXTENDED_OPERANDS_PROPERTY); |
| String prefixString= ' ' + operation + ' '; |
| |
| if (needsNewOperation) { |
| int startPos= pos; |
| TextEditGroup editGroup= getEditGroup(node, InfixExpression.OPERATOR_PROPERTY); |
| |
| if (event != null && event.getChangeKind() != RewriteEvent.UNCHANGED) { |
| RewriteEvent[] extendedOperands= event.getChildren(); |
| for (int i= 0; i < extendedOperands.length; i++) { |
| RewriteEvent curr= extendedOperands[i]; |
| ASTNode elem= (ASTNode) curr.getOriginalValue(); |
| if (elem != null) { |
| if (curr.getChangeKind() != RewriteEvent.REPLACED) { |
| replaceOperation(startPos, operation, editGroup); |
| } |
| startPos= elem.getStartPosition() + elem.getLength(); |
| } |
| } |
| } else { |
| List extendedOperands= (List) getOriginalValue(node, InfixExpression.EXTENDED_OPERANDS_PROPERTY); |
| for (int i= 0; i < extendedOperands.size(); i++) { |
| ASTNode elem= (ASTNode) extendedOperands.get(i); |
| replaceOperation(startPos, operation, editGroup); |
| startPos= elem.getStartPosition() + elem.getLength(); |
| } |
| } |
| } |
| rewriteNodeList(node, InfixExpression.EXTENDED_OPERANDS_PROPERTY, pos, prefixString, prefixString); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(InstanceofExpression) |
| */ |
| public boolean visit(InstanceofExpression node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| rewriteRequiredNode(node, InstanceofExpression.LEFT_OPERAND_PROPERTY); |
| ensureSpaceAfterReplace(node, InstanceofExpression.LEFT_OPERAND_PROPERTY); |
| rewriteRequiredNode(node, InstanceofExpression.RIGHT_OPERAND_PROPERTY); |
| return false; |
| } |
| |
| public void ensureSpaceAfterReplace(ASTNode node, ChildPropertyDescriptor desc) { |
| if (getChangeKind(node, desc) == RewriteEvent.REPLACED) { |
| int leftOperandEnd= getExtendedEnd((ASTNode) getOriginalValue(node, desc)); |
| try { |
| int offset= getScanner().getNextStartOffset(leftOperandEnd, true); // instanceof |
| |
| if (offset == leftOperandEnd) { |
| doTextInsert(offset, String.valueOf(' '), getEditGroup(node, desc)); |
| } |
| } catch (CoreException e) { |
| handleException(e); |
| } |
| } |
| } |
| |
| public void ensureSpaceBeforeReplace(ASTNode node, ChildPropertyDescriptor desc, int offset, int numTokenBefore) { |
| // bug 103970 |
| if (getChangeKind(node, desc) == RewriteEvent.REPLACED) { |
| try { |
| while (numTokenBefore > 0) { |
| offset= getScanner().getNextEndOffset(offset, true); |
| numTokenBefore--; |
| } |
| if (offset == getExtendedOffset((ASTNode) getOriginalValue(node, desc))) { |
| doTextInsert(offset, String.valueOf(' '), getEditGroup(node, desc)); |
| } |
| } catch (CoreException e) { |
| handleException(e); |
| } |
| } |
| } |
| |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(Javadoc) |
| */ |
| public boolean visit(JSdoc node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| int startPos= node.getStartPosition() + 3; |
| String separator= getLineDelimiter() + getIndentAtOffset(node.getStartPosition()) + " * "; //$NON-NLS-1$ |
| |
| rewriteNodeList(node, JSdoc.TAGS_PROPERTY, startPos, separator, separator); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(LabeledStatement) |
| */ |
| public boolean visit(LabeledStatement node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| rewriteRequiredNode(node, LabeledStatement.LABEL_PROPERTY); |
| rewriteRequiredNode(node, LabeledStatement.BODY_PROPERTY); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(FunctionInvocation) |
| */ |
| public boolean visit(FunctionInvocation node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| int pos= rewriteOptionalQualifier(node, FunctionInvocation.EXPRESSION_PROPERTY, node.getStartPosition()); |
| if (node.getAST().apiLevel() >= AST.JLS3) { |
| pos= rewriteOptionalTypeParameters(node, FunctionInvocation.TYPE_ARGUMENTS_PROPERTY, pos, "", false, false); //$NON-NLS-1$ |
| } |
| |
| pos= rewriteOptionalQualifier(node, FunctionInvocation.NAME_PROPERTY,pos); |
| |
| if (isChanged(node, FunctionInvocation.ARGUMENTS_PROPERTY)) { |
| // eval position after opening parent |
| try { |
| int startOffset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLPAREN, pos); |
| rewriteNodeList(node, FunctionInvocation.ARGUMENTS_PROPERTY, startOffset, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$ |
| } catch (CoreException e) { |
| handleException(e); |
| } |
| } else { |
| voidVisit(node, FunctionInvocation.ARGUMENTS_PROPERTY); |
| } |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(NullLiteral) |
| */ |
| public boolean visit(NullLiteral node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| changeNotSupported(node); // no modification possible |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(ParenthesizedExpression) |
| */ |
| public boolean visit(ParenthesizedExpression node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| rewriteRequiredNode(node, ParenthesizedExpression.EXPRESSION_PROPERTY); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(PostfixExpression) |
| */ |
| public boolean visit(PostfixExpression node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| int pos= rewriteRequiredNode(node, PostfixExpression.OPERAND_PROPERTY); |
| rewriteOperation(node, PostfixExpression.OPERATOR_PROPERTY, pos); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(PrefixExpression) |
| */ |
| public boolean visit(PrefixExpression node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| rewriteOperation(node, PrefixExpression.OPERATOR_PROPERTY, node.getStartPosition()); |
| rewriteRequiredNode(node, PrefixExpression.OPERAND_PROPERTY); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(QualifiedName) |
| */ |
| public boolean visit(QualifiedName node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| rewriteRequiredNode(node, QualifiedName.QUALIFIER_PROPERTY); |
| rewriteRequiredNode(node, QualifiedName.NAME_PROPERTY); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(SimpleType) |
| */ |
| public boolean visit(SimpleType node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| rewriteRequiredNode(node, SimpleType.NAME_PROPERTY); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.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); |
| // } |
| if (!node.getType().isInferred()) |
| 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)); |
| } 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.eclipse.wst.jsdt.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.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(SuperFieldAccess) |
| */ |
| public boolean visit(SuperFieldAccess node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| rewriteOptionalQualifier(node, SuperFieldAccess.QUALIFIER_PROPERTY, node.getStartPosition()); |
| rewriteRequiredNode(node, SuperFieldAccess.NAME_PROPERTY); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.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; |
| } |
| |
| 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.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(ThisExpression) |
| */ |
| public boolean visit(ThisExpression node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| rewriteOptionalQualifier(node, ThisExpression.QUALIFIER_PROPERTY, node.getStartPosition()); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(ThrowStatement) |
| */ |
| public boolean visit(ThrowStatement node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| rewriteRequiredNode(node, ThrowStatement.EXPRESSION_PROPERTY); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(TypeLiteral) |
| */ |
| public boolean visit(TypeLiteral node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| rewriteRequiredNode(node, TypeLiteral.TYPE_PROPERTY); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.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); |
| // } |
| if (!node.getType().isInferred()) |
| pos= rewriteRequiredNode(node, VariableDeclarationExpression.TYPE_PROPERTY); |
| rewriteNodeList(node, VariableDeclarationExpression.FRAGMENTS_PROPERTY, pos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$ |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.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); |
| // } |
| if (!node.getType().isInferred()) |
| pos= rewriteRequiredNode(node, VariableDeclarationStatement.TYPE_PROPERTY); |
| |
| rewriteNodeList(node, VariableDeclarationStatement.FRAGMENTS_PROPERTY, pos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$ |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.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; |
| } |
| |
| |
| public boolean visit(WithStatement node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| int pos= rewriteRequiredNode(node, WithStatement.EXPRESSION_PROPERTY); |
| |
| try { |
| if (isChanged(node, WithStatement.BODY_PROPERTY)) { |
| int startOffset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameRPAREN, pos); |
| rewriteBodyNode(node, WithStatement.BODY_PROPERTY, startOffset, -1, getIndent(node.getStartPosition()), this.formatter.WHILE_BLOCK); // body |
| } else { |
| voidVisit(node, WithStatement.BODY_PROPERTY); |
| } |
| } catch (CoreException e) { |
| handleException(e); |
| } |
| return false; |
| } |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(org.eclipse.wst.jsdt.core.dom.MemberRef) |
| */ |
| public boolean visit(MemberRef node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| rewriteNode(node, MemberRef.QUALIFIER_PROPERTY, node.getStartPosition(), ASTRewriteFormatter.NONE); |
| |
| rewriteRequiredNode(node, MemberRef.NAME_PROPERTY); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(org.eclipse.wst.jsdt.core.dom.FunctionRef) |
| */ |
| public boolean visit(FunctionRef node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| rewriteNode(node, FunctionRef.QUALIFIER_PROPERTY, node.getStartPosition(), ASTRewriteFormatter.NONE); |
| |
| int pos= rewriteRequiredNode(node, FunctionRef.NAME_PROPERTY); |
| |
| if (isChanged(node, FunctionRef.PARAMETERS_PROPERTY)) { |
| // eval position after opening parent |
| try { |
| int startOffset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLPAREN, pos); |
| rewriteNodeList(node, FunctionRef.PARAMETERS_PROPERTY, startOffset, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$ |
| } catch (CoreException e) { |
| handleException(e); |
| } |
| } else { |
| voidVisit(node, FunctionRef.PARAMETERS_PROPERTY); |
| } |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(org.eclipse.wst.jsdt.core.dom.FunctionRefParameter) |
| */ |
| public boolean visit(FunctionRefParameter node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| int pos= rewriteRequiredNode(node, FunctionRefParameter.TYPE_PROPERTY); |
| if (node.getAST().apiLevel() >= AST.JLS3) { |
| if (isChanged(node, FunctionRefParameter.VARARGS_PROPERTY)) { |
| if (getNewValue(node, FunctionRefParameter.VARARGS_PROPERTY).equals(Boolean.TRUE)) { |
| doTextInsert(pos, "...", getEditGroup(node, FunctionRefParameter.VARARGS_PROPERTY)); //$NON-NLS-1$ |
| } else { |
| try { |
| int ellipsisEnd= getScanner().getNextEndOffset(pos, true); |
| doTextRemove(pos, ellipsisEnd - pos, getEditGroup(node, FunctionRefParameter.VARARGS_PROPERTY)); |
| } catch (CoreException e) { |
| handleException(e); |
| } |
| } |
| } |
| } |
| rewriteNode(node, FunctionRefParameter.NAME_PROPERTY, pos, ASTRewriteFormatter.SPACE); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(org.eclipse.wst.jsdt.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) { |
| char[] cont= getContent(); |
| int len= cont.length; |
| int i= tagNode.getStartPosition(); |
| while (i < len && !IndentManipulation.isIndentChar(cont[i])) { |
| i++; |
| } |
| return i; |
| } |
| return tagNode.getStartPosition(); |
| } |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(org.eclipse.wst.jsdt.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$ |
| |
| 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, pos); |
| } |
| |
| 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); |
| } |
| return false; |
| } |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(org.eclipse.wst.jsdt.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$ |
| |
| 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])); |
| } |
| 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])); |
| } |
| pos= endPos; |
| } |
| } catch (CoreException e) { |
| handleException(e); |
| } |
| } |
| rewriteParagraphList(node, EnumDeclaration.BODY_DECLARATIONS_PROPERTY, pos, indent, -1, 2); |
| return false; |
| } |
| |
| public boolean visit(ListExpression node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| int startPos= node.getStartPosition(); |
| rewriteNodeList(node, ListExpression.EXPRESSIONS_PROPERTY, startPos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$ |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(org.eclipse.wst.jsdt.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; |
| } |
| public boolean visit(UndefinedLiteral node) { |
| if (!hasChildrenChanges(node)) { |
| return doVisitUnchangedChildren(node); |
| } |
| |
| changeNotSupported(node); // no modification possible |
| return false; |
| } |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(org.eclipse.wst.jsdt.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.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(org.eclipse.wst.jsdt.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; |
| } |
| } |