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); }