/* * xtc - The eXTensible Compiler * Copyright (C) 2007 Robert Grimm * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ package xtc.type; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import xtc.util.Utilities; /** * A tuple type. Tuples may be either anonymous, without a name, or * named. For named tuples, this class provides accessors to the full * name and the simple name, which is the full name without any * qualifier. * * @author Robert Grimm * @version $Revision: 1.7 $ */ public class TupleT extends DerivedT { /** The qualified name. */ final private String qname; /** The simple name. */ final private String sname; /** The element types. */ private List<Type> types; /** Create a new incomplete and anonymous tuple type. */ public TupleT() { this(null, null, null); } /** * Create a new anonymous tuple type. * * @param types The types. */ public TupleT(List<Type> types) { this(null, null, types); } /** * Create a new incomplete tuple type. * * @param name The name. */ public TupleT(String name) { this(null, name, null); } /** * Create a new tuple type. * * @param name The name. * @param type The only element type. */ public TupleT(String name, Type type) { this(null, name, new ArrayList<Type>(1)); types.add(type); } /** * Create a new tuple type. * * @param name The name. * @param types The element types. */ public TupleT(String name, List<Type> types) { this(null, name, types); } /** * Create a new tuple type. * * @param template The type whose annotations to copy. * @param name The name. * @param types The element types. */ public TupleT(Type template, String name, List<Type> types) { super(template); this.qname = name; this.sname = (null == name) ? null : Utilities.unqualify(name); this.types = types; } public Type seal() { if (! isSealed()) { super.seal(); types = Type.seal(types); } return this; } public TupleT copy() { return new TupleT(this, qname, copy(types)); } public Type.Tag tag() { return Type.Tag.TUPLE; } public boolean isTuple() { return true; } public TupleT toTuple() { return this; } /** * Determine whether this tuple has a name. * * @return <code>true</code> if this tuple has a name. */ public boolean hasName() { return null != qname; } /** * Determine whether this tuple has the specified name. * * @param name The name. * @return <code>true</code> if this tuple has the name. */ public boolean hasName(String name) { return name.equals(this.qname); } /** * Determine whether this tuple has the specified simple name. * * @param name The simple name. * @return <code>true</code> if this tuple has the simple name. */ public boolean hasSimpleName(String name) { return name.equals(this.sname); } /** * Get this tuple's name. * * @return The name or <code>null</code> if this tuple is anonymous. */ public String getName() { return qname; } /** * Get this tuple's simple name. * * @return The simple name or <code>null</code> if this tuple is * anonymous. */ public String getSimpleName() { return sname; } /** * Get the element types. * * @return The element types. */ public List<Type> getTypes() { return types; } /** * Set the element types. * * @param types The new element types. */ public void setTypes(List<Type> types) { checkNotSealed(); this.types = types; } public int hashCode() { int hash = 0; if (null != qname) hash = qname.hashCode(); if (null != types) hash = 7 * hash + types.hashCode(); return hash; } public boolean equals(Object o) { if (! (o instanceof Type)) return false; Type t = resolve(o); if (this == t) return true; if (! t.isTuple()) return false; TupleT other = t.toTuple(); if (null == qname) { if (null != other.qname) return false; } else { if (! qname.equals(other.qname)) return false; } return null == types ? null == other.types : types.equals(other.types); } public void write(Appendable out) throws IOException { if (null == qname) { out.append("<anonymous>"); } else { out.append(qname); } out.append('('); if (null == types) { out.append("..."); } else { for (Iterator<Type> iter = types.iterator(); iter.hasNext(); ) { iter.next().write(out); if (iter.hasNext()) out.append(", "); } } out.append(')'); } }