/* ____ ____ ____ ____ ______ *\ ** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** ** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** ** /_____/\____/\___/\____/____/ ** \* */ // $Id$ package scalac.ast; import ch.epfl.lamp.util.Position; import scalac.Global; import scalac.checkers.CheckTreeNodes; import scalac.symtab.Symbol; import scalac.symtab.Type; import scalac.util.Debug; import java.io.StringWriter; import scalac.ast.printer.TextTreePrinter; {#Imports#} public class Tree { //######################################################################## // Public Constants {#EmptyArrays#} //######################################################################## // Public Fields /** The position of the tree */ public int pos = Position.NOPOS; /** The type of the tree */ public Type type; //######################################################################## // Public Cases {#TreeCases#} //######################################################################## // Public Methods - queries {#IsKind#} /** Returns true if this tree is empty or error. */ public boolean isMissing() { switch (this) { case Bad(): case Empty: return true; default: return false; } } //######################################################################## // Public Methods - tree type /** Get the type of the node. */ public final Type getType() { return type; } /** Get the type of the node, which must be non-null. */ public Type type() { assert type != null : Debug.show(this); return type; } /** Set the type of the node. */ public Tree setType(Type type) { assert !(type instanceof Type.LazyType) : Debug.show(this); this.type = type; return this; } /** Get types attached to array of nodes. */ public static Type[] typeOf(Tree[] trees) { Type[] types = new Type[trees.length]; for (int i = 0; i < trees.length; i++) types[i] = trees[i].getType(); return types; } //######################################################################## // Public Methods - tree symbol /** Has this tree a symbol field? */ public boolean hasSymbol() { return false; } /** Tells if the tree defines a symbol. */ public boolean definesSymbol() { return false; } /** Get symbol attached to the node, if any. */ public Symbol symbol() { return null; } /** Set symbol attached to the node, if possible. */ public Tree setSymbol(Symbol sym) { throw Debug.abort("no settable symbol for node", this); } /** Get symbols attached to array of nodes. */ public static Symbol[] symbolOf(Tree[] trees) { Symbol[] symbols = new Symbol[trees.length]; for (int i = 0; i < trees.length; i++) symbols[i] = trees[i].symbol(); return symbols; } //######################################################################## // Public Methods - tree to string /** * Get string corresponding to this tree only implemented for * prefix trees, maybe we should generalize this; the PatternMatch * phase needs support for Apply, so this case got added */ public String toString() { StringWriter out = new StringWriter(); new TextTreePrinter(out).print(this).flush(); return out.toString(); } //######################################################################## // Public Methods - duplication public static Transformer duplicator = new Transformer( Global.instance, Global.instance.make, new StrictTreeCopier(Global.instance.make)); /** Returns a shallow copy of the given array. */ public static Tree[] cloneArray(Tree[] array) { return cloneArray(0, array, 0); } /** * Returns a shallow copy of the given array prefixed by "prefix" * null items. */ public static Tree[] cloneArray(int prefix, Tree[] array) { return cloneArray(prefix, array, 0); } /** * Returns a shallow copy of the given array suffixed by "suffix" * null items. */ public static Tree[] cloneArray(Tree[] array, int suffix) { return cloneArray(0, array, suffix); } /** * Returns a shallow copy of the given array prefixed by "prefix" * null items and suffixed by "suffix" null items. */ public static Tree[] cloneArray(int prefix, Tree[] array, int suffix) { assert prefix >= 0 && suffix >= 0: prefix + " - " + suffix; int size = prefix + array.length + suffix; if (size == 0) return EMPTY_ARRAY; Tree[] clone = new Tree[size]; for (int i = 0; i < array.length; i++) clone[prefix + i] = array[i]; return clone; } /** Returns the concatenation of the two arrays. */ public static Tree[] concat(Tree[] array1, Tree[] array2) { if (array1.length == 0) return array2; if (array2.length == 0) return array1; Tree[] clone = cloneArray(array1.length, array2); for (int i = 0; i < array1.length; i++) clone[i] = array1[i]; return clone; } public Tree duplicate() { return duplicator.transform(this); } //######################################################################## // Public Classes {#ExtClasses#} //######################################################################## // Empty Switch /* public void foobar(Tree tree) { switch (tree) { {#EmptyCases#} default: throw Debug.abort("illegal case", tree); } } */ //######################################################################## }