/*******************************************************************************
* Copyright (c) 2000, 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.core.dom;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Abstract superclass of all Abstract Syntax Tree (AST) node types.
*
* An AST node represents a Java source code construct, such
* as a name, type, expression, statement, or declaration.
*
*
* Each AST node belongs to a unique AST instance, called the owning AST.
* The children of an AST node always have the same owner as their parent node.
* If a node from one AST is to be added to a different AST, the subtree must
* be cloned first to ensure that the added nodes have the correct owning AST.
*
*
* When an AST node is part of an AST, it has a unique parent node.
* Clients can navigate upwards, from child to parent, as well as downwards,
* from parent to child. Newly created nodes are unparented. When an
* unparented node is set as a child of a node (using a
* setCHILD method), its parent link is set automatically
* and the parent link of the former child is set to null.
* For nodes with properties that include a list of children (for example,
* Block whose statements property is a list
* of statements), adding or removing an element to/for the list property
* automatically updates the parent links. These lists support the
* List.set method; however, the constraint that the same
* node cannot appear more than once means that this method cannot be used
* to swap elements without first removing the node.
*
*
* ASTs must not contain cycles. All operations that could create a cycle
* detect this possibility and fail.
*
*
* ASTs do not contain "holes" (missing subtrees). If a node is required to
* have a certain property, a syntactically plausible initial value is
* always supplied.
*
*
* The hierarchy of AST node types has some convenient groupings marked
* by abstract superclasses:
*
*
expressions - Expression
*
names - Name (a sub-kind of expression)
*
statements - Statement
*
types - Type
*
type body declarations - BodyDeclaration
*
*
*
* Abstract syntax trees may be hand constructed by clients, using the
* newTYPE factory methods (see AST) to
* create new nodes, and the various setCHILD methods
* to connect them together.
*
*
* The class {@link ASTParser} parses a string
* containing a Java source code and returns an abstract syntax tree
* for it. The resulting nodes carry source ranges relating the node back to
* the original source characters. The source range covers the construct
* as a whole.
*
*
* Each AST node carries bit flags, which may convey additional information about
* the node. For instance, the parser uses a flag to indicate a syntax error.
* Newly created nodes have no flags set.
*
*
* Each AST node is capable of carrying an open-ended collection of
* client-defined properties. Newly created nodes have none.
* getProperty and setProperty are used to access
* these properties.
*
*
* AST nodes are thread-safe for readers provided there are no active writers.
* If one thread is modifying an AST, including creating new nodes or cloning
* existing ones, it is not safe for another thread to read, visit,
* write, create, or clone any of the nodes on the same AST.
* When synchronization is required, consider using the common AST
* object that owns the node; that is, use
* synchronize (node.getAST()) {...}.
*
*
* ASTs also support the visitor pattern; see the class ASTVisitor
* for details.
*
*
* Compilation units created by ASTParser from a
* source document can be serialized after arbitrary modifications
* with minimal loss of original formatting. See
* {@link CompilationUnit#recordModifications()} for details.
* See also {@link org.eclipse.jdt.core.dom.rewrite.ASTRewrite} for
* an alternative way to describe and serialize changes to a
* read-only AST.
*
*
* @see ASTParser
* @see ASTVisitor
* @since 2.0
*/
public abstract class ASTNode {
/*
* INSTRUCTIONS FOR ADDING NEW CONCRETE AST NODE TYPES
*
* There are several things that need to be changed when a
* new concrete AST node type (call it "FooBar"):
*
* 1. Create the FooBar AST node type class.
* The most effective way to do this is to copy a similar
* existing concrete node class to get a template that
* includes all the framework methods that must be implemented.
*
* 2. Add node type constant ASTNode.FOO_BAR.
* Node constants are numbered consecutively. Add the
* constant after the existing ones.
*
* 3. Add entry to ASTNode.nodeClassForType(int).
*
* 4. Add AST.newFooBar() factory method.
*
* 5. Add ASTVisitor.visit(FooBar) and endVisit(FooBar) methods.
*
* 6. Add ASTMatcher.match(FooBar,Object) method.
*
* 7. Ensure that SimpleName.isDeclaration() covers FooBar
* nodes if required.
*
* 8. Add NaiveASTFlattener.visit(FooBar) method to illustrate
* how these nodes should be serialized.
*
* 9. Update the AST test suites.
*
* The next steps are to update AST.parse* to start generating
* the new type of nodes, and ASTRewrite to serialize them back out.
*/
/**
* Node type constant indicating a node of type
* AnonymousClassDeclaration.
* @see AnonymousClassDeclaration
*/
public static final int ANONYMOUS_CLASS_DECLARATION = 1;
/**
* Node type constant indicating a node of type
* ArrayAccess.
* @see ArrayAccess
*/
public static final int ARRAY_ACCESS = 2;
/**
* Node type constant indicating a node of type
* ArrayCreation.
* @see ArrayCreation
*/
public static final int ARRAY_CREATION = 3;
/**
* Node type constant indicating a node of type
* ArrayInitializer.
* @see ArrayInitializer
*/
public static final int ARRAY_INITIALIZER = 4;
/**
* Node type constant indicating a node of type
* ArrayType.
* @see ArrayType
*/
public static final int ARRAY_TYPE = 5;
/**
* Node type constant indicating a node of type
* AssertStatement.
* @see AssertStatement
*/
public static final int ASSERT_STATEMENT = 6;
/**
* Node type constant indicating a node of type
* Assignment.
* @see Assignment
*/
public static final int ASSIGNMENT = 7;
/**
* Node type constant indicating a node of type
* Block.
* @see Block
*/
public static final int BLOCK = 8;
/**
* Node type constant indicating a node of type
* BooleanLiteral.
* @see BooleanLiteral
*/
public static final int BOOLEAN_LITERAL = 9;
/**
* Node type constant indicating a node of type
* BreakStatement.
* @see BreakStatement
*/
public static final int BREAK_STATEMENT = 10;
/**
* Node type constant indicating a node of type
* CastExpression.
* @see CastExpression
*/
public static final int CAST_EXPRESSION = 11;
/**
* Node type constant indicating a node of type
* CatchClause.
* @see CatchClause
*/
public static final int CATCH_CLAUSE = 12;
/**
* Node type constant indicating a node of type
* CharacterLiteral.
* @see CharacterLiteral
*/
public static final int CHARACTER_LITERAL = 13;
/**
* Node type constant indicating a node of type
* ClassInstanceCreation.
* @see ClassInstanceCreation
*/
public static final int CLASS_INSTANCE_CREATION = 14;
/**
* Node type constant indicating a node of type
* CompilationUnit.
* @see CompilationUnit
*/
public static final int COMPILATION_UNIT = 15;
/**
* Node type constant indicating a node of type
* ConditionalExpression.
* @see ConditionalExpression
*/
public static final int CONDITIONAL_EXPRESSION = 16;
/**
* Node type constant indicating a node of type
* ConstructorInvocation.
* @see ConstructorInvocation
*/
public static final int CONSTRUCTOR_INVOCATION = 17;
/**
* Node type constant indicating a node of type
* ContinueStatement.
* @see ContinueStatement
*/
public static final int CONTINUE_STATEMENT = 18;
/**
* Node type constant indicating a node of type
* DoStatement.
* @see DoStatement
*/
public static final int DO_STATEMENT = 19;
/**
* Node type constant indicating a node of type
* EmptyStatement.
* @see EmptyStatement
*/
public static final int EMPTY_STATEMENT = 20;
/**
* Node type constant indicating a node of type
* ExpressionStatement.
* @see ExpressionStatement
*/
public static final int EXPRESSION_STATEMENT = 21;
/**
* Node type constant indicating a node of type
* FieldAccess.
* @see FieldAccess
*/
public static final int FIELD_ACCESS = 22;
/**
* Node type constant indicating a node of type
* FieldDeclaration.
* @see FieldDeclaration
*/
public static final int FIELD_DECLARATION = 23;
/**
* Node type constant indicating a node of type
* ForStatement.
* @see ForStatement
*/
public static final int FOR_STATEMENT = 24;
/**
* Node type constant indicating a node of type
* IfStatement.
* @see IfStatement
*/
public static final int IF_STATEMENT = 25;
/**
* Node type constant indicating a node of type
* ImportDeclaration.
* @see ImportDeclaration
*/
public static final int IMPORT_DECLARATION = 26;
/**
* Node type constant indicating a node of type
* InfixExpression.
* @see InfixExpression
*/
public static final int INFIX_EXPRESSION = 27;
/**
* Node type constant indicating a node of type
* Initializer.
* @see Initializer
*/
public static final int INITIALIZER = 28;
/**
* Node type constant indicating a node of type
* Javadoc.
* @see Javadoc
*/
public static final int JAVADOC = 29;
/**
* Node type constant indicating a node of type
* LabeledStatement.
* @see LabeledStatement
*/
public static final int LABELED_STATEMENT = 30;
/**
* Node type constant indicating a node of type
* MethodDeclaration.
* @see MethodDeclaration
*/
public static final int METHOD_DECLARATION = 31;
/**
* Node type constant indicating a node of type
* MethodInvocation.
* @see MethodInvocation
*/
public static final int METHOD_INVOCATION = 32;
/**
* Node type constant indicating a node of type
* NullLiteral.
* @see NullLiteral
*/
public static final int NULL_LITERAL = 33;
/**
* Node type constant indicating a node of type
* NumberLiteral.
* @see NumberLiteral
*/
public static final int NUMBER_LITERAL = 34;
/**
* Node type constant indicating a node of type
* PackageDeclaration.
* @see PackageDeclaration
*/
public static final int PACKAGE_DECLARATION = 35;
/**
* Node type constant indicating a node of type
* ParenthesizedExpression.
* @see ParenthesizedExpression
*/
public static final int PARENTHESIZED_EXPRESSION = 36;
/**
* Node type constant indicating a node of type
* PostfixExpression.
* @see PostfixExpression
*/
public static final int POSTFIX_EXPRESSION = 37;
/**
* Node type constant indicating a node of type
* PrefixExpression.
* @see PrefixExpression
*/
public static final int PREFIX_EXPRESSION = 38;
/**
* Node type constant indicating a node of type
* PrimitiveType.
* @see PrimitiveType
*/
public static final int PRIMITIVE_TYPE = 39;
/**
* Node type constant indicating a node of type
* QualifiedName.
* @see QualifiedName
*/
public static final int QUALIFIED_NAME = 40;
/**
* Node type constant indicating a node of type
* ReturnStatement.
* @see ReturnStatement
*/
public static final int RETURN_STATEMENT = 41;
/**
* Node type constant indicating a node of type
* SimpleName.
* @see SimpleName
*/
public static final int SIMPLE_NAME = 42;
/**
* Node type constant indicating a node of type
* SimpleType.
* @see SimpleType
*/
public static final int SIMPLE_TYPE = 43;
/**
* Node type constant indicating a node of type
* SingleVariableDeclaration.
* @see SingleVariableDeclaration
*/
public static final int SINGLE_VARIABLE_DECLARATION = 44;
/**
* Node type constant indicating a node of type
* StringLiteral.
* @see StringLiteral
*/
public static final int STRING_LITERAL = 45;
/**
* Node type constant indicating a node of type
* SuperConstructorInvocation.
* @see SuperConstructorInvocation
*/
public static final int SUPER_CONSTRUCTOR_INVOCATION = 46;
/**
* Node type constant indicating a node of type
* SuperFieldAccess.
* @see SuperFieldAccess
*/
public static final int SUPER_FIELD_ACCESS = 47;
/**
* Node type constant indicating a node of type
* SuperMethodInvocation.
* @see SuperMethodInvocation
*/
public static final int SUPER_METHOD_INVOCATION = 48;
/**
* Node type constant indicating a node of type
* SwitchCase.
* @see SwitchCase
*/
public static final int SWITCH_CASE = 49;
/**
* Node type constant indicating a node of type
* SwitchStatement.
* @see SwitchStatement
*/
public static final int SWITCH_STATEMENT = 50;
/**
* Node type constant indicating a node of type
* SynchronizedStatement.
* @see SynchronizedStatement
*/
public static final int SYNCHRONIZED_STATEMENT = 51;
/**
* Node type constant indicating a node of type
* ThisExpression.
* @see ThisExpression
*/
public static final int THIS_EXPRESSION = 52;
/**
* Node type constant indicating a node of type
* ThrowStatement.
* @see ThrowStatement
*/
public static final int THROW_STATEMENT = 53;
/**
* Node type constant indicating a node of type
* TryStatement.
* @see TryStatement
*/
public static final int TRY_STATEMENT = 54;
/**
* Node type constant indicating a node of type
* TypeDeclaration.
* @see TypeDeclaration
*/
public static final int TYPE_DECLARATION = 55;
/**
* Node type constant indicating a node of type
* TypeDeclarationStatement.
* @see TypeDeclarationStatement
*/
public static final int TYPE_DECLARATION_STATEMENT = 56;
/**
* Node type constant indicating a node of type
* TypeLiteral.
* @see TypeLiteral
*/
public static final int TYPE_LITERAL = 57;
/**
* Node type constant indicating a node of type
* VariableDeclarationExpression.
* @see VariableDeclarationExpression
*/
public static final int VARIABLE_DECLARATION_EXPRESSION = 58;
/**
* Node type constant indicating a node of type
* VariableDeclarationFragment.
* @see VariableDeclarationFragment
*/
public static final int VARIABLE_DECLARATION_FRAGMENT = 59;
/**
* Node type constant indicating a node of type
* VariableDeclarationStatement.
* @see VariableDeclarationStatement
*/
public static final int VARIABLE_DECLARATION_STATEMENT = 60;
/**
* Node type constant indicating a node of type
* WhileStatement.
* @see WhileStatement
*/
public static final int WHILE_STATEMENT = 61;
/**
* Node type constant indicating a node of type
* InstanceofExpression.
* @see InstanceofExpression
*/
public static final int INSTANCEOF_EXPRESSION = 62;
/**
* Node type constant indicating a node of type
* LineComment.
* @see LineComment
* @since 3.0
*/
public static final int LINE_COMMENT = 63;
/**
* Node type constant indicating a node of type
* BlockComment.
* @see BlockComment
* @since 3.0
*/
public static final int BLOCK_COMMENT = 64;
/**
* Node type constant indicating a node of type
* TagElement.
* @see TagElement
* @since 3.0
*/
public static final int TAG_ELEMENT = 65;
/**
* Node type constant indicating a node of type
* TextElement.
* @see TextElement
* @since 3.0
*/
public static final int TEXT_ELEMENT = 66;
/**
* Node type constant indicating a node of type
* MemberRef.
* @see MemberRef
* @since 3.0
*/
public static final int MEMBER_REF = 67;
/**
* Node type constant indicating a node of type
* MethodRef.
* @see MethodRef
* @since 3.0
*/
public static final int METHOD_REF = 68;
/**
* Node type constant indicating a node of type
* MethodRefParameter.
* @see MethodRefParameter
* @since 3.0
*/
public static final int METHOD_REF_PARAMETER = 69;
/**
* Node type constant indicating a node of type
* EnhancedForStatement.
* @see EnhancedForStatement
* @since 3.1
*/
public static final int ENHANCED_FOR_STATEMENT = 70;
/**
* Node type constant indicating a node of type
* EnumDeclaration.
* @see EnumDeclaration
* @since 3.1
*/
public static final int ENUM_DECLARATION = 71;
/**
* Node type constant indicating a node of type
* EnumConstantDeclaration.
* @see EnumConstantDeclaration
* @since 3.1
*/
public static final int ENUM_CONSTANT_DECLARATION = 72;
/**
* Node type constant indicating a node of type
* TypeParameter.
* @see TypeParameter
* @since 3.1
*/
public static final int TYPE_PARAMETER = 73;
/**
* Node type constant indicating a node of type
* ParameterizedType.
* @see ParameterizedType
* @since 3.1
*/
public static final int PARAMETERIZED_TYPE = 74;
/**
* Node type constant indicating a node of type
* QualifiedType.
* @see QualifiedType
* @since 3.1
*/
public static final int QUALIFIED_TYPE = 75;
/**
* Node type constant indicating a node of type
* WildcardType.
* @see WildcardType
* @since 3.1
*/
public static final int WILDCARD_TYPE = 76;
/**
* Node type constant indicating a node of type
* NormalAnnotation.
* @see NormalAnnotation
* @since 3.1
*/
public static final int NORMAL_ANNOTATION = 77;
/**
* Node type constant indicating a node of type
* MarkerAnnotation.
* @see MarkerAnnotation
* @since 3.1
*/
public static final int MARKER_ANNOTATION = 78;
/**
* Node type constant indicating a node of type
* SingleMemberAnnotation.
* @see SingleMemberAnnotation
* @since 3.1
*/
public static final int SINGLE_MEMBER_ANNOTATION = 79;
/**
* Node type constant indicating a node of type
* MemberValuePair.
* @see MemberValuePair
* @since 3.1
*/
public static final int MEMBER_VALUE_PAIR = 80;
/**
* Node type constant indicating a node of type
* AnnotationTypeDeclaration.
* @see AnnotationTypeDeclaration
* @since 3.1
*/
public static final int ANNOTATION_TYPE_DECLARATION = 81;
/**
* Node type constant indicating a node of type
* AnnotationTypeMemberDeclaration.
* @see AnnotationTypeMemberDeclaration
* @since 3.1
*/
public static final int ANNOTATION_TYPE_MEMBER_DECLARATION = 82;
/**
* Node type constant indicating a node of type
* Modifier.
* @see Modifier
* @since 3.1
*/
public static final int MODIFIER = 83;
/**
* Returns the node class for the corresponding node type.
*
* @param nodeType AST node type
* @return the corresponding ASTNode subclass
* @exception IllegalArgumentException if nodeType is
* not a legal AST node type
* @see #getNodeType()
* @since 3.0
*/
public static Class nodeClassForType(int nodeType) {
switch (nodeType) {
case ANNOTATION_TYPE_DECLARATION :
return AnnotationTypeDeclaration.class;
case ANNOTATION_TYPE_MEMBER_DECLARATION :
return AnnotationTypeMemberDeclaration.class;
case ANONYMOUS_CLASS_DECLARATION :
return AnonymousClassDeclaration.class;
case ARRAY_ACCESS :
return ArrayAccess.class;
case ARRAY_CREATION :
return ArrayCreation.class;
case ARRAY_INITIALIZER :
return ArrayInitializer.class;
case ARRAY_TYPE :
return ArrayType.class;
case ASSERT_STATEMENT :
return AssertStatement.class;
case ASSIGNMENT :
return Assignment.class;
case BLOCK :
return Block.class;
case BLOCK_COMMENT :
return BlockComment.class;
case BOOLEAN_LITERAL :
return BooleanLiteral.class;
case BREAK_STATEMENT :
return BreakStatement.class;
case CAST_EXPRESSION :
return CastExpression.class;
case CATCH_CLAUSE :
return CatchClause.class;
case CHARACTER_LITERAL :
return CharacterLiteral.class;
case CLASS_INSTANCE_CREATION :
return ClassInstanceCreation.class;
case COMPILATION_UNIT :
return CompilationUnit.class;
case CONDITIONAL_EXPRESSION :
return ConditionalExpression.class;
case CONSTRUCTOR_INVOCATION :
return ConstructorInvocation.class;
case CONTINUE_STATEMENT :
return ContinueStatement.class;
case DO_STATEMENT :
return DoStatement.class;
case EMPTY_STATEMENT :
return EmptyStatement.class;
case ENHANCED_FOR_STATEMENT :
return EnhancedForStatement.class;
case ENUM_CONSTANT_DECLARATION :
return EnumConstantDeclaration.class;
case ENUM_DECLARATION :
return EnumDeclaration.class;
case EXPRESSION_STATEMENT :
return ExpressionStatement.class;
case FIELD_ACCESS :
return FieldAccess.class;
case FIELD_DECLARATION :
return FieldDeclaration.class;
case FOR_STATEMENT :
return ForStatement.class;
case IF_STATEMENT :
return IfStatement.class;
case IMPORT_DECLARATION :
return ImportDeclaration.class;
case INFIX_EXPRESSION :
return InfixExpression.class;
case INITIALIZER :
return Initializer.class;
case INSTANCEOF_EXPRESSION :
return InstanceofExpression.class;
case JAVADOC :
return Javadoc.class;
case LABELED_STATEMENT :
return LabeledStatement.class;
case LINE_COMMENT :
return LineComment.class;
case MARKER_ANNOTATION :
return MarkerAnnotation.class;
case MEMBER_REF :
return MemberRef.class;
case MEMBER_VALUE_PAIR :
return MemberValuePair.class;
case METHOD_DECLARATION :
return MethodDeclaration.class;
case METHOD_INVOCATION :
return MethodInvocation.class;
case METHOD_REF :
return MethodRef.class;
case METHOD_REF_PARAMETER :
return MethodRefParameter.class;
case MODIFIER :
return Modifier.class;
case NORMAL_ANNOTATION :
return NormalAnnotation.class;
case NULL_LITERAL :
return NullLiteral.class;
case NUMBER_LITERAL :
return NumberLiteral.class;
case PACKAGE_DECLARATION :
return PackageDeclaration.class;
case PARAMETERIZED_TYPE :
return ParameterizedType.class;
case PARENTHESIZED_EXPRESSION :
return ParenthesizedExpression.class;
case POSTFIX_EXPRESSION :
return PostfixExpression.class;
case PREFIX_EXPRESSION :
return PrefixExpression.class;
case PRIMITIVE_TYPE :
return PrimitiveType.class;
case QUALIFIED_NAME :
return QualifiedName.class;
case QUALIFIED_TYPE :
return QualifiedType.class;
case RETURN_STATEMENT :
return ReturnStatement.class;
case SIMPLE_NAME :
return SimpleName.class;
case SIMPLE_TYPE :
return SimpleType.class;
case SINGLE_MEMBER_ANNOTATION :
return SingleMemberAnnotation.class;
case SINGLE_VARIABLE_DECLARATION :
return SingleVariableDeclaration.class;
case STRING_LITERAL :
return StringLiteral.class;
case SUPER_CONSTRUCTOR_INVOCATION :
return SuperConstructorInvocation.class;
case SUPER_FIELD_ACCESS :
return SuperFieldAccess.class;
case SUPER_METHOD_INVOCATION :
return SuperMethodInvocation.class;
case SWITCH_CASE:
return SwitchCase.class;
case SWITCH_STATEMENT :
return SwitchStatement.class;
case SYNCHRONIZED_STATEMENT :
return SynchronizedStatement.class;
case TAG_ELEMENT :
return TagElement.class;
case TEXT_ELEMENT :
return TextElement.class;
case THIS_EXPRESSION :
return ThisExpression.class;
case THROW_STATEMENT :
return ThrowStatement.class;
case TRY_STATEMENT :
return TryStatement.class;
case TYPE_DECLARATION :
return TypeDeclaration.class;
case TYPE_DECLARATION_STATEMENT :
return TypeDeclarationStatement.class;
case TYPE_LITERAL :
return TypeLiteral.class;
case TYPE_PARAMETER :
return TypeParameter.class;
case VARIABLE_DECLARATION_EXPRESSION :
return VariableDeclarationExpression.class;
case VARIABLE_DECLARATION_FRAGMENT :
return VariableDeclarationFragment.class;
case VARIABLE_DECLARATION_STATEMENT :
return VariableDeclarationStatement.class;
case WHILE_STATEMENT :
return WhileStatement.class;
case WILDCARD_TYPE :
return WildcardType.class;
}
throw new IllegalArgumentException();
}
/**
* Owning AST.
*
* N.B. This ia a private field, but declared as package-visible
* for more efficient access from inner classes.
*
*/
final AST ast;
/**
* Parent AST node, or null if this node is a root.
* Initially null.
*/
private ASTNode parent = null;
/**
* An unmodifiable empty map (used to implement properties()).
*/
private static final Map