/******************************************************************************* * Copyright (c) 2004, 2014 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: * Doug Schaefer - Initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.core.dom.ast; import org.eclipse.cdt.core.parser.IToken; /** * This is the root node in the physical AST. A physical node represents a chunk * of text in the source program. * * Classes implementing this interface are not thread safe. * Even 'get' methods may cause changes to the underlying object. * * @noimplement This interface is not intended to be implemented by clients. * @noextend This interface is not intended to be extended by clients. */ public interface IASTNode { /** @since 5.3 */ public enum CopyStyle { /** * Copy without location, this copy is independent of the index and can be shared. */ withoutLocations, /** * The copied node has a {@link IASTCopyLocation} linking the copy to the original node. * If the index was supplied creating the original AST, the caller has to hold a read lock * on it. The returned copy is valid only while the read lock is being held and should * not be accessed after releasing the lock. */ withLocations } public static final IASTNode[] EMPTY_NODE_ARRAY = {}; /** * Returns the translation unit (master) node that is the ancestor of all nodes * in this AST. * * @return {@code IASTTranslationUnit} */ public IASTTranslationUnit getTranslationUnit(); /** * Returns the location of this node. In cases not involving macro expansions, * the IASTNodeLocation[] result will only have one element in it, and it * will be an {@link IASTFileLocation}. * <p> * Where the node is completely generated within a macro expansion, * IASTNodeLocation[] result will have one element in it, and it will be an * {@link IASTMacroExpansionLocation}. * <p> * Nodes that span file context into a macro expansion (and potentially out * of the macro expansion again) result in an IASTNodeLocation[] result * that is of length > 1. * <p> * We do not provide meaningful node locations for nested macro references * (see {@link IASTPreprocessorMacroExpansion#getNestedMacroReferences()}). * For those, the file location of the enclosing explicit macro reference is * returned. You can however compute their image-location using * {@link IASTName#getImageLocation()} */ public IASTNodeLocation[] getNodeLocations(); /** * Computes a file location for the node. When the node actually resides in a macro-expansion * the location of the expansion is returned. In case the node spans multiple files the location * will be in a common root file and will contain the appropriate include directives. * <p> * The method may return {@code null} in case the node does not have a file-location. This * is for instance the case for built-in macro names or empty names for anonymous type * declarations. * * @return the mapped file location or {@code null}. */ public IASTFileLocation getFileLocation(); /** * Lightweight check for understanding what file we are in. * * @return {@code String} absolute path */ public String getContainingFilename(); /** * Lightweight check to see whether this node is part of the root file. * @since 5.0 */ public boolean isPartOfTranslationUnitFile(); /** * Returns the parent node of this node in the tree. */ public IASTNode getParent(); /** * Returns the children of this node. * @since 5.1 */ IASTNode[] getChildren(); /** * Sets the parent node of this node in the tree. * * @param node {@code IASTNode} */ public void setParent(IASTNode node); /** * Describes relationship between this child node and it's parent. * * @return {@code ASTNodeProperty} */ public ASTNodeProperty getPropertyInParent(); /** * Sets the parent property of the node. * * @param property */ public void setPropertyInParent(ASTNodeProperty property); /** * Abstract method to be overridden by all subclasses. Necessary for * visitation of the tree using an {@code ASTVisitor}. * * @param visitor * @return continue on (true) or quit (false) */ public boolean accept(ASTVisitor visitor); /** * Returns the raw signature of the IASTNode before it is processed by the preprocessor. * * Example: * <pre> * #define ONE 1 * int x=ONE; // getRawSignature() for this declaration would return "int x=ONE;" * </pre> * * @return the raw signature of the IASTNode before it is processed by the preprocessor */ public String getRawSignature(); /** * Returns whether this node contains the given one. The decision is made * purely on location information and therefore the method is fast. * * @param node the node to check * @return whether this node contains the given one. * @since 4.0 */ public boolean contains(IASTNode node); /** * Returns the tokens that can be found between this node and its left sibling (or the * beginning of the parent, if there is no left sibling). The tokens are obtained * from the lexer, no preprocessing is performed. * The offsets of the tokens are relative to the file-offset of this node. * <p> * <b>Examples</b> looking at the condition of if-statements: * <pre> * #define IF if * #define IF_P if ( * #define IF_P_T if (true * #define SEMI_IF ; if * #define IF_COND if (true) * void test() { * if (true) {} // leading syntax: 'if (' * IF (true) {} // leading syntax: 'IF (' * IF_P true) {} // leading syntax: 'IF_P' * IF_P_T ) {} // throws ExpansionOverlapsBoundaryException * SEMI_IF (true) {} // throws ExpansionOverlapsBoundaryException * IF_COND // throws ExpansionOverlapsBoundaryException * </pre> * * @return a chain of tokens or {@code null}, if there are none. * @throws ExpansionOverlapsBoundaryException if one of the boundaries of the leading syntax is * overlapped by a macro-expansion. * @throws UnsupportedOperationException if invoked on preprocessor nodes, or nodes that are not * part of a translation unit. * @since 5.1 */ public IToken getLeadingSyntax() throws ExpansionOverlapsBoundaryException, UnsupportedOperationException; /** * Returns the tokens that can be found between this node and its right sibling (or the * end of the parent, if there is no right sibling). The tokens are obtained from the lexer, * no preprocessing is performed. * The offsets of the tokens are relative to the file-offset of the end of this node. * <p> * For examples see {@link #getLeadingSyntax()}. * * @return a chain of tokens or {@code null}, if there are none. * @throws ExpansionOverlapsBoundaryException if one of the boundaries of the trailing syntax is * overlapped by a macro-expansion. * @throws UnsupportedOperationException if invoked on preprocessor nodes, or nodes that are not * part of a translation unit. * @since 5.1 */ public IToken getTrailingSyntax() throws ExpansionOverlapsBoundaryException, UnsupportedOperationException; /** * Returns the tokens that make up this node. The tokens are obtained from the lexer, * no preprocessing is performed. * The offsets of the tokens are relative to the file-offset of the beginning of this node. * <p> * For examples see {@link #getLeadingSyntax()}. * * @return a chain of tokens or {@code null}, if there are none. * @throws ExpansionOverlapsBoundaryException if one of the boundaries of the node is * overlapped by a macro-expansion. * @throws UnsupportedOperationException if invoked on preprocessor nodes, or nodes that are not * part of a translation unit. * @since 5.1 */ public IToken getSyntax() throws ExpansionOverlapsBoundaryException; /** * Returns true if this node is frozen, false otherwise. * If the node is frozen then any attempt to call a method that changes * the node's state will result in an IllegalStateException. * @since 5.1 */ public boolean isFrozen(); /** * Returns false if this node was parsed in an inactive code branch. * @since 5.1 */ public boolean isActive(); /** * Returns a mutable copy of the tree rooted at this node. The following postconditions hold: * <pre> * copy.getParent() == null * copy.getPropertyInParent() == null * copy.isFrozen() == false * </pre> * * Preprocessor nodes do not currently support being copied. * * Implicit name nodes are not copied, instead they can be regenerated if required. * <p> * Calling this method is equivalent to {@code copy(CopyStyle.withoutLocations)}. * * @since 5.1 * @throws UnsupportedOperationException * if this node or one of its descendants does not support copying */ public IASTNode copy(); /** * Returns a mutable copy of the tree rooted at this node. The following postconditions hold: * * <pre> * copy.getParent() == null * copy.getPropertyInParent() == null * copy.isFrozen() == false * </pre> * * Preprocessor nodes do not currently support being copied. * * Implicit name nodes are not copied, instead they can be regenerated if required. * * @param style * {@link CopyStyle} create a copy with or without locations. Please see * {@link CopyStyle} for restrictions on copies with Locations. * @since 5.3 * @throws UnsupportedOperationException * if this node or one of its descendants does not support copying */ public IASTNode copy(CopyStyle style); /** * If the node is a copy of some other node, returns the original node. * Otherwise returns the node itself. * @since 5.4 */ public IASTNode getOriginalNode(); }