Source Code Cross Referenced for ASTNode.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) 2000, 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.AbstractList;
0013:        import java.util.ArrayList;
0014:        import java.util.Collections;
0015:        import java.util.HashMap;
0016:        import java.util.Iterator;
0017:        import java.util.List;
0018:        import java.util.Map;
0019:
0020:        /**
0021:         * Abstract superclass of all Abstract Syntax Tree (AST) node types.
0022:         * <p>
0023:         * An AST node represents a Java source code construct, such
0024:         * as a name, type, expression, statement, or declaration.
0025:         * </p>
0026:         * <p>
0027:         * Each AST node belongs to a unique AST instance, called the owning AST.
0028:         * The children of an AST node always have the same owner as their parent node.
0029:         * If a node from one AST is to be added to a different AST, the subtree must
0030:         * be cloned first to ensure that the added nodes have the correct owning AST.
0031:         * </p>
0032:         * <p>
0033:         * When an AST node is part of an AST, it has a unique parent node.
0034:         * Clients can navigate upwards, from child to parent, as well as downwards,
0035:         * from parent to child. Newly created nodes are unparented. When an 
0036:         * unparented node is set as a child of a node (using a 
0037:         * <code>set<i>CHILD</i></code> method), its parent link is set automatically
0038:         * and the parent link of the former child is set to <code>null</code>.
0039:         * For nodes with properties that include a list of children (for example,
0040:         * <code>Block</code> whose <code>statements</code> property is a list
0041:         * of statements), adding or removing an element to/for the list property
0042:         * automatically updates the parent links. These lists support the 
0043:         * <code>List.set</code> method; however, the constraint that the same
0044:         * node cannot appear more than once means that this method cannot be used
0045:         * to swap elements without first removing the node.
0046:         * </p>
0047:         * <p>
0048:         * ASTs must not contain cycles. All operations that could create a cycle
0049:         * detect this possibility and fail.
0050:         * </p>
0051:         * <p>
0052:         * ASTs do not contain "holes" (missing subtrees). If a node is required to
0053:         * have a certain property, a syntactically plausible initial value is
0054:         * always supplied. 
0055:         * </p>
0056:         * <p>
0057:         * The hierarchy of AST node types has some convenient groupings marked
0058:         * by abstract superclasses:
0059:         * <ul>
0060:         * <li>expressions - <code>Expression</code></li>
0061:         * <li>names - <code>Name</code> (a sub-kind of expression)</li>
0062:         * <li>statements - <code>Statement</code></li>
0063:         * <li>types - <code>Type</code></li>
0064:         * <li>type body declarations - <code>BodyDeclaration</code></li>
0065:         * </ul>
0066:         * </p>
0067:         * <p>
0068:         * Abstract syntax trees may be hand constructed by clients, using the
0069:         * <code>new<i>TYPE</i></code> factory methods (see <code>AST</code>) to
0070:         * create new nodes, and the various <code>set<i>CHILD</i></code> methods
0071:         * to connect them together.
0072:         * </p>
0073:         * <p>
0074:         * The class {@link ASTParser} parses a string
0075:         * containing a Java source code and returns an abstract syntax tree
0076:         * for it. The resulting nodes carry source ranges relating the node back to
0077:         * the original source characters. The source range covers the construct
0078:         * as a whole.
0079:         * </p>
0080:         * <p>
0081:         * Each AST node carries bit flags, which may convey additional information about
0082:         * the node. For instance, the parser uses a flag to indicate a syntax error.
0083:         * Newly created nodes have no flags set.
0084:         * </p>
0085:         * <p>
0086:         * Each AST node is capable of carrying an open-ended collection of
0087:         * client-defined properties. Newly created nodes have none. 
0088:         * <code>getProperty</code> and <code>setProperty</code> are used to access
0089:         * these properties.
0090:         * </p>
0091:         * <p>
0092:         * AST nodes are thread-safe for readers provided there are no active writers.
0093:         * If one thread is modifying an AST, including creating new nodes or cloning
0094:         * existing ones, it is <b>not</b> safe for another thread to read, visit,
0095:         * write, create, or clone <em>any</em> of the nodes on the same AST.
0096:         * When synchronization is required, consider using the common AST
0097:         * object that owns the node; that is, use  
0098:         * <code>synchronize (node.getAST()) {...}</code>.
0099:         * </p>
0100:         * <p>
0101:         * ASTs also support the visitor pattern; see the class <code>ASTVisitor</code>
0102:         * for details.
0103:         * </p>
0104:         * <p>
0105:         * Compilation units created by <code>ASTParser</code> from a
0106:         * source document can be serialized after arbitrary modifications
0107:         * with minimal loss of original formatting. See 
0108:         * {@link CompilationUnit#recordModifications()} for details.
0109:         * See also {@link org.eclipse.jdt.core.dom.rewrite.ASTRewrite} for
0110:         * an alternative way to describe and serialize changes to a
0111:         * read-only AST.
0112:         * </p>
0113:         * This class is not intended to be subclassed by clients.
0114:         * 
0115:         * @see ASTParser
0116:         * @see ASTVisitor
0117:         * @since 2.0
0118:         */
0119:        public abstract class ASTNode {
0120:            /*
0121:             * INSTRUCTIONS FOR ADDING NEW CONCRETE AST NODE TYPES
0122:             * 
0123:             * There are several things that need to be changed when a
0124:             * new concrete AST node type (call it "FooBar"):
0125:             * 
0126:             * 1. Create the FooBar AST node type class.
0127:             * The most effective way to do this is to copy a similar
0128:             * existing concrete node class to get a template that
0129:             * includes all the framework methods that must be implemented.
0130:             * 
0131:             * 2. Add node type constant ASTNode.FOO_BAR.
0132:             * Node constants are numbered consecutively. Add the
0133:             * constant after the existing ones.
0134:             * 
0135:             * 3. Add entry to ASTNode.nodeClassForType(int).
0136:             * 
0137:             * 4. Add AST.newFooBar() factory method.
0138:             * 
0139:             * 5. Add ASTVisitor.visit(FooBar) and endVisit(FooBar) methods.
0140:             * 
0141:             * 6. Add ASTMatcher.match(FooBar,Object) method.
0142:             * 
0143:             * 7. Ensure that SimpleName.isDeclaration() covers FooBar
0144:             * nodes if required.
0145:             * 
0146:             * 8. Add NaiveASTFlattener.visit(FooBar) method to illustrate
0147:             * how these nodes should be serialized.
0148:             * 
0149:             * 9. Update the AST test suites.
0150:             * 
0151:             * The next steps are to update AST.parse* to start generating
0152:             * the new type of nodes, and ASTRewrite to serialize them back out.
0153:             */
0154:
0155:            /**
0156:             * Node type constant indicating a node of type 
0157:             * <code>AnonymousClassDeclaration</code>.
0158:             * @see AnonymousClassDeclaration
0159:             */
0160:            public static final int ANONYMOUS_CLASS_DECLARATION = 1;
0161:
0162:            /**
0163:             * Node type constant indicating a node of type 
0164:             * <code>ArrayAccess</code>.
0165:             * @see ArrayAccess
0166:             */
0167:            public static final int ARRAY_ACCESS = 2;
0168:
0169:            /**
0170:             * Node type constant indicating a node of type 
0171:             * <code>ArrayCreation</code>.
0172:             * @see ArrayCreation
0173:             */
0174:            public static final int ARRAY_CREATION = 3;
0175:
0176:            /**
0177:             * Node type constant indicating a node of type 
0178:             * <code>ArrayInitializer</code>.
0179:             * @see ArrayInitializer
0180:             */
0181:            public static final int ARRAY_INITIALIZER = 4;
0182:
0183:            /**
0184:             * Node type constant indicating a node of type 
0185:             * <code>ArrayType</code>.
0186:             * @see ArrayType
0187:             */
0188:            public static final int ARRAY_TYPE = 5;
0189:
0190:            /**
0191:             * Node type constant indicating a node of type 
0192:             * <code>AssertStatement</code>.
0193:             * @see AssertStatement
0194:             */
0195:            public static final int ASSERT_STATEMENT = 6;
0196:
0197:            /**
0198:             * Node type constant indicating a node of type 
0199:             * <code>Assignment</code>.
0200:             * @see Assignment
0201:             */
0202:            public static final int ASSIGNMENT = 7;
0203:
0204:            /**
0205:             * Node type constant indicating a node of type 
0206:             * <code>Block</code>.
0207:             * @see Block
0208:             */
0209:            public static final int BLOCK = 8;
0210:
0211:            /**
0212:             * Node type constant indicating a node of type 
0213:             * <code>BooleanLiteral</code>.
0214:             * @see BooleanLiteral
0215:             */
0216:            public static final int BOOLEAN_LITERAL = 9;
0217:
0218:            /**
0219:             * Node type constant indicating a node of type 
0220:             * <code>BreakStatement</code>.
0221:             * @see BreakStatement
0222:             */
0223:            public static final int BREAK_STATEMENT = 10;
0224:
0225:            /**
0226:             * Node type constant indicating a node of type 
0227:             * <code>CastExpression</code>.
0228:             * @see CastExpression
0229:             */
0230:            public static final int CAST_EXPRESSION = 11;
0231:
0232:            /**
0233:             * Node type constant indicating a node of type 
0234:             * <code>CatchClause</code>.
0235:             * @see CatchClause
0236:             */
0237:            public static final int CATCH_CLAUSE = 12;
0238:
0239:            /**
0240:             * Node type constant indicating a node of type 
0241:             * <code>CharacterLiteral</code>.
0242:             * @see CharacterLiteral
0243:             */
0244:            public static final int CHARACTER_LITERAL = 13;
0245:
0246:            /**
0247:             * Node type constant indicating a node of type 
0248:             * <code>ClassInstanceCreation</code>.
0249:             * @see ClassInstanceCreation
0250:             */
0251:            public static final int CLASS_INSTANCE_CREATION = 14;
0252:
0253:            /**
0254:             * Node type constant indicating a node of type 
0255:             * <code>CompilationUnit</code>.
0256:             * @see CompilationUnit
0257:             */
0258:            public static final int COMPILATION_UNIT = 15;
0259:
0260:            /**
0261:             * Node type constant indicating a node of type 
0262:             * <code>ConditionalExpression</code>.
0263:             * @see ConditionalExpression
0264:             */
0265:            public static final int CONDITIONAL_EXPRESSION = 16;
0266:
0267:            /**
0268:             * Node type constant indicating a node of type 
0269:             * <code>ConstructorInvocation</code>.
0270:             * @see ConstructorInvocation
0271:             */
0272:            public static final int CONSTRUCTOR_INVOCATION = 17;
0273:
0274:            /**
0275:             * Node type constant indicating a node of type 
0276:             * <code>ContinueStatement</code>.
0277:             * @see ContinueStatement
0278:             */
0279:            public static final int CONTINUE_STATEMENT = 18;
0280:
0281:            /**
0282:             * Node type constant indicating a node of type 
0283:             * <code>DoStatement</code>.
0284:             * @see DoStatement
0285:             */
0286:            public static final int DO_STATEMENT = 19;
0287:
0288:            /**
0289:             * Node type constant indicating a node of type 
0290:             * <code>EmptyStatement</code>.
0291:             * @see EmptyStatement
0292:             */
0293:            public static final int EMPTY_STATEMENT = 20;
0294:
0295:            /**
0296:             * Node type constant indicating a node of type 
0297:             * <code>ExpressionStatement</code>.
0298:             * @see ExpressionStatement
0299:             */
0300:            public static final int EXPRESSION_STATEMENT = 21;
0301:
0302:            /**
0303:             * Node type constant indicating a node of type 
0304:             * <code>FieldAccess</code>.
0305:             * @see FieldAccess
0306:             */
0307:            public static final int FIELD_ACCESS = 22;
0308:
0309:            /**
0310:             * Node type constant indicating a node of type 
0311:             * <code>FieldDeclaration</code>.
0312:             * @see FieldDeclaration
0313:             */
0314:            public static final int FIELD_DECLARATION = 23;
0315:
0316:            /**
0317:             * Node type constant indicating a node of type 
0318:             * <code>ForStatement</code>.
0319:             * @see ForStatement
0320:             */
0321:            public static final int FOR_STATEMENT = 24;
0322:
0323:            /**
0324:             * Node type constant indicating a node of type 
0325:             * <code>IfStatement</code>.
0326:             * @see IfStatement
0327:             */
0328:            public static final int IF_STATEMENT = 25;
0329:
0330:            /**
0331:             * Node type constant indicating a node of type 
0332:             * <code>ImportDeclaration</code>.
0333:             * @see ImportDeclaration
0334:             */
0335:            public static final int IMPORT_DECLARATION = 26;
0336:
0337:            /**
0338:             * Node type constant indicating a node of type 
0339:             * <code>InfixExpression</code>.
0340:             * @see InfixExpression
0341:             */
0342:            public static final int INFIX_EXPRESSION = 27;
0343:
0344:            /**
0345:             * Node type constant indicating a node of type 
0346:             * <code>Initializer</code>.
0347:             * @see Initializer
0348:             */
0349:            public static final int INITIALIZER = 28;
0350:
0351:            /**
0352:             * Node type constant indicating a node of type 
0353:             * <code>Javadoc</code>.
0354:             * @see Javadoc
0355:             */
0356:            public static final int JAVADOC = 29;
0357:
0358:            /**
0359:             * Node type constant indicating a node of type 
0360:             * <code>LabeledStatement</code>.
0361:             * @see LabeledStatement
0362:             */
0363:            public static final int LABELED_STATEMENT = 30;
0364:
0365:            /**
0366:             * Node type constant indicating a node of type 
0367:             * <code>MethodDeclaration</code>.
0368:             * @see MethodDeclaration
0369:             */
0370:            public static final int METHOD_DECLARATION = 31;
0371:
0372:            /**
0373:             * Node type constant indicating a node of type 
0374:             * <code>MethodInvocation</code>.
0375:             * @see MethodInvocation
0376:             */
0377:            public static final int METHOD_INVOCATION = 32;
0378:
0379:            /**
0380:             * Node type constant indicating a node of type 
0381:             * <code>NullLiteral</code>.
0382:             * @see NullLiteral
0383:             */
0384:            public static final int NULL_LITERAL = 33;
0385:
0386:            /**
0387:             * Node type constant indicating a node of type 
0388:             * <code>NumberLiteral</code>.
0389:             * @see NumberLiteral
0390:             */
0391:            public static final int NUMBER_LITERAL = 34;
0392:
0393:            /**
0394:             * Node type constant indicating a node of type 
0395:             * <code>PackageDeclaration</code>.
0396:             * @see PackageDeclaration
0397:             */
0398:            public static final int PACKAGE_DECLARATION = 35;
0399:
0400:            /**
0401:             * Node type constant indicating a node of type 
0402:             * <code>ParenthesizedExpression</code>.
0403:             * @see ParenthesizedExpression
0404:             */
0405:            public static final int PARENTHESIZED_EXPRESSION = 36;
0406:
0407:            /**
0408:             * Node type constant indicating a node of type 
0409:             * <code>PostfixExpression</code>.
0410:             * @see PostfixExpression
0411:             */
0412:            public static final int POSTFIX_EXPRESSION = 37;
0413:
0414:            /**
0415:             * Node type constant indicating a node of type 
0416:             * <code>PrefixExpression</code>.
0417:             * @see PrefixExpression
0418:             */
0419:            public static final int PREFIX_EXPRESSION = 38;
0420:
0421:            /**
0422:             * Node type constant indicating a node of type 
0423:             * <code>PrimitiveType</code>.
0424:             * @see PrimitiveType
0425:             */
0426:            public static final int PRIMITIVE_TYPE = 39;
0427:
0428:            /**
0429:             * Node type constant indicating a node of type 
0430:             * <code>QualifiedName</code>.
0431:             * @see QualifiedName
0432:             */
0433:            public static final int QUALIFIED_NAME = 40;
0434:
0435:            /**
0436:             * Node type constant indicating a node of type 
0437:             * <code>ReturnStatement</code>.
0438:             * @see ReturnStatement
0439:             */
0440:            public static final int RETURN_STATEMENT = 41;
0441:
0442:            /**
0443:             * Node type constant indicating a node of type 
0444:             * <code>SimpleName</code>.
0445:             * @see SimpleName
0446:             */
0447:            public static final int SIMPLE_NAME = 42;
0448:
0449:            /**
0450:             * Node type constant indicating a node of type 
0451:             * <code>SimpleType</code>.
0452:             * @see SimpleType
0453:             */
0454:            public static final int SIMPLE_TYPE = 43;
0455:
0456:            /**
0457:             * Node type constant indicating a node of type 
0458:             * <code>SingleVariableDeclaration</code>.
0459:             * @see SingleVariableDeclaration
0460:             */
0461:            public static final int SINGLE_VARIABLE_DECLARATION = 44;
0462:
0463:            /**
0464:             * Node type constant indicating a node of type 
0465:             * <code>StringLiteral</code>.
0466:             * @see StringLiteral
0467:             */
0468:            public static final int STRING_LITERAL = 45;
0469:
0470:            /**
0471:             * Node type constant indicating a node of type 
0472:             * <code>SuperConstructorInvocation</code>.
0473:             * @see SuperConstructorInvocation
0474:             */
0475:            public static final int SUPER_CONSTRUCTOR_INVOCATION = 46;
0476:
0477:            /**
0478:             * Node type constant indicating a node of type 
0479:             * <code>SuperFieldAccess</code>.
0480:             * @see SuperFieldAccess
0481:             */
0482:            public static final int SUPER_FIELD_ACCESS = 47;
0483:
0484:            /**
0485:             * Node type constant indicating a node of type 
0486:             * <code>SuperMethodInvocation</code>.
0487:             * @see SuperMethodInvocation
0488:             */
0489:            public static final int SUPER_METHOD_INVOCATION = 48;
0490:
0491:            /**
0492:             * Node type constant indicating a node of type 
0493:             * <code>SwitchCase</code>.
0494:             * @see SwitchCase
0495:             */
0496:            public static final int SWITCH_CASE = 49;
0497:
0498:            /**
0499:             * Node type constant indicating a node of type 
0500:             * <code>SwitchStatement</code>.
0501:             * @see SwitchStatement
0502:             */
0503:            public static final int SWITCH_STATEMENT = 50;
0504:
0505:            /**
0506:             * Node type constant indicating a node of type 
0507:             * <code>SynchronizedStatement</code>.
0508:             * @see SynchronizedStatement
0509:             */
0510:            public static final int SYNCHRONIZED_STATEMENT = 51;
0511:
0512:            /**
0513:             * Node type constant indicating a node of type 
0514:             * <code>ThisExpression</code>.
0515:             * @see ThisExpression
0516:             */
0517:            public static final int THIS_EXPRESSION = 52;
0518:
0519:            /**
0520:             * Node type constant indicating a node of type 
0521:             * <code>ThrowStatement</code>.
0522:             * @see ThrowStatement
0523:             */
0524:            public static final int THROW_STATEMENT = 53;
0525:
0526:            /**
0527:             * Node type constant indicating a node of type 
0528:             * <code>TryStatement</code>.
0529:             * @see TryStatement
0530:             */
0531:            public static final int TRY_STATEMENT = 54;
0532:
0533:            /**
0534:             * Node type constant indicating a node of type 
0535:             * <code>TypeDeclaration</code>.
0536:             * @see TypeDeclaration
0537:             */
0538:            public static final int TYPE_DECLARATION = 55;
0539:
0540:            /**
0541:             * Node type constant indicating a node of type 
0542:             * <code>TypeDeclarationStatement</code>.
0543:             * @see TypeDeclarationStatement
0544:             */
0545:            public static final int TYPE_DECLARATION_STATEMENT = 56;
0546:
0547:            /**
0548:             * Node type constant indicating a node of type 
0549:             * <code>TypeLiteral</code>.
0550:             * @see TypeLiteral
0551:             */
0552:            public static final int TYPE_LITERAL = 57;
0553:
0554:            /**
0555:             * Node type constant indicating a node of type 
0556:             * <code>VariableDeclarationExpression</code>.
0557:             * @see VariableDeclarationExpression
0558:             */
0559:            public static final int VARIABLE_DECLARATION_EXPRESSION = 58;
0560:
0561:            /**
0562:             * Node type constant indicating a node of type 
0563:             * <code>VariableDeclarationFragment</code>.
0564:             * @see VariableDeclarationFragment
0565:             */
0566:            public static final int VARIABLE_DECLARATION_FRAGMENT = 59;
0567:
0568:            /**
0569:             * Node type constant indicating a node of type 
0570:             * <code>VariableDeclarationStatement</code>.
0571:             * @see VariableDeclarationStatement
0572:             */
0573:            public static final int VARIABLE_DECLARATION_STATEMENT = 60;
0574:
0575:            /**
0576:             * Node type constant indicating a node of type 
0577:             * <code>WhileStatement</code>.
0578:             * @see WhileStatement
0579:             */
0580:            public static final int WHILE_STATEMENT = 61;
0581:
0582:            /**
0583:             * Node type constant indicating a node of type 
0584:             * <code>InstanceofExpression</code>.
0585:             * @see InstanceofExpression
0586:             */
0587:            public static final int INSTANCEOF_EXPRESSION = 62;
0588:
0589:            /**
0590:             * Node type constant indicating a node of type 
0591:             * <code>LineComment</code>.
0592:             * @see LineComment
0593:             * @since 3.0
0594:             */
0595:            public static final int LINE_COMMENT = 63;
0596:
0597:            /**
0598:             * Node type constant indicating a node of type 
0599:             * <code>BlockComment</code>.
0600:             * @see BlockComment
0601:             * @since 3.0
0602:             */
0603:            public static final int BLOCK_COMMENT = 64;
0604:
0605:            /**
0606:             * Node type constant indicating a node of type 
0607:             * <code>TagElement</code>.
0608:             * @see TagElement
0609:             * @since 3.0
0610:             */
0611:            public static final int TAG_ELEMENT = 65;
0612:
0613:            /**
0614:             * Node type constant indicating a node of type 
0615:             * <code>TextElement</code>.
0616:             * @see TextElement
0617:             * @since 3.0
0618:             */
0619:            public static final int TEXT_ELEMENT = 66;
0620:
0621:            /**
0622:             * Node type constant indicating a node of type 
0623:             * <code>MemberRef</code>.
0624:             * @see MemberRef
0625:             * @since 3.0
0626:             */
0627:            public static final int MEMBER_REF = 67;
0628:
0629:            /**
0630:             * Node type constant indicating a node of type 
0631:             * <code>MethodRef</code>.
0632:             * @see MethodRef
0633:             * @since 3.0
0634:             */
0635:            public static final int METHOD_REF = 68;
0636:
0637:            /**
0638:             * Node type constant indicating a node of type 
0639:             * <code>MethodRefParameter</code>.
0640:             * @see MethodRefParameter
0641:             * @since 3.0
0642:             */
0643:            public static final int METHOD_REF_PARAMETER = 69;
0644:
0645:            /**
0646:             * Node type constant indicating a node of type 
0647:             * <code>EnhancedForStatement</code>.
0648:             * @see EnhancedForStatement
0649:             * @since 3.1
0650:             */
0651:            public static final int ENHANCED_FOR_STATEMENT = 70;
0652:
0653:            /**
0654:             * Node type constant indicating a node of type 
0655:             * <code>EnumDeclaration</code>.
0656:             * @see EnumDeclaration
0657:             * @since 3.1
0658:             */
0659:            public static final int ENUM_DECLARATION = 71;
0660:
0661:            /**
0662:             * Node type constant indicating a node of type 
0663:             * <code>EnumConstantDeclaration</code>.
0664:             * @see EnumConstantDeclaration
0665:             * @since 3.1
0666:             */
0667:            public static final int ENUM_CONSTANT_DECLARATION = 72;
0668:
0669:            /**
0670:             * Node type constant indicating a node of type 
0671:             * <code>TypeParameter</code>.
0672:             * @see TypeParameter
0673:             * @since 3.1
0674:             */
0675:            public static final int TYPE_PARAMETER = 73;
0676:
0677:            /**
0678:             * Node type constant indicating a node of type 
0679:             * <code>ParameterizedType</code>.
0680:             * @see ParameterizedType
0681:             * @since 3.1
0682:             */
0683:            public static final int PARAMETERIZED_TYPE = 74;
0684:
0685:            /**
0686:             * Node type constant indicating a node of type 
0687:             * <code>QualifiedType</code>.
0688:             * @see QualifiedType
0689:             * @since 3.1
0690:             */
0691:            public static final int QUALIFIED_TYPE = 75;
0692:
0693:            /**
0694:             * Node type constant indicating a node of type 
0695:             * <code>WildcardType</code>.
0696:             * @see WildcardType
0697:             * @since 3.1
0698:             */
0699:            public static final int WILDCARD_TYPE = 76;
0700:
0701:            /**
0702:             * Node type constant indicating a node of type 
0703:             * <code>NormalAnnotation</code>.
0704:             * @see NormalAnnotation
0705:             * @since 3.1
0706:             */
0707:            public static final int NORMAL_ANNOTATION = 77;
0708:
0709:            /**
0710:             * Node type constant indicating a node of type 
0711:             * <code>MarkerAnnotation</code>.
0712:             * @see MarkerAnnotation
0713:             * @since 3.1
0714:             */
0715:            public static final int MARKER_ANNOTATION = 78;
0716:
0717:            /**
0718:             * Node type constant indicating a node of type 
0719:             * <code>SingleMemberAnnotation</code>.
0720:             * @see SingleMemberAnnotation
0721:             * @since 3.1
0722:             */
0723:            public static final int SINGLE_MEMBER_ANNOTATION = 79;
0724:
0725:            /**
0726:             * Node type constant indicating a node of type 
0727:             * <code>MemberValuePair</code>.
0728:             * @see MemberValuePair
0729:             * @since 3.1
0730:             */
0731:            public static final int MEMBER_VALUE_PAIR = 80;
0732:
0733:            /**
0734:             * Node type constant indicating a node of type 
0735:             * <code>AnnotationTypeDeclaration</code>.
0736:             * @see AnnotationTypeDeclaration
0737:             * @since 3.1
0738:             */
0739:            public static final int ANNOTATION_TYPE_DECLARATION = 81;
0740:
0741:            /**
0742:             * Node type constant indicating a node of type 
0743:             * <code>AnnotationTypeMemberDeclaration</code>.
0744:             * @see AnnotationTypeMemberDeclaration
0745:             * @since 3.1
0746:             */
0747:            public static final int ANNOTATION_TYPE_MEMBER_DECLARATION = 82;
0748:
0749:            /**
0750:             * Node type constant indicating a node of type 
0751:             * <code>Modifier</code>.
0752:             * @see Modifier
0753:             * @since 3.1
0754:             */
0755:            public static final int MODIFIER = 83;
0756:
0757:            /**
0758:             * Returns the node class for the corresponding node type.
0759:             * 
0760:             * @param nodeType AST node type
0761:             * @return the corresponding <code>ASTNode</code> subclass
0762:             * @exception IllegalArgumentException if <code>nodeType</code> is 
0763:             * not a legal AST node type
0764:             * @see #getNodeType()
0765:             * @since 3.0
0766:             */
0767:            public static Class nodeClassForType(int nodeType) {
0768:                switch (nodeType) {
0769:                case ANNOTATION_TYPE_DECLARATION:
0770:                    return AnnotationTypeDeclaration.class;
0771:                case ANNOTATION_TYPE_MEMBER_DECLARATION:
0772:                    return AnnotationTypeMemberDeclaration.class;
0773:                case ANONYMOUS_CLASS_DECLARATION:
0774:                    return AnonymousClassDeclaration.class;
0775:                case ARRAY_ACCESS:
0776:                    return ArrayAccess.class;
0777:                case ARRAY_CREATION:
0778:                    return ArrayCreation.class;
0779:                case ARRAY_INITIALIZER:
0780:                    return ArrayInitializer.class;
0781:                case ARRAY_TYPE:
0782:                    return ArrayType.class;
0783:                case ASSERT_STATEMENT:
0784:                    return AssertStatement.class;
0785:                case ASSIGNMENT:
0786:                    return Assignment.class;
0787:                case BLOCK:
0788:                    return Block.class;
0789:                case BLOCK_COMMENT:
0790:                    return BlockComment.class;
0791:                case BOOLEAN_LITERAL:
0792:                    return BooleanLiteral.class;
0793:                case BREAK_STATEMENT:
0794:                    return BreakStatement.class;
0795:                case CAST_EXPRESSION:
0796:                    return CastExpression.class;
0797:                case CATCH_CLAUSE:
0798:                    return CatchClause.class;
0799:                case CHARACTER_LITERAL:
0800:                    return CharacterLiteral.class;
0801:                case CLASS_INSTANCE_CREATION:
0802:                    return ClassInstanceCreation.class;
0803:                case COMPILATION_UNIT:
0804:                    return CompilationUnit.class;
0805:                case CONDITIONAL_EXPRESSION:
0806:                    return ConditionalExpression.class;
0807:                case CONSTRUCTOR_INVOCATION:
0808:                    return ConstructorInvocation.class;
0809:                case CONTINUE_STATEMENT:
0810:                    return ContinueStatement.class;
0811:                case DO_STATEMENT:
0812:                    return DoStatement.class;
0813:                case EMPTY_STATEMENT:
0814:                    return EmptyStatement.class;
0815:                case ENHANCED_FOR_STATEMENT:
0816:                    return EnhancedForStatement.class;
0817:                case ENUM_CONSTANT_DECLARATION:
0818:                    return EnumConstantDeclaration.class;
0819:                case ENUM_DECLARATION:
0820:                    return EnumDeclaration.class;
0821:                case EXPRESSION_STATEMENT:
0822:                    return ExpressionStatement.class;
0823:                case FIELD_ACCESS:
0824:                    return FieldAccess.class;
0825:                case FIELD_DECLARATION:
0826:                    return FieldDeclaration.class;
0827:                case FOR_STATEMENT:
0828:                    return ForStatement.class;
0829:                case IF_STATEMENT:
0830:                    return IfStatement.class;
0831:                case IMPORT_DECLARATION:
0832:                    return ImportDeclaration.class;
0833:                case INFIX_EXPRESSION:
0834:                    return InfixExpression.class;
0835:                case INITIALIZER:
0836:                    return Initializer.class;
0837:                case INSTANCEOF_EXPRESSION:
0838:                    return InstanceofExpression.class;
0839:                case JAVADOC:
0840:                    return Javadoc.class;
0841:                case LABELED_STATEMENT:
0842:                    return LabeledStatement.class;
0843:                case LINE_COMMENT:
0844:                    return LineComment.class;
0845:                case MARKER_ANNOTATION:
0846:                    return MarkerAnnotation.class;
0847:                case MEMBER_REF:
0848:                    return MemberRef.class;
0849:                case MEMBER_VALUE_PAIR:
0850:                    return MemberValuePair.class;
0851:                case METHOD_DECLARATION:
0852:                    return MethodDeclaration.class;
0853:                case METHOD_INVOCATION:
0854:                    return MethodInvocation.class;
0855:                case METHOD_REF:
0856:                    return MethodRef.class;
0857:                case METHOD_REF_PARAMETER:
0858:                    return MethodRefParameter.class;
0859:                case MODIFIER:
0860:                    return Modifier.class;
0861:                case NORMAL_ANNOTATION:
0862:                    return NormalAnnotation.class;
0863:                case NULL_LITERAL:
0864:                    return NullLiteral.class;
0865:                case NUMBER_LITERAL:
0866:                    return NumberLiteral.class;
0867:                case PACKAGE_DECLARATION:
0868:                    return PackageDeclaration.class;
0869:                case PARAMETERIZED_TYPE:
0870:                    return ParameterizedType.class;
0871:                case PARENTHESIZED_EXPRESSION:
0872:                    return ParenthesizedExpression.class;
0873:                case POSTFIX_EXPRESSION:
0874:                    return PostfixExpression.class;
0875:                case PREFIX_EXPRESSION:
0876:                    return PrefixExpression.class;
0877:                case PRIMITIVE_TYPE:
0878:                    return PrimitiveType.class;
0879:                case QUALIFIED_NAME:
0880:                    return QualifiedName.class;
0881:                case QUALIFIED_TYPE:
0882:                    return QualifiedType.class;
0883:                case RETURN_STATEMENT:
0884:                    return ReturnStatement.class;
0885:                case SIMPLE_NAME:
0886:                    return SimpleName.class;
0887:                case SIMPLE_TYPE:
0888:                    return SimpleType.class;
0889:                case SINGLE_MEMBER_ANNOTATION:
0890:                    return SingleMemberAnnotation.class;
0891:                case SINGLE_VARIABLE_DECLARATION:
0892:                    return SingleVariableDeclaration.class;
0893:                case STRING_LITERAL:
0894:                    return StringLiteral.class;
0895:                case SUPER_CONSTRUCTOR_INVOCATION:
0896:                    return SuperConstructorInvocation.class;
0897:                case SUPER_FIELD_ACCESS:
0898:                    return SuperFieldAccess.class;
0899:                case SUPER_METHOD_INVOCATION:
0900:                    return SuperMethodInvocation.class;
0901:                case SWITCH_CASE:
0902:                    return SwitchCase.class;
0903:                case SWITCH_STATEMENT:
0904:                    return SwitchStatement.class;
0905:                case SYNCHRONIZED_STATEMENT:
0906:                    return SynchronizedStatement.class;
0907:                case TAG_ELEMENT:
0908:                    return TagElement.class;
0909:                case TEXT_ELEMENT:
0910:                    return TextElement.class;
0911:                case THIS_EXPRESSION:
0912:                    return ThisExpression.class;
0913:                case THROW_STATEMENT:
0914:                    return ThrowStatement.class;
0915:                case TRY_STATEMENT:
0916:                    return TryStatement.class;
0917:                case TYPE_DECLARATION:
0918:                    return TypeDeclaration.class;
0919:                case TYPE_DECLARATION_STATEMENT:
0920:                    return TypeDeclarationStatement.class;
0921:                case TYPE_LITERAL:
0922:                    return TypeLiteral.class;
0923:                case TYPE_PARAMETER:
0924:                    return TypeParameter.class;
0925:                case VARIABLE_DECLARATION_EXPRESSION:
0926:                    return VariableDeclarationExpression.class;
0927:                case VARIABLE_DECLARATION_FRAGMENT:
0928:                    return VariableDeclarationFragment.class;
0929:                case VARIABLE_DECLARATION_STATEMENT:
0930:                    return VariableDeclarationStatement.class;
0931:                case WHILE_STATEMENT:
0932:                    return WhileStatement.class;
0933:                case WILDCARD_TYPE:
0934:                    return WildcardType.class;
0935:                }
0936:                throw new IllegalArgumentException();
0937:            }
0938:
0939:            /**
0940:             * Owning AST.
0941:             * <p>
0942:             * N.B. This ia a private field, but declared as package-visible
0943:             * for more efficient access from inner classes.
0944:             * </p>
0945:             */
0946:            final AST ast;
0947:
0948:            /**
0949:             * Parent AST node, or <code>null</code> if this node is a root.
0950:             * Initially <code>null</code>.
0951:             */
0952:            private ASTNode parent = null;
0953:
0954:            /**
0955:             * An unmodifiable empty map (used to implement <code>properties()</code>).
0956:             */
0957:            private static final Map UNMODIFIABLE_EMPTY_MAP = Collections
0958:                    .unmodifiableMap(new HashMap(1));
0959:
0960:            /**
0961:             * Primary field used in representing node properties efficiently.
0962:             * If <code>null</code>, this node has no properties.
0963:             * If a <code>String</code>, this is the name of this node's sole property,
0964:             * and <code>property2</code> contains its value.
0965:             * If a <code>HashMap</code>, this is the table of property name-value
0966:             * mappings; <code>property2</code>, if non-null is its unmodifiable
0967:             * equivalent.
0968:             * Initially <code>null</code>.
0969:             * 
0970:             * @see #property2
0971:             */
0972:            private Object property1 = null;
0973:
0974:            /**
0975:             * Auxillary field used in representing node properties efficiently.
0976:             * 
0977:             * @see #property1
0978:             */
0979:            private Object property2 = null;
0980:
0981:            /**
0982:             * A character index into the original source string, 
0983:             * or <code>-1</code> if no source position information is available
0984:             * for this node; <code>-1</code> by default.
0985:             */
0986:            private int startPosition = -1;
0987:
0988:            /**
0989:             * A character length, or <code>0</code> if no source position
0990:             * information is recorded for this node; <code>0</code> by default.
0991:             */
0992:            private int length = 0;
0993:
0994:            /**
0995:             * Flag constant (bit mask, value 1) indicating that there is something
0996:             * not quite right with this AST node.
0997:             * <p>
0998:             * The standard parser (<code>ASTParser</code>) sets this
0999:             * flag on a node to indicate a syntax error detected in the vicinity.
1000:             * </p>
1001:             */
1002:            public static final int MALFORMED = 1;
1003:
1004:            /**
1005:             * Flag constant (bit mask, value 2) indicating that this is a node
1006:             * that was created by the parser (as opposed to one created by another
1007:             * party).
1008:             * <p>
1009:             * The standard parser (<code>ASTParser</code>) sets this
1010:             * flag on the nodes it creates.
1011:             * </p>
1012:             * @since 3.0
1013:             */
1014:            public static final int ORIGINAL = 2;
1015:
1016:            /**
1017:             * Flag constant (bit mask, value 4) indicating that this node
1018:             * is unmodifiable. When a node is marked unmodifiable, the
1019:             * following operations result in a runtime exception:
1020:             * <ul>
1021:             * <li>Change a simple property of this node.</li>
1022:             * <li>Add or remove a child node from this node.</li>
1023:             * <li>Parent (or reparent) this node.</li>
1024:             * </ul>
1025:             * <p>
1026:             * The standard parser (<code>ASTParser</code>) does not set
1027:             * this flag on the nodes it creates. However, clients may set
1028:             * this flag on a node to prevent further modification of the
1029:             * its structural properties.
1030:             * </p>
1031:             * @since 3.0
1032:             */
1033:            public static final int PROTECT = 4;
1034:
1035:            /**
1036:             * Flag constant (bit mask, value 8) indicating that this node
1037:             * or a part of this node is recovered from source that contains
1038:             * a syntax error detected in the vicinity.
1039:             * <p>
1040:             * The standard parser (<code>ASTParser</code>) sets this
1041:             * flag on a node to indicate a recovered node.
1042:             * </p>
1043:             * @since 3.2
1044:             */
1045:            public static final int RECOVERED = 8;
1046:
1047:            /**
1048:             * int containing the node type in the top 16 bits and
1049:             * flags in the bottom 16 bits; none set by default.
1050:             * <p>
1051:             * N.B. This is a private field, but declared as package-visible
1052:             * for more efficient access from inner classes.
1053:             * </p>
1054:             * 
1055:             * @see #MALFORMED
1056:             */
1057:            int typeAndFlags = 0;
1058:
1059:            /**
1060:             * Property of parent in which this node is a child, or <code>null</code>
1061:             * if this node is a root. Initially <code>null</code>.
1062:             * 
1063:             * @see #getLocationInParent
1064:             * @since 3.0
1065:             */
1066:            private StructuralPropertyDescriptor location = null;
1067:
1068:            /** Internal convenience constant indicating that there is definite risk of cycles.
1069:             * @since 3.0
1070:             */
1071:            static final boolean CYCLE_RISK = true;
1072:
1073:            /** Internal convenience constant indicating that there is no risk of cycles.
1074:             * @since 3.0
1075:             */
1076:            static final boolean NO_CYCLE_RISK = false;
1077:
1078:            /** Internal convenience constant indicating that a structural property is mandatory.
1079:             * @since 3.0
1080:             */
1081:            static final boolean MANDATORY = true;
1082:
1083:            /** Internal convenience constant indicating that a structural property is optional.
1084:             * @since 3.0
1085:             */
1086:            static final boolean OPTIONAL = false;
1087:
1088:            /**
1089:             * A specialized implementation of a list of ASTNodes. The
1090:             * implementation is based on an ArrayList.
1091:             */
1092:            class NodeList extends AbstractList {
1093:
1094:                /**
1095:                 * The underlying list in which the nodes of this list are
1096:                 * stored (element type: <code>ASTNode</code>).
1097:                 * <p>
1098:                 * Be stingy on storage - assume that list will be empty.
1099:                 * </p>
1100:                 * <p>
1101:                 * This field declared default visibility (rather than private)
1102:                 * so that accesses from <code>NodeList.Cursor</code> do not require
1103:                 * a synthetic accessor method.
1104:                 * </p>
1105:                 */
1106:                ArrayList store = new ArrayList(0);
1107:
1108:                /**
1109:                 * The property descriptor for this list.
1110:                 */
1111:                ChildListPropertyDescriptor propertyDescriptor;
1112:
1113:                /**
1114:                 * A cursor for iterating over the elements of the list.
1115:                 * Does not lose its position if the list is changed during
1116:                 * the iteration.
1117:                 */
1118:                class Cursor implements  Iterator {
1119:                    /**
1120:                     * The position of the cursor between elements. If the value
1121:                     * is N, then the cursor sits between the element at positions
1122:                     * N-1 and N. Initially just before the first element of the
1123:                     * list.
1124:                     */
1125:                    private int position = 0;
1126:
1127:                    /* (non-Javadoc)
1128:                     * Method declared on <code>Iterator</code>.
1129:                     */
1130:                    public boolean hasNext() {
1131:                        return this .position < NodeList.this .store.size();
1132:                    }
1133:
1134:                    /* (non-Javadoc)
1135:                     * Method declared on <code>Iterator</code>.
1136:                     */
1137:                    public Object next() {
1138:                        Object result = NodeList.this .store.get(this .position);
1139:                        this .position++;
1140:                        return result;
1141:                    }
1142:
1143:                    /* (non-Javadoc)
1144:                     * Method declared on <code>Iterator</code>.
1145:                     */
1146:                    public void remove() {
1147:                        throw new UnsupportedOperationException();
1148:                    }
1149:
1150:                    /**
1151:                     * Adjusts this cursor to accomodate an add/remove at the given
1152:                     * index.
1153:                     * 
1154:                     * @param index the position at which the element was added
1155:                     *    or removed
1156:                     * @param delta +1 for add, and -1 for remove
1157:                     */
1158:                    void update(int index, int delta) {
1159:                        if (this .position > index) {
1160:                            // the cursor has passed the added or removed element
1161:                            this .position += delta;
1162:                        }
1163:                    }
1164:                }
1165:
1166:                /**
1167:                 * A list of currently active cursors (element type:
1168:                 * <code>Cursor</code>), or <code>null</code> if there are no
1169:                 * active cursors.
1170:                 * <p>
1171:                 * It is important for storage considerations to maintain the
1172:                 * null-means-empty invariant; otherwise, every NodeList instance
1173:                 * will waste a lot of space. A cursor is needed only for the duration
1174:                 * of a visit to the child nodes. Under normal circumstances, only a 
1175:                 * single cursor is needed; multiple cursors are only required if there
1176:                 * are multiple visits going on at the same time.
1177:                 * </p>
1178:                 */
1179:                private List cursors = null;
1180:
1181:                /**
1182:                 * Creates a new empty list of nodes owned by this node.
1183:                 * This node will be the common parent of all nodes added to 
1184:                 * this list.
1185:                 * 
1186:                 * @param property the property descriptor
1187:                 * @since 3.0
1188:                 */
1189:                NodeList(ChildListPropertyDescriptor property) {
1190:                    super ();
1191:                    this .propertyDescriptor = property;
1192:                }
1193:
1194:                /* (non-javadoc)
1195:                 * @see java.util.AbstractCollection#size()
1196:                 */
1197:                public int size() {
1198:                    return this .store.size();
1199:                }
1200:
1201:                /* (non-javadoc)
1202:                 * @see AbstractList#get(int)
1203:                 */
1204:                public Object get(int index) {
1205:                    return this .store.get(index);
1206:                }
1207:
1208:                /* (non-javadoc)
1209:                 * @see List#set(int, java.lang.Object)
1210:                 */
1211:                public Object set(int index, Object element) {
1212:                    if (element == null) {
1213:                        throw new IllegalArgumentException();
1214:                    }
1215:                    if ((ASTNode.this .typeAndFlags & PROTECT) != 0) {
1216:                        // this node is protected => cannot gain or lose children
1217:                        throw new IllegalArgumentException(
1218:                                "AST node cannot be modified"); //$NON-NLS-1$
1219:                    }
1220:                    // delink old child from parent, and link new child to parent
1221:                    ASTNode newChild = (ASTNode) element;
1222:                    ASTNode oldChild = (ASTNode) this .store.get(index);
1223:                    if (oldChild == newChild) {
1224:                        return oldChild;
1225:                    }
1226:                    if ((oldChild.typeAndFlags & PROTECT) != 0) {
1227:                        // old child is protected => cannot be unparented
1228:                        throw new IllegalArgumentException(
1229:                                "AST node cannot be modified"); //$NON-NLS-1$
1230:                    }
1231:                    ASTNode.checkNewChild(ASTNode.this , newChild,
1232:                            this .propertyDescriptor.cycleRisk,
1233:                            this .propertyDescriptor.elementType);
1234:                    ASTNode.this .ast.preReplaceChildEvent(ASTNode.this ,
1235:                            oldChild, newChild, this .propertyDescriptor);
1236:
1237:                    Object result = this .store.set(index, newChild);
1238:                    // n.b. setParent will call ast.modifying()
1239:                    oldChild.setParent(null, null);
1240:                    newChild.setParent(ASTNode.this , this .propertyDescriptor);
1241:                    ASTNode.this .ast.postReplaceChildEvent(ASTNode.this ,
1242:                            oldChild, newChild, this .propertyDescriptor);
1243:                    return result;
1244:                }
1245:
1246:                /* (non-javadoc)
1247:                 * @see List#add(int, java.lang.Object)
1248:                 */
1249:                public void add(int index, Object element) {
1250:                    if (element == null) {
1251:                        throw new IllegalArgumentException();
1252:                    }
1253:                    if ((ASTNode.this .typeAndFlags & PROTECT) != 0) {
1254:                        // this node is protected => cannot gain or lose children
1255:                        throw new IllegalArgumentException(
1256:                                "AST node cannot be modified"); //$NON-NLS-1$
1257:                    }
1258:                    // link new child to parent
1259:                    ASTNode newChild = (ASTNode) element;
1260:                    ASTNode.checkNewChild(ASTNode.this , newChild,
1261:                            this .propertyDescriptor.cycleRisk,
1262:                            this .propertyDescriptor.elementType);
1263:                    ASTNode.this .ast.preAddChildEvent(ASTNode.this , newChild,
1264:                            this .propertyDescriptor);
1265:
1266:                    this .store.add(index, element);
1267:                    updateCursors(index, +1);
1268:                    // n.b. setParent will call ast.modifying()
1269:                    newChild.setParent(ASTNode.this , this .propertyDescriptor);
1270:                    ASTNode.this .ast.postAddChildEvent(ASTNode.this , newChild,
1271:                            this .propertyDescriptor);
1272:                }
1273:
1274:                /* (non-javadoc)
1275:                 * @see List#remove(int)
1276:                 */
1277:                public Object remove(int index) {
1278:                    if ((ASTNode.this .typeAndFlags & PROTECT) != 0) {
1279:                        // this node is protected => cannot gain or lose children
1280:                        throw new IllegalArgumentException(
1281:                                "AST node cannot be modified"); //$NON-NLS-1$
1282:                    }
1283:                    // delink old child from parent
1284:                    ASTNode oldChild = (ASTNode) this .store.get(index);
1285:                    if ((oldChild.typeAndFlags & PROTECT) != 0) {
1286:                        // old child is protected => cannot be unparented
1287:                        throw new IllegalArgumentException(
1288:                                "AST node cannot be modified"); //$NON-NLS-1$
1289:                    }
1290:
1291:                    ASTNode.this .ast.preRemoveChildEvent(ASTNode.this ,
1292:                            oldChild, this .propertyDescriptor);
1293:                    // n.b. setParent will call ast.modifying()
1294:                    oldChild.setParent(null, null);
1295:                    Object result = this .store.remove(index);
1296:                    updateCursors(index, -1);
1297:                    ASTNode.this .ast.postRemoveChildEvent(ASTNode.this ,
1298:                            oldChild, this .propertyDescriptor);
1299:                    return result;
1300:
1301:                }
1302:
1303:                /**
1304:                 * Allocate a cursor to use for a visit. The client must call
1305:                 * <code>releaseCursor</code> when done.
1306:                 * <p>
1307:                 * This method is internally synchronized on this NodeList.
1308:                 * It is thread-safe to create a cursor.
1309:                 * </p>
1310:                 * 
1311:                 * @return a new cursor positioned before the first element 
1312:                 *    of the list
1313:                 */
1314:                Cursor newCursor() {
1315:                    synchronized (this ) {
1316:                        // serialize cursor management on this NodeList
1317:                        if (this .cursors == null) {
1318:                            // convert null to empty list
1319:                            this .cursors = new ArrayList(1);
1320:                        }
1321:                        Cursor result = new Cursor();
1322:                        this .cursors.add(result);
1323:                        return result;
1324:                    }
1325:                }
1326:
1327:                /**
1328:                 * Releases the given cursor at the end of a visit.
1329:                 * <p>
1330:                 * This method is internally synchronized on this NodeList.
1331:                 * It is thread-safe to release a cursor.
1332:                 * </p>
1333:                 * 
1334:                 * @param cursor the cursor
1335:                 */
1336:                void releaseCursor(Cursor cursor) {
1337:                    synchronized (this ) {
1338:                        // serialize cursor management on this NodeList
1339:                        this .cursors.remove(cursor);
1340:                        if (this .cursors.isEmpty()) {
1341:                            // important: convert empty list back to null
1342:                            // otherwise the node will hang on to needless junk
1343:                            this .cursors = null;
1344:                        }
1345:                    }
1346:                }
1347:
1348:                /**
1349:                 * Adjusts all cursors to accomodate an add/remove at the given
1350:                 * index.
1351:                 * <p>
1352:                 * This method is only used when the list is being modified.
1353:                 * The AST is not thread-safe if any of the clients are modifying it.
1354:                 * </p>
1355:                 * 
1356:                 * @param index the position at which the element was added
1357:                 *    or removed
1358:                 * @param delta +1 for add, and -1 for remove
1359:                 */
1360:                private void updateCursors(int index, int delta) {
1361:                    if (this .cursors == null) {
1362:                        // there are no cursors to worry about
1363:                        return;
1364:                    }
1365:                    for (Iterator it = this .cursors.iterator(); it.hasNext();) {
1366:                        Cursor c = (Cursor) it.next();
1367:                        c.update(index, delta);
1368:                    }
1369:                }
1370:
1371:                /**
1372:                 * Returns an estimate of the memory footprint of this node list 
1373:                 * instance in bytes.
1374:                 * <ul>
1375:                 * <li>1 object header for the NodeList instance</li>
1376:                 * <li>5 4-byte fields of the NodeList instance</li>
1377:                 * <li>0 for cursors since null unless walk in progress</li>
1378:                 * <li>1 object header for the ArrayList instance</li>
1379:                 * <li>2 4-byte fields of the ArrayList instance</li>
1380:                 * <li>1 object header for an Object[] instance</li>
1381:                 * <li>4 bytes in array for each element</li>
1382:                 * </ul>
1383:                 * 
1384:                 * @return the size of this node list in bytes
1385:                 */
1386:                int memSize() {
1387:                    int result = HEADERS + 5 * 4;
1388:                    result += HEADERS + 2 * 4;
1389:                    result += HEADERS + 4 * size();
1390:                    return result;
1391:                }
1392:
1393:                /**
1394:                 * Returns an estimate of the memory footprint in bytes of this node
1395:                 * list and all its subtrees.
1396:                 * 
1397:                 * @return the size of this list of subtrees in bytes
1398:                 */
1399:                int listSize() {
1400:                    int result = memSize();
1401:                    for (Iterator it = iterator(); it.hasNext();) {
1402:                        ASTNode child = (ASTNode) it.next();
1403:                        result += child.treeSize();
1404:                    }
1405:                    return result;
1406:                }
1407:            }
1408:
1409:            /**
1410:             * Creates a new AST node owned by the given AST. Once established,
1411:             * the relationship between an AST node and its owning AST does not change
1412:             * over the lifetime of the node. The new node has no parent node,
1413:             * and no properties.
1414:             * <p>
1415:             * N.B. This constructor is package-private; all subclasses my be 
1416:             * declared in the same package; clients are unable to declare 
1417:             * additional subclasses.
1418:             * </p>
1419:             * 
1420:             * @param ast the AST that is to own this node
1421:             */
1422:            ASTNode(AST ast) {
1423:                if (ast == null) {
1424:                    throw new IllegalArgumentException();
1425:                }
1426:
1427:                this .ast = ast;
1428:                setNodeType(getNodeType0());
1429:                setFlags(ast.getDefaultNodeFlag());
1430:                // setFlags calls modifying();
1431:            }
1432:
1433:            /**
1434:             * Returns this node's AST.
1435:             * <p>
1436:             * Note that the relationship between an AST node and its owing AST does
1437:             * not change over the lifetime of a node.
1438:             * </p>
1439:             * 
1440:             * @return the AST that owns this node
1441:             */
1442:            public final AST getAST() {
1443:                return this .ast;
1444:            }
1445:
1446:            /**
1447:             * Returns this node's parent node, or <code>null</code> if this is the
1448:             * root node.
1449:             * <p>
1450:             * Note that the relationship between an AST node and its parent node
1451:             * may change over the lifetime of a node.
1452:             * </p>
1453:             * 
1454:             * @return the parent of this node, or <code>null</code> if none
1455:             */
1456:            public final ASTNode getParent() {
1457:                return this .parent;
1458:            }
1459:
1460:            /**
1461:             * Returns the location of this node within its parent,
1462:             * or <code>null</code> if this is a root node.
1463:             * <p>
1464:             * <pre>
1465:             * ASTNode node = ...;
1466:             * ASTNode parent = node.getParent();
1467:             * StructuralPropertyDescriptor location = node.getLocationInParent();
1468:             * assert (parent != null) == (location != null);
1469:             * if ((location != null) && location.isChildProperty())
1470:             *    assert parent.getStructuralProperty(location) == node;
1471:             * if ((location != null) && location.isChildListProperty())
1472:             *    assert ((List) parent.getStructuralProperty(location)).contains(node);
1473:             * </pre>
1474:             * </p>
1475:             * <p>
1476:             * Note that the relationship between an AST node and its parent node
1477:             * may change over the lifetime of a node.
1478:             * </p>
1479:             * 
1480:             * @return the location of this node in its parent, 
1481:             * or <code>null</code> if this node has no parent
1482:             * @since 3.0
1483:             */
1484:            public final StructuralPropertyDescriptor getLocationInParent() {
1485:                return this .location;
1486:            }
1487:
1488:            /**
1489:             * Returns the root node at or above this node; returns this node if 
1490:             * it is a root.
1491:             * 
1492:             * @return the root node at or above this node
1493:             */
1494:            public final ASTNode getRoot() {
1495:                ASTNode candidate = this ;
1496:                while (true) {
1497:                    ASTNode p = candidate.getParent();
1498:                    if (p == null) {
1499:                        // candidate has no parent - that's the guy
1500:                        return candidate;
1501:                    }
1502:                    candidate = p;
1503:                }
1504:            }
1505:
1506:            /**
1507:             * Returns the value of the given structural property for this node. The value
1508:             * returned depends on the kind of property:
1509:             * <ul>
1510:             * <li>{@link SimplePropertyDescriptor} - the value of the given simple property,
1511:             * or <code>null</code> if none; primitive values are "boxed"</li>
1512:             * <li>{@link ChildPropertyDescriptor} - the child node (type <code>ASTNode</code>),
1513:             * or <code>null</code> if none</li>
1514:             * <li>{@link ChildListPropertyDescriptor} - the list (element type: {@link ASTNode})</li>
1515:             * </ul>
1516:             * 
1517:             * @param property the property
1518:             * @return the value, or <code>null</code> if none
1519:             * @exception RuntimeException if this node does not have the given property
1520:             * @since 3.0
1521:             */
1522:            public final Object getStructuralProperty(
1523:                    StructuralPropertyDescriptor property) {
1524:                if (property instanceof  SimplePropertyDescriptor) {
1525:                    SimplePropertyDescriptor p = (SimplePropertyDescriptor) property;
1526:                    if (p.getValueType() == int.class) {
1527:                        int result = internalGetSetIntProperty(p, true, 0);
1528:                        return new Integer(result);
1529:                    } else if (p.getValueType() == boolean.class) {
1530:                        boolean result = internalGetSetBooleanProperty(p, true,
1531:                                false);
1532:                        return Boolean.valueOf(result);
1533:                    } else {
1534:                        return internalGetSetObjectProperty(p, true, null);
1535:                    }
1536:                }
1537:                if (property instanceof  ChildPropertyDescriptor) {
1538:                    return internalGetSetChildProperty(
1539:                            (ChildPropertyDescriptor) property, true, null);
1540:                }
1541:                if (property instanceof  ChildListPropertyDescriptor) {
1542:                    return internalGetChildListProperty((ChildListPropertyDescriptor) property);
1543:                }
1544:                throw new IllegalArgumentException();
1545:            }
1546:
1547:            /**
1548:             * Sets the value of the given structural property for this node. The value
1549:             * passed depends on the kind of property:
1550:             * <ul>
1551:             * <li>{@link SimplePropertyDescriptor} - the new value of the given simple property,
1552:             * or <code>null</code> if none; primitive values are "boxed"</li>
1553:             * <li>{@link ChildPropertyDescriptor} - the new child node (type <code>ASTNode</code>),
1554:             * or <code>null</code> if none</li>
1555:             * <li>{@link ChildListPropertyDescriptor} - not allowed</li>
1556:             * </ul>
1557:             * 
1558:             * @param property the property
1559:             * @param value the property value
1560:             * @exception RuntimeException if this node does not have the
1561:             * given property, or if the given property cannot be set
1562:             * @since 3.0
1563:             */
1564:            public final void setStructuralProperty(
1565:                    StructuralPropertyDescriptor property, Object value) {
1566:                if (property instanceof  SimplePropertyDescriptor) {
1567:                    SimplePropertyDescriptor p = (SimplePropertyDescriptor) property;
1568:                    if (p.getValueType() == int.class) {
1569:                        int arg = ((Integer) value).intValue();
1570:                        internalGetSetIntProperty(p, false, arg);
1571:                        return;
1572:                    } else if (p.getValueType() == boolean.class) {
1573:                        boolean arg = ((Boolean) value).booleanValue();
1574:                        internalGetSetBooleanProperty(p, false, arg);
1575:                        return;
1576:                    } else {
1577:                        if (value == null && p.isMandatory()) {
1578:                            throw new IllegalArgumentException();
1579:                        }
1580:                        internalGetSetObjectProperty(p, false, value);
1581:                        return;
1582:                    }
1583:                }
1584:                if (property instanceof  ChildPropertyDescriptor) {
1585:                    ChildPropertyDescriptor p = (ChildPropertyDescriptor) property;
1586:                    ASTNode child = (ASTNode) value;
1587:                    if (child == null && p.isMandatory()) {
1588:                        throw new IllegalArgumentException();
1589:                    }
1590:                    internalGetSetChildProperty(p, false, child);
1591:                    return;
1592:                }
1593:                if (property instanceof  ChildListPropertyDescriptor) {
1594:                    throw new IllegalArgumentException(
1595:                            "Cannot set the list of child list property"); //$NON-NLS-1$
1596:                }
1597:            }
1598:
1599:            /**
1600:             * Sets the value of the given int-valued property for this node.
1601:             * The default implementation of this method throws an exception explaining
1602:             * that this node does not have such a property. This method should be
1603:             * extended in subclasses that have at leasy one simple property whose value
1604:             * type is int.
1605:             * 
1606:             * @param property the property
1607:             * @param get <code>true</code> for a get operation, and 
1608:             * <code>false</code> for a set operation
1609:             * @param value the new property value; ignored for get operations
1610:             * @return the value; always returns
1611:             * <code>0</code> for set operations
1612:             * @exception RuntimeException if this node does not have the 
1613:             * given property, or if the given value cannot be set as specified
1614:             * @since 3.0
1615:             */
1616:            int internalGetSetIntProperty(SimplePropertyDescriptor property,
1617:                    boolean get, int value) {
1618:                throw new RuntimeException("Node does not have this property"); //$NON-NLS-1$
1619:            }
1620:
1621:            /**
1622:             * Sets the value of the given boolean-valued property for this node.
1623:             * The default implementation of this method throws an exception explaining
1624:             * that this node does not have such a property. This method should be
1625:             * extended in subclasses that have at leasy one simple property whose value
1626:             * type is boolean.
1627:             * 
1628:             * @param property the property
1629:             * @param get <code>true</code> for a get operation, and 
1630:             * <code>false</code> for a set operation
1631:             * @param value the new property value; ignored for get operations
1632:             * @return the value; always returns
1633:             * <code>false</code> for set operations
1634:             * @exception RuntimeException if this node does not have the 
1635:             * given property, or if the given value cannot be set as specified
1636:             * @since 3.0
1637:             */
1638:            boolean internalGetSetBooleanProperty(
1639:                    SimplePropertyDescriptor property, boolean get,
1640:                    boolean value) {
1641:                throw new RuntimeException("Node does not have this property"); //$NON-NLS-1$
1642:            }
1643:
1644:            /**
1645:             * Sets the value of the given property for this node.
1646:             * The default implementation of this method throws an exception explaining
1647:             * that this node does not have such a property. This method should be
1648:             * extended in subclasses that have at leasy one simple property whose value
1649:             * type is a reference type.
1650:             * 
1651:             * @param property the property
1652:             * @param get <code>true</code> for a get operation, and 
1653:             * <code>false</code> for a set operation
1654:             * @param value the new property value, or <code>null</code> if none;
1655:             * ignored for get operations
1656:             * @return the value, or <code>null</code> if none; always returns
1657:             * <code>null</code> for set operations
1658:             * @exception RuntimeException if this node does not have the 
1659:             * given property, or if the given value cannot be set as specified
1660:             * @since 3.0
1661:             */
1662:            Object internalGetSetObjectProperty(
1663:                    SimplePropertyDescriptor property, boolean get, Object value) {
1664:                throw new RuntimeException("Node does not have this property"); //$NON-NLS-1$
1665:            }
1666:
1667:            /**
1668:             * Sets the child value of the given property for this node.
1669:             * The default implementation of this method throws an exception explaining
1670:             * that this node does not have such a property. This method should be
1671:             * extended in subclasses that have at leasy one child property.
1672:             * 
1673:             * @param property the property
1674:             * @param get <code>true</code> for a get operation, and 
1675:             * <code>false</code> for a set operation
1676:             * @param child the new child value, or <code>null</code> if none;
1677:             * always <code>null</code> for get operations
1678:             * @return the child, or <code>null</code> if none; always returns
1679:             * <code>null</code> for set operations
1680:             * @exception RuntimeException if this node does not have the
1681:             * given property, or if the given child cannot be set as specified
1682:             * @since 3.0
1683:             */
1684:            ASTNode internalGetSetChildProperty(
1685:                    ChildPropertyDescriptor property, boolean get, ASTNode child) {
1686:                throw new RuntimeException("Node does not have this property"); //$NON-NLS-1$
1687:            }
1688:
1689:            /**
1690:             * Returns the list value of the given property for this node.
1691:             * The default implementation of this method throws an exception explaining
1692:             * that this noed does not have such a property. This method should be
1693:             * extended in subclasses that have at leasy one child list property.
1694:             * 
1695:             * @param property the property
1696:             * @return the list (element type: {@link ASTNode})
1697:             * @exception RuntimeException if the given node does not have the
1698:             * given property
1699:             * @since 3.0
1700:             */
1701:            List internalGetChildListProperty(
1702:                    ChildListPropertyDescriptor property) {
1703:                throw new RuntimeException("Node does not have this property"); //$NON-NLS-1$
1704:            }
1705:
1706:            /**
1707:             * Returns a list of structural property descriptors for nodes of the
1708:             * same type as this node. Clients must not modify the result.
1709:             * <p>
1710:             * Note that property descriptors are a meta-level mechanism
1711:             * for manipulating ASTNodes in a generic way. They are
1712:             * unrelated to <code>get/setProperty</code>.
1713:             * </p>
1714:             * 
1715:             * @return a list of property descriptors (element type: 
1716:             * {@link StructuralPropertyDescriptor})
1717:             * @since 3.0
1718:             */
1719:            public final List structuralPropertiesForType() {
1720:                return internalStructuralPropertiesForType(this .ast.apiLevel);
1721:            }
1722:
1723:            /**
1724:             * Returns a list of property descriptors for this node type.
1725:             * Clients must not modify the result. This abstract method
1726:             * must be implemented in each concrete AST node type.
1727:             * <p>
1728:             * N.B. This method is package-private, so that the implementations
1729:             * of this method in each of the concrete AST node types do not
1730:             * clutter up the API doc.
1731:             * </p>
1732:             * 
1733:             * @param apiLevel the API level; one of the <code>AST.JLS*</code> constants
1734:             * @return a list of property descriptors (element type: 
1735:             * {@link StructuralPropertyDescriptor})
1736:             * @since 3.0
1737:             */
1738:            abstract List internalStructuralPropertiesForType(int apiLevel);
1739:
1740:            /**
1741:             * Internal helper method that starts the building a list of
1742:             * property descriptors for the given node type.
1743:             * 
1744:             * @param nodeClass the class for a concrete node type
1745:             * @param propertyList empty list
1746:             */
1747:            static void createPropertyList(Class nodeClass, List propertyList) {
1748:                // stuff nodeClass at head of list for future ref
1749:                propertyList.add(nodeClass);
1750:            }
1751:
1752:            /**
1753:             * Internal helper method that adding a property descriptor.
1754:             * 
1755:             * @param property the structural property descriptor
1756:             * @param propertyList list beginning with the AST node class
1757:             * followed by accumulated structural property descriptors
1758:             */
1759:            static void addProperty(StructuralPropertyDescriptor property,
1760:                    List propertyList) {
1761:                Class nodeClass = (Class) propertyList.get(0);
1762:                if (property.getNodeClass() != nodeClass) {
1763:                    // easily made cut-and-paste mistake
1764:                    throw new RuntimeException(
1765:                            "Structural property descriptor has wrong node class!"); //$NON-NLS-1$
1766:                }
1767:                propertyList.add(property);
1768:            }
1769:
1770:            /**
1771:             * Internal helper method that completes the building of
1772:             * a node type's structural property descriptor list.
1773:             * 
1774:             * @param propertyList list beginning with the AST node class
1775:             * followed by accumulated structural property descriptors
1776:             * @return unmodifiable list of structural property descriptors
1777:             * (element type: <code>StructuralPropertyDescriptor</code>)
1778:             */
1779:            static List reapPropertyList(List propertyList) {
1780:                propertyList.remove(0); // remove nodeClass
1781:                // compact
1782:                ArrayList a = new ArrayList(propertyList.size());
1783:                a.addAll(propertyList);
1784:                return Collections.unmodifiableList(a);
1785:            }
1786:
1787:            /**
1788:             * Checks that this AST operation is not used when
1789:             * building JLS2 level ASTs.
1790:
1791:             * @exception UnsupportedOperationException
1792:             * @since 3.0
1793:             */
1794:            final void unsupportedIn2() {
1795:                if (this .ast.apiLevel == AST.JLS2_INTERNAL) {
1796:                    throw new UnsupportedOperationException(
1797:                            "Operation not supported in JLS2 AST"); //$NON-NLS-1$
1798:                }
1799:            }
1800:
1801:            /**
1802:             * Checks that this AST operation is only used when
1803:             * building JLS2 level ASTs.
1804:
1805:             * @exception UnsupportedOperationException
1806:             * @since 3.0
1807:             */
1808:            final void supportedOnlyIn2() {
1809:                if (this .ast.apiLevel != AST.JLS2_INTERNAL) {
1810:                    throw new UnsupportedOperationException(
1811:                            "Operation only supported in JLS2 AST"); //$NON-NLS-1$
1812:                }
1813:            }
1814:
1815:            /**
1816:             * Sets or clears this node's parent node and location.
1817:             * <p>
1818:             * Note that this method is package-private. The pointer from a node
1819:             * to its parent is set implicitly as a side effect of inserting or
1820:             * removing the node as a child of another node. This method calls
1821:             * <code>ast.modifying()</code>.
1822:             * </p>
1823:             * 
1824:             * @param parent the new parent of this node, or <code>null</code> if none
1825:             * @param property the location of this node in its parent, 
1826:             * or <code>null</code> if <code>parent</code> is <code>null</code>
1827:             * @see #getLocationInParent
1828:             * @see #getParent
1829:             * @since 3.0
1830:             */
1831:            final void setParent(ASTNode parent,
1832:                    StructuralPropertyDescriptor property) {
1833:                this .ast.modifying();
1834:                this .parent = parent;
1835:                this .location = property;
1836:            }
1837:
1838:            /**
1839:             * Removes this node from its parent. Has no effect if this node
1840:             * is unparented. If this node appears as an element of a child list
1841:             * property of its parent, then this node is removed from the
1842:             * list using <code>List.remove</code>.
1843:             * If this node appears as the value of a child property of its
1844:             * parent, then this node is detached from its parent 
1845:             * by passing <code>null</code> to the appropriate setter method;
1846:             * this operation fails if this node is in a mandatory property.
1847:             * 
1848:             * @since 3.0
1849:             */
1850:            public final void delete() {
1851:                StructuralPropertyDescriptor p = getLocationInParent();
1852:                if (p == null) {
1853:                    // node is unparented
1854:                    return;
1855:                }
1856:                if (p.isChildProperty()) {
1857:                    getParent().setStructuralProperty(this .location, null);
1858:                    return;
1859:                }
1860:                if (p.isChildListProperty()) {
1861:                    List l = (List) getParent().getStructuralProperty(
1862:                            this .location);
1863:                    l.remove(this );
1864:                }
1865:            }
1866:
1867:            /**
1868:             * Checks whether the given new child node is a node 
1869:             * in a different AST from its parent-to-be, whether it is
1870:             * already has a parent, whether adding it to its
1871:             * parent-to-be would create a cycle, and whether the child is of
1872:             * the right type. The parent-to-be is the enclosing instance.
1873:             * 
1874:             * @param node the parent-to-be node
1875:             * @param newChild the new child of the parent
1876:             * @param cycleCheck <code>true</code> if cycles are possible and need 
1877:             *   to be checked, <code>false</code> if cycles are impossible and do 
1878:             *   not need to be checked
1879:             * @param nodeType a type constraint on child nodes, or <code>null</code>
1880:             *   if no special check is required
1881:             * @exception IllegalArgumentException if:
1882:             * <ul>
1883:             * <li>the child is null</li>
1884:             * <li>the node belongs to a different AST</li>
1885:             * <li>the child has the incorrect node type</li>
1886:             * <li>the node already has a parent</li>
1887:             * <li>a cycle in would be created</li>
1888:             * </ul>
1889:             */
1890:            static void checkNewChild(ASTNode node, ASTNode newChild,
1891:                    boolean cycleCheck, Class nodeType) {
1892:                if (newChild.ast != node.ast) {
1893:                    // new child is from a different AST
1894:                    throw new IllegalArgumentException();
1895:                }
1896:                if (newChild.getParent() != null) {
1897:                    // new child currently has a different parent
1898:                    throw new IllegalArgumentException();
1899:                }
1900:                if (cycleCheck && newChild == node.getRoot()) {
1901:                    // inserting new child would create a cycle
1902:                    throw new IllegalArgumentException();
1903:                }
1904:                Class childClass = newChild.getClass();
1905:                if (nodeType != null && !nodeType.isAssignableFrom(childClass)) {
1906:                    // new child is not of the right type
1907:                    throw new ClassCastException();
1908:                }
1909:                if ((newChild.typeAndFlags & PROTECT) != 0) {
1910:                    // new child node is protected => cannot be parented
1911:                    throw new IllegalArgumentException(
1912:                            "AST node cannot be modified"); //$NON-NLS-1$
1913:                }
1914:            }
1915:
1916:            /**
1917:             * Prelude portion of the "3 step program" for replacing the
1918:             * old child of this node with another node.
1919:             * Here is the code pattern found in all AST node subclasses:
1920:             * <pre>
1921:             * ASTNode oldChild = this.foo;
1922:             * preReplaceChild(oldChild, newFoo, FOO_PROPERTY);
1923:             * this.foo = newFoo;
1924:             * postReplaceChild(oldChild, newFoo, FOO_PROPERTY);
1925:             * </pre>
1926:             * The first part (preReplaceChild) does all the precondition checks,
1927:             * reports pre-delete events, and changes parent links.
1928:             * The old child is delinked from its parent (making it a root node),
1929:             * and the new child node is linked to its parent. The new child node
1930:             * must be a root node in the same AST as its new parent, and must not
1931:             * be an ancestor of this node. All three nodes must be
1932:             * modifiable (not PROTECTED). The replace operation must fail
1933:             * atomically; so it is crucial that all precondition checks
1934:             * be done before any linking and delinking happens.
1935:             * The final part (postReplaceChild )reports post-add events.
1936:             * <p>
1937:             * This method calls <code>ast.modifying()</code> for the nodes affected.
1938:             * </p>
1939:             * 
1940:             * @param oldChild the old child of this node, or <code>null</code> if
1941:             *   there was no old child to replace
1942:             * @param newChild the new child of this node, or <code>null</code> if
1943:             *   there is no replacement child
1944:             * @param property the property descriptor of this node describing
1945:             * the relationship between node and child
1946:             * @exception RuntimeException if:
1947:             * <ul>
1948:             * <li>the node belongs to a different AST</li>
1949:             * <li>the node already has a parent</li>
1950:             * <li>a cycle in would be created</li>
1951:             * <li>any of the nodes involved are unmodifiable</li>
1952:             * </ul>
1953:             * @since 3.0
1954:             */
1955:            final void preReplaceChild(ASTNode oldChild, ASTNode newChild,
1956:                    ChildPropertyDescriptor property) {
1957:                if ((this .typeAndFlags & PROTECT) != 0) {
1958:                    // this node is protected => cannot gain or lose children
1959:                    throw new IllegalArgumentException(
1960:                            "AST node cannot be modified"); //$NON-NLS-1$
1961:                }
1962:                if (newChild != null) {
1963:                    checkNewChild(this , newChild, property.cycleRisk, null);
1964:                }
1965:                // delink old child from parent
1966:                if (oldChild != null) {
1967:                    if ((oldChild.typeAndFlags & PROTECT) != 0) {
1968:                        // old child node is protected => cannot be unparented
1969:                        throw new IllegalArgumentException(
1970:                                "AST node cannot be modified"); //$NON-NLS-1$
1971:                    }
1972:                    if (newChild != null) {
1973:                        this .ast.preReplaceChildEvent(this , oldChild, newChild,
1974:                                property);
1975:                    } else {
1976:                        this .ast.preRemoveChildEvent(this , oldChild, property);
1977:                    }
1978:                    oldChild.setParent(null, null);
1979:                } else {
1980:                    if (newChild != null) {
1981:                        this .ast.preAddChildEvent(this , newChild, property);
1982:                    }
1983:                }
1984:                // link new child to parent
1985:                if (newChild != null) {
1986:                    newChild.setParent(this , property);
1987:                    // cannot notify postAddChildEvent until parent is linked to child too
1988:                }
1989:            }
1990:
1991:            /**
1992:             * Postlude portion of the "3 step program" for replacing the
1993:             * old child of this node with another node.
1994:             * See {@link #preReplaceChild(ASTNode, ASTNode, ChildPropertyDescriptor)}
1995:             * for details.
1996:             * @since 3.0
1997:             */
1998:            final void postReplaceChild(ASTNode oldChild, ASTNode newChild,
1999:                    ChildPropertyDescriptor property) {
2000:                // link new child to parent
2001:                if (newChild != null) {
2002:                    if (oldChild != null) {
2003:                        this .ast.postReplaceChildEvent(this , oldChild,
2004:                                newChild, property);
2005:                    } else {
2006:                        this .ast.postAddChildEvent(this , newChild, property);
2007:                    }
2008:                } else {
2009:                    this .ast.postRemoveChildEvent(this , oldChild, property);
2010:                }
2011:            }
2012:
2013:            /**
2014:             * Prelude portion of the "3 step program" for changing the
2015:             * value of a simple property of this node.
2016:             * Here is the code pattern found in all AST node subclasses:
2017:             * <pre>
2018:             * preValueChange(FOO_PROPERTY);
2019:             * this.foo = newFoo;
2020:             * postValueChange(FOO_PROPERTY);
2021:             * </pre>
2022:             * The first part (preValueChange) does the precondition check
2023:             * to make sure the node is modifiable (not PROTECTED).
2024:             * The change operation must fail atomically; so it is crucial
2025:             * that the precondition checks are done before the field is
2026:             * hammered. The final part (postValueChange)reports post-change
2027:             * events.
2028:             * <p>
2029:             * This method calls <code>ast.modifying()</code> for the node affected.
2030:             * </p>
2031:             * 
2032:             * @param property the property descriptor of this node 
2033:             * @exception RuntimeException if:
2034:             * <ul>
2035:             * <li>this node is unmodifiable</li>
2036:             * </ul>
2037:             * @since 3.0
2038:             */
2039:            final void preValueChange(SimplePropertyDescriptor property) {
2040:                if ((this .typeAndFlags & PROTECT) != 0) {
2041:                    // this node is protected => cannot change valure of properties
2042:                    throw new IllegalArgumentException(
2043:                            "AST node cannot be modified"); //$NON-NLS-1$
2044:                }
2045:                this .ast.preValueChangeEvent(this , property);
2046:                this .ast.modifying();
2047:            }
2048:
2049:            /**
2050:             * Postlude portion of the "3 step program" for replacing the
2051:             * old child of this node with another node.
2052:             * See {@link #preValueChange(SimplePropertyDescriptor)} for details.
2053:             * @since 3.0
2054:             */
2055:            final void postValueChange(SimplePropertyDescriptor property) {
2056:                this .ast.postValueChangeEvent(this , property);
2057:            }
2058:
2059:            /**
2060:             * Ensures that this node is modifiable (that is, not marked PROTECTED).
2061:             * If successful, calls ast.modifying().
2062:             * @exception RuntimeException is not modifiable
2063:             */
2064:            final void checkModifiable() {
2065:                if ((this .typeAndFlags & PROTECT) != 0) {
2066:                    throw new IllegalArgumentException(
2067:                            "AST node cannot be modified"); //$NON-NLS-1$
2068:                }
2069:                this .ast.modifying();
2070:            }
2071:
2072:            /**
2073:             * Begin lazy initialization of this node.
2074:             * Here is the code pattern found in all AST
2075:             * node subclasses:
2076:             * <pre>
2077:             * if (this.foo == null) {
2078:             *    // lazy init must be thread-safe for readers
2079:             *    synchronized (this) {
2080:             *       if (this.foo == null) {
2081:             *          preLazyInit();
2082:             *          this.foo = ...; // code to create new node
2083:             *          postLazyInit(this.foo, FOO_PROPERTY);
2084:             *       }
2085:             *    }
2086:             * }
2087:             * </pre>
2088:             * @since 3.0
2089:             */
2090:            final void preLazyInit() {
2091:                // IMPORTANT: this method is called by readers
2092:                // ASTNode.this is locked at this point
2093:                this .ast.disableEvents();
2094:                // will turn events back on in postLasyInit
2095:            }
2096:
2097:            /**
2098:             * End lazy initialization of this node.
2099:             * 
2100:             * @param newChild the new child of this node, or <code>null</code> if
2101:             *   there is no replacement child
2102:             * @param property the property descriptor of this node describing
2103:             * the relationship between node and child
2104:             * @since 3.0
2105:             */
2106:            final void postLazyInit(ASTNode newChild,
2107:                    ChildPropertyDescriptor property) {
2108:                // IMPORTANT: this method is called by readers
2109:                // ASTNode.this is locked at this point
2110:                // newChild is brand new (so no chance of concurrent access)
2111:                newChild.setParent(this , property);
2112:                // turn events back on (they were turned off in corresponding preLazyInit)
2113:                this .ast.reenableEvents();
2114:            }
2115:
2116:            /**
2117:             * Returns the named property of this node, or <code>null</code> if none.
2118:             * 
2119:             * @param propertyName the property name
2120:             * @return the property value, or <code>null</code> if none
2121:             * @see #setProperty(String,Object)
2122:             */
2123:            public final Object getProperty(String propertyName) {
2124:                if (propertyName == null) {
2125:                    throw new IllegalArgumentException();
2126:                }
2127:                if (this .property1 == null) {
2128:                    // node has no properties at all
2129:                    return null;
2130:                }
2131:                if (this .property1 instanceof  String) {
2132:                    // node has only a single property
2133:                    if (propertyName.equals(this .property1)) {
2134:                        return this .property2;
2135:                    } else {
2136:                        return null;
2137:                    }
2138:                }
2139:                // otherwise node has table of properties
2140:                Map m = (Map) this .property1;
2141:                return m.get(propertyName);
2142:            }
2143:
2144:            /**
2145:             * Sets the named property of this node to the given value,
2146:             * or to <code>null</code> to clear it.
2147:             * <p>
2148:             * Clients should employ property names that are sufficiently unique
2149:             * to avoid inadvertent conflicts with other clients that might also be
2150:             * setting properties on the same node.
2151:             * </p>
2152:             * <p>
2153:             * Note that modifying a property is not considered a modification to the 
2154:             * AST itself. This is to allow clients to decorate existing nodes with 
2155:             * their own properties without jeopardizing certain things (like the 
2156:             * validity of bindings), which rely on the underlying tree remaining static.
2157:             * </p>
2158:             * 
2159:             * @param propertyName the property name
2160:             * @param data the new property value, or <code>null</code> if none
2161:             * @see #getProperty(String)
2162:             */
2163:            public final void setProperty(String propertyName, Object data) {
2164:                if (propertyName == null) {
2165:                    throw new IllegalArgumentException();
2166:                }
2167:                // N.B. DO NOT CALL ast.modifying();
2168:
2169:                if (this .property1 == null) {
2170:                    // node has no properties at all
2171:                    if (data == null) {
2172:                        // we already know this
2173:                        return;
2174:                    }
2175:                    // node gets its fist property
2176:                    this .property1 = propertyName;
2177:                    this .property2 = data;
2178:                    return;
2179:                }
2180:
2181:                if (this .property1 instanceof  String) {
2182:                    // node has only a single property
2183:                    if (propertyName.equals(this .property1)) {
2184:                        // we're in luck
2185:                        this .property2 = data;
2186:                        if (data == null) {
2187:                            // just deleted last property
2188:                            this .property1 = null;
2189:                            this .property2 = null;
2190:                        }
2191:                        return;
2192:                    }
2193:                    if (data == null) {
2194:                        // we already know this
2195:                        return;
2196:                    }
2197:                    // node already has one property - getting its second
2198:                    // convert to more flexible representation
2199:                    HashMap m = new HashMap(2);
2200:                    m.put(this .property1, this .property2);
2201:                    m.put(propertyName, data);
2202:                    this .property1 = m;
2203:                    this .property2 = null;
2204:                    return;
2205:                }
2206:
2207:                // node has two or more properties
2208:                HashMap m = (HashMap) this .property1;
2209:                if (data == null) {
2210:                    m.remove(propertyName);
2211:                    // check for just one property left
2212:                    if (m.size() == 1) {
2213:                        // convert to more efficient representation
2214:                        Map.Entry[] entries = (Map.Entry[]) m.entrySet()
2215:                                .toArray(new Map.Entry[1]);
2216:                        this .property1 = entries[0].getKey();
2217:                        this .property2 = entries[0].getValue();
2218:                    }
2219:                    return;
2220:                } else {
2221:                    m.put(propertyName, data);
2222:                    // still has two or more properties
2223:                    return;
2224:                }
2225:            }
2226:
2227:            /**
2228:             * Returns an unmodifiable table of the properties of this node with 
2229:             * non-<code>null</code> values.
2230:             * 
2231:             * @return the table of property values keyed by property name
2232:             *   (key type: <code>String</code>; value type: <code>Object</code>)
2233:             */
2234:            public final Map properties() {
2235:                if (this .property1 == null) {
2236:                    // node has no properties at all
2237:                    return UNMODIFIABLE_EMPTY_MAP;
2238:                }
2239:                if (this .property1 instanceof  String) {
2240:                    // node has a single property
2241:                    return Collections.singletonMap(this .property1,
2242:                            this .property2);
2243:                }
2244:
2245:                // node has two or more properties
2246:                if (this .property2 == null) {
2247:                    this .property2 = Collections
2248:                            .unmodifiableMap((Map) this .property1);
2249:                }
2250:                // property2 is unmodifiable wrapper for map in property1
2251:                return (Map) this .property2;
2252:            }
2253:
2254:            /**
2255:             * Returns the flags associated with this node.
2256:             * <p>
2257:             * No flags are associated with newly created nodes.
2258:             * </p>
2259:             * <p>
2260:             * The flags are the bitwise-or of individual flags.
2261:             * The following flags are currently defined:
2262:             * <ul>
2263:             * <li>{@link #MALFORMED} - indicates node is syntactically 
2264:             *   malformed</li>
2265:             * <li>{@link #ORIGINAL} - indicates original node
2266:             * created by ASTParser</li>
2267:             * <li>{@link #PROTECT} - indicates node is protected
2268:             * from further modification</li>
2269:             * <li>{@link #RECOVERED} - indicates node or a part of this node
2270:             *  is recovered from source that contains a syntax error</li>
2271:             * </ul>
2272:             * Other bit positions are reserved for future use.
2273:             * </p>
2274:             * 
2275:             * @return the bitwise-or of individual flags
2276:             * @see #setFlags(int)
2277:             */
2278:            public final int getFlags() {
2279:                return this .typeAndFlags & 0xFFFF;
2280:            }
2281:
2282:            /**
2283:             * Sets the flags associated with this node to the given value.
2284:             * <p>
2285:             * The flags are the bitwise-or of individual flags.
2286:             * The following flags are currently defined:
2287:             * <ul>
2288:             * <li>{@link #MALFORMED} - indicates node is syntactically 
2289:             *   malformed</li>
2290:             * <li>{@link #ORIGINAL} - indicates original node
2291:             * created by ASTParser</li>
2292:             * <li>{@link #PROTECT} - indicates node is protected
2293:             * from further modification</li>
2294:             * <li>{@link #RECOVERED} - indicates node or a part of this node
2295:             *  is recovered from source that contains a syntax error</li>
2296:             * </ul>
2297:             * Other bit positions are reserved for future use.
2298:             * </p>
2299:             * <p>
2300:             * Note that the flags are <em>not</em> considered a structural
2301:             * property of the node, and can be changed even if the
2302:             * node is marked as protected.
2303:             * </p>
2304:             * 
2305:             * @param flags the bitwise-or of individual flags
2306:             * @see #getFlags()
2307:             */
2308:            public final void setFlags(int flags) {
2309:                this .ast.modifying();
2310:                int old = this .typeAndFlags & 0xFFFF0000;
2311:                this .typeAndFlags = old | (flags & 0xFFFF);
2312:            }
2313:
2314:            /**
2315:             * Returns an integer value identifying the type of this concrete AST node.
2316:             * The values are small positive integers, suitable for use in switch statements.
2317:             * <p>
2318:             * For each concrete node type there is a unique node type constant (name
2319:             * and value). The unique node type constant for a concrete node type such as 
2320:             * <code>CastExpression</code> is <code>ASTNode.CAST_EXPRESSION</code>.
2321:             * </p>
2322:             * 
2323:             * @return one of the node type constants
2324:             */
2325:            public final int getNodeType() {
2326:                return this .typeAndFlags >>> 16;
2327:            }
2328:
2329:            /**
2330:             * Sets the integer value identifying the type of this concrete AST node.
2331:             * The values are small positive integers, suitable for use in switch statements.
2332:             * 
2333:             * @param nodeType one of the node type constants
2334:             */
2335:            private void setNodeType(int nodeType) {
2336:                int old = this .typeAndFlags & 0xFFFF0000;
2337:                this .typeAndFlags = old | (nodeType << 16);
2338:            }
2339:
2340:            /**
2341:             * Returns an integer value identifying the type of this concrete AST node.
2342:             * <p>
2343:             * This internal method is implemented in each of the
2344:             * concrete node subclasses.
2345:             * </p>
2346:             * 
2347:             * @return one of the node type constants
2348:             */
2349:            abstract int getNodeType0();
2350:
2351:            /**
2352:             * The <code>ASTNode</code> implementation of this <code>Object</code>
2353:             * method uses object identity (==). Use <code>subtreeMatch</code> to
2354:             * compare two subtrees for equality.
2355:             * 
2356:             * @param obj {@inheritDoc}
2357:             * @return {@inheritDoc}
2358:             * @see #subtreeMatch(ASTMatcher matcher, Object other)
2359:             */
2360:            public final boolean equals(Object obj) {
2361:                return this  == obj; // equivalent to Object.equals
2362:            }
2363:
2364:            /*
2365:             * (non-Javadoc)
2366:             * This makes it consistent with the fact that a equals methods has been provided.
2367:             * @see java.lang.Object#hashCode()
2368:             */
2369:            public final int hashCode() {
2370:                return super .hashCode();
2371:            }
2372:
2373:            /**
2374:             * Returns whether the subtree rooted at the given node matches the
2375:             * given other object as decided by the given matcher.
2376:             * 
2377:             * @param matcher the matcher
2378:             * @param other the other object, or <code>null</code>
2379:             * @return <code>true</code> if the subtree matches, or 
2380:             * <code>false</code> if they do not match
2381:             */
2382:            public final boolean subtreeMatch(ASTMatcher matcher, Object other) {
2383:                return subtreeMatch0(matcher, other);
2384:            }
2385:
2386:            /**
2387:             * Returns whether the subtree rooted at the given node matches the
2388:             * given other object as decided by the given matcher.
2389:             * <p>
2390:             * This internal method is implemented in each of the
2391:             * concrete node subclasses.
2392:             * </p>
2393:             * 
2394:             * @param matcher the matcher
2395:             * @param other the other object, or <code>null</code>
2396:             * @return <code>true</code> if the subtree matches, or 
2397:             * <code>false</code> if they do not match
2398:             */
2399:            abstract boolean subtreeMatch0(ASTMatcher matcher, Object other);
2400:
2401:            /**
2402:             * Returns a deep copy of the subtree of AST nodes rooted at the
2403:             * given node. The resulting nodes are owned by the given AST,
2404:             * which may be different from the ASTs of the given node. 
2405:             * Even if the given node has a parent, the result node will be unparented.
2406:             * <p>
2407:             * Source range information on the original nodes is automatically copied to the new
2408:             * nodes. Client properties (<code>properties</code>) are not carried over.
2409:             * </p>
2410:             * <p>
2411:             * The node's <code>AST</code> and the target <code>AST</code> must support
2412:             * the same API level.
2413:             * </p>
2414:             * 
2415:             * @param target the AST that is to own the nodes in the result
2416:             * @param node the node to copy, or <code>null</code> if none
2417:             * @return the copied node, or <code>null</code> if <code>node</code>
2418:             *    is <code>null</code>
2419:             */
2420:            public static ASTNode copySubtree(AST target, ASTNode node) {
2421:                if (node == null) {
2422:                    return null;
2423:                }
2424:                if (target == null) {
2425:                    throw new IllegalArgumentException();
2426:                }
2427:                if (target.apiLevel() != node.getAST().apiLevel()) {
2428:                    throw new UnsupportedOperationException();
2429:                }
2430:                ASTNode newNode = node.clone(target);
2431:                return newNode;
2432:            }
2433:
2434:            /**
2435:             * Returns a deep copy of the subtrees of AST nodes rooted at the
2436:             * given list of nodes. The resulting nodes are owned by the given AST,
2437:             * which may be different from the ASTs of the nodes in the list. 
2438:             * Even if the nodes in the list have parents, the nodes in the result
2439:             * will be unparented.
2440:             * <p>
2441:             * Source range information on the original nodes is automatically copied to the new
2442:             * nodes. Client properties (<code>properties</code>) are not carried over.
2443:             * </p>
2444:             * 
2445:             * @param target the AST that is to own the nodes in the result
2446:             * @param nodes the list of nodes to copy
2447:             *    (element type: <code>ASTNode</code>)
2448:             * @return the list of copied subtrees
2449:             *    (element type: <code>ASTNode</code>)
2450:             */
2451:            public static List copySubtrees(AST target, List nodes) {
2452:                List result = new ArrayList(nodes.size());
2453:                for (Iterator it = nodes.iterator(); it.hasNext();) {
2454:                    ASTNode oldNode = (ASTNode) it.next();
2455:                    ASTNode newNode = oldNode.clone(target);
2456:                    result.add(newNode);
2457:                }
2458:                return result;
2459:            }
2460:
2461:            /**
2462:             * Returns a deep copy of the subtree of AST nodes rooted at this node.
2463:             * The resulting nodes are owned by the given AST, which may be different
2464:             * from the AST of this node. Even if this node has a parent, the 
2465:             * result node will be unparented.
2466:             * <p>
2467:             * This method reports pre- and post-clone events, and dispatches
2468:             * to <code>clone0(AST)</code> which is reimplemented in node subclasses.
2469:             * </p>
2470:             * 
2471:             * @param target the AST that is to own the nodes in the result
2472:             * @return the root node of the copies subtree
2473:             */
2474:            final ASTNode clone(AST target) {
2475:                this .ast.preCloneNodeEvent(this );
2476:                ASTNode c = this .clone0(target);
2477:                this .ast.postCloneNodeEvent(this , c);
2478:                return c;
2479:            }
2480:
2481:            /**
2482:             * Returns a deep copy of the subtree of AST nodes rooted at this node.
2483:             * The resulting nodes are owned by the given AST, which may be different
2484:             * from the AST of this node. Even if this node has a parent, the 
2485:             * result node will be unparented.
2486:             * <p>
2487:             * This method must be implemented in subclasses.
2488:             * </p>
2489:             * <p>
2490:             * This method does not report pre- and post-clone events.
2491:             * All callers should instead call <code>clone(AST)</code>
2492:             * to ensure that pre- and post-clone events are reported.
2493:             * </p>
2494:             * <p>
2495:             * N.B. This method is package-private, so that the implementations
2496:             * of this method in each of the concrete AST node types do not
2497:             * clutter up the API doc. 
2498:             * </p>
2499:             * 
2500:             * @param target the AST that is to own the nodes in the result
2501:             * @return the root node of the copies subtree
2502:             */
2503:            abstract ASTNode clone0(AST target);
2504:
2505:            /**
2506:             * Accepts the given visitor on a visit of the current node.
2507:             * 
2508:             * @param visitor the visitor object
2509:             * @exception IllegalArgumentException if the visitor is null
2510:             */
2511:            public final void accept(ASTVisitor visitor) {
2512:                if (visitor == null) {
2513:                    throw new IllegalArgumentException();
2514:                }
2515:                // begin with the generic pre-visit
2516:                visitor.preVisit(this );
2517:                // dynamic dispatch to internal method for type-specific visit/endVisit
2518:                accept0(visitor);
2519:                // end with the generic post-visit
2520:                visitor.postVisit(this );
2521:            }
2522:
2523:            /**
2524:             * Accepts the given visitor on a type-specific visit of the current node.
2525:             * This method must be implemented in all concrete AST node types.
2526:             * <p>
2527:             * General template for implementation on each concrete ASTNode class:
2528:             * <pre>
2529:             * <code>
2530:             * boolean visitChildren = visitor.visit(this);
2531:             * if (visitChildren) {
2532:             *    // visit children in normal left to right reading order
2533:             *    acceptChild(visitor, getProperty1());
2534:             *    acceptChildren(visitor, rawListProperty);
2535:             *    acceptChild(visitor, getProperty2());
2536:             * }
2537:             * visitor.endVisit(this);
2538:             * </code>
2539:             * </pre>
2540:             * Note that the caller (<code>accept</code>) take cares of invoking
2541:             * <code>visitor.preVisit(this)</code> and <code>visitor.postVisit(this)</code>.
2542:             * </p>
2543:             * 
2544:             * @param visitor the visitor object
2545:             */
2546:            abstract void accept0(ASTVisitor visitor);
2547:
2548:            /**
2549:             * Accepts the given visitor on a visit of the current node.
2550:             * <p>
2551:             * This method should be used by the concrete implementations of
2552:             * <code>accept0</code> to traverse optional properties. Equivalent
2553:             * to <code>child.accept(visitor)</code> if <code>child</code>
2554:             * is not <code>null</code>.
2555:             * </p>
2556:             * 
2557:             * @param visitor the visitor object
2558:             * @param child the child AST node to dispatch too, or <code>null</code>
2559:             *    if none
2560:             */
2561:            final void acceptChild(ASTVisitor visitor, ASTNode child) {
2562:                if (child == null) {
2563:                    return;
2564:                }
2565:                child.accept(visitor);
2566:            }
2567:
2568:            /**
2569:             * Accepts the given visitor on a visit of the given live list of
2570:             * child nodes. 
2571:             * <p>
2572:             * This method must be used by the concrete implementations of
2573:             * <code>accept</code> to traverse list-values properties; it
2574:             * encapsulates the proper handling of on-the-fly changes to the list.
2575:             * </p>
2576:             * 
2577:             * @param visitor the visitor object
2578:             * @param children the child AST node to dispatch too, or <code>null</code>
2579:             *    if none
2580:             */
2581:            final void acceptChildren(ASTVisitor visitor,
2582:                    ASTNode.NodeList children) {
2583:                // use a cursor to keep track of where we are up to
2584:                // (the list may be changing under foot)
2585:                NodeList.Cursor cursor = children.newCursor();
2586:                try {
2587:                    while (cursor.hasNext()) {
2588:                        ASTNode child = (ASTNode) cursor.next();
2589:                        child.accept(visitor);
2590:                    }
2591:                } finally {
2592:                    children.releaseCursor(cursor);
2593:                }
2594:            }
2595:
2596:            /**
2597:             * Returns the character index into the original source file indicating
2598:             * where the source fragment corresponding to this node begins.
2599:             * <p>
2600:             * The parser supplies useful well-defined source ranges to the nodes it creates.
2601:             * See {@link ASTParser#setKind(int)} for details
2602:             * on precisely where source ranges begin and end.
2603:             * </p>
2604:             * 
2605:             * @return the 0-based character index, or <code>-1</code>
2606:             *    if no source position information is recorded for this node
2607:             * @see #getLength()
2608:             * @see ASTParser
2609:             */
2610:            public final int getStartPosition() {
2611:                return this .startPosition;
2612:            }
2613:
2614:            /**
2615:             * Returns the length in characters of the original source file indicating
2616:             * where the source fragment corresponding to this node ends.
2617:             * <p>
2618:             * The parser supplies useful well-defined source ranges to the nodes it creates.
2619:             * See {@link ASTParser#setKind(int)} methods for details
2620:             * on precisely where source ranges begin and end.
2621:             * </p>
2622:             * 
2623:             * @return a (possibly 0) length, or <code>0</code>
2624:             *    if no source position information is recorded for this node
2625:             * @see #getStartPosition()
2626:             * @see ASTParser
2627:             */
2628:            public final int getLength() {
2629:                return this .length;
2630:            }
2631:
2632:            /**
2633:             * Sets the source range of the original source file where the source
2634:             * fragment corresponding to this node was found.
2635:             * <p>
2636:             * See {@link ASTParser#setKind(int)} for details
2637:             * on precisely where source ranges are supposed to begin and end.
2638:             * </p>
2639:             * 
2640:             * @param startPosition a 0-based character index, 
2641:             *    or <code>-1</code> if no source position information is 
2642:             *    available for this node
2643:             * @param length a (possibly 0) length, 
2644:             *    or <code>0</code> if no source position information is recorded 
2645:             *    for this node
2646:             * @see #getStartPosition()
2647:             * @see #getLength()
2648:             * @see ASTParser
2649:             */
2650:            public final void setSourceRange(int startPosition, int length) {
2651:                if (startPosition >= 0 && length < 0) {
2652:                    throw new IllegalArgumentException();
2653:                }
2654:                if (startPosition < 0 && length != 0) {
2655:                    throw new IllegalArgumentException();
2656:                }
2657:                // source positions are not considered a structural property
2658:                // but we protect them nevertheless
2659:                checkModifiable();
2660:                this .startPosition = startPosition;
2661:                this .length = length;
2662:            }
2663:
2664:            /**
2665:             * Returns a string representation of this node suitable for debugging
2666:             * purposes only.
2667:             * 
2668:             * @return a debug string 
2669:             */
2670:            public final String toString() {
2671:                StringBuffer buffer = new StringBuffer();
2672:                int p = buffer.length();
2673:                try {
2674:                    appendDebugString(buffer);
2675:                } catch (RuntimeException e) {
2676:                    // since debugger sometimes call toString methods, problems can easily happen when
2677:                    // toString is called on an instance that is being initialized
2678:                    buffer.setLength(p);
2679:                    buffer.append("!"); //$NON-NLS-1$
2680:                    buffer.append(standardToString());
2681:                }
2682:                return buffer.toString();
2683:            }
2684:
2685:            /**
2686:             * Returns the string representation of this node produced by the standard
2687:             * <code>Object.toString</code> method.
2688:             * 
2689:             * @return a debug string 
2690:             */
2691:            final String standardToString() {
2692:                return super .toString();
2693:            }
2694:
2695:            /**
2696:             * Appends a debug representation of this node to the given string buffer.
2697:             * <p>
2698:             * The <code>ASTNode</code> implementation of this method prints out the entire 
2699:             * subtree. Subclasses may override to provide a more succinct representation.
2700:             * </p>
2701:             * 
2702:             * @param buffer the string buffer to append to
2703:             */
2704:            void appendDebugString(StringBuffer buffer) {
2705:                // print the subtree by default
2706:                appendPrintString(buffer);
2707:            }
2708:
2709:            /**
2710:             * Appends a standard Java source code representation of this subtree to the given
2711:             * string buffer.
2712:             * 
2713:             * @param buffer the string buffer to append to
2714:             */
2715:            final void appendPrintString(StringBuffer buffer) {
2716:                NaiveASTFlattener printer = new NaiveASTFlattener();
2717:                this .accept(printer);
2718:                buffer.append(printer.getResult());
2719:            }
2720:
2721:            /**
2722:             * Estimate of size of an object header in bytes.
2723:             */
2724:            static final int HEADERS = 12;
2725:
2726:            /**
2727:             * Approximate base size of an AST node instance in bytes, 
2728:             * including object header and instance fields.
2729:             * That is, HEADERS + (# instance vars in ASTNode)*4.
2730:             */
2731:            static final int BASE_NODE_SIZE = HEADERS + 7 * 4;
2732:
2733:            /**
2734:             * Returns an estimate of the memory footprint, in bytes,
2735:             * of the given string.
2736:             * 
2737:             * @param string the string to measure, or <code>null</code>
2738:             * @return the size of this string object in bytes, or
2739:             *   0 if the string is <code>null</code>
2740:             * @since 3.0
2741:             */
2742:            static int stringSize(String string) {
2743:                int size = 0;
2744:                if (string != null) {
2745:                    // Strings usually have 4 instance fields, one of which is a char[]
2746:                    size += HEADERS + 4 * 4;
2747:                    // char[] has 2 bytes per character
2748:                    size += HEADERS + 2 * string.length();
2749:                }
2750:                return size;
2751:            }
2752:
2753:            /**
2754:             * Returns an estimate of the memory footprint in bytes of the entire 
2755:             * subtree rooted at this node.
2756:             * 
2757:             * @return the size of this subtree in bytes
2758:             */
2759:            public final int subtreeBytes() {
2760:                return treeSize();
2761:            }
2762:
2763:            /**
2764:             * Returns an estimate of the memory footprint in bytes of the entire 
2765:             * subtree rooted at this node.
2766:             * <p>
2767:             * N.B. This method is package-private, so that the implementations
2768:             * of this method in each of the concrete AST node types do not
2769:             * clutter up the API doc.
2770:             * </p>
2771:             * 
2772:             * @return the size of this subtree in bytes
2773:             */
2774:            abstract int treeSize();
2775:
2776:            /**
2777:             * Returns an estimate of the memory footprint of this node in bytes.
2778:             * The estimate does not include the space occupied by child nodes.
2779:             * 
2780:             * @return the size of this node in bytes
2781:             */
2782:            abstract int memSize();
2783:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.