001: /*
002: * xtc - The eXTensible Compiler
003: * Copyright (C) 2006-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.Iterator;
024: import java.util.List;
025:
026: /**
027: * The superclass of function and method types.
028: *
029: * @author Robert Grimm
030: * @version $Revision: 1.22 $
031: */
032: public abstract class FunctionOrMethodT extends DerivedT {
033:
034: /** The result type. */
035: protected Type result;
036:
037: /** The optional name. */
038: protected String name;
039:
040: /** The list of parameter types. */
041: protected List<Type> parameters;
042:
043: /**
044: * The flag for whether the function accepts a variable number of
045: * arguments.
046: */
047: protected boolean varargs;
048:
049: /** The optional list of exceptions. */
050: protected List<Type> exceptions;
051:
052: /**
053: * Create a new function or method type.
054: *
055: * @param template The type whose annotations to copy.
056: * @param result The result type.
057: * @param name The name.
058: * @param parameters The list of parameter types.
059: * @param varargs The flag for accepting a variable number of arguments.
060: * @param exceptions The list of exception types.
061: */
062: public FunctionOrMethodT(Type template, Type result, String name,
063: List<Type> parameters, boolean varargs,
064: List<Type> exceptions) {
065: super (template);
066: this .result = result;
067: this .name = name;
068: this .parameters = parameters;
069: this .varargs = varargs;
070: this .exceptions = exceptions;
071: }
072:
073: public Type seal() {
074: if (!isSealed()) {
075: super .seal();
076: result.seal();
077: parameters = Type.seal(parameters);
078: exceptions = Type.seal(exceptions);
079: }
080: return this ;
081: }
082:
083: /**
084: * Get the result type.
085: *
086: * @return The result type.
087: */
088: public Type getResult() {
089: return result;
090: }
091:
092: /**
093: * Set the result type.
094: *
095: * @param result The new result type.
096: * @throws IllegalStateException Signals that this type is sealed.
097: */
098: public void setResult(Type result) {
099: checkNotSealed();
100: this .result = result;
101: }
102:
103: /**
104: * Get the name.
105: *
106: * @return The name.
107: */
108: public String getName() {
109: return name;
110: }
111:
112: /**
113: * Get the list of parameter types.
114: *
115: * @return The parameter types.
116: */
117: public List<Type> getParameters() {
118: return parameters;
119: }
120:
121: /**
122: * Set the list of parameter types.
123: *
124: * @param parameters The list of parameter types.
125: * @throws IllegalStateException Signals that this type is sealed.
126: */
127: public void setParameters(List<Type> parameters) {
128: checkNotSealed();
129: this .parameters = parameters;
130: }
131:
132: /**
133: * Determine whether this function accepts a variable number of
134: * arguments.
135: *
136: * @return <code>true</code> if this function accepts a variable
137: * number of arguments.
138: */
139: public boolean isVarArgs() {
140: return varargs;
141: }
142:
143: /**
144: * Get the list of exceptions.
145: *
146: * @return The list of exceptions.
147: */
148: public List<Type> getExceptions() {
149: return exceptions;
150: }
151:
152: /**
153: * Set the list of parameter types.
154: *
155: * @param exceptions The list of exception types.
156: * @throws IllegalStateException Signals that this type is sealed.
157: */
158: public void setExceptions(List<Type> exceptions) {
159: checkNotSealed();
160: this .exceptions = exceptions;
161: }
162:
163: public int hashCode() {
164: return parameters.hashCode() * 37 + result.hashCode();
165: }
166:
167: public boolean equals(Object o) {
168: if (!(o instanceof Type))
169: return false;
170: Type t = resolve(o);
171:
172: if (this == t)
173: return true;
174: if (!getClass().equals(t.getClass()))
175: return false;
176: FunctionOrMethodT other = (FunctionOrMethodT) t;
177:
178: if (varargs != other.varargs)
179: return false;
180: if (!result.equals(other.result))
181: return false;
182: if (null == exceptions) {
183: if (null != other.exceptions)
184: return false;
185: } else {
186: if (!exceptions.equals(other.exceptions))
187: return false;
188: }
189: return parameters.equals(other.parameters);
190: }
191:
192: public void write(Appendable out) throws IOException {
193: out.append('(');
194: for (Iterator<Type> iter = parameters.iterator(); iter
195: .hasNext();) {
196: iter.next().write(out);
197: if (iter.hasNext() || varargs) {
198: out.append(", ");
199: }
200: }
201: if (varargs)
202: out.append("...");
203: out.append(") -> ");
204: if (result.resolve().isFunction()) {
205: out.append('(');
206: result.write(out);
207: out.append(')');
208: } else {
209: result.write(out);
210: }
211: }
212:
213: }
|