Source Code Cross Referenced for ASTParser.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » core » dom » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » jdt » org.eclipse.jdt.core.dom 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 2004, 2007 IBM Corporation and others.
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         *     IBM Corporation - initial API and implementation
0010:         *******************************************************************************/package org.eclipse.jdt.core.dom;
0011:
0012:        import java.util.HashMap;
0013:        import java.util.Map;
0014:
0015:        import org.eclipse.core.runtime.IProgressMonitor;
0016:        import org.eclipse.jdt.core.IClassFile;
0017:        import org.eclipse.jdt.core.ICompilationUnit;
0018:        import org.eclipse.jdt.core.IJavaElement;
0019:        import org.eclipse.jdt.core.ITypeRoot;
0020:        import org.eclipse.jdt.core.IJavaProject;
0021:        import org.eclipse.jdt.core.JavaCore;
0022:        import org.eclipse.jdt.core.JavaModelException;
0023:        import org.eclipse.jdt.core.WorkingCopyOwner;
0024:        import org.eclipse.jdt.core.compiler.CategorizedProblem;
0025:        import org.eclipse.jdt.core.compiler.CharOperation;
0026:        import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
0027:        import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
0028:        import org.eclipse.jdt.internal.compiler.env.IBinaryType;
0029:        import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner;
0030:        import org.eclipse.jdt.internal.compiler.parser.RecoveryScannerData;
0031:        import org.eclipse.jdt.internal.compiler.parser.Scanner;
0032:        import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
0033:        import org.eclipse.jdt.internal.core.*;
0034:        import org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil;
0035:        import org.eclipse.jdt.internal.core.util.RecordedParsingInformation;
0036:        import org.eclipse.jdt.internal.core.util.Util;
0037:
0038:        /**
0039:         * A Java language parser for creating abstract syntax trees (ASTs).
0040:         * <p>
0041:         * Example: Create basic AST from source string
0042:         * <pre>
0043:         * char[] source = ...;
0044:         * ASTParser parser = ASTParser.newParser(AST.JLS3);  // handles JDK 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6
0045:         * parser.setSource(source);
0046:         * CompilationUnit result = (CompilationUnit) parser.createAST(null);
0047:         * </pre>
0048:         * Once a configured parser instance has been used to create an AST,
0049:         * the settings are automatically reset to their defaults,
0050:         * ready for the parser instance to be reused.
0051:         * </p>
0052:         * <p>
0053:         * There are a number of configurable features:
0054:         * <ul>
0055:         * <li>Source string from {@link #setSource(char[]) char[]},
0056:         * {@link #setSource(ICompilationUnit) ICompilationUnit},
0057:         * or {@link #setSource(IClassFile) IClassFile}, and limited
0058:         * to a specified {@linkplain #setSourceRange(int,int) subrange}.</li>
0059:         * <li>Whether {@linkplain #setResolveBindings(boolean) bindings} will be created.</li>
0060:         * <li>Which {@linkplain #setWorkingCopyOwner(WorkingCopyOwner)
0061:         * working set owner} to use when resolving bindings).</li>
0062:         * <li>A hypothetical {@linkplain #setUnitName(String) compilation unit file name}
0063:         * and {@linkplain #setProject(IJavaProject) Java project}
0064:         * for locating a raw source string in the Java model (when
0065:         * resolving bindings)</li>
0066:         * <li>Which {@linkplain #setCompilerOptions(Map) compiler options}
0067:         * to use. This is especially important to use if the parsing/scanning of the source code requires a
0068:         * different version than the default of the workspace. For example, the workspace defaults are 1.4 and
0069:         * you want to create an AST for a source code that is using 1.5 constructs.</li>
0070:         * <li>Whether to parse just {@linkplain #setKind(int) an expression, statements,
0071:         * or body declarations} rather than an entire compilation unit.</li>
0072:         * <li>Whether to return a {@linkplain #setFocalPosition(int) abridged AST}
0073:         * focused on the declaration containing a given source position.</li>
0074:         * </ul>
0075:         * </p>
0076:         *
0077:         * @since 3.0
0078:         */
0079:        public class ASTParser {
0080:
0081:            /**
0082:             * Kind constant used to request that the source be parsed
0083:             * as a single expression.
0084:             */
0085:            public static final int K_EXPRESSION = 0x01;
0086:
0087:            /**
0088:             * Kind constant used to request that the source be parsed
0089:             * as a sequence of statements.
0090:             */
0091:            public static final int K_STATEMENTS = 0x02;
0092:
0093:            /**
0094:             * Kind constant used to request that the source be parsed
0095:             * as a sequence of class body declarations.
0096:             */
0097:            public static final int K_CLASS_BODY_DECLARATIONS = 0x04;
0098:
0099:            /**
0100:             * Kind constant used to request that the source be parsed
0101:             * as a compilation unit.
0102:             */
0103:            public static final int K_COMPILATION_UNIT = 0x08;
0104:
0105:            /**
0106:             * Creates a new object for creating a Java abstract syntax tree
0107:             * (AST) following the specified set of API rules.
0108:             *
0109:             * @param level the API level; one of the LEVEL constants
0110:             * declared on <code>AST</code>
0111:             * @return new ASTParser instance
0112:             */
0113:            public static ASTParser newParser(int level) {
0114:                return new ASTParser(level);
0115:            }
0116:
0117:            /**
0118:             * Level of AST API desired.
0119:             */
0120:            private final int apiLevel;
0121:
0122:            /**
0123:             * Kind of parse requested. Defaults to an entire compilation unit.
0124:             */
0125:            private int astKind;
0126:
0127:            /**
0128:             * Compiler options. Defaults to JavaCore.getOptions().
0129:             */
0130:            private Map compilerOptions;
0131:
0132:            /**
0133:             * Request for bindings. Defaults to <code>false</code>.
0134:             */
0135:            private boolean resolveBindings;
0136:
0137:            /**
0138:             * Request for a partial AST. Defaults to <code>false</code>.
0139:             */
0140:            private boolean partial = false;
0141:
0142:            /**
0143:             * Request for a statements recovery. Defaults to <code>false</code>.
0144:             */
0145:            private boolean statementsRecovery;
0146:
0147:            /**
0148:             * Request for a bindings recovery. Defaults to <code>false</code>.
0149:             */
0150:            private boolean bindingsRecovery;
0151:
0152:            /**
0153:             * The focal point for a partial AST request.
0154:             * Only used when <code>partial</code> is <code>true</code>.
0155:             */
0156:            private int focalPointPosition;
0157:
0158:            /**
0159:             * Source string.
0160:             */
0161:            private char[] rawSource = null;
0162:
0163:            /**
0164:             * Java model class file or compilation unit supplying the source.
0165:             */
0166:            private ITypeRoot typeRoot = null;
0167:
0168:            /**
0169:             * Character-based offset into the source string where parsing is to
0170:             * begin. Defaults to 0.
0171:             */
0172:            private int sourceOffset = 0;
0173:
0174:            /**
0175:             * Character-based length limit, or -1 if unlimited.
0176:             * All characters in the source string between <code>offset</code>
0177:             * and <code>offset+length-1</code> inclusive are parsed. Defaults to -1,
0178:             * which means the rest of the source string.
0179:             */
0180:            private int sourceLength = -1;
0181:
0182:            /**
0183:             * Working copy owner. Defaults to primary owner.
0184:             */
0185:            private WorkingCopyOwner workingCopyOwner = DefaultWorkingCopyOwner.PRIMARY;
0186:
0187:            /**
0188:             * Java project used to resolve names, or <code>null</code> if none.
0189:             * Defaults to none.
0190:             */
0191:            private IJavaProject project = null;
0192:
0193:            /**
0194:             * Name of the compilation unit for resolving bindings, or
0195:             * <code>null</code> if none. Defaults to none.
0196:             */
0197:            private String unitName = null;
0198:
0199:            /**
0200:             * Creates a new AST parser for the given API level.
0201:             * <p>
0202:             * N.B. This constructor is package-private.
0203:             * </p>
0204:             *
0205:             * @param level the API level; one of the LEVEL constants
0206:             * declared on <code>AST</code>
0207:             */
0208:            ASTParser(int level) {
0209:                if ((level != AST.JLS2_INTERNAL) && (level != AST.JLS3)) {
0210:                    throw new IllegalArgumentException();
0211:                }
0212:                this .apiLevel = level;
0213:                initializeDefaults();
0214:            }
0215:
0216:            /**
0217:             * Sets all the setting to their default values.
0218:             */
0219:            private void initializeDefaults() {
0220:                this .astKind = K_COMPILATION_UNIT;
0221:                this .rawSource = null;
0222:                this .typeRoot = null;
0223:                this .resolveBindings = false;
0224:                this .sourceLength = -1;
0225:                this .sourceOffset = 0;
0226:                this .workingCopyOwner = DefaultWorkingCopyOwner.PRIMARY;
0227:                this .unitName = null;
0228:                this .project = null;
0229:                this .partial = false;
0230:                Map options = JavaCore.getOptions();
0231:                options.remove(JavaCore.COMPILER_TASK_TAGS); // no need to parse task tags
0232:                this .compilerOptions = options;
0233:            }
0234:
0235:            /**
0236:             * Requests that the compiler should perform bindings recovery.
0237:             * When bindings recovery is enabled the compiler returns incomplete bindings.
0238:             * <p>
0239:             * Default to <code>false</code>.
0240:             * </p>
0241:             * <p>This should be set to true only if bindings are resolved. It has no effect if there is no binding
0242:             * resolution.</p>
0243:             *
0244:             * @param enabled <code>true</code> if incomplete bindings are expected,
0245:             *   and <code>false</code> if only complete bindings are expected.
0246:             *
0247:             * @see IBinding#isRecovered()
0248:             * @since 3.3
0249:             */
0250:            public void setBindingsRecovery(boolean enabled) {
0251:                this .bindingsRecovery = enabled;
0252:            }
0253:
0254:            /**
0255:             * Sets the compiler options to be used when parsing.
0256:             * <p>
0257:             * Note that {@link #setSource(IClassFile)},
0258:             * {@link #setSource(ICompilationUnit)},
0259:             * and {@link #setProject(IJavaProject)} reset the compiler options
0260:             * based on the Java project. In other cases, compiler options default
0261:             * to {@link JavaCore#getOptions()}. In either case, and especially
0262:             * in the latter, the caller should carefully weight the consequences of
0263:             * allowing compiler options to be defaulted as opposed to being
0264:             * explicitly specified for the <code>ASTParser</code> instance.
0265:             * For instance, there is a compiler option called "Source Compatibility Mode"
0266:             * which determines which JDK level the source code is expected to meet.
0267:             * If you specify "1.4", then "assert" is treated as a keyword and disallowed
0268:             * as an identifier; if you specify "1.3", then "assert" is allowed as an
0269:             * identifier. So this particular setting has a major bearing on what is
0270:             * considered syntactically legal. By explicitly specifying the setting,
0271:             * the client control exactly how the parser works. On the other hand,
0272:             * allowing default settings means the parsing behaves like other JDT tools.
0273:             * </p>
0274:             *
0275:             * @param options the table of options (key type: <code>String</code>;
0276:             * value type: <code>String</code>), or <code>null</code>
0277:             * to set it back to the default
0278:             */
0279:            public void setCompilerOptions(Map options) {
0280:                if (options == null) {
0281:                    options = JavaCore.getOptions();
0282:                } else {
0283:                    // copy client's options so as to not do any side effect on them
0284:                    options = new HashMap(options);
0285:                }
0286:                options.remove(JavaCore.COMPILER_TASK_TAGS); // no need to parse task tags
0287:                this .compilerOptions = options;
0288:            }
0289:
0290:            /**
0291:             * Requests that the compiler should provide binding information for
0292:             * the AST nodes it creates.
0293:             * <p>
0294:             * Default to <code>false</code> (no bindings).
0295:             * </p>
0296:             * <p>
0297:             * If <code>setResolveBindings(true)</code>, the various names
0298:             * and types appearing in the AST can be resolved to "bindings"
0299:             * by calling the <code>resolveBinding</code> methods. These bindings
0300:             * draw connections between the different parts of a program, and
0301:             * generally afford a more powerful vantage point for clients who wish to
0302:             * analyze a program's structure more deeply. These bindings come at a
0303:             * considerable cost in both time and space, however, and should not be
0304:             * requested frivolously. The additional space is not reclaimed until the
0305:             * AST, all its nodes, and all its bindings become garbage. So it is very
0306:             * important to not retain any of these objects longer than absolutely
0307:             * necessary. Bindings are resolved at the time the AST is created. Subsequent
0308:             * modifications to the AST do not affect the bindings returned by
0309:             * <code>resolveBinding</code> methods in any way; these methods return the
0310:             * same binding as before the AST was modified (including modifications
0311:             * that rearrange subtrees by reparenting nodes).
0312:             * If <code>setResolveBindings(false)</code> (the default), the analysis
0313:             * does not go beyond parsing and building the tree, and all
0314:             * <code>resolveBinding</code> methods return <code>null</code> from the
0315:             * outset.
0316:             * </p>
0317:             * <p>
0318:             * When bindings are requested, instead of considering compilation units on disk only
0319:             * one can supply a <code>WorkingCopyOwner</code>. Working copies owned
0320:             * by this owner take precedence over the underlying compilation units when looking
0321:             * up names and drawing the connections.
0322:             * </p>
0323:             * <p>
0324:             * Binding information is obtained from the Java model.
0325:             * This means that the compilation unit must be located relative to the
0326:             * Java model. This happens automatically when the source code comes from
0327:             * either {@link #setSource(ICompilationUnit) setSource(ICompilationUnit)}
0328:             * or {@link #setSource(IClassFile) setSource(IClassFile)}.
0329:             * When source is supplied by {@link #setSource(char[]) setSource(char[])},
0330:             * the location must be extablished explicitly by calling
0331:             * {@link #setProject(IJavaProject)} and  {@link #setUnitName(String)}.
0332:             * Note that the compiler options that affect doc comment checking may also
0333:             * affect whether any bindings are resolved for nodes within doc comments.
0334:             * </p>
0335:             *
0336:             * @param bindings <code>true</code> if bindings are wanted,
0337:             *   and <code>false</code> if bindings are not of interest
0338:             */
0339:            public void setResolveBindings(boolean bindings) {
0340:                this .resolveBindings = bindings;
0341:            }
0342:
0343:            /**
0344:             * Requests an abridged abstract syntax tree.
0345:             * By default, complete ASTs are returned.
0346:             * <p>
0347:             * When <code>true</code> the resulting AST does not have nodes for
0348:             * the entire compilation unit. Rather, the AST is only fleshed out
0349:             * for the node that include the given source position. This kind of limited
0350:             * AST is sufficient for certain purposes but totally unsuitable for others.
0351:             * In places where it can be used, the limited AST offers the advantage of
0352:             * being smaller and faster to construct.
0353:             * </p>
0354:             * <p>
0355:             * The AST will include nodes for all of the compilation unit's
0356:             * package, import, and top-level type declarations. It will also always contain
0357:             * nodes for all the body declarations for those top-level types, as well
0358:             * as body declarations for any member types. However, some of the body
0359:             * declarations may be abridged. In particular, the statements ordinarily
0360:             * found in the body of a method declaration node will not be included
0361:             * (the block will be empty) unless the source position falls somewhere
0362:             * within the source range of that method declaration node. The same is true
0363:             * for initializer declarations; the statements ordinarily found in the body
0364:             * of initializer node will not be included unless the source position falls
0365:             * somewhere within the source range of that initializer declaration node.
0366:             * Field declarations are never abridged. Note that the AST for the body of
0367:             * that one unabridged method (or initializer) is 100% complete; it has all
0368:             * its statements, including any local or anonymous type declarations
0369:             * embedded within them. When the the given position is not located within
0370:             * the source range of any body declaration of a top-level type, the AST
0371:             * returned will be a skeleton that includes nodes for all and only the major
0372:             * declarations; this kind of AST is still quite useful because it contains
0373:             * all the constructs that introduce names visible to the world outside the
0374:             * compilation unit.
0375:             * </p>
0376:             *
0377:             * @param position a position into the corresponding body declaration
0378:             */
0379:            public void setFocalPosition(int position) {
0380:                this .partial = true;
0381:                this .focalPointPosition = position;
0382:            }
0383:
0384:            /**
0385:             * Sets the kind of constructs to be parsed from the source.
0386:             * Defaults to an entire compilation unit.
0387:             * <p>
0388:             * When the parse is successful the result returned includes the ASTs for the
0389:             * requested source:
0390:             * <ul>
0391:             * <li>{@link #K_COMPILATION_UNIT K_COMPILATION_UNIT}: The result node
0392:             * is a {@link CompilationUnit}.</li>
0393:             * <li>{@link #K_CLASS_BODY_DECLARATIONS K_CLASS_BODY_DECLARATIONS}: The result node
0394:             * is a {@link TypeDeclaration} whose
0395:             * {@link TypeDeclaration#bodyDeclarations() bodyDeclarations}
0396:             * are the new trees. Other aspects of the type declaration are unspecified.</li>
0397:             * <li>{@link #K_STATEMENTS K_STATEMENTS}: The result node is a
0398:             * {@link Block Block} whose {@link Block#statements() statements}
0399:             * are the new trees. Other aspects of the block are unspecified.</li>
0400:             * <li>{@link #K_EXPRESSION K_EXPRESSION}: The result node is a subclass of
0401:             * {@link Expression Expression}. Other aspects of the expression are unspecified.</li>
0402:             * </ul>
0403:             * The resulting AST node is rooted under (possibly contrived)
0404:             * {@link CompilationUnit CompilationUnit} node, to allow the
0405:             * client to retrieve the following pieces of information
0406:             * available there:
0407:             * <ul>
0408:             * <li>{@linkplain CompilationUnit#getLineNumber(int) Line number map}. Line
0409:             * numbers start at 1 and only cover the subrange scanned
0410:             * (<code>source[offset]</code> through <code>source[offset+length-1]</code>).</li>
0411:             * <li>{@linkplain CompilationUnit#getMessages() Compiler messages}
0412:             * and {@linkplain CompilationUnit#getProblems() detailed problem reports}.
0413:             * Character positions are relative to the start of
0414:             * <code>source</code>; line positions are for the subrange scanned.</li>
0415:             * <li>{@linkplain CompilationUnit#getCommentList() Comment list}
0416:             * for the subrange scanned.</li>
0417:             * </ul>
0418:             * The contrived nodes do not have source positions. Other aspects of the
0419:             * {@link CompilationUnit CompilationUnit} node are unspecified, including
0420:             * the exact arrangment of intervening nodes.
0421:             * </p>
0422:             * <p>
0423:             * Lexical or syntax errors detected while parsing can result in
0424:             * a result node being marked as {@link ASTNode#MALFORMED MALFORMED}.
0425:             * In more severe failure cases where the parser is unable to
0426:             * recognize the input, this method returns
0427:             * a {@link CompilationUnit CompilationUnit} node with at least the
0428:             * compiler messages.
0429:             * </p>
0430:             * <p>Each node in the subtree (other than the contrived nodes)
0431:             * carries source range(s) information relating back
0432:             * to positions in the given source (the given source itself
0433:             * is not remembered with the AST).
0434:             * The source range usually begins at the first character of the first token
0435:             * corresponding to the node; leading whitespace and comments are <b>not</b>
0436:             * included. The source range usually extends through the last character of
0437:             * the last token corresponding to the node; trailing whitespace and
0438:             * comments are <b>not</b> included. There are a handful of exceptions
0439:             * (including the various body declarations); the
0440:             * specification for these node type spells out the details.
0441:             * Source ranges nest properly: the source range for a child is always
0442:             * within the source range of its parent, and the source ranges of sibling
0443:             * nodes never overlap.
0444:             * </p>
0445:             * <p>
0446:             * Binding information is only computed when <code>kind</code> is
0447:             * <code>K_COMPILATION_UNIT</code>.
0448:             * </p>
0449:             *
0450:             * @param kind the kind of construct to parse: one of
0451:             * {@link #K_COMPILATION_UNIT},
0452:             * {@link #K_CLASS_BODY_DECLARATIONS},
0453:             * {@link #K_EXPRESSION},
0454:             * {@link #K_STATEMENTS}
0455:             */
0456:            public void setKind(int kind) {
0457:                if ((kind != K_COMPILATION_UNIT)
0458:                        && (kind != K_CLASS_BODY_DECLARATIONS)
0459:                        && (kind != K_EXPRESSION) && (kind != K_STATEMENTS)) {
0460:                    throw new IllegalArgumentException();
0461:                }
0462:                this .astKind = kind;
0463:            }
0464:
0465:            /**
0466:             * Sets the source code to be parsed.
0467:             *
0468:             * @param source the source string to be parsed,
0469:             * or <code>null</code> if none
0470:             */
0471:            public void setSource(char[] source) {
0472:                this .rawSource = source;
0473:                // clear the type root
0474:                this .typeRoot = null;
0475:            }
0476:
0477:            /**
0478:             * Sets the source code to be parsed.
0479:             * This method automatically sets the project (and compiler
0480:             * options) based on the given compilation unit, in a manner
0481:             * equivalent to <code>setProject(source.getJavaProject())</code>
0482:             *
0483:             * @param source the Java model compilation unit whose source code
0484:             * is to be parsed, or <code>null</code> if none
0485:             */
0486:            public void setSource(ICompilationUnit source) {
0487:                setSource((ITypeRoot) source);
0488:            }
0489:
0490:            /**
0491:             * Sets the source code to be parsed.
0492:             * <p>This method automatically sets the project (and compiler
0493:             * options) based on the given compilation unit, in a manner
0494:             * equivalent to <code>setProject(source.getJavaProject())</code>.</p>
0495:             * <p>If the given class file has  no source attachment, the creation of the
0496:             * ast will fail with an IllegalStateException.</p>
0497:             *
0498:             * @param source the Java model class file whose corresponding source code
0499:             * is to be parsed, or <code>null</code> if none
0500:             */
0501:            public void setSource(IClassFile source) {
0502:                setSource((ITypeRoot) source);
0503:            }
0504:
0505:            /**
0506:             * Sets the source code to be parsed.
0507:             * <p>This method automatically sets the project (and compiler
0508:             * options) based on the given compilation unit of class file, in a manner
0509:             * equivalent to <code>setProject(source.getJavaProject())</code>.</p>
0510:             * <p>If the source is a class file without source attachment, the creation of the
0511:             * ast will fail with an IllegalStateException.</p>
0512:             *
0513:             * @param source the Java model compilation unit or class file whose corresponding source code
0514:             * is to be parsed, or <code>null</code> if none
0515:             * @since 3.3
0516:             */
0517:            public void setSource(ITypeRoot source) {
0518:                this .typeRoot = source;
0519:                // clear the raw source
0520:                this .rawSource = null;
0521:                if (source != null) {
0522:                    this .project = source.getJavaProject();
0523:                    Map options = this .project.getOptions(true);
0524:                    options.remove(JavaCore.COMPILER_TASK_TAGS); // no need to parse task tags
0525:                    this .compilerOptions = options;
0526:                }
0527:            }
0528:
0529:            /**
0530:             * Sets the subrange of the source code to be parsed.
0531:             * By default, the entire source string will be parsed
0532:             * (<code>offset</code> 0 and <code>length</code> -1).
0533:             *
0534:             * @param offset the index of the first character to parse
0535:             * @param length the number of characters to parse, or -1 if
0536:             * the remainder of the source string is
0537:             */
0538:            public void setSourceRange(int offset, int length) {
0539:                if (offset < 0 || length < -1) {
0540:                    throw new IllegalArgumentException();
0541:                }
0542:                this .sourceOffset = offset;
0543:                this .sourceLength = length;
0544:            }
0545:
0546:            /**
0547:             * Requests that the compiler should perform statements recovery.
0548:             * When statements recovery is enabled the compiler tries to create statement nodes
0549:             * from code containing syntax errors
0550:             * <p>
0551:             * Default to <code>false</code>.
0552:             * </p>
0553:             *
0554:             * @param enabled <code>true</code> if statements containing syntax errors are wanted,
0555:             *   and <code>false</code> if these statements aren't wanted.
0556:             *
0557:             * @since 3.2
0558:             */
0559:            public void setStatementsRecovery(boolean enabled) {
0560:                this .statementsRecovery = enabled;
0561:            }
0562:
0563:            /**
0564:             * Sets the working copy owner using when resolving bindings, where
0565:             * <code>null</code> means the primary owner. Defaults to the primary owner.
0566:             *
0567:             * @param owner the owner of working copies that take precedence over underlying
0568:             *   compilation units, or <code>null</code> if the primary owner should be used
0569:             */
0570:            public void setWorkingCopyOwner(WorkingCopyOwner owner) {
0571:                if (owner == null) {
0572:                    this .workingCopyOwner = DefaultWorkingCopyOwner.PRIMARY;
0573:                } else {
0574:                    this .workingCopyOwner = owner;
0575:                }
0576:            }
0577:
0578:            /**
0579:             * Sets the name of the compilation unit that would hypothetically contains
0580:             * the source string. This is used in conjunction with {@link #setSource(char[])}
0581:             * and {@link #setProject(IJavaProject) } to locate the compilation unit relative to a Java project.
0582:             * Defaults to none (<code>null</code>).
0583:             * <p>
0584:             * The name of the compilation unit must be supplied for resolving bindings.
0585:             * This name should be suffixed by a dot ('.') followed by one of the
0586:             * {@link JavaCore#getJavaLikeExtensions() Java-like extensions}
0587:             * and match the name of the main (public) class or interface declared in the source.</p>
0588:             *
0589:             * <p>This name must represent the full path of the unit inside the given project. For example, if the source
0590:             * declares a public class named "Foo" in a project "P", the name of the compilation unit must be
0591:             * "/P/Foo.java". If the source declares a public class name "Bar" in a package "p1.p2" in a project "P",
0592:             * the name of the compilation unit must be "/P/p1/p2/Bar.java".</p>
0593:             *
0594:             * @param unitName the name of the compilation unit that would contain the source
0595:             *    string, or <code>null</code> if none
0596:             */
0597:            public void setUnitName(String unitName) {
0598:                this .unitName = unitName;
0599:            }
0600:
0601:            /**
0602:             * Sets the Java project used when resolving bindings.
0603:             * This method automatically sets the compiler
0604:             * options based on the given project:
0605:             * <pre>
0606:             * setCompilerOptions(project.getOptions(true));
0607:             * </pre>
0608:             * See {@link #setCompilerOptions(Map)} for a discussion of
0609:             * the pros and cons of using these options vs specifying
0610:             * compiler options explicitly.
0611:             * This setting is used in conjunction with <code>setSource(char[])</code>.
0612:             * For the purposes of resolving bindings, types declared in the
0613:             * source string will hide types by the same name available
0614:             * through the classpath of the given project.
0615:             * Defaults to none (<code>null</code>).
0616:             *
0617:             * @param project the Java project used to resolve names, or
0618:             *    <code>null</code> if none
0619:             */
0620:            public void setProject(IJavaProject project) {
0621:                this .project = project;
0622:                if (project != null) {
0623:                    Map options = project.getOptions(true);
0624:                    options.remove(JavaCore.COMPILER_TASK_TAGS); // no need to parse task tags
0625:                    this .compilerOptions = options;
0626:                }
0627:            }
0628:
0629:            /**
0630:             * Creates an abstract syntax tree.
0631:             * <p>
0632:             * A successful call to this method returns all settings to their
0633:             * default values so the object is ready to be reused.
0634:             * </p>
0635:             *
0636:             * @param monitor the progress monitor used to report progress and request cancelation,
0637:             *   or <code>null</code> if none
0638:             * @return an AST node whose type depends on the kind of parse
0639:             *  requested, with a fallback to a <code>CompilationUnit</code>
0640:             *  in the case of severe parsing errors
0641:             * @exception IllegalStateException if the settings provided
0642:             * are insufficient, contradictory, or otherwise unsupported
0643:             */
0644:            public ASTNode createAST(IProgressMonitor monitor) {
0645:                ASTNode result = null;
0646:                if (monitor != null)
0647:                    monitor.beginTask("", 1); //$NON-NLS-1$
0648:                try {
0649:                    if (this .rawSource == null && this .typeRoot == null) {
0650:                        throw new IllegalStateException("source not specified"); //$NON-NLS-1$
0651:                    }
0652:                    result = internalCreateAST(monitor);
0653:                } finally {
0654:                    // re-init defaults to allow reuse (and avoid leaking)
0655:                    initializeDefaults();
0656:                    if (monitor != null)
0657:                        monitor.done();
0658:                }
0659:                return result;
0660:            }
0661:
0662:            /**
0663:             * Creates ASTs for a batch of compilation units.
0664:             * When bindings are being resolved, processing a
0665:             * batch of compilation units is more efficient because much
0666:             * of the work involved in resolving bindings can be shared.
0667:             * <p>
0668:             * When bindings are being resolved, all compilation units must
0669:             * come from the same Java project, which must be set beforehand
0670:             * with <code>setProject</code>.
0671:             * The compilation units are processed one at a time in no
0672:             * specified order. For each of the compilation units in turn,
0673:             * <ul>
0674:             * <li><code>ASTParser.createAST</code> is called to parse it
0675:             * and create a corresponding AST. The calls to
0676:             * <code>ASTParser.createAST</code> all employ the same settings.</li>
0677:             * <li><code>ASTRequestor.acceptAST</code> is called passing
0678:             * the compilation unit and the corresponding AST to
0679:             * <code>requestor</code>.
0680:             * </li>
0681:             * </ul>
0682:             * Note only ASTs from the given compilation units are reported
0683:             * to the requestor. If additional compilation units are required to
0684:             * resolve the original ones, the corresponding ASTs are <b>not</b>
0685:             * reported to the requestor.
0686:             * </p>
0687:             * <p>
0688:             * Note also the following parser parameters are used, regardless of what
0689:             * may have been specified:
0690:             * <ul>
0691:             * <li>The {@linkplain #setKind(int) parser kind} is <code>K_COMPILATION_UNIT</code></li>
0692:             * <li>The {@linkplain #setSourceRange(int,int) source range} is <code>(0, -1)</code></li>
0693:             * <li>The {@linkplain #setFocalPosition(int) focal position} is not set</li>
0694:             * </ul>
0695:             * </p>
0696:             * <p>
0697:             * The <code>bindingKeys</code> parameter specifies bindings keys
0698:             * ({@link IBinding#getKey()}) that are to be looked up. These keys may
0699:             * be for elements either inside or outside the set of compilation
0700:             * units being processed. When bindings are being resolved,
0701:             * the keys and corresponding bindings (or <code>null</code> if none) are
0702:             * passed to <code>ASTRequestor.acceptBinding</code>. Note that binding keys
0703:             * for elements outside the set of compilation units being processed are looked up
0704:             * after all <code>ASTRequestor.acceptAST</code> callbacks have been made.
0705:             * Binding keys for elements inside the set of compilation units being processed
0706:             * are looked up and reported right after the corresponding
0707:             * <code>ASTRequestor.acceptAST</code> callback has been made.
0708:             * No <code>ASTRequestor.acceptBinding</code> callbacks are made unless
0709:             * bindings are being resolved.
0710:             * </p>
0711:             * <p>
0712:             * A successful call to this method returns all settings to their
0713:             * default values so the object is ready to be reused.
0714:             * </p>
0715:             *
0716:             * @param compilationUnits the compilation units to create ASTs for
0717:             * @param bindingKeys the binding keys to create bindings for
0718:             * @param requestor the AST requestor that collects abtract syntax trees and bindings
0719:             * @param monitor the progress monitor used to report progress and request cancelation,
0720:             *   or <code>null</code> if none
0721:             * @exception IllegalStateException if the settings provided
0722:             * are insufficient, contradictory, or otherwise unsupported
0723:             * @since 3.1
0724:             */
0725:            public void createASTs(ICompilationUnit[] compilationUnits,
0726:                    String[] bindingKeys, ASTRequestor requestor,
0727:                    IProgressMonitor monitor) {
0728:                try {
0729:                    int flags = 0;
0730:                    if (this .statementsRecovery)
0731:                        flags |= ICompilationUnit.ENABLE_STATEMENTS_RECOVERY;
0732:                    if (this .resolveBindings) {
0733:                        if (this .project == null)
0734:                            throw new IllegalStateException(
0735:                                    "project not specified"); //$NON-NLS-1$
0736:                        if (this .bindingsRecovery)
0737:                            flags |= ICompilationUnit.ENABLE_BINDINGS_RECOVERY;
0738:                        CompilationUnitResolver.resolve(compilationUnits,
0739:                                bindingKeys, requestor, this .apiLevel,
0740:                                this .compilerOptions, this .project,
0741:                                this .workingCopyOwner, flags, monitor);
0742:                    } else {
0743:                        CompilationUnitResolver.parse(compilationUnits,
0744:                                requestor, this .apiLevel, this .compilerOptions,
0745:                                flags, monitor);
0746:                    }
0747:                } finally {
0748:                    // re-init defaults to allow reuse (and avoid leaking)
0749:                    initializeDefaults();
0750:                }
0751:            }
0752:
0753:            /**
0754:             * Creates bindings for a batch of Java elements. These elements are either
0755:             * enclosed in {@link ICompilationUnit}s or in {@link IClassFile}s.
0756:             * <p>
0757:             * All enclosing compilation units and class files must
0758:             * come from the same Java project, which must be set beforehand
0759:             * with <code>setProject</code>.
0760:             * </p>
0761:             * <p>
0762:             * All elements must exist. If one doesn't exist, an <code>IllegalStateException</code>
0763:             * is thrown.
0764:             * </p>
0765:             * <p>
0766:             * The returned array has the same size as the given elements array. At a given position
0767:             * it contains the binding of the corresponding Java element, or <code>null</code>
0768:             * if no binding could be created.
0769:             * </p>
0770:             * <p>
0771:             * Note also the following parser parameters are used, regardless of what
0772:             * may have been specified:
0773:             * <ul>
0774:             * <li>The {@linkplain #setResolveBindings(boolean) binding resolution flag} is <code>true</code></li>
0775:             * <li>The {@linkplain #setKind(int) parser kind} is <code>K_COMPILATION_UNIT</code></li>
0776:             * <li>The {@linkplain #setSourceRange(int,int) source range} is <code>(0, -1)</code></li>
0777:             * <li>The {@linkplain #setFocalPosition(int) focal position} is not set</li>
0778:             * </ul>
0779:             * </p>
0780:             * <p>
0781:             * A successful call to this method returns all settings to their
0782:             * default values so the object is ready to be reused.
0783:             * </p>
0784:             *
0785:             * @param elements the Java elements to create bindings for
0786:             * @return the bindings for the given Java elements, possibly containing <code>null</code>s
0787:             *              if some bindings could not be created
0788:             * @exception IllegalStateException if the settings provided
0789:             * are insufficient, contradictory, or otherwise unsupported
0790:             * @since 3.1
0791:             */
0792:            public IBinding[] createBindings(IJavaElement[] elements,
0793:                    IProgressMonitor monitor) {
0794:                try {
0795:                    if (this .project == null)
0796:                        throw new IllegalStateException("project not specified"); //$NON-NLS-1$
0797:                    int flags = 0;
0798:                    if (this .statementsRecovery)
0799:                        flags |= ICompilationUnit.ENABLE_STATEMENTS_RECOVERY;
0800:                    if (this .bindingsRecovery)
0801:                        flags |= ICompilationUnit.ENABLE_BINDINGS_RECOVERY;
0802:                    return CompilationUnitResolver.resolve(elements,
0803:                            this .apiLevel, this .compilerOptions, this .project,
0804:                            this .workingCopyOwner, flags, monitor);
0805:                } finally {
0806:                    // re-init defaults to allow reuse (and avoid leaking)
0807:                    initializeDefaults();
0808:                }
0809:            }
0810:
0811:            private ASTNode internalCreateAST(IProgressMonitor monitor) {
0812:                boolean needToResolveBindings = this .resolveBindings;
0813:                switch (this .astKind) {
0814:                case K_CLASS_BODY_DECLARATIONS:
0815:                case K_EXPRESSION:
0816:                case K_STATEMENTS:
0817:                    if (this .rawSource != null) {
0818:                        if (this .sourceOffset + this .sourceLength > this .rawSource.length) {
0819:                            throw new IllegalStateException();
0820:                        }
0821:                        return internalCreateASTForKind();
0822:                    }
0823:                    break;
0824:                case K_COMPILATION_UNIT:
0825:                    CompilationUnitDeclaration compilationUnitDeclaration = null;
0826:                    try {
0827:                        NodeSearcher searcher = null;
0828:                        org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = null;
0829:                        WorkingCopyOwner wcOwner = this .workingCopyOwner;
0830:                        if (this .typeRoot instanceof  ICompilationUnit) {
0831:                            /*
0832:                             * this.compilationUnitSource is an instance of org.eclipse.jdt.internal.core.CompilationUnit that implements
0833:                             * both org.eclipse.jdt.core.ICompilationUnit and org.eclipse.jdt.internal.compiler.env.ICompilationUnit
0834:                             */
0835:                            sourceUnit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) this .typeRoot;
0836:                            /*
0837:                             * use a BasicCompilation that caches the source instead of using the compilationUnitSource directly
0838:                             * (if it is a working copy, the source can change between the parse and the AST convertion)
0839:                             * (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=75632)
0840:                             */
0841:                            sourceUnit = new BasicCompilationUnit(sourceUnit
0842:                                    .getContents(),
0843:                                    sourceUnit.getPackageName(), new String(
0844:                                            sourceUnit.getFileName()),
0845:                                    this .project);
0846:                            wcOwner = ((ICompilationUnit) this .typeRoot)
0847:                                    .getOwner();
0848:                        } else if (this .typeRoot instanceof  IClassFile) {
0849:                            try {
0850:                                String sourceString = this .typeRoot.getSource();
0851:                                if (sourceString == null) {
0852:                                    throw new IllegalStateException();
0853:                                }
0854:                                PackageFragment packageFragment = (PackageFragment) this .typeRoot
0855:                                        .getParent();
0856:                                BinaryType type = (BinaryType) this .typeRoot
0857:                                        .findPrimaryType();
0858:                                IBinaryType binaryType = (IBinaryType) type
0859:                                        .getElementInfo();
0860:                                // file name is used to recreate the Java element, so it has to be the toplevel .class file name
0861:                                char[] fileName = binaryType.getFileName();
0862:                                int firstDollar = CharOperation.indexOf('$',
0863:                                        fileName);
0864:                                if (firstDollar != -1) {
0865:                                    char[] suffix = SuffixConstants.SUFFIX_class;
0866:                                    int suffixLength = suffix.length;
0867:                                    char[] newFileName = new char[firstDollar
0868:                                            + suffixLength];
0869:                                    System.arraycopy(fileName, 0, newFileName,
0870:                                            0, firstDollar);
0871:                                    System.arraycopy(suffix, 0, newFileName,
0872:                                            firstDollar, suffixLength);
0873:                                    fileName = newFileName;
0874:                                }
0875:                                sourceUnit = new BasicCompilationUnit(
0876:                                        sourceString.toCharArray(),
0877:                                        Util
0878:                                                .toCharArrays(packageFragment.names),
0879:                                        new String(fileName), this .project);
0880:                            } catch (JavaModelException e) {
0881:                                // an error occured accessing the java element
0882:                                throw new IllegalStateException();
0883:                            }
0884:                        } else if (this .rawSource != null) {
0885:                            needToResolveBindings = this .resolveBindings
0886:                                    && this .unitName != null
0887:                                    && this .project != null
0888:                                    && this .compilerOptions != null;
0889:                            sourceUnit = new BasicCompilationUnit(
0890:                                    this .rawSource,
0891:                                    null,
0892:                                    this .unitName == null ? "" : this .unitName, this .project); //$NON-NLS-1$
0893:                        } else {
0894:                            throw new IllegalStateException();
0895:                        }
0896:                        if (this .partial) {
0897:                            searcher = new NodeSearcher(this .focalPointPosition);
0898:                        }
0899:                        int flags = 0;
0900:                        if (this .statementsRecovery)
0901:                            flags |= ICompilationUnit.ENABLE_STATEMENTS_RECOVERY;
0902:                        if (needToResolveBindings) {
0903:                            if (this .bindingsRecovery)
0904:                                flags |= ICompilationUnit.ENABLE_BINDINGS_RECOVERY;
0905:                            try {
0906:                                // parse and resolve
0907:                                compilationUnitDeclaration = CompilationUnitResolver
0908:                                        .resolve(sourceUnit, this .project,
0909:                                                searcher, this .compilerOptions,
0910:                                                this .workingCopyOwner, flags,
0911:                                                monitor);
0912:                            } catch (JavaModelException e) {
0913:                                flags &= ~ICompilationUnit.ENABLE_BINDINGS_RECOVERY;
0914:                                compilationUnitDeclaration = CompilationUnitResolver
0915:                                        .parse(sourceUnit, searcher,
0916:                                                this .compilerOptions, flags);
0917:                                needToResolveBindings = false;
0918:                            }
0919:                        } else {
0920:                            compilationUnitDeclaration = CompilationUnitResolver
0921:                                    .parse(sourceUnit, searcher,
0922:                                            this .compilerOptions, flags);
0923:                            needToResolveBindings = false;
0924:                        }
0925:                        CompilationUnit result = CompilationUnitResolver
0926:                                .convert(
0927:                                        compilationUnitDeclaration,
0928:                                        sourceUnit.getContents(),
0929:                                        this .apiLevel,
0930:                                        this .compilerOptions,
0931:                                        needToResolveBindings,
0932:                                        wcOwner,
0933:                                        needToResolveBindings ? new DefaultBindingResolver.BindingTables()
0934:                                                : null, flags, monitor);
0935:                        result.setTypeRoot(this .typeRoot);
0936:                        return result;
0937:                    } finally {
0938:                        if (compilationUnitDeclaration != null
0939:                                && this .resolveBindings) {
0940:                            compilationUnitDeclaration.cleanUp();
0941:                        }
0942:                    }
0943:                }
0944:                throw new IllegalStateException();
0945:            }
0946:
0947:            /**
0948:             * Parses the given source between the bounds specified by the given offset (inclusive)
0949:             * and the given length and creates and returns a corresponding abstract syntax tree.
0950:             * <p>
0951:             * When the parse is successful the result returned includes the ASTs for the
0952:             * requested source:
0953:             * <ul>
0954:             * <li>{@link #K_CLASS_BODY_DECLARATIONS K_CLASS_BODY_DECLARATIONS}: The result node
0955:             * is a {@link TypeDeclaration TypeDeclaration} whose
0956:             * {@link TypeDeclaration#bodyDeclarations() bodyDeclarations}
0957:             * are the new trees. Other aspects of the type declaration are unspecified.</li>
0958:             * <li>{@link #K_STATEMENTS K_STATEMENTS}: The result node is a
0959:             * {@link Block Block} whose {@link Block#statements() statements}
0960:             * are the new trees. Other aspects of the block are unspecified.</li>
0961:             * <li>{@link #K_EXPRESSION K_EXPRESSION}: The result node is a subclass of
0962:             * {@link Expression Expression}. Other aspects of the expression are unspecified.</li>
0963:             * </ul>
0964:             * The resulting AST node is rooted under an contrived
0965:             * {@link CompilationUnit CompilationUnit} node, to allow the
0966:             * client to retrieve the following pieces of information
0967:             * available there:
0968:             * <ul>
0969:             * <li>{@linkplain CompilationUnit#getLineNumber(int) Line number map}. Line
0970:             * numbers start at 1 and only cover the subrange scanned
0971:             * (<code>source[offset]</code> through <code>source[offset+length-1]</code>).</li>
0972:             * <li>{@linkplain CompilationUnit#getMessages() Compiler messages}
0973:             * and {@linkplain CompilationUnit#getProblems() detailed problem reports}.
0974:             * Character positions are relative to the start of
0975:             * <code>source</code>; line positions are for the subrange scanned.</li>
0976:             * <li>{@linkplain CompilationUnit#getCommentList() Comment list}
0977:             * for the subrange scanned.</li>
0978:             * </ul>
0979:             * The contrived nodes do not have source positions. Other aspects of the
0980:             * {@link CompilationUnit CompilationUnit} node are unspecified, including
0981:             * the exact arrangment of intervening nodes.
0982:             * </p>
0983:             * <p>
0984:             * Lexical or syntax errors detected while parsing can result in
0985:             * a result node being marked as {@link ASTNode#MALFORMED MALFORMED}.
0986:             * In more severe failure cases where the parser is unable to
0987:             * recognize the input, this method returns
0988:             * a {@link CompilationUnit CompilationUnit} node with at least the
0989:             * compiler messages.
0990:             * </p>
0991:             * <p>Each node in the subtree (other than the contrived nodes)
0992:             * carries source range(s) information relating back
0993:             * to positions in the given source (the given source itself
0994:             * is not remembered with the AST).
0995:             * The source range usually begins at the first character of the first token
0996:             * corresponding to the node; leading whitespace and comments are <b>not</b>
0997:             * included. The source range usually extends through the last character of
0998:             * the last token corresponding to the node; trailing whitespace and
0999:             * comments are <b>not</b> included. There are a handful of exceptions
1000:             * (including the various body declarations); the
1001:             * specification for these node type spells out the details.
1002:             * Source ranges nest properly: the source range for a child is always
1003:             * within the source range of its parent, and the source ranges of sibling
1004:             * nodes never overlap.
1005:             * </p>
1006:             * <p>
1007:             * This method does not compute binding information; all <code>resolveBinding</code>
1008:             * methods applied to nodes of the resulting AST return <code>null</code>.
1009:             * </p>
1010:             *
1011:             * @return an AST node whose type depends on the kind of parse
1012:             *  requested, with a fallback to a <code>CompilationUnit</code>
1013:             *  in the case of severe parsing errors
1014:             * @see ASTNode#getStartPosition()
1015:             * @see ASTNode#getLength()
1016:             */
1017:            private ASTNode internalCreateASTForKind() {
1018:                final ASTConverter converter = new ASTConverter(
1019:                        this .compilerOptions, false, null);
1020:                converter.compilationUnitSource = this .rawSource;
1021:                converter.compilationUnitSourceLength = this .rawSource.length;
1022:                converter.scanner.setSource(this .rawSource);
1023:
1024:                AST ast = AST.newAST(this .apiLevel);
1025:                ast.setDefaultNodeFlag(ASTNode.ORIGINAL);
1026:                ast.setBindingResolver(new BindingResolver());
1027:                if (this .statementsRecovery) {
1028:                    ast.setFlag(ICompilationUnit.ENABLE_STATEMENTS_RECOVERY);
1029:                }
1030:                converter.setAST(ast);
1031:                CodeSnippetParsingUtil codeSnippetParsingUtil = new CodeSnippetParsingUtil();
1032:                CompilationUnit compilationUnit = ast.newCompilationUnit();
1033:                if (this .sourceLength == -1) {
1034:                    this .sourceLength = this .rawSource.length;
1035:                }
1036:                switch (this .astKind) {
1037:                case K_STATEMENTS:
1038:                    ConstructorDeclaration constructorDeclaration = codeSnippetParsingUtil
1039:                            .parseStatements(this .rawSource, this .sourceOffset,
1040:                                    this .sourceLength, this .compilerOptions,
1041:                                    true, this .statementsRecovery);
1042:                    RecoveryScannerData data = constructorDeclaration.compilationResult.recoveryScannerData;
1043:                    if (data != null) {
1044:                        Scanner scanner = converter.scanner;
1045:                        converter.scanner = new RecoveryScanner(scanner, data
1046:                                .removeUnused());
1047:                        converter.docParser.scanner = converter.scanner;
1048:                        converter.scanner.setSource(scanner.source);
1049:                    }
1050:                    RecordedParsingInformation recordedParsingInformation = codeSnippetParsingUtil.recordedParsingInformation;
1051:                    int[][] comments = recordedParsingInformation.commentPositions;
1052:                    if (comments != null) {
1053:                        converter.buildCommentsTable(compilationUnit, comments);
1054:                    }
1055:                    compilationUnit
1056:                            .setLineEndTable(recordedParsingInformation.lineEnds);
1057:                    Block block = ast.newBlock();
1058:                    block.setSourceRange(this .sourceOffset, this .sourceOffset
1059:                            + this .sourceLength);
1060:                    org.eclipse.jdt.internal.compiler.ast.Statement[] statements = constructorDeclaration.statements;
1061:                    if (statements != null) {
1062:                        int statementsLength = statements.length;
1063:                        for (int i = 0; i < statementsLength; i++) {
1064:                            if (statements[i] instanceof  org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
1065:                                converter.checkAndAddMultipleLocalDeclaration(
1066:                                        statements, i, block.statements());
1067:                            } else {
1068:                                Statement statement = converter
1069:                                        .convert(statements[i]);
1070:                                if (statement != null) {
1071:                                    block.statements().add(statement);
1072:                                }
1073:                            }
1074:                        }
1075:                    }
1076:                    rootNodeToCompilationUnit(ast, compilationUnit, block,
1077:                            recordedParsingInformation, data);
1078:                    ast.setDefaultNodeFlag(0);
1079:                    ast.setOriginalModificationCount(ast.modificationCount());
1080:                    return block;
1081:                case K_EXPRESSION:
1082:                    org.eclipse.jdt.internal.compiler.ast.Expression expression = codeSnippetParsingUtil
1083:                            .parseExpression(this .rawSource, this .sourceOffset,
1084:                                    this .sourceLength, this .compilerOptions,
1085:                                    true);
1086:                    recordedParsingInformation = codeSnippetParsingUtil.recordedParsingInformation;
1087:                    comments = recordedParsingInformation.commentPositions;
1088:                    if (comments != null) {
1089:                        converter.buildCommentsTable(compilationUnit, comments);
1090:                    }
1091:                    compilationUnit
1092:                            .setLineEndTable(recordedParsingInformation.lineEnds);
1093:                    if (expression != null) {
1094:                        Expression expression2 = converter.convert(expression);
1095:                        rootNodeToCompilationUnit(
1096:                                expression2.getAST(),
1097:                                compilationUnit,
1098:                                expression2,
1099:                                codeSnippetParsingUtil.recordedParsingInformation,
1100:                                null);
1101:                        ast.setDefaultNodeFlag(0);
1102:                        ast.setOriginalModificationCount(ast
1103:                                .modificationCount());
1104:                        return expression2;
1105:                    } else {
1106:                        CategorizedProblem[] problems = recordedParsingInformation.problems;
1107:                        if (problems != null) {
1108:                            compilationUnit.setProblems(problems);
1109:                        }
1110:                        ast.setDefaultNodeFlag(0);
1111:                        ast.setOriginalModificationCount(ast
1112:                                .modificationCount());
1113:                        return compilationUnit;
1114:                    }
1115:                case K_CLASS_BODY_DECLARATIONS:
1116:                    final org.eclipse.jdt.internal.compiler.ast.ASTNode[] nodes = codeSnippetParsingUtil
1117:                            .parseClassBodyDeclarations(this .rawSource,
1118:                                    this .sourceOffset, this .sourceLength,
1119:                                    this .compilerOptions, true);
1120:                    recordedParsingInformation = codeSnippetParsingUtil.recordedParsingInformation;
1121:                    comments = recordedParsingInformation.commentPositions;
1122:                    if (comments != null) {
1123:                        converter.buildCommentsTable(compilationUnit, comments);
1124:                    }
1125:                    compilationUnit
1126:                            .setLineEndTable(recordedParsingInformation.lineEnds);
1127:                    if (nodes != null) {
1128:                        TypeDeclaration typeDeclaration = converter
1129:                                .convert(nodes);
1130:                        typeDeclaration.setSourceRange(this .sourceOffset,
1131:                                this .sourceOffset + this .sourceLength);
1132:                        rootNodeToCompilationUnit(
1133:                                typeDeclaration.getAST(),
1134:                                compilationUnit,
1135:                                typeDeclaration,
1136:                                codeSnippetParsingUtil.recordedParsingInformation,
1137:                                null);
1138:                        ast.setDefaultNodeFlag(0);
1139:                        ast.setOriginalModificationCount(ast
1140:                                .modificationCount());
1141:                        return typeDeclaration;
1142:                    } else {
1143:                        CategorizedProblem[] problems = recordedParsingInformation.problems;
1144:                        if (problems != null) {
1145:                            compilationUnit.setProblems(problems);
1146:                        }
1147:                        ast.setDefaultNodeFlag(0);
1148:                        ast.setOriginalModificationCount(ast
1149:                                .modificationCount());
1150:                        return compilationUnit;
1151:                    }
1152:                }
1153:                throw new IllegalStateException();
1154:            }
1155:
1156:            private void propagateErrors(ASTNode astNode,
1157:                    CategorizedProblem[] problems, RecoveryScannerData data) {
1158:                astNode.accept(new ASTSyntaxErrorPropagator(problems));
1159:                if (data != null) {
1160:                    astNode.accept(new ASTRecoveryPropagator(problems, data));
1161:                }
1162:            }
1163:
1164:            private void rootNodeToCompilationUnit(AST ast,
1165:                    CompilationUnit compilationUnit, ASTNode node,
1166:                    RecordedParsingInformation recordedParsingInformation,
1167:                    RecoveryScannerData data) {
1168:                final int problemsCount = recordedParsingInformation.problemsCount;
1169:                switch (node.getNodeType()) {
1170:                case ASTNode.BLOCK: {
1171:                    Block block = (Block) node;
1172:                    if (problemsCount != 0) {
1173:                        // propagate and record problems
1174:                        final CategorizedProblem[] problems = recordedParsingInformation.problems;
1175:                        propagateErrors(block, problems, data);
1176:                        compilationUnit.setProblems(problems);
1177:                    }
1178:                    TypeDeclaration typeDeclaration = ast.newTypeDeclaration();
1179:                    Initializer initializer = ast.newInitializer();
1180:                    initializer.setBody(block);
1181:                    typeDeclaration.bodyDeclarations().add(initializer);
1182:                    compilationUnit.types().add(typeDeclaration);
1183:                }
1184:                    break;
1185:                case ASTNode.TYPE_DECLARATION: {
1186:                    TypeDeclaration typeDeclaration = (TypeDeclaration) node;
1187:                    if (problemsCount != 0) {
1188:                        // propagate and record problems
1189:                        final CategorizedProblem[] problems = recordedParsingInformation.problems;
1190:                        propagateErrors(typeDeclaration, problems, data);
1191:                        compilationUnit.setProblems(problems);
1192:                    }
1193:                    compilationUnit.types().add(typeDeclaration);
1194:                }
1195:                    break;
1196:                default:
1197:                    if (node instanceof  Expression) {
1198:                        Expression expression = (Expression) node;
1199:                        if (problemsCount != 0) {
1200:                            // propagate and record problems
1201:                            final CategorizedProblem[] problems = recordedParsingInformation.problems;
1202:                            propagateErrors(expression, problems, data);
1203:                            compilationUnit.setProblems(problems);
1204:                        }
1205:                        ExpressionStatement expressionStatement = ast
1206:                                .newExpressionStatement(expression);
1207:                        Block block = ast.newBlock();
1208:                        block.statements().add(expressionStatement);
1209:                        Initializer initializer = ast.newInitializer();
1210:                        initializer.setBody(block);
1211:                        TypeDeclaration typeDeclaration = ast
1212:                                .newTypeDeclaration();
1213:                        typeDeclaration.bodyDeclarations().add(initializer);
1214:                        compilationUnit.types().add(typeDeclaration);
1215:                    }
1216:                }
1217:            }
1218:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.