Index: dom/org/eclipse/jdt/core/dom/CompilationUnit.java
===================================================================
RCS file: /home/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java,v
retrieving revision 1.60
diff -u -r1.60 CompilationUnit.java
--- dom/org/eclipse/jdt/core/dom/CompilationUnit.java 30 Nov 2004 14:34:38 -0000 1.60
+++ dom/org/eclipse/jdt/core/dom/CompilationUnit.java 5 Jan 2005 16:43:47 -0000
@@ -484,8 +484,12 @@
* @since 3.0
*/
public int getExtendedStartPosition(ASTNode node) {
- if (this.commentMapper == null) {
- return -1;
+ if (node == null) {
+ throw new IllegalArgumentException();
+ }
+ if (this.commentMapper == null || node.getAST() != getAST()) {
+ // fall back: use best info available
+ return node.getStartPosition();
} else {
return this.commentMapper.getExtendedStartPosition(node);
}
@@ -504,8 +508,12 @@
* @since 3.0
*/
public int getExtendedLength(ASTNode node) {
- if (this.commentMapper == null) {
- return 0;
+ if (node == null) {
+ throw new IllegalArgumentException();
+ }
+ if (this.commentMapper == null || node.getAST() != getAST()) {
+ // fall back: use best info available
+ return node.getLength();
} else {
return this.commentMapper.getExtendedLength(node);
}
Index: dom/org/eclipse/jdt/core/dom/InternalASTRewrite.java
===================================================================
RCS file: /home/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InternalASTRewrite.java,v
retrieving revision 1.4
diff -u -r1.4 InternalASTRewrite.java
--- dom/org/eclipse/jdt/core/dom/InternalASTRewrite.java 14 Apr 2004 23:03:10 -0000 1.4
+++ dom/org/eclipse/jdt/core/dom/InternalASTRewrite.java 5 Jan 2005 16:43:47 -0000
@@ -20,6 +20,7 @@
import org.eclipse.jdt.core.dom.SimplePropertyDescriptor;
import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
+import org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer;
import org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer;
import org.eclipse.jdt.internal.core.dom.rewrite.ListRewriteEvent;
import org.eclipse.jdt.internal.core.dom.rewrite.NodeInfoStore;
@@ -65,9 +66,23 @@
public TextEdit rewriteAST(IDocument document, Map options) {
TextEdit result = new MultiTextEdit();
- CompilationUnit rootNode = getRootNode();
+ final CompilationUnit rootNode = getRootNode();
if (rootNode != null) {
- ASTRewriteAnalyzer visitor = new ASTRewriteAnalyzer(document, rootNode, result, this.eventStore, this.nodeStore, options);
+ TargetSourceRangeComputer xsrComputer = new TargetSourceRangeComputer() {
+ /**
+ * This implementation of
+ * {@link TargetSourceRangeComputer#computeSourceRange(ASTNode)}
+ * is specialized to work in the case of internal AST rewriting, where the
+ * original AST has been modified from its original form. This means that
+ * one cannot trust that the root of the given node is the compilation unit.
+ */
+ public SourceRange computeSourceRange(ASTNode node) {
+ int extendedStartPosition = rootNode.getExtendedStartPosition(node);
+ int extendedLength = rootNode.getExtendedLength(node);
+ return new SourceRange(extendedStartPosition, extendedLength);
+ }
+ };
+ ASTRewriteAnalyzer visitor = new ASTRewriteAnalyzer(document, rootNode, result, this.eventStore, this.nodeStore, options, xsrComputer);
rootNode.accept(visitor);
}
return result;
Index: dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java
===================================================================
RCS file: /home/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java,v
retrieving revision 1.14
diff -u -r1.14 ASTRewrite.java
--- dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java 3 Dec 2004 17:28:43 -0000 1.14
+++ dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java 5 Jan 2005 16:43:47 -0000
@@ -85,6 +85,13 @@
private final NodeInfoStore nodeStore;
/**
+ * Target source range computer; null means uninitialized;
+ * lazy initialized to new TargetSourceRangeComputer()
.
+ * @since 3.1
+ */
+ private TargetSourceRangeComputer targetSourceRangeComputer = null;
+
+ /**
* Creates a new instance for describing manipulations of
* the given AST.
*
@@ -140,6 +147,11 @@
* edits to the given document containing the original source
* code. The document itself is not modified.
*
+ * For nodes in the original that are being replaced or deleted,
+ * this rewriter computes the adjusted source ranges
+ * by calling getTargetSourceRangeComputer().computeSourceRange(node)
.
+ *
* Calling this methods does not discard the modifications
* on record. Subsequence modifications are added to the ones
* already on record. If this method is called again later,
@@ -170,7 +182,7 @@
getRewriteEventStore().markMovedNodesRemoved();
CompilationUnit astRoot= (CompilationUnit) rootNode.getRoot();
- ASTRewriteAnalyzer visitor= new ASTRewriteAnalyzer(document, astRoot, result, this.eventStore, this.nodeStore, options);
+ ASTRewriteAnalyzer visitor= new ASTRewriteAnalyzer(document, astRoot, result, this.eventStore, this.nodeStore, options, getExtendedSourceRangeComputer());
rootNode.accept(visitor); // throws IllegalArgumentException
}
return result;
@@ -499,6 +511,34 @@
public final ASTNode createMoveTarget(ASTNode node) {
return createTargetNode(node, true);
}
+
+ /**
+ * Returns the extended source range computer for this AST rewriter.
+ * The default value is a new ExtendedSourceRangeComputer()
.
+ *
+ * @return an extended source range computer
+ * @since 3.1
+ */
+ public final TargetSourceRangeComputer getExtendedSourceRangeComputer() {
+ if (this.targetSourceRangeComputer == null) {
+ // lazy initialize
+ this.targetSourceRangeComputer = new TargetSourceRangeComputer();
+ }
+ return this.targetSourceRangeComputer;
+ }
+
+ /**
+ * Sets the target source range computer for this AST rewriter.
+ *
+ * @param computer a target source range computer,
+ * or null
to restore the default value of
+ * new TargetSourceRangeComputer()
+ * @since 3.1
+ */
+ public final void setTargetSourceRangeComputer(TargetSourceRangeComputer computer) {
+ // if computer==null, rely on lazy init code in getTargetSourceRangeComputer()
+ this.targetSourceRangeComputer = computer;
+ }
/**
* Returns a string suitable for debugging purposes (only).
Index: dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
===================================================================
RCS file: /home/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java,v
retrieving revision 1.14
diff -u -r1.14 ASTRewriteAnalyzer.java
--- dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java 30 Nov 2004 22:54:28 -0000 1.14
+++ dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java 5 Jan 2005 16:43:47 -0000
@@ -41,6 +41,7 @@
import org.eclipse.jdt.core.compiler.ITerminalSymbols;
import org.eclipse.jdt.core.dom.*;
+import org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer;
import org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteFormatter.BlockContext;
import org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteFormatter.NodeMarker;
@@ -73,11 +74,12 @@
private final ASTRewriteFormatter formatter;
private final NodeInfoStore nodeInfos;
private final CompilationUnit astRoot;
+ private final TargetSourceRangeComputer extendedSourceRangeComputer;
/*
* Constructor for ASTRewriteAnalyzer.
*/
- public ASTRewriteAnalyzer(IDocument document, CompilationUnit astRoot, TextEdit rootEdit, RewriteEventStore eventStore, NodeInfoStore nodeInfos, Map options) {
+ public ASTRewriteAnalyzer(IDocument document, CompilationUnit astRoot, TextEdit rootEdit, RewriteEventStore eventStore, NodeInfoStore nodeInfos, Map options, TargetSourceRangeComputer extendedSourceRangeComputer) {
this.astRoot= astRoot;
this.eventStore= eventStore;
this.document= document;
@@ -88,6 +90,8 @@
this.sourceCopyEndNodes= new Stack();
this.formatter= new ASTRewriteFormatter(nodeInfos, eventStore, options, getLineDelimiter());
+
+ this.extendedSourceRangeComputer = extendedSourceRangeComputer;
}
final TokenScanner getScanner() {
@@ -103,16 +107,28 @@
return this.document;
}
+ /**
+ * Returns the extended source range computer for this AST rewriter.
+ *
+ * @return an extended source range computer (never null)
+ * @since 3.1
+ */
+ private TargetSourceRangeComputer getExtendedSourceRangeComputer() {
+ return this.extendedSourceRangeComputer;
+ }
+
final int getExtendedOffset(ASTNode node) {
- return this.astRoot.getExtendedStartPosition(node);
+ return getExtendedSourceRangeComputer().computeSourceRange(node).getStartPosition();
}
final int getExtendedLength(ASTNode node) {
- return this.astRoot.getExtendedLength(node);
+ return getExtendedSourceRangeComputer().computeSourceRange(node).getLength();
}
final int getExtendedEnd(ASTNode node) {
- return this.astRoot.getExtendedStartPosition(node) + this.astRoot.getExtendedLength(node);
+ TargetSourceRangeComputer.SourceRange range =
+ getExtendedSourceRangeComputer().computeSourceRange(node);
+ return range.getStartPosition() + range.getLength();
}
final TextEdit getCopySourceEdit(CopySourceInfo info) {
Index: dom/org/eclipse/jdt/core/dom/rewrite/TargetSourceRangeComputer.java
===================================================================
RCS file: dom/org/eclipse/jdt/core/dom/rewrite/TargetSourceRangeComputer.java
diff -N dom/org/eclipse/jdt/core/dom/rewrite/TargetSourceRangeComputer.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dom/org/eclipse/jdt/core/dom/rewrite/TargetSourceRangeComputer.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom.rewrite;
+
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+
+/**
+ * An object for computing adjusted source ranges for AST nodes
+ * that are being replaced or deleted.
+ *
+ * For example, a refactoring like inline method may choose to replace + * calls to the method but leave intact any comments immediately preceding + * the calls. On the other hand, a refactoring like extract method may choose + * to extract not only the nodes for the selected code but also any + * comments preceding or following them. + *
+ *+ * Clients should subclass if they need to influence the + * the source range to be affected when replacing or deleting a particular node. + * An instance of the subclass should be registered with + * {@link ASTRewrite#setTargetSourceRangeComputer(TargetSourceRangeComputer)}. + * During a call to {@link ASTRewrite#rewriteAST(org.eclipse.jface.text.IDocument, java.util.Map)}, + * the {@link #computeSourceRange(ASTNode)} method on this object will be + * used to compute the source range for a node being deleted or replaced. + *
+ * + * @since 3.1 + */ +public class TargetSourceRangeComputer { + + /** + * Reified source range. Instances are "value" object + * (cannot be modified). + * + * @since 3.1 + */ + public static final class SourceRange { + /** + * 0-based character index, or-1
+ * if no source position information is known.
+ */
+ private int startPosition;
+
+ /**
+ * (possibly 0) length, or 0
+ * if no source position information is known.
+ */
+ private int length;
+
+ /**
+ * Creates a new source range.
+ *
+ * @param startPosition the 0-based character index, or -1
+ * if no source position information is known
+ * @param length the (possibly 0) length, or 0
+ * if no source position information is known
+ */
+ public SourceRange(int startPosition, int length) {
+ this.startPosition = startPosition;
+ this.length = length;
+ }
+
+ /**
+ * Returns the start position.
+ *
+ * @return the 0-based character index, or -1
+ * if no source position information is known
+ */
+ public int getStartPosition() {
+ return this.startPosition;
+ }
+
+ /**
+ * Returns the source length.
+ *
+ * @return a (possibly 0) length, or 0
+ * if no source position information is known
+ */
+ public int getLength() {
+ return this.length;
+ }
+ }
+
+ /**
+ * Creates a new target source range computer.
+ */
+ public TargetSourceRangeComputer() {
+ // do nothing
+ }
+
+ /**
+ * Returns the target source range of the given node. Unlike
+ * {@link ASTNode#getStartPosition()} and {@link ASTNode#getLength()},
+ * the extended source range may include comments and whitespace
+ * immediately before or after the normal source range for the node.
+ * + * The default implementation uses + * {@link CompilationUnit#getExtendedStartPosition(ASTNode)} + * and {@link CompilationUnit#getExtendedLength(ASTNode)} + * to compute the target source range. Clients may override or + * extend this method to expand or contract the source range of the + * given node. The resulting source range must cover at least the + * original source range of the node. + *
+ * + * @param node the node with a known source range in the compilation unit + * being rewritten + * @return the exact source range in the compilation unit being rewritten + * that should be replaced (or deleted) + */ + public SourceRange computeSourceRange(ASTNode node) { + // TODO (Martin) Is it true that this method will only be called on AST nodes that are part of the original tree and have at least a basic source position? + CompilationUnit cu = (CompilationUnit) node.getRoot(); + return new SourceRange( + cu.getExtendedStartPosition(node), + cu.getExtendedLength(node)); + } +}