001: /*
002: * xtc - The eXTensible Compiler
003: * Copyright (C) 2007 Robert Grimm
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License
007: * version 2 as published by the Free Software Foundation.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
017: * USA.
018: */
019: package xtc.type;
020:
021: import java.io.IOException;
022:
023: import java.util.ArrayList;
024: import java.util.Iterator;
025: import java.util.List;
026:
027: import xtc.util.Utilities;
028:
029: /**
030: * A tuple type. Tuples may be either anonymous, without a name, or
031: * named. For named tuples, this class provides accessors to the full
032: * name and the simple name, which is the full name without any
033: * qualifier.
034: *
035: * @author Robert Grimm
036: * @version $Revision: 1.7 $
037: */
038: public class TupleT extends DerivedT {
039:
040: /** The qualified name. */
041: final private String qname;
042:
043: /** The simple name. */
044: final private String sname;
045:
046: /** The element types. */
047: private List<Type> types;
048:
049: /** Create a new incomplete and anonymous tuple type. */
050: public TupleT() {
051: this (null, null, null);
052: }
053:
054: /**
055: * Create a new anonymous tuple type.
056: *
057: * @param types The types.
058: */
059: public TupleT(List<Type> types) {
060: this (null, null, types);
061: }
062:
063: /**
064: * Create a new incomplete tuple type.
065: *
066: * @param name The name.
067: */
068: public TupleT(String name) {
069: this (null, name, null);
070: }
071:
072: /**
073: * Create a new tuple type.
074: *
075: * @param name The name.
076: * @param type The only element type.
077: */
078: public TupleT(String name, Type type) {
079: this (null, name, new ArrayList<Type>(1));
080: types.add(type);
081: }
082:
083: /**
084: * Create a new tuple type.
085: *
086: * @param name The name.
087: * @param types The element types.
088: */
089: public TupleT(String name, List<Type> types) {
090: this (null, name, types);
091: }
092:
093: /**
094: * Create a new tuple type.
095: *
096: * @param template The type whose annotations to copy.
097: * @param name The name.
098: * @param types The element types.
099: */
100: public TupleT(Type template, String name, List<Type> types) {
101: super (template);
102: this .qname = name;
103: this .sname = (null == name) ? null : Utilities.unqualify(name);
104: this .types = types;
105: }
106:
107: public Type seal() {
108: if (!isSealed()) {
109: super .seal();
110: types = Type.seal(types);
111: }
112: return this ;
113: }
114:
115: public TupleT copy() {
116: return new TupleT(this , qname, copy(types));
117: }
118:
119: public Type.Tag tag() {
120: return Type.Tag.TUPLE;
121: }
122:
123: public boolean isTuple() {
124: return true;
125: }
126:
127: public TupleT toTuple() {
128: return this ;
129: }
130:
131: /**
132: * Determine whether this tuple has a name.
133: *
134: * @return <code>true</code> if this tuple has a name.
135: */
136: public boolean hasName() {
137: return null != qname;
138: }
139:
140: /**
141: * Determine whether this tuple has the specified name.
142: *
143: * @param name The name.
144: * @return <code>true</code> if this tuple has the name.
145: */
146: public boolean hasName(String name) {
147: return name.equals(this .qname);
148: }
149:
150: /**
151: * Determine whether this tuple has the specified simple name.
152: *
153: * @param name The simple name.
154: * @return <code>true</code> if this tuple has the simple name.
155: */
156: public boolean hasSimpleName(String name) {
157: return name.equals(this .sname);
158: }
159:
160: /**
161: * Get this tuple's name.
162: *
163: * @return The name or <code>null</code> if this tuple is anonymous.
164: */
165: public String getName() {
166: return qname;
167: }
168:
169: /**
170: * Get this tuple's simple name.
171: *
172: * @return The simple name or <code>null</code> if this tuple is
173: * anonymous.
174: */
175: public String getSimpleName() {
176: return sname;
177: }
178:
179: /**
180: * Get the element types.
181: *
182: * @return The element types.
183: */
184: public List<Type> getTypes() {
185: return types;
186: }
187:
188: /**
189: * Set the element types.
190: *
191: * @param types The new element types.
192: */
193: public void setTypes(List<Type> types) {
194: checkNotSealed();
195: this .types = types;
196: }
197:
198: public int hashCode() {
199: int hash = 0;
200: if (null != qname)
201: hash = qname.hashCode();
202: if (null != types)
203: hash = 7 * hash + types.hashCode();
204: return hash;
205: }
206:
207: public boolean equals(Object o) {
208: if (!(o instanceof Type))
209: return false;
210: Type t = resolve(o);
211:
212: if (this == t)
213: return true;
214: if (!t.isTuple())
215: return false;
216: TupleT other = t.toTuple();
217:
218: if (null == qname) {
219: if (null != other.qname)
220: return false;
221: } else {
222: if (!qname.equals(other.qname))
223: return false;
224: }
225: return null == types ? null == other.types : types
226: .equals(other.types);
227: }
228:
229: public void write(Appendable out) throws IOException {
230: if (null == qname) {
231: out.append("<anonymous>");
232: } else {
233: out.append(qname);
234: }
235: out.append('(');
236: if (null == types) {
237: out.append("...");
238: } else {
239: for (Iterator<Type> iter = types.iterator(); iter.hasNext();) {
240: iter.next().write(out);
241: if (iter.hasNext())
242: out.append(", ");
243: }
244: }
245: out.append(')');
246: }
247:
248: }
|