Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 685f176845d123213b62def3bc3714cf9d83de2e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
/*******************************************************************************
 * Copyright (c) 2004, 2014 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * 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();
}

Back to the top