EclipseJDT Source Viewer

Home|eclipse_jdt/src/org/eclipse/jdt/core/dom/CompilationUnit.java
1/*******************************************************************************
2 * Copyright (c) 2000, 2019 IBM Corporation and others.
3 *
4 * This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
6 * which accompanies this distribution, and is available at
7 * https://www.eclipse.org/legal/epl-2.0/
8 *
9 * SPDX-License-Identifier: EPL-2.0
10 *
11 * Contributors:
12 *     IBM Corporation - initial API and implementation
13 *******************************************************************************/
14
15package org.eclipse.jdt.core.dom;
16
17import java.util.ArrayList;
18import java.util.Arrays;
19import java.util.Collections;
20import java.util.List;
21import java.util.Map;
22
23import org.eclipse.jdt.core.IJavaElement;
24import org.eclipse.jdt.core.ITypeRoot;
25import org.eclipse.jdt.core.compiler.IProblem;
26import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
27import org.eclipse.jdt.internal.compiler.parser.Scanner;
28import org.eclipse.jdt.internal.compiler.util.Util;
29
30/**
31 * Java compilation unit AST node type. This is the type of the root of an AST.
32 * In JLS9 and later, this node can also contain a ModuleDeclaration (with a
33 * completely different grammar).
34 * <p>
35 * The source range for this type of node is ordinarily the entire source file,
36 * including leading and trailing whitespace and comments.
37 * </p>
38 * 
39 * <pre>
40 * CompilationUnit:
41 *     OrdinaryCompilationUnit
42 *     ModularCompilationUnit
43 *
44 * OrdinaryCompilationUnit:
45 *     [ PackageDeclaration ]
46 *         { ImportDeclaration }
47 *         { TypeDeclaration | EnumDeclaration | AnnotationTypeDeclaration | <b>;</b> }
48 *
49 * ModularCompilationUnit:
50 *     {ImportDeclaration}
51 *         ModuleDeclaration
52 * </pre>
53 *
54 * @since 2.0
55 * @noinstantiate This class is not intended to be instantiated by clients.
56 * @noextend This class is not intended to be subclassed by clients.
57 */
58@SuppressWarnings({ "rawtypes""unchecked" })
59public class CompilationUnit extends ASTNode {
60
61    /**
62     * Canonical empty list of messages.
63     */
64    private static final Message[] EMPTY_MESSAGES = new Message[0];
65
66    /**
67     * Canonical empty list of problems.
68     */
69    private static final IProblem[] EMPTY_PROBLEMS = new IProblem[0];
70
71    /**
72     * The "imports" structural property of this node type (element type:
73     * {@link ImportDeclaration}).
74     *
75     * @since 3.0
76     */
77    public static final ChildListPropertyDescriptor IMPORTS_PROPERTY = new ChildListPropertyDescriptor(
78            CompilationUnit.class"imports"ImportDeclaration.classNO_CYCLE_RISK); //$NON-NLS-1$
79
80    /**
81     * The "package" structural property of this node type (child type:
82     * {@link PackageDeclaration}).
83     *
84     * @since 3.0
85     */
86    public static final ChildPropertyDescriptor PACKAGE_PROPERTY = new ChildPropertyDescriptor(CompilationUnit.class,
87            "package"PackageDeclaration.classOPTIONALNO_CYCLE_RISK); //$NON-NLS-1$
88
89    /**
90     * The "module" structural property of this node type (child type:
91     * {@link ModuleDeclaration}) (added in JLS9 API).
92     *
93     * @since 3.14
94     */
95    public static final ChildPropertyDescriptor MODULE_PROPERTY = new ChildPropertyDescriptor(CompilationUnit.class,
96            "module"ModuleDeclaration.classOPTIONALNO_CYCLE_RISK); //$NON-NLS-1$
97
98    /**
99     * A list of property descriptors (element type:
100     * {@link StructuralPropertyDescriptor}),
101     * or null if uninitialized.
102     * 
103     * @since 3.0
104     */
105    private static final List PROPERTY_DESCRIPTORS;
106
107    /**
108     * A list of property descriptors (element type:
109     * {@link StructuralPropertyDescriptor}),
110     * or null if uninitialized.
111     * 
112     * @since 3.14
113     */
114    private static final List PROPERTY_DESCRIPTORS_9_0;
115
116    /**
117     * The "types" structural property of this node type (element type:
118     * {@link AbstractTypeDeclaration}).
119     *
120     * @since 3.0
121     */
122    public static final ChildListPropertyDescriptor TYPES_PROPERTY = new ChildListPropertyDescriptor(
123            CompilationUnit.class"types"AbstractTypeDeclaration.classCYCLE_RISK); //$NON-NLS-1$
124
125    static {
126        List properyList = new ArrayList(4);
127        createPropertyList(CompilationUnit.classproperyList);
128        addProperty(PACKAGE_PROPERTYproperyList);
129        addProperty(IMPORTS_PROPERTYproperyList);
130        addProperty(TYPES_PROPERTYproperyList);
131        PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
132
133        properyList = new ArrayList(5);
134        createPropertyList(CompilationUnit.classproperyList);
135        addProperty(PACKAGE_PROPERTYproperyList);
136        addProperty(IMPORTS_PROPERTYproperyList);
137        addProperty(TYPES_PROPERTYproperyList);
138        addProperty(MODULE_PROPERTYproperyList);
139        PROPERTY_DESCRIPTORS_9_0 = reapPropertyList(properyList);
140    }
141
142    /**
143     * Returns a list of structural property descriptors for this node type.
144     * Clients must not modify the result.
145     *
146     * @param apiLevel the API level; one of the
147     *                 <code>AST.JLS*</code> constants
148     * 
149     * @return a list of property descriptors (element type:
150     *         {@link StructuralPropertyDescriptor})
151     * @since 3.0
152     */
153    public static List propertyDescriptors(int apiLevel) {
154        if (apiLevel < AST.JLS9_INTERNAL)
155            return PROPERTY_DESCRIPTORS;
156        else
157            return PROPERTY_DESCRIPTORS_9_0;
158    }
159
160    /**
161     * The comment mapper, or <code>null</code> if none;
162     * initially <code>null</code>.
163     * 
164     * @since 3.0
165     */
166    private DefaultCommentMapper commentMapper = null;
167
168    /**
169     * The Java type root (an <code>org.eclipse.jdt.core.ICompilationUnit</code> or
170     * an <code>org.eclipse.jdt.core.IClassFile</code>)
171     * this compilation unit was created from, or <code>null</code> if it was not
172     * created from a Java type root.
173     */
174    private ITypeRoot typeRoot = null;
175
176    /**
177     * The list of import declarations in textual order order;
178     * initially none (elementType: <code>ImportDeclaration</code>).
179     */
180    private ASTNode.NodeList imports = new ASTNode.NodeList(IMPORTS_PROPERTY);
181
182    /**
183     * Line end table. If <code>lineEndTable[i] == p</code> then the
184     * line number <code>i+1</code> ends at character position
185     * <code>p</code>. Except for the last line, the positions are that
186     * of the last character of the line delimiter.
187     * For example, the source string <code>A\nB\nC</code> has
188     * line end table {1, 3} (if \n is one character).
189     */
190    private int[] lineEndTable = Util.EMPTY_INT_ARRAY;
191
192    /**
193     * Messages reported by the compiler during parsing or name resolution.
194     */
195    private Message[] messages;
196
197    /**
198     * The comment list (element type: {@link Comment},
199     * or <code>null</code> if none; initially <code>null</code>.
200     * 
201     * @since 3.0
202     */
203    private List optionalCommentList = null;
204
205    /**
206     * The comment table, or <code>null</code> if none; initially
207     * <code>null</code>. This array is the storage underlying
208     * the <code>optionalCommentList</code> ArrayList.
209     * 
210     * @since 3.0
211     */
212    Comment[] optionalCommentTable = null;
213
214    /**
215     * The package declaration, or <code>null</code> if none; initially
216     * <code>null</code>.
217     */
218    private PackageDeclaration optionalPackageDeclaration = null;
219
220    /**
221     * The module declaration, or <code>null</code> if none; initially
222     * <code>null</code>.
223     */
224    private ModuleDeclaration module = null;
225    /**
226     * Problems reported by the compiler during parsing or name resolution.
227     */
228    private IProblem[] problems = EMPTY_PROBLEMS;
229
230    /**
231     * Internal data used to perform statements recovery.
232     */
233    private Object statementsRecoveryData;
234
235    /**
236     * The list of type declarations in textual order order;
237     * initially none (elementType: <code>AbstractTypeDeclaration</code>)
238     */
239    private ASTNode.NodeList types = new ASTNode.NodeList(TYPES_PROPERTY);
240
241    /**
242     * Creates a new AST node for a compilation owned by the given AST.
243     * The compilation unit initially has no package declaration, no
244     * import declarations, and no type declarations.
245     * <p>
246     * N.B. This constructor is package-private; all subclasses must be
247     * declared in the same package; clients are unable to declare
248     * additional subclasses.
249     * </p>
250     *
251     * @param ast the AST that is to own this node
252     */
253    CompilationUnit(AST ast) {
254        super(ast);
255    }
256
257    @Override
258    void accept0(ASTVisitor visitor) {
259        boolean visitChildren = visitor.visit(this);
260        if (visitChildren) {
261            // visit children in normal left to right reading order
262            if (this.ast.apiLevel >= AST.JLS9_INTERNAL) {
263                acceptChild(visitorgetModule());
264            }
265            acceptChild(visitorgetPackage());
266            acceptChildren(visitor, this.imports);
267            acceptChildren(visitor, this.types);
268        }
269        visitor.endVisit(this);
270    }
271
272    @Override
273    ASTNode clone0(AST target) {
274        CompilationUnit result = new CompilationUnit(target);
275        // n.b do not copy line number table or messages
276        result.setSourceRange(getStartPosition(), getLength());
277        if (this.ast.apiLevel >= AST.JLS9_INTERNAL) {
278            result.setModule((ModuleDeclarationASTNode.copySubtree(targetgetModule()));
279        }
280        result.setPackage(
281                (PackageDeclarationASTNode.copySubtree(targetgetPackage()));
282        result.imports().addAll(ASTNode.copySubtrees(targetimports()));
283        result.types().addAll(ASTNode.copySubtrees(targettypes()));
284        return result;
285    }
286
287    /**
288     * Returns the column number corresponding to the given source character
289     * position in the original source string. Column number are zero-based.
290     * Return <code>-1</code> if it is beyond the valid range or <code>-2</code>
291     * if the column number information is unknown.
292     *
293     * @param position a 0-based character position, possibly
294     *                 negative or out of range
295     * @return the 0-based column number, or <code>-1</code> if the character
296     *         position does not correspond to a source line in the original
297     *         source file or <code>-2</code> if column number information is
298     *         unknown for this
299     *         compilation unit
300     * @see ASTParser
301     * @since 3.2
302     */
303    public int getColumnNumber(final int position) {
304        if (this.lineEndTable == null)
305            return -2;
306        final int line = getLineNumber(position);
307        if (line == -1) {
308            return -1;
309        }
310        if (line == 1) {
311            if (position >= getStartPosition() + getLength())
312                return -1;
313            return position;
314        }
315        // length is different from 0
316        int length = this.lineEndTable.length;
317        // -1 to for one-based to zero-based conversion.
318        // -1, again, to get previous line.
319        final int previousLineOffset = this.lineEndTable[line - 2];
320        // previousLineOffset + 1 is the first character of the current line
321        final int offsetForLine = previousLineOffset + 1;
322        final int currentLineEnd = line == length + 1 ? getStartPosition() + getLength() - 1
323                : this.lineEndTable[line - 1];
324        if (offsetForLine > currentLineEnd) {
325            return -1;
326        } else {
327            return position - offsetForLine;
328        }
329    }
330
331    /**
332     * Finds the corresponding AST node in the given compilation unit from
333     * which the given binding originated. Returns <code>null</code> if the
334     * binding does not correspond to any node in this compilation unit.
335     * This method always returns <code>null</code> if bindings were not requested
336     * when this AST was built.
337     * <p>
338     * The following table indicates the expected node type for the various
339     * different kinds of bindings:
340     * <ul>
341     * <li>package - a <code>PackageDeclaration</code></li>
342     * <li>class or interface - a <code>TypeDeclaration</code> or a
343     * <code>AnonymousClassDeclaration</code> (for anonymous classes)</li>
344     * <li>primitive type - none</li>
345     * <li>array type - none</li>
346     * <li>field - a <code>VariableDeclarationFragment</code> in a
347     * <code>FieldDeclaration</code></li>
348     * <li>local variable - a <code>SingleVariableDeclaration</code>, or
349     * a <code>VariableDeclarationFragment</code> in a
350     * <code>VariableDeclarationStatement</code> or
351     * <code>VariableDeclarationExpression</code></li>
352     * <li>method - a <code>MethodDeclaration</code></li>
353     * <li>constructor - a <code>MethodDeclaration</code></li>
354     * <li>annotation type - an <code>AnnotationTypeDeclaration</code></li>
355     * <li>annotation type member - an
356     * <code>AnnotationTypeMemberDeclaration</code></li>
357     * <li>enum type - an <code>EnumDeclaration</code></li>
358     * <li>enum constant - an <code>EnumConstantDeclaration</code></li>
359     * <li>type variable - a <code>TypeParameter</code></li>
360     * <li>capture binding - none</li>
361     * <li>annotation binding - an <code>Annotation</code></li>
362     * <li>member value pair binding - an <code>MemberValuePair</code>,
363     * or <code>null</code> if it represents a default value or a single member
364     * value</li>
365     * </ul>
366     * <p>
367     * For parameterized or raw type bindings, the declaring node is
368     * that of the corresponding generic type. And for parameterized or raw
369     * method bindings, the declaring node is that of the corresponding
370     * generic method.
371     * </p>
372     * <p>
373     * Each call to
374     * {@link ASTParser#createAST(org.eclipse.core.runtime.IProgressMonitor)} with a
375     * request for bindings
376     * gives rise to separate universe of binding objects. This method always
377     * returns
378     * <code>null</code> when the binding object comes from a different AST.
379     * Use <code>findDeclaringNode(binding.getKey())</code> when the binding comes
380     * from a different AST.
381     * </p>
382     *
383     * @param binding the binding
384     * @return the corresponding node where the given binding is declared,
385     *         or <code>null</code> if the binding does not correspond to a node in
386     *         this
387     *         compilation unit or if bindings were not requested when this AST was
388     *         built
389     * @see #findDeclaringNode(String)
390     */
391    public ASTNode findDeclaringNode(IBinding binding) {
392        return this.ast.getBindingResolver().findDeclaringNode(binding);
393    }
394
395    /**
396     * Finds the corresponding AST node in the given compilation unit from
397     * which the binding with the given key originated. Returns
398     * <code>null</code> if the corresponding node cannot be determined.
399     * This method always returns <code>null</code> if bindings were not requested
400     * when this AST was built.
401     * <p>
402     * The following table indicates the expected node type for the various
403     * different kinds of binding keys:
404     * <ul>
405     * <li></li>
406     * <li>package - a <code>PackageDeclaration</code></li>
407     * <li>class or interface - a <code>TypeDeclaration</code> or a
408     * <code>AnonymousClassDeclaration</code> (for anonymous classes)</li>
409     * <li>primitive type - none</li>
410     * <li>array type - none</li>
411     * <li>field - a <code>VariableDeclarationFragment</code> in a
412     * <code>FieldDeclaration</code></li>
413     * <li>local variable - a <code>SingleVariableDeclaration</code>, or
414     * a <code>VariableDeclarationFragment</code> in a
415     * <code>VariableDeclarationStatement</code> or
416     * <code>VariableDeclarationExpression</code></li>
417     * <li>method - a <code>MethodDeclaration</code></li>
418     * <li>constructor - a <code>MethodDeclaration</code></li>
419     * <li>annotation type - an <code>AnnotationTypeDeclaration</code></li>
420     * <li>annotation type member - an
421     * <code>AnnotationTypeMemberDeclaration</code></li>
422     * <li>enum type - an <code>EnumDeclaration</code></li>
423     * <li>enum constant - an <code>EnumConstantDeclaration</code></li>
424     * <li>type variable - a <code>TypeParameter</code></li>
425     * <li>capture binding - none</li>
426     * </ul>
427     * For parameterized or raw type bindings, the declaring node is
428     * that of the corresponding generic type. And for parameterized or raw
429     * method bindings, the declaring node is that of the corresponding
430     * generic method.
431     *
432     * @param key the binding key, or <code>null</code>
433     * @return the corresponding node where a binding with the given
434     *         key is declared, or <code>null</code> if the key is <code>null</code>
435     *         or if the key does not correspond to a node in this compilation unit
436     *         or if bindings were not requested when this AST was built
437     * @see IBinding#getKey()
438     * @since 2.1
439     */
440    public ASTNode findDeclaringNode(String key) {
441        return this.ast.getBindingResolver().findDeclaringNode(key);
442    }
443
444    /**
445     * Returns a list of the comments encountered while parsing
446     * this compilation unit.
447     * <p>
448     * Since the Java language allows comments to appear most anywhere
449     * in the source text, it is problematic to locate comments in relation
450     * to the structure of an AST. The one exception is doc comments
451     * which, by convention, immediately precede type, field, and
452     * method declarations; these comments are located in the AST
453     * by {@link BodyDeclaration#getJavadoc BodyDeclaration.getJavadoc}.
454     * Other comments do not show up in the AST. The table of comments
455     * is provided for clients that need to find the source ranges of
456     * all comments in the original source string. It includes entries
457     * for comments of all kinds (line, block, and doc), arranged in order
458     * of increasing source position.
459     * </p>
460     * <p>
461     * Note on comment parenting: The {@link ASTNode#getParent() getParent()}
462     * of a doc comment associated with a body declaration is the body
463     * declaration node; for these comment nodes
464     * {@link ASTNode#getRoot() getRoot()} will return the compilation unit
465     * (assuming an unmodified AST) reflecting the fact that these nodes
466     * are property located in the AST for the compilation unit.
467     * However, for other comment nodes, {@link ASTNode#getParent() getParent()}
468     * will return <code>null</code>, and {@link ASTNode#getRoot() getRoot()}
469     * will return the comment node itself, indicating that these comment nodes
470     * are not directly connected to the AST for the compilation unit. The
471     * {@link Comment#getAlternateRoot Comment.getAlternateRoot}
472     * method provides a way to navigate from a comment to its compilation
473     * unit.
474     * </p>
475     * <p>
476     * A note on visitors: The only comment nodes that will be visited when
477     * visiting a compilation unit are the doc comments parented by body
478     * declarations. To visit all comments in normal reading order, iterate
479     * over the comment table and call {@link ASTNode#accept(ASTVisitor) accept}
480     * on each element.
481     * </p>
482     * <p>
483     * Clients cannot modify the resulting list.
484     * </p>
485     *
486     * @return an unmodifiable list of comments in increasing order of source
487     *         start position (element type: {@link Comment}, or <code>null</code>
488     *         if comment information
489     *         for this compilation unit is not available
490     * @see ASTParser
491     * @since 3.0
492     */
493    public List getCommentList() {
494        return this.optionalCommentList;
495    }
496
497    /**
498     * Returns the internal comment mapper.
499     *
500     * @return the comment mapper, or <code>null</code> if none.
501     * @since 3.0
502     */
503    DefaultCommentMapper getCommentMapper() {
504        return this.commentMapper;
505    }
506
507    /**
508     * Returns the extended source length of the given node. Unlike
509     * {@link ASTNode#getStartPosition()} and {@link ASTNode#getLength()},
510     * the extended source range may include comments and whitespace
511     * immediately before or after the normal source range for the node.
512     *
513     * @param node the node
514     * @return a (possibly 0) length, or <code>0</code>
515     *         if no source position information is recorded for this node
516     * @see #getExtendedStartPosition(ASTNode)
517     * @since 3.0
518     */
519    public int getExtendedLength(ASTNode node) {
520        if (node == null) {
521            throw new IllegalArgumentException();
522        }
523        if (this.commentMapper == null || node.getAST() != getAST()) {
524            // fall back: use best info available
525            return node.getLength();
526        } else {
527            return this.commentMapper.getExtendedLength(node);
528        }
529    }
530
531    /**
532     * Returns the extended start position of the given node. Unlike
533     * {@link ASTNode#getStartPosition()} and {@link ASTNode#getLength()},
534     * the extended source range may include comments and whitespace
535     * immediately before or after the normal source range for the node.
536     *
537     * @param node the node
538     * @return the 0-based character index, or <code>-1</code>
539     *         if no source position information is recorded for this node
540     * @see #getExtendedLength(ASTNode)
541     * @since 3.0
542     */
543    public int getExtendedStartPosition(ASTNode node) {
544        if (node == null) {
545            throw new IllegalArgumentException();
546        }
547        if (this.commentMapper == null || node.getAST() != getAST()) {
548            // fall back: use best info available
549            return node.getStartPosition();
550        } else {
551            return this.commentMapper.getExtendedStartPosition(node);
552        }
553    }
554
555    /**
556     * The Java element (an <code>org.eclipse.jdt.core.ICompilationUnit</code> or an
557     * <code>org.eclipse.jdt.core.IClassFile</code>)
558     * this compilation unit was created from, or <code>null</code> if it was not
559     * created from a Java element.
560     *
561     * @return the Java element this compilation unit was created from, or
562     *         <code>null</code> if none
563     * @since 3.1
564     * @see #getTypeRoot()
565     */
566    public IJavaElement getJavaElement() {
567        return this.typeRoot;
568    }
569
570    /**
571     * Returns the list of messages reported by the compiler during the parsing
572     * or the type checking of this compilation unit. This list might be a subset of
573     * errors detected and reported by a Java compiler.
574     * <p>
575     * This list of messages is suitable for simple clients that do little
576     * more than log the messages or display them to the user. Clients that
577     * need further details should call <code>getProblems</code> to get
578     * compiler problem objects.
579     * </p>
580     *
581     * @return the list of messages, possibly empty
582     * @see #getProblems()
583     * @see ASTParser
584     */
585    public Message[] getMessages() {
586        if (this.messages == null) {
587            int problemLength = this.problems.length;
588            if (problemLength == 0) {
589                this.messages = EMPTY_MESSAGES;
590            } else {
591                this.messages = new Message[problemLength];
592                for (int i = 0i < problemLengthi++) {
593                    IProblem problem = this.problems[i];
594                    int start = problem.getSourceStart();
595                    int end = problem.getSourceEnd();
596                    this.messages[i] = new Message(problem.getMessage(), startend - start + 1);
597                }
598            }
599        }
600        return this.messages;
601    }
602
603    @Override
604    final int getNodeType0() {
605        return COMPILATION_UNIT;
606    }
607
608    /**
609     * Returns the node for the module declaration of this compilation
610     * unit, or <code>null</code> if this compilation unit is not a module info.
611     *
612     * @return the module declaration node, or <code>null</code> if none
613     * @exception UnsupportedOperationException if this operation is used below JLS9
614     * @since 3.14
615     */
616    public ModuleDeclaration getModule() {
617        unsupportedBelow9();
618        return this.module;
619    }
620
621    /**
622     * Returns the node for the package declaration of this compilation
623     * unit, or <code>null</code> if this compilation unit is in the
624     * default package.
625     *
626     * @return the package declaration node, or <code>null</code> if none
627     */
628    public PackageDeclaration getPackage() {
629        return this.optionalPackageDeclaration;
630    }
631
632    /**
633     * Given a line number and column number, returns the corresponding
634     * position in the original source string.
635     * Returns -2 if no line number information is available for this
636     * compilation unit.
637     * Returns the total size of the source string if <code>line</code>
638     * is greater than the actual number lines in the unit.
639     * Returns -1 if <code>column</code> is less than 0,
640     * or the position of the last character of the line if <code>column</code>
641     * is beyond the legal range, or the given line number is less than one.
642     *
643     * @param line   the one-based line number
644     * @param column the zero-based column number
645     * @return the 0-based character position in the source string;
646     *         <code>-2</code> if line/column number information is not known
647     *         for this compilation unit or <code>-1</code> the inputs are not valid
648     * @since 3.2
649     */
650    public int getPosition(int lineint column) {
651        if (this.lineEndTable == null)
652            return -2;
653        if (line < 1 || column < 0)
654            return -1;
655        int length;
656        if ((length = this.lineEndTable.length) == 0) {
657            if (line != 1)
658                return -1;
659            return column >= getStartPosition() + getLength() ? -1 : column;
660        }
661        if (line == 1) {
662            final int endOfLine = this.lineEndTable[0];
663            return column > endOfLine ? -1 : column;
664        } else if (line > length + 1) {
665            // greater than the number of lines in the source string.
666            return -1;
667        }
668        // -1 to for one-based to zero-based conversion.
669        // -1, again, to get previous line.
670        final int previousLineOffset = this.lineEndTable[line - 2];
671        // previousLineOffset + 1 is the first character of the current line
672        final int offsetForLine = previousLineOffset + 1;
673        final int currentLineEnd = line == length + 1 ? getStartPosition() + getLength() - 1
674                : this.lineEndTable[line - 1];
675        if ((offsetForLine + column) > currentLineEnd) {
676            return -1;
677        } else {
678            return offsetForLine + column;
679        }
680    }
681
682    /**
683     * Returns the list of detailed problem reports noted by the compiler
684     * during the parsing or the type checking of this compilation unit. This
685     * list might be a subset of errors detected and reported by a Java
686     * compiler.
687     * <p>
688     * Simple clients that do little more than log the messages or display
689     * them to the user should probably call <code>getMessages</code> instead.
690     * </p>
691     *
692     * @return the list of detailed problem objects, possibly empty
693     * @see #getMessages()
694     * @see ASTParser
695     * @since 2.1
696     */
697    public IProblem[] getProblems() {
698        return this.problems;
699    }
700
701    /**
702     * Internal method
703     *
704     * This method return internal data used to perform statements recovery.
705     *
706     * @return internal data used to perform statements recovery.
707     *
708     * @noreference This method is not intended to be referenced by clients.
709     * @since 3.5
710     */
711    public Object getStatementsRecoveryData() {
712        return this.statementsRecoveryData;
713    }
714
715    /**
716     * The Java type root (a {@link org.eclipse.jdt.core.ICompilationUnit
717     * compilation unit} or a {@link org.eclipse.jdt.core.IClassFile class file})
718     * this compilation unit was created from, or <code>null</code> if it was not
719     * created from a Java type root.
720     *
721     * @return the Java type root this compilation unit was created from, or
722     *         <code>null</code> if none
723     * @since 3.3
724     */
725    public ITypeRoot getTypeRoot() {
726        return this.typeRoot;
727    }
728
729    /**
730     * Returns the live list of nodes for the import declarations of this
731     * compilation unit, in order of appearance.
732     *
733     * @return the live list of import declaration nodes
734     *         (elementType: {@link ImportDeclaration})
735     */
736    public List imports() {
737        return this.imports;
738    }
739
740    /**
741     * Return the index in the whole comments list {@link #getCommentList() }
742     * of the first leading comments associated with the given node.
743     *
744     * @param node the node
745     * @return 0-based index of first leading comment or -1 if node has no
746     *         associated
747     *         comment before its start position.
748     * @since 3.2
749     */
750    public int firstLeadingCommentIndex(ASTNode node) {
751        if (node == null) {
752            throw new IllegalArgumentException();
753        }
754        if (this.commentMapper == null || node.getAST() != getAST()) {
755            return -1;
756        }
757        return this.commentMapper.firstLeadingCommentIndex(node);
758    }
759
760    /**
761     * Return the index in the whole comments list {@link #getCommentList() }
762     * of the last trailing comments associated with the given node.
763     *
764     * @param node the node
765     * @return 0-based index of last trailing comment or -1 if node has no
766     *         associated comment after its end position.
767     * @since 3.2
768     */
769    public int lastTrailingCommentIndex(ASTNode node) {
770        if (node == null) {
771            throw new IllegalArgumentException();
772        }
773        if (this.commentMapper == null || node.getAST() != getAST()) {
774            return -1;
775        }
776        return this.commentMapper.lastTrailingCommentIndex(node);
777    }
778
779    /**
780     * Initializes the internal comment mapper with the given
781     * scanner.
782     *
783     * @param scanner the scanner
784     * @since 3.0
785     */
786    void initCommentMapper(Scanner scanner) {
787        this.commentMapper = new DefaultCommentMapper(this.optionalCommentTable);
788        this.commentMapper.initialize(this, scanner);
789    }
790
791    @Override
792    final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
793        if (property == IMPORTS_PROPERTY) {
794            return imports();
795        }
796        if (property == TYPES_PROPERTY) {
797            return types();
798        }
799        // allow default implementation to flag the error
800        return super.internalGetChildListProperty(property);
801    }
802
803    @Override
804    final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor propertyboolean getASTNode child) {
805        if (property == MODULE_PROPERTY) {
806            if (get) {
807                return getModule();
808            } else {
809                setModule((ModuleDeclarationchild);
810                return null;
811            }
812        }
813        if (property == PACKAGE_PROPERTY) {
814            if (get) {
815                return getPackage();
816            } else {
817                setPackage((PackageDeclarationchild);
818                return null;
819            }
820        }
821        // allow default implementation to flag the error
822        return super.internalGetSetChildProperty(propertygetchild);
823    }
824
825    @Override
826    final List internalStructuralPropertiesForType(int apiLevel) {
827        return propertyDescriptors(apiLevel);
828    }
829
830    /**
831     * Returns the line number corresponding to the given source character
832     * position in the original source string. The initial line of the
833     * compilation unit is numbered 1, and each line extends through the
834     * last character of the end-of-line delimiter. The very last line extends
835     * through the end of the source string and has no line delimiter.
836     * For example, the source string <code>class A\n{\n}</code> has 3 lines
837     * corresponding to inclusive character ranges [0,7], [8,9], and [10,10].
838     * Returns 1 for a character position that does not correspond to any
839     * source line, or if no line number information is available for this
840     * compilation unit.
841     *
842     * @param position a 0-based character position, possibly
843     *                 negative or out of range
844     * @return the 1-based line number, or <code>1</code> if the character
845     *         position does not correspond to a source line in the original
846     *         source file or if line number information is not known for this
847     *         compilation unit
848     * @deprecated Use getLineNumber(int) instead. Be careful to handle the negative
849     *             values.
850     * @see ASTParser
851     * @see #getLineNumber(int)
852     */
853    public int lineNumber(int position) {
854        int lineNumber = getLineNumber(position);
855        return lineNumber < 1 ? 1 : lineNumber;
856    }
857
858    /**
859     * Returns the line number corresponding to the given source character
860     * position in the original source string. The initial line of the
861     * compilation unit is numbered 1, and each line extends through the
862     * last character of the end-of-line delimiter. The very last line extends
863     * through the end of the source string and has no line delimiter.
864     * For example, the source string <code>class A\n{\n}</code> has 3 lines
865     * corresponding to inclusive character ranges [0,7], [8,9], and [10,10].
866     * Returns -1 for a character position that does not correspond to any
867     * source line, or -2 if no line number information is available for this
868     * compilation unit.
869     *
870     * @param position a 0-based character position, possibly
871     *                 negative or out of range
872     * @return the 1-based line number, or <code>-1</code> if the character
873     *         position does not correspond to a source line in the original
874     *         source file or <code>-2</code> if line number information is not
875     *         known for this
876     *         compilation unit
877     * @see ASTParser
878     * @since 3.2
879     */
880    public int getLineNumber(int position) {
881        if (this.lineEndTable == null)
882            return -2;
883        int length;
884        if ((length = this.lineEndTable.length) == 0) {
885            if (position >= getStartPosition() + getLength()) {
886                return -1;
887            }
888            return 1;
889        }
890        int low = 0;
891        if (position < 0) {
892            // position illegal
893            return -1;
894        }
895        if (position <= this.lineEndTable[low]) {
896            // before the first line delimiter
897            return 1;
898        }
899        // assert position > lineEndTable[low+1] && low == 0
900        int hi = length - 1;
901        if (position > this.lineEndTable[hi]) {
902            // position beyond the last line separator
903            if (position >= getStartPosition() + getLength()) {
904                // this is beyond the end of the source length
905                return -1;
906            } else {
907                return length + 1;
908            }
909        }
910        // assert lineEndTable[low] < position <= lineEndTable[hi]
911        // && low == 0 && hi == length - 1 && low < hi
912
913        // binary search line end table
914        while (true) {
915            // invariant lineEndTable[low] < position <= lineEndTable[hi]
916            // && 0 <= low < hi <= length - 1
917            // reducing measure hi - low
918            if (low + 1 == hi) {
919                // assert lineEndTable[low] < position <= lineEndTable[low+1]
920                // position is on line low+1 (line number is low+2)
921                return low + 2;
922            }
923            // assert hi - low >= 2, so average is truly in between
924            int mid = low + (hi - low) / 2;
925            // assert 0 <= low < mid < hi <= length - 1
926            if (position <= this.lineEndTable[mid]) {
927                // assert lineEndTable[low] < position <= lineEndTable[mid]
928                // && 0 <= low < mid < hi <= length - 1
929                hi = mid;
930            } else {
931                // position > lineEndTable[mid]
932                // assert lineEndTable[mid] < position <= lineEndTable[hi]
933                // && 0 <= low < mid < hi <= length - 1
934                low = mid;
935            }
936            // in both cases, invariant reachieved with reduced measure
937        }
938    }
939
940    @Override
941    int memSize() {
942        int size = BASE_NODE_SIZE + 8 * 4;
943        if (this.lineEndTable != null) {
944            size += HEADERS + 4 * this.lineEndTable.length;
945        }
946        if (this.optionalCommentTable != null) {
947            size += HEADERS + 4 * this.optionalCommentTable.length;
948        }
949        // ignore the space taken up by optionalCommentList
950        return size;
951    }
952
953    /**
954     * Enables the recording of changes to this compilation
955     * unit and its descendants. The compilation unit must have
956     * been created by {@link ASTParser} and still be in
957     * its original state. Once recording is on,
958     * arbitrary changes to the subtree rooted at this compilation
959     * unit are recorded internally. Once the modification has
960     * been completed, call {@link #rewrite(IDocument, Map)} to get an object
961     * representing the corresponding edits to the original
962     * source code string.
963     * <p>
964     * Note that this way of manipulating an AST only allows a single line of
965     * modifications,
966     * and it lacks important functionality like
967     * {@link ASTRewrite#createStringPlaceholder(String, int) string placeholders}
968     * and support for
969     * {@link ASTRewrite#createCopyTarget(ASTNode) copying} nodes including comments
970     * and formatting.
971     * </p>
972     * <p>
973     * To future-proof your code, <em>consider using an external {@link ASTRewrite}
974     * instead</em>,
975     * which doesn't suffer from these limitations and allows to modify an AST in a
976     * non-destructive way.
977     * </p>
978     *
979     * @exception IllegalArgumentException if this compilation unit is
980     *                                     marked as unmodifiable, or if this
981     *                                     compilation unit has already
982     *                                     been tampered with, or recording has
983     *                                     already been enabled
984     * @see ASTRewrite
985     * @since 3.0
986     */
987    public void recordModifications() {
988        getAST().recordModifications(this);
989    }
990
991    /**
992     * Sets the list of the comments encountered while parsing
993     * this compilation unit.
994     *
995     * @param commentTable a list of comments in increasing order
996     *                     of source start position, or <code>null</code> if comment
997     *                     information for this compilation unit is not available
998     * @exception IllegalArgumentException if the comment table is
999     *                                     not in increasing order of source
1000     *                                     position
1001     * @see #getCommentList()
1002     * @see ASTParser
1003     * @since 3.0
1004     */
1005    void setCommentTable(Comment[] commentTable) {
1006        // double check table to ensure that all comments have
1007        // source positions and are in strictly increasing order
1008        if (commentTable == null) {
1009            this.optionalCommentList = null;
1010            this.optionalCommentTable = null;
1011        } else {
1012            int nextAvailablePosition = 0;
1013            for (int i = 0i < commentTable.lengthi++) {
1014                Comment comment = commentTable[i];
1015                if (comment == null) {
1016                    throw new IllegalArgumentException();
1017                }
1018                int start = comment.getStartPosition();
1019                int length = comment.getLength();
1020                if (start < 0 || length < 0 || start < nextAvailablePosition) {
1021                    throw new IllegalArgumentException();
1022                }
1023                nextAvailablePosition = comment.getStartPosition() + comment.getLength();
1024            }
1025            this.optionalCommentTable = commentTable;
1026            List commentList = Arrays.asList(commentTable);
1027            // protect the list from further modification
1028            this.optionalCommentList = Collections.unmodifiableList(commentList);
1029        }
1030    }
1031
1032    /**
1033     * Sets the Java type root (a {@link org.eclipse.jdt.core.ICompilationUnit
1034     * compilation unit} or a {@link org.eclipse.jdt.core.IClassFile class file})
1035     * this compilation unit was created from, or <code>null</code> if it was not
1036     * created from a Java type root.
1037     *
1038     * @param typeRoot the Java type root this compilation unit was created from
1039     */
1040    void setTypeRoot(ITypeRoot typeRoot) {
1041        this.typeRoot = typeRoot;
1042    }
1043
1044    /**
1045     * Sets the line end table for this compilation unit.
1046     * If <code>lineEndTable[i] == p</code> then line number <code>i+1</code>
1047     * ends at character position <code>p</code>. Except for the last line, the
1048     * positions are that of (the last character of) the line delimiter.
1049     * For example, the source string <code>A\nB\nC</code> has
1050     * line end table {1, 3, 4}.
1051     *
1052     * @param lineEndTable the line end table
1053     */
1054    void setLineEndTable(int[] lineEndTable) {
1055        if (lineEndTable == null) {
1056            throw new NullPointerException();
1057        }
1058        // alternate root is *not* considered a structural property
1059        // but we protect them nevertheless
1060        checkModifiable();
1061        this.lineEndTable = lineEndTable;
1062    }
1063
1064    /**
1065     * Sets or clears the module declaration of this compilation unit
1066     * node to the given module declaration node.
1067     *
1068     * @param module the new module declaration node, or
1069     *               <code>null</code> if this compilation unit does not have a
1070     *               module
1071     * @exception IllegalArgumentException      if:
1072     *                                          <ul>
1073     *                                          <li>the node belongs to a different
1074     *                                          AST</li>
1075     *                                          <li>the node already has a
1076     *                                          parent</li>
1077     *                                          </ul>
1078     * @exception UnsupportedOperationException if this operation is used below JLS9
1079     * @since 3.14
1080     */
1081    public void setModule(ModuleDeclaration module) {
1082        unsupportedBelow9();
1083        ASTNode oldChild = this.module;
1084        preReplaceChild(oldChildmoduleMODULE_PROPERTY);
1085        this.module = module;
1086        postReplaceChild(oldChildmoduleMODULE_PROPERTY);
1087    }
1088
1089    /**
1090     * Sets or clears the package declaration of this compilation unit
1091     * node to the given package declaration node.
1092     *
1093     * @param pkgDecl the new package declaration node, or
1094     *                <code>null</code> if this compilation unit does not have a
1095     *                package
1096     *                declaration (that is in the default package)
1097     * @exception IllegalArgumentException if:
1098     *                                     <ul>
1099     *                                     <li>the node belongs to a different
1100     *                                     AST</li>
1101     *                                     <li>the node already has a parent</li>
1102     *                                     </ul>
1103     */
1104    public void setPackage(PackageDeclaration pkgDecl) {
1105        ASTNode oldChild = this.optionalPackageDeclaration;
1106        preReplaceChild(oldChildpkgDeclPACKAGE_PROPERTY);
1107        this.optionalPackageDeclaration = pkgDecl;
1108        postReplaceChild(oldChildpkgDeclPACKAGE_PROPERTY);
1109    }
1110
1111    /**
1112     * Sets the array of problems reported by the compiler during the parsing or
1113     * name resolution of this compilation unit.
1114     *
1115     * @param problems the list of problems
1116     */
1117    void setProblems(IProblem[] problems) {
1118        if (problems == null) {
1119            throw new IllegalArgumentException();
1120        }
1121        this.problems = problems;
1122    }
1123
1124    /**
1125     * Internal method
1126     *
1127     * Sets internal data used to perform statements recovery.
1128     * 
1129     * @param data
1130     *
1131     * @since 3.5
1132     */
1133    void setStatementsRecoveryData(Object data) {
1134        this.statementsRecoveryData = data;
1135    }
1136
1137    @Override
1138    final boolean subtreeMatch0(ASTMatcher matcherObject other) {
1139        // dispatch to correct overloaded match method
1140        return matcher.match(this, other);
1141    }
1142
1143    @Override
1144    int treeSize() {
1145        int size = memSize();
1146        if (this.module != null) {
1147            size += getModule().treeSize();
1148        }
1149        if (this.optionalPackageDeclaration != null) {
1150            size += getPackage().treeSize();
1151        }
1152        size += this.imports.listSize();
1153        size += this.types.listSize();
1154        // include disconnected comments
1155        if (this.optionalCommentList != null) {
1156            for (int i = 0i < this.optionalCommentList.size(); i++) {
1157                Comment comment = (Comment) this.optionalCommentList.get(i);
1158                if (comment != null && comment.getParent() == null) {
1159                    size += comment.treeSize();
1160                }
1161            }
1162        }
1163        return size;
1164    }
1165
1166    /**
1167     * Returns the live list of nodes for the top-level type declarations of this
1168     * compilation unit, in order of appearance.
1169     * <p>
1170     * Note that in JLS3, the types may include both enum declarations
1171     * and annotation type declarations introduced in J2SE 5.
1172     * For JLS2, the elements are always <code>TypeDeclaration</code>.
1173     * </p>
1174     *
1175     * @return the live list of top-level type declaration
1176     *         nodes (element type: {@link AbstractTypeDeclaration})
1177     */
1178    public List types() {
1179        return this.types;
1180    }
1181}
1182
MembersX
CompilationUnit:getColumnNumber:Block:line
CompilationUnit:getJavaElement
CompilationUnit:memSize
CompilationUnit:internalGetSetChildProperty
CompilationUnit:module
CompilationUnit:optionalCommentTable
CompilationUnit:getMessages:Block:Block:Block:Block:end
CompilationUnit:treeSize
CompilationUnit:optionalPackageDeclaration
CompilationUnit:statementsRecoveryData
CompilationUnit:getMessages:Block:Block:Block:Block:problem
CompilationUnit:getPosition:Block:Block:endOfLine
CompilationUnit:PROPERTY_DESCRIPTORS
CompilationUnit:treeSize:Block:size
CompilationUnit:problems
CompilationUnit:setStatementsRecoveryData
CompilationUnit:setTypeRoot
CompilationUnit:getExtendedLength
CompilationUnit:typeRoot
CompilationUnit:getMessages
CompilationUnit:findDeclaringNode
CompilationUnit:setCommentTable:Block:Block:Block:length
CompilationUnit:EMPTY_MESSAGES
CompilationUnit:TYPES_PROPERTY
CompilationUnit:getPosition:Block:currentLineEnd
CompilationUnit:getColumnNumber:Block:previousLineOffset
CompilationUnit:internalGetChildListProperty
CompilationUnit:IMPORTS_PROPERTY
CompilationUnit:getLineNumber:Block:hi
CompilationUnit:setCommentTable:Block:Block:Block:start
CompilationUnit:optionalCommentList
CompilationUnit:setModule
CompilationUnit:getColumnNumber:Block:currentLineEnd
CompilationUnit:getNodeType0
CompilationUnit:getLineNumber:Block:Block:mid
CompilationUnit:setPackage
CompilationUnit:accept0
CompilationUnit:getPackage
CompilationUnit:setCommentTable
CompilationUnit:PACKAGE_PROPERTY
CompilationUnit:getColumnNumber
CompilationUnit:getLineNumber
CompilationUnit:setModule:Block:oldChild
CompilationUnit:recordModifications
CompilationUnit:treeSize:Block:Block:Block:comment
CompilationUnit:getExtendedStartPosition
CompilationUnit:getTypeRoot
CompilationUnit:commentMapper
CompilationUnit:types
CompilationUnit:lineNumber
CompilationUnit:Block:properyList
CompilationUnit:clone0:Block:result
CompilationUnit:getLineNumber:Block:length
CompilationUnit:setCommentTable:Block:Block:commentList
CompilationUnit:getModule
CompilationUnit:initCommentMapper
CompilationUnit:getPosition:Block:offsetForLine
CompilationUnit:messages
CompilationUnit:setProblems
CompilationUnit:getColumnNumber:Block:offsetForLine
CompilationUnit:subtreeMatch0
CompilationUnit:lineNumber:Block:lineNumber
CompilationUnit:imports
CompilationUnit:CompilationUnit
CompilationUnit:lineEndTable
CompilationUnit:setCommentTable:Block:Block:nextAvailablePosition
CompilationUnit:getCommentList
CompilationUnit:getPosition
CompilationUnit:lastTrailingCommentIndex
CompilationUnit:setLineEndTable
CompilationUnit:getStatementsRecoveryData
CompilationUnit:EMPTY_PROBLEMS
CompilationUnit:PROPERTY_DESCRIPTORS_9_0
CompilationUnit:accept0:Block:visitChildren
CompilationUnit:firstLeadingCommentIndex
CompilationUnit:getProblems
CompilationUnit:getPosition:Block:previousLineOffset
CompilationUnit:propertyDescriptors
CompilationUnit:memSize:Block:size
CompilationUnit:getCommentMapper
CompilationUnit:getLineNumber:Block:low
CompilationUnit:setPackage:Block:oldChild
CompilationUnit:getPosition:Block:length
CompilationUnit:setCommentTable:Block:Block:Block:comment
CompilationUnit:getMessages:Block:Block:problemLength
CompilationUnit:MODULE_PROPERTY
CompilationUnit:clone0
CompilationUnit:getMessages:Block:Block:Block:Block:start
CompilationUnit:getColumnNumber:Block:length
CompilationUnit:internalStructuralPropertiesForType
Members
X