/******************************************************************************* * 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()); } }