/* * xtc - The eXTensible Compiler * Copyright (C) 2006-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.Iterator; import java.util.List; /** * The superclass of function and method types. * * @author Robert Grimm * @version $Revision: 1.22 $ */ public abstract class FunctionOrMethodT extends DerivedT { /** The result type. */ protected Type result; /** The optional name. */ protected String name; /** The list of parameter types. */ protected List<Type> parameters; /** * The flag for whether the function accepts a variable number of * arguments. */ protected boolean varargs; /** The optional list of exceptions. */ protected List<Type> exceptions; /** * Create a new function or method type. * * @param template The type whose annotations to copy. * @param result The result type. * @param name The name. * @param parameters The list of parameter types. * @param varargs The flag for accepting a variable number of arguments. * @param exceptions The list of exception types. */ public FunctionOrMethodT(Type template, Type result, String name, List<Type> parameters, boolean varargs, List<Type> exceptions) { super(template); this.result = result; this.name = name; this.parameters = parameters; this.varargs = varargs; this.exceptions = exceptions; } public Type seal() { if (! isSealed()) { super.seal(); result.seal(); parameters = Type.seal(parameters); exceptions = Type.seal(exceptions); } return this; } /** * Get the result type. * * @return The result type. */ public Type getResult() { return result; } /** * Set the result type. * * @param result The new result type. * @throws IllegalStateException Signals that this type is sealed. */ public void setResult(Type result) { checkNotSealed(); this.result = result; } /** * Get the name. * * @return The name. */ public String getName() { return name; } /** * Get the list of parameter types. * * @return The parameter types. */ public List<Type> getParameters() { return parameters; } /** * Set the list of parameter types. * * @param parameters The list of parameter types. * @throws IllegalStateException Signals that this type is sealed. */ public void setParameters(List<Type> parameters) { checkNotSealed(); this.parameters = parameters; } /** * Determine whether this function accepts a variable number of * arguments. * * @return <code>true</code> if this function accepts a variable * number of arguments. */ public boolean isVarArgs() { return varargs; } /** * Get the list of exceptions. * * @return The list of exceptions. */ public List<Type> getExceptions() { return exceptions; } /** * Set the list of parameter types. * * @param exceptions The list of exception types. * @throws IllegalStateException Signals that this type is sealed. */ public void setExceptions(List<Type> exceptions) { checkNotSealed(); this.exceptions = exceptions; } public int hashCode() { return parameters.hashCode() * 37 + result.hashCode(); } public boolean equals(Object o) { if (! (o instanceof Type)) return false; Type t = resolve(o); if (this == t) return true; if (! getClass().equals(t.getClass())) return false; FunctionOrMethodT other = (FunctionOrMethodT)t; if (varargs != other.varargs) return false; if (! result.equals(other.result)) return false; if (null == exceptions) { if (null != other.exceptions) return false; } else { if (! exceptions.equals(other.exceptions)) return false; } return parameters.equals(other.parameters); } public void write(Appendable out) throws IOException { out.append('('); for (Iterator<Type> iter = parameters.iterator(); iter.hasNext(); ) { iter.next().write(out); if (iter.hasNext() || varargs) { out.append(", "); } } if (varargs) out.append("..."); out.append(") -> "); if (result.resolve().isFunction()) { out.append('('); result.write(out); out.append(')'); } else { result.write(out); } } }