/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.devtools.j2objc.ast; import org.eclipse.jdt.core.dom.ASTNode; /** * Base class for nodes in the J2ObjC AST. */ public abstract class TreeNode { private ChildLink<? extends TreeNode> owner = null; private int startPosition = -1; private int length = 0; private int lineNumber = -1; protected TreeNode() { } // TODO(tball): remove when all subclasses are converted. protected TreeNode(ASTNode jdtNode) { this(); startPosition = jdtNode.getStartPosition(); length = jdtNode.getLength(); ASTNode root = jdtNode.getRoot(); if (root instanceof org.eclipse.jdt.core.dom.CompilationUnit) { lineNumber = ((org.eclipse.jdt.core.dom.CompilationUnit) root).getLineNumber(startPosition); } } protected TreeNode(TreeNode other) { startPosition = other.getStartPosition(); length = other.getLength(); lineNumber = other.getLineNumber(); } public abstract Kind getKind(); public TreeNode getParent() { return owner == null ? null : owner.getParent(); } /* package */ void setOwner(ChildLink<? extends TreeNode> newOwner) { assert owner == null || newOwner == null : "Node is already parented"; owner = newOwner; } public void remove() { if (owner != null) { owner.remove(); } } public void replaceWith(TreeNode other) { assert owner != null : "Can't replace a parentless node."; owner.setDynamic(other); } public final int getStartPosition() { return startPosition; } public final int getLength() { return length; } public void setSourceRange(int newStartPosition, int newLength) { startPosition = newStartPosition; length = newLength; } public final int getLineNumber() { return lineNumber; } public void setLineNumber(int lineNumber) { this.lineNumber = lineNumber; } public final void accept(TreeVisitor visitor) { try { if (visitor.preVisit(this)) { acceptInner(visitor); } visitor.postVisit(this); } catch (TreeVisitorError e) { // Avoid re-wrapping. throw e; } catch (Throwable t) { throw new TreeVisitorError(t, this); } } protected abstract void acceptInner(TreeVisitor visitor); /** * Returns an unparented deep copy of this node. */ public abstract TreeNode copy(); /** * Validates the tree to preemptively catch errors. */ public final void validate() { this.accept(new TreeVisitor() { @Override public boolean preVisit(TreeNode node) { node.validateInner(); return true; } }); } public void validateInner() {} public TreeNode setPosition(SourcePosition position) { this.startPosition = position.getStartPosition(); this.length = position.getLength(); this.lineNumber = position.getLineNumber(); return this; } @Override public String toString() { try { return DebugASTPrinter.toString(this); } catch (RuntimeException e) { // Debugger may sometimes call toString methods on an instance that is partially initialized. return super.toString(); } } /** * Enumeration of all the node types. Useful for switch statements. */ public enum Kind { ANNOTATION_TYPE_DECLARATION, ANNOTATION_TYPE_MEMBER_DECLARATION, ARRAY_ACCESS, ARRAY_CREATION, ARRAY_INITIALIZER, ARRAY_TYPE, ASSERT_STATEMENT, ASSIGNMENT, BLOCK, BLOCK_COMMENT, BOOLEAN_LITERAL, BREAK_STATEMENT, C_STRING_LITERAL, CAST_EXPRESSION, CATCH_CLAUSE, CHARACTER_LITERAL, CLASS_INSTANCE_CREATION, COMMA_EXPRESSION, COMPILATION_UNIT, CONDITIONAL_EXPRESSION, CONSTRUCTOR_INVOCATION, CONTINUE_STATEMENT, CREATION_REFERENCE, DIMENSION, DO_STATEMENT, EMPTY_STATEMENT, ENHANCED_FOR_STATEMENT, ENUM_CONSTANT_DECLARATION, ENUM_DECLARATION, EXPRESSION_METHOD_REFERENCE, EXPRESSION_STATEMENT, FIELD_ACCESS, FIELD_DECLARATION, FOR_STATEMENT, FUNCTION_DECLARATION, FUNCTION_INVOCATION, IF_STATEMENT, INFIX_EXPRESSION, INITIALIZER, INSTANCEOF_EXPRESSION, INTERSECTION_TYPE, JAVADOC, LABELED_STATEMENT, LAMBDA_EXPRESSION, LINE_COMMENT, MARKER_ANNOTATION, MEMBER_VALUE_PAIR, METHOD_DECLARATION, METHOD_INVOCATION, NAME_QUALIFIED_TYPE, NATIVE_DECLARATION, NATIVE_EXPRESSION, NATIVE_STATEMENT, NORMAL_ANNOTATION, NULL_LITERAL, NUMBER_LITERAL, PACKAGE_DECLARATION, PARAMETERIZED_TYPE, PARENTHESIZED_EXPRESSION, POSTFIX_EXPRESSION, PREFIX_EXPRESSION, PRIMITIVE_TYPE, PROPERTY_ANNOTATION, QUALIFIED_NAME, QUALIFIED_TYPE, RETURN_STATEMENT, SIMPLE_NAME, SIMPLE_TYPE, SINGLE_MEMBER_ANNOTATION, SINGLE_VARIABLE_DECLARATION, STRING_LITERAL, SUPER_CONSTRUCTOR_INVOCATION, SUPER_METHOD_INVOCATION, SUPER_METHOD_REFERENCE, SUPER_FIELD_ACCESS, SWITCH_CASE, SWITCH_STATEMENT, SYNCHRONIZED_STATEMENT, TAG_ELEMENT, TEXT_ELEMENT, THIS_EXPRESSION, THROW_STATEMENT, TRY_STATEMENT, TYPE_DECLARATION, TYPE_DECLARATION_STATEMENT, TYPE_LITERAL, TYPE_METHOD_REFERENCE, UNION_TYPE, VARIABLE_DECLARATION_EXPRESSION, VARIABLE_DECLARATION_FRAGMENT, VARIABLE_DECLARATION_STATEMENT, WHILE_STATEMENT } }