/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* This file was originally derived from the Polyglot extensible compiler framework.
*
* (C) Copyright 2000-2007 Polyglot project group, Cornell University
* (C) Copyright IBM Corporation 2007-2012.
*/
package polyglot.ast;
import java.io.OutputStream;
import java.io.Writer;
import java.util.List;
import polyglot.frontend.ExtensionInfo;
import polyglot.types.*;
import polyglot.util.CodeWriter;
import polyglot.visit.*;
/**
* A <code>Node</code> represents an AST node. All AST nodes must implement
* this interface. Nodes should be immutable: methods which set fields
* of the node should copy the node, set the field in the copy, and then
* return the copy.
*/
public interface NodeOps
{
/**
* Visit the children of the node.
*
* @param v The visitor that will traverse/rewrite the AST.
* @return A new AST if a change was made, or <code>this</code>.
*/
Node visitChildren(NodeVisitor v);
/**
* Push a new scope upon entering this node, and add any declarations to the
* context that should be in scope when visiting children of this node.
* This should <i>not</i> update the old context
* imperatively. Use <code>addDecls</code> when leaving the node
* for that.
* @param c the current <code>Context</code>
* @return the <code>Context</code> to be used for visiting this node.
*/
public Context enterScope(Context c);
/**
* Push a new scope for visiting the child node <code>child</code>.
* The default behavior is to delegate the call to the child node, and let
* it add appropriate declarations that should be in scope. However,
* this method gives parent nodes have the ability to modify this behavior.
* @param child The child node about to be entered.
* @param c The current <code>Context</code>
* @return the <code>Context</code> to be used for visiting node
* <code>child</code>
*/
public Context enterChildScope(Node child, Context c);
/**
* Add any declarations to the context that should be in scope when
* visiting later sibling nodes.
* @param c The context to which to add declarations.
*/
void addDecls(Context c);
/**
* Collects classes, methods, and fields from the AST rooted at this node
* and constructs type objects for these. These type objects may be
* ambiguous. Inserts classes into the <code>TypeSystem</code>.
*
* This method is called by the <code>enter()</code> method of the
* visitor. The * method should perform work that should be done
* before visiting the children of the node. The method may return
* <code>this</code> or a new copy of the node on which
* <code>visitChildren()</code> and <code>leave()</code> will be
* invoked.
*
* @param tb The visitor which adds new type objects to the
* <code>TypeSystem</code>.
*/
NodeVisitor buildTypesEnter(TypeBuilder tb);
/**
* Collects classes, methods, and fields from the AST rooted at this node
* and constructs type objects for these. These type objects may be
* ambiguous. Inserts classes into the <code>TypeSystem</code>.
*
* This method is called by the <code>leave()</code> method of the
* visitor. The method should perform work that should be done
* after visiting the children of the node. The method may return
* <code>this</code> or a new copy of the node which will be
* installed as a child of the node's parent.
*
* @param tb The visitor which adds new type objects to the
* <code>TypeSystem</code>.
*/
Node buildTypesOverride(TypeBuilder tb);
Node buildTypes(TypeBuilder tb);
/**
* Remove any remaining ambiguities from the AST.
* This method is called after the compute types pass and
* reconstructs the node from the type information computed there.
*
* This method is called by the <code>leave()</code> method of the
* visitor. The method should perform work that should be done
* after visiting the children of the node. The method may return
* <code>this</code> or a new copy of the node which will be
* installed as a child of the node's parent.
*
* The node should not assume that its children have been disambiguated.
* If it depends on a child being disambiguated,
* it may just return <code>this</code> without doing any work.
*
* @param ar The visitor which disambiguates.
*/
Node disambiguate(ContextVisitor ar);
Node setResolverOverride(Node parent, TypeCheckPreparer v);
void setResolver(Node parent, TypeCheckPreparer v);
/**
* Type check the AST.
*
* This method is called by the <code>enter()</code> method of the
* visitor. The * method should perform work that should be done
* before visiting the children of the node. The method may return
* <code>this</code> or a new copy of the node on which
* <code>visitChildren()</code> and <code>leave()</code> will be
* invoked.
*
* @param tc The type checking visitor.
*/
NodeVisitor typeCheckEnter(TypeChecker tc);
/**
* Type check the AST.
*
* This method is called by the <code>override()</code> method of the
* visitor. If this method returns non-null, the node's children
* will not be visited automatically. Thus, the method should check
* both the node <code>this</code> and it's children, usually by
* invoking <code>visitChildren</code> with <code>tc</code> or
* with another visitor, returning a non-null node. OR, the method
* should do nothing and simply return <code>null</code> to allow
* <code>enter</code>, <code>visitChildren</code>, and <code>leave</code>
* to be invoked on the node.
*
* The default implementation returns <code>null</code>.
* Overriding of this method is discouraged, but sometimes necessary.
*
* @param tc The type checking visitor.
*/
Node typeCheckOverride(Node parent, ContextVisitor tc);
/**
* Type check the AST.
*
* This method is called by the <code>leave()</code> method of the
* visitor. The method should perform work that should be done
* after visiting the children of the node. The method may return
* <code>this</code> or a new copy of the node which will be
* installed as a child of the node's parent.
*
* @param tc The type checking visitor.
*/
Node typeCheck(ContextVisitor tc);
Node conformanceCheck(ContextVisitor tc);
/**
* Check if the node is a compile-time constant.
*
* This method is called by the <code>leave()</code> method of the
* visitor. The method should perform work that should be done
* after visiting the children of the node. The method may return
* <code>this</code> or a new copy of the node which will be
* installed as a child of the node's parent.
*
* @param tc The constant checking visitor.
*/
Node checkConstants(ContextVisitor tc);
/**
* Check that exceptions are properly propagated throughout the AST.
*
* This method is called by the <code>enter()</code> method of the
* visitor. The * method should perform work that should be done
* before visiting the children of the node. The method may return
* <code>this</code> or a new copy of the node on which
* <code>visitChildren()</code> and <code>leave()</code> will be
* invoked.
*
* @param ec The visitor.
*/
NodeVisitor exceptionCheckEnter(ExceptionChecker ec);
/**
* Check that exceptions are properly propagated throughout the AST.
*
* This method is called by the <code>leave()</code> method of the
* visitor. The method should perform work that should be done
* after visiting the children of the node. The method may return
* <code>this</code> or a new copy of the node which will be
* installed as a child of the node's parent.
*
* @param ec The visitor.
*/
Node exceptionCheck(ExceptionChecker ec);
/**
* List of Types of exceptions that might get thrown. The result is
* not necessarily correct until after type checking.
*/
List<Type> throwTypes(TypeSystem ts);
/** Dump the AST for debugging. */
public void dump(OutputStream os);
/** Dump the AST for debugging. */
public void dump(Writer w);
/** Pretty-print the AST for debugging. */
public void prettyPrint(OutputStream os);
/** Pretty-print the AST for debugging. */
public void prettyPrint(Writer w);
/**
* Pretty-print the AST using the given code writer.
*
* @param w The code writer to which to write.
* @param pp The pretty printer. This is <i>not</i> a visitor.
*/
void prettyPrint(CodeWriter w, PrettyPrinter pp);
/**
* Translate the AST using the given code writer.
*
* @param w The code writer to which to write.
* @param tr The translation pass. This is <i>not</i> a visitor.
*/
void translate(CodeWriter w, Translator tr);
/**
* Produce a copy of this node using the given NodeFactory.
*/
Node copy(NodeFactory nf);
/**
* Produce a copy of this node using the given ExtensionInfo.
* This will typically be implemented by calling
* copy(NodeFactory nf), and then potentially copying over
* type information.
* @throws SemanticException If the type information cannot be copied.
*/
Node copy(ExtensionInfo extInfo) throws SemanticException;
}