/* * 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; /** * An instantiated type. * * @author Robert Grimm * @version $Revision: 1.4 $ */ public class InstantiatedT extends WrappedT { /** The list of arguments. */ private List<Type> arguments; /** * Create a new instantiated type. The specified type must contain * a parameterized type with a single parameter. * * @param argument The argument. * @param type The type. * @throws IllegalArgumentException Signals that the specified type * does not contain a parameterized type or that the number of * arguments does not match the parameterized type's number of * parameters. */ public InstantiatedT(Type argument, Type type) { super(type); this.arguments = new ArrayList<Type>(1); this.arguments.add(argument); if (! type.hasParameterized()) { throw new IllegalArgumentException("Not a parameterized type " + type); } else if (1 != type.toParameterized().getParameters().size()) { throw new IllegalArgumentException("Wrong number of parameters " + type); } } /** * Create a new instantiated type. The specified type must contain * a parameterized type with the same number of parameters as the * specified arguments. * * @param arguments The arguments. * @param type The type. * @throws IllegalArgumentException Signals that the specified type * does not contain a parameterized type or that the number of * arguments does not match the parameterized type's number of * parameters. */ public InstantiatedT(List<Type> arguments, Type type) { super(type); this.arguments = arguments; if (! type.hasParameterized()) { throw new IllegalArgumentException("Not a parameterized type " + type); } else if (arguments.size()!=type.toParameterized().getParameters().size()) { throw new IllegalArgumentException("Wrong number of parameters " + type); } } /** * Create a new instantiated type. * * @param template The type whose annotations to copy. * @param arguments The arguments. * @param type The type. * @throws IllegalArgumentException Signals that the specified type * does not contain a parameterized type or that the number of * arguments does not match the parameterized type's number of * parameters. */ public InstantiatedT(Type template, List<Type> arguments, Type type) { super(template, type); this.arguments = arguments; if (! type.hasParameterized()) { throw new IllegalArgumentException("Not a parameterized type " + type); } else if (arguments.size()!=type.toParameterized().getParameters().size()) { throw new IllegalArgumentException("Wrong number of parameters " + type); } } public InstantiatedT copy() { return new InstantiatedT(this, Type.copy(arguments), getType().copy()); } public Type seal() { if (! isSealed()) { super.seal(); arguments = Type.seal(arguments); } return this; } public Type.Tag wtag() { return Type.Tag.INSTANTIATED; } public boolean isInstantiated() { return true; } public boolean hasInstantiated() { return true; } public InstantiatedT toInstantiated() { return this; } /** * Get this instantiated type's arguments. * * @return The arguments. */ public List<Type> getArguments() { return arguments; } /** * Determine whether this type equals the specified object. This * instantiated type equals the specified object if the object is an * equal wrapped type instantiated with equal types. * * @param o The object. * @return <code>true</code> if this type equals the specified * object. */ public boolean equals(Object o) { if (! (o instanceof Type)) return false; Type t = cast(o); if (! t.hasInstantiated()) return false; InstantiatedT other = t.toInstantiated(); if (arguments.size() != other.arguments.size()) return false; for (int i=0; i<arguments.size(); i++) { if (! arguments.get(i).equals(other.arguments.get(i))) return false; } return getType().equals(other.getType()); } public void write(Appendable out) throws IOException { if (1 == arguments.size()) { out.append("argument("); } else { out.append("arguments("); } for (Iterator<Type> iter = arguments.iterator(); iter.hasNext(); ) { iter.next().write(out); if (iter.hasNext()) out.append(", "); } out.append(") "); getType().write(out); } }