/* * 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.util.Collections; import java.util.List; import polyglot.types.*; import polyglot.util.CodeWriter; import polyglot.util.Position; import polyglot.visit.*; /** * A <code>Formal</code> represents a formal parameter for a procedure * or catch block. It consists of a type and a variable identifier. */ public abstract class Formal_c extends Term_c implements Formal { protected LocalDef li; protected FlagsNode flags; protected TypeNode type; protected Id name; // protected boolean reachable; public Formal_c(Position pos, FlagsNode flags, TypeNode type, Id name) { super(pos); assert(flags != null && type != null && name != null); this.flags = flags; this.type = type; this.name = name; } public List<Def> defs() { return Collections.<Def>singletonList(li); } /** Get the type of the formal. */ public abstract Type declType(); /** Get the flags of the formal. */ public FlagsNode flags() { return flags; } /** Set the flags of the formal. */ public Formal flags(FlagsNode flags) { Formal_c n = (Formal_c) copy(); n.flags = flags; return n; } /** Get the type node of the formal. */ public TypeNode type() { return type; } /** Set the type node of the formal. */ public Formal type(TypeNode type) { Formal_c n = (Formal_c) copy(); n.type = type; return n; } /** Get the name of the formal. */ public Id name() { return name; } /** Set the name of the formal. */ public Formal name(Id name) { Formal_c n = (Formal_c) copy(); n.name = name; return n; } /** Get the local instance of the formal. */ public LocalDef localDef() { return li; } /** Set the local instance of the formal. */ public Formal localDef(LocalDef li) { if (li == this.li) return this; Formal_c n = (Formal_c) copy(); n.li = li; return n; } /** Reconstruct the formal. */ protected Formal_c reconstruct(FlagsNode flags, TypeNode type, Id name) { if (flags != this.flags || this.type != type || name != this.name) { Formal_c n = (Formal_c) copy(); n.flags = flags; n.type = type; n.name = name; return n; } return this; } /** Visit the children of the formal. */ public Node visitChildren(NodeVisitor v) { FlagsNode flags = (FlagsNode) visitChild(this.flags, v); TypeNode type = (TypeNode) visitChild(this.type, v); Id name = (Id) visitChild(this.name, v); return reconstruct(flags, type, name); } public abstract void addDecls(Context c); /** Write the formal to an output file. */ public void prettyPrint(CodeWriter w, PrettyPrinter tr) { print(flags, w, tr); print(type, w, tr); w.write(" "); tr.print(this, name, w); } /** Build type objects for the formal. */ public Node buildTypes(TypeBuilder tb) { Formal_c n = (Formal_c) super.buildTypes(tb); TypeSystem ts = tb.typeSystem(); LocalDef li = ts.localDef(position(), flags().flags(), type.typeRef(), name.id()); // Formal parameters are never compile-time constants. li.setNotConstant(); return n.localDef(li); } /** Type check the formal. */ public abstract Node typeCheck(ContextVisitor tc); public Term firstChild() { return type; } public <S> List<S> acceptCFG(CFGBuilder v, List<S> succs) { v.visitCFG(type, this, EXIT); return succs; } public void dump(CodeWriter w) { super.dump(w); if (li != null) { w.allowBreak(4, " "); w.begin(0); w.write("(instance " + li + ")"); w.end(); } w.allowBreak(4, " "); w.begin(0); w.write("(name " + name + ")"); w.end(); } public abstract String toString(); }