package polyglot.ast;
import java.util.List;
import polyglot.util.CodeWriter;
import polyglot.types.SemanticException;
import polyglot.types.Context;
import polyglot.types.TypeSystem;
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 enterScope(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) throws SemanticException;
/**
* 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 buildTypes(TypeBuilder tb) throws SemanticException;
/**
* Remove any remaining ambiguities from 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 ar The visitor which disambiguates.
*/
NodeVisitor disambiguateEnter(AmbiguityRemover ar) throws SemanticException;
/**
* Remove any remaining ambiguities from 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 ar The visitor which disambiguates.
*/
Node disambiguate(AmbiguityRemover ar) throws SemanticException;
/**
* Adds disambiguated methods and fields to the types.
*
* 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 am The visitor which builds types.
*/
NodeVisitor addMembersEnter(AddMemberVisitor am) throws SemanticException;
/**
* Adds disambiguated methods and fields to the types.
*
* 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 am The visitor which builds types.
*/
Node addMembers(AddMemberVisitor am) throws SemanticException;
/**
* 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) throws SemanticException;
/**
* 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(TypeChecker tc) throws SemanticException;
/**
* 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) throws SemanticException;
/**
* 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) throws SemanticException;
/**
* List of Types of exceptions that might get thrown. The result is
* not necessarily correct until after type checking.
*/
List throwTypes(TypeSystem ts);
/**
* 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);
}