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: /**
028: * An instantiated type.
029: *
030: * @author Robert Grimm
031: * @version $Revision: 1.4 $
032: */
033: public class InstantiatedT extends WrappedT {
034:
035: /** The list of arguments. */
036: private List<Type> arguments;
037:
038: /**
039: * Create a new instantiated type. The specified type must contain
040: * a parameterized type with a single parameter.
041: *
042: * @param argument The argument.
043: * @param type The type.
044: * @throws IllegalArgumentException Signals that the specified type
045: * does not contain a parameterized type or that the number of
046: * arguments does not match the parameterized type's number of
047: * parameters.
048: */
049: public InstantiatedT(Type argument, Type type) {
050: super (type);
051: this .arguments = new ArrayList<Type>(1);
052: this .arguments.add(argument);
053: if (!type.hasParameterized()) {
054: throw new IllegalArgumentException(
055: "Not a parameterized type " + type);
056: } else if (1 != type.toParameterized().getParameters().size()) {
057: throw new IllegalArgumentException(
058: "Wrong number of parameters " + type);
059: }
060: }
061:
062: /**
063: * Create a new instantiated type. The specified type must contain
064: * a parameterized type with the same number of parameters as the
065: * specified arguments.
066: *
067: * @param arguments The arguments.
068: * @param type The type.
069: * @throws IllegalArgumentException Signals that the specified type
070: * does not contain a parameterized type or that the number of
071: * arguments does not match the parameterized type's number of
072: * parameters.
073: */
074: public InstantiatedT(List<Type> arguments, Type type) {
075: super (type);
076: this .arguments = arguments;
077: if (!type.hasParameterized()) {
078: throw new IllegalArgumentException(
079: "Not a parameterized type " + type);
080: } else if (arguments.size() != type.toParameterized()
081: .getParameters().size()) {
082: throw new IllegalArgumentException(
083: "Wrong number of parameters " + type);
084: }
085: }
086:
087: /**
088: * Create a new instantiated type.
089: *
090: * @param template The type whose annotations to copy.
091: * @param arguments The arguments.
092: * @param type The type.
093: * @throws IllegalArgumentException Signals that the specified type
094: * does not contain a parameterized type or that the number of
095: * arguments does not match the parameterized type's number of
096: * parameters.
097: */
098: public InstantiatedT(Type template, List<Type> arguments, Type type) {
099: super (template, type);
100: this .arguments = arguments;
101: if (!type.hasParameterized()) {
102: throw new IllegalArgumentException(
103: "Not a parameterized type " + type);
104: } else if (arguments.size() != type.toParameterized()
105: .getParameters().size()) {
106: throw new IllegalArgumentException(
107: "Wrong number of parameters " + type);
108: }
109: }
110:
111: public InstantiatedT copy() {
112: return new InstantiatedT(this , Type.copy(arguments), getType()
113: .copy());
114: }
115:
116: public Type seal() {
117: if (!isSealed()) {
118: super .seal();
119: arguments = Type.seal(arguments);
120: }
121: return this ;
122: }
123:
124: public Type.Tag wtag() {
125: return Type.Tag.INSTANTIATED;
126: }
127:
128: public boolean isInstantiated() {
129: return true;
130: }
131:
132: public boolean hasInstantiated() {
133: return true;
134: }
135:
136: public InstantiatedT toInstantiated() {
137: return this ;
138: }
139:
140: /**
141: * Get this instantiated type's arguments.
142: *
143: * @return The arguments.
144: */
145: public List<Type> getArguments() {
146: return arguments;
147: }
148:
149: /**
150: * Determine whether this type equals the specified object. This
151: * instantiated type equals the specified object if the object is an
152: * equal wrapped type instantiated with equal types.
153: *
154: * @param o The object.
155: * @return <code>true</code> if this type equals the specified
156: * object.
157: */
158: public boolean equals(Object o) {
159: if (!(o instanceof Type))
160: return false;
161: Type t = cast(o);
162:
163: if (!t.hasInstantiated())
164: return false;
165: InstantiatedT other = t.toInstantiated();
166: if (arguments.size() != other.arguments.size())
167: return false;
168: for (int i = 0; i < arguments.size(); i++) {
169: if (!arguments.get(i).equals(other.arguments.get(i)))
170: return false;
171: }
172: return getType().equals(other.getType());
173: }
174:
175: public void write(Appendable out) throws IOException {
176: if (1 == arguments.size()) {
177: out.append("argument(");
178: } else {
179: out.append("arguments(");
180: }
181: for (Iterator<Type> iter = arguments.iterator(); iter.hasNext();) {
182: iter.next().write(out);
183: if (iter.hasNext())
184: out.append(", ");
185: }
186: out.append(") ");
187: getType().write(out);
188: }
189:
190: }
|