blob: 5079d1bc061154f40b665f1513e0b2eae714f6ea [file] [log] [blame]
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.google.dart.compiler.ast;
import com.google.dart.compiler.common.AbstractNode;
import com.google.dart.compiler.resolver.Element;
import com.google.dart.compiler.type.Type;
import com.google.dart.compiler.util.DefaultTextOutput;
import java.util.List;
/**
* Base class for all Dart AST nodes.
*/
public abstract class DartNode extends AbstractNode {
private DartNode parent;
private Type type;
public final String toSource() {
DefaultTextOutput out = new DefaultTextOutput(false);
accept(new DartToSourceVisitor(out));
return out.toString();
}
public Element getElement() {
return null;
}
public void setElement(Element element) {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
public void setType(Type type) {
this.type = type;
}
public Type getType() {
return type;
}
@Override
public String toString() {
return this.toSource();
}
/**
* Returns this node's parent node, or <code>null</code> if this is the
* root node.
* <p>
* Note that the relationship between an AST node and its parent node
* may change over the lifetime of a node.
*
* @return the parent of this node, or <code>null</code> if none
*/
public final DartNode getParent() {
return parent;
}
/**
* Return the node at the root of this node's AST structure. Note that this
* method's performance is linear with respect to the depth of the node in
* the AST structure (O(depth)).
*
* @return the node at the root of this node's AST structure
*/
public final DartNode getRoot() {
DartNode root = this;
DartNode parent = getParent();
while (parent != null) {
root = parent;
parent = root.getParent();
}
return root;
}
protected <T extends DartNode> T becomeParentOf(T child) {
if (child != null) {
DartNode node = child; // Java 7 access rules require a temp of a concrete type.
node.setParent(this);
}
return child;
}
protected <L extends List<? extends DartNode>> L becomeParentOf(L children) {
if (children != null) {
for (DartNode child : children) {
child.setParent(this);
}
}
return children;
}
private void setParent(DartNode newParent) {
parent = newParent;
}
public abstract void visitChildren(ASTVisitor<?> visitor);
public abstract <R> R accept(ASTVisitor<R> visitor);
@Override
public DartNode clone() {
// TODO (fabiomfv) - Implement proper cloning when strictly needed.
return this;
}
public String getObjectIdentifier(){
return super.toString();
}
/**
* If the given child is not <code>null</code>, use the given visitor to visit it.
*
* @param child the child to be visited
* @param visitor the visitor that will be used to visit the child
*/
protected void safelyVisitChild(DartNode child, ASTVisitor<?> visitor) {
if (child != null) {
child.accept(visitor);
}
}
}