001: /*******************************************************************************
002: * Copyright (c) 2005 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.core.dom.rewrite;
011:
012: import org.eclipse.jdt.core.dom.ASTNode;
013: import org.eclipse.jdt.core.dom.CompilationUnit;
014:
015: /**
016: * An object for computing adjusted source ranges for AST nodes
017: * that are being replaced or deleted.
018: * <p>
019: * For example, a refactoring like inline method may choose to replace
020: * calls to the method but leave intact any comments immediately preceding
021: * the calls. On the other hand, a refactoring like extract method may choose
022: * to extract not only the nodes for the selected code but also any
023: * comments preceding or following them.
024: * </p>
025: * <p>
026: * Clients should subclass if they need to influence the
027: * the source range to be affected when replacing or deleting a particular node.
028: * An instance of the subclass should be registered with
029: * {@link ASTRewrite#setTargetSourceRangeComputer(TargetSourceRangeComputer)}.
030: * During a call to {@link ASTRewrite#rewriteAST(org.eclipse.jface.text.IDocument, java.util.Map)},
031: * the {@link #computeSourceRange(ASTNode)} method on this object will be
032: * used to compute the source range for a node being deleted or replaced.
033: * </p>
034: *
035: * @since 3.1
036: */
037: public class TargetSourceRangeComputer {
038:
039: /**
040: * Reified source range. Instances are "value" object
041: * (cannot be modified).
042: *
043: * @since 3.1
044: */
045: public static final class SourceRange {
046: /**
047: * 0-based character index, or <code>-1</code>
048: * if no source position information is known.
049: */
050: private int startPosition;
051:
052: /**
053: * (possibly 0) length, or <code>0</code>
054: * if no source position information is known.
055: */
056: private int length;
057:
058: /**
059: * Creates a new source range.
060: *
061: * @param startPosition the 0-based character index, or <code>-1</code>
062: * if no source position information is known
063: * @param length the (possibly 0) length, or <code>0</code>
064: * if no source position information is known
065: */
066: public SourceRange(int startPosition, int length) {
067: this .startPosition = startPosition;
068: this .length = length;
069: }
070:
071: /**
072: * Returns the start position.
073: *
074: * @return the 0-based character index, or <code>-1</code>
075: * if no source position information is known
076: */
077: public int getStartPosition() {
078: return this .startPosition;
079: }
080:
081: /**
082: * Returns the source length.
083: *
084: * @return a (possibly 0) length, or <code>0</code>
085: * if no source position information is known
086: */
087: public int getLength() {
088: return this .length;
089: }
090: }
091:
092: /**
093: * Creates a new target source range computer.
094: */
095: public TargetSourceRangeComputer() {
096: // do nothing
097: }
098:
099: /**
100: * Returns the target source range of the given node. Unlike
101: * {@link ASTNode#getStartPosition()} and {@link ASTNode#getLength()},
102: * the extended source range may include comments and whitespace
103: * immediately before or after the normal source range for the node.
104: * <p>
105: * The returned source ranges must satisfy the following conditions:
106: * <dl>
107: * <li>no two source ranges in an AST may be overlapping</li>
108: * <li>a source range of a parent node must fully cover the source ranges of its children</li>
109: * </dl>
110: * </p>
111: * <p>
112: * The default implementation uses
113: * {@link CompilationUnit#getExtendedStartPosition(ASTNode)}
114: * and {@link CompilationUnit#getExtendedLength(ASTNode)}
115: * to compute the target source range. Clients may override or
116: * extend this method to expand or contract the source range of the
117: * given node. The resulting source range must cover at least the
118: * original source range of the node.
119: * </p>
120: *
121: * @param node the node with a known source range in the compilation unit
122: * being rewritten
123: * @return the exact source range in the compilation unit being rewritten
124: * that should be replaced (or deleted)
125: */
126: public SourceRange computeSourceRange(ASTNode node) {
127: ASTNode root = node.getRoot();
128: if (root instanceof CompilationUnit) {
129: CompilationUnit cu = (CompilationUnit) root;
130: return new SourceRange(cu.getExtendedStartPosition(node),
131: cu.getExtendedLength(node));
132: }
133: return new SourceRange(node.getStartPosition(), node
134: .getLength());
135: }
136: }
|