/******************************************************************************* * Copyright (c) 2005, 2009 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.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. * <p> * 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. * </p> * <p> * 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. * </p> * * @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 <code>-1</code> if no source position information is known. */ private int startPosition; /** * (possibly 0) length, or <code>0</code> if no source position information is known. */ private int length; /** * Creates a new source range. * * @param startPosition the 0-based character index, or <code>-1</code> if no source * position information is known * @param length the (possibly 0) length, or <code>0</code> 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 <code>-1</code> if no source position information * is known */ public int getStartPosition() { return this.startPosition; } /** * Returns the source length. * * @return a (possibly 0) length, or <code>0</code> 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. * <p> * The returned source ranges must satisfy the following conditions: * <dl> * <li>no two source ranges in an AST may be overlapping</li> * <li>a source range of a parent node must fully cover the source ranges of its children</li> * </dl> * </p> * <p> * 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. * </p> * * @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) { ASTNode root= node.getRoot(); if (root instanceof CompilationUnit) { CompilationUnit cu= (CompilationUnit)root; return new SourceRange(cu.getExtendedStartPosition(node), cu.getExtendedLength(node)); } return new SourceRange(node.getStartPosition(), node.getLength()); } }