001: /*
002: * xtc - The eXTensible Compiler
003: * Copyright (C) 2005-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: /**
024: * An array type. An array can either be of fixed or variable length,
025: * with a length of <code>-1</code> indicating that a fixed length
026: * array is incomplete.
027: *
028: * @author Robert Grimm
029: * @version $Revision: 1.40 $
030: */
031: public class ArrayT extends DerivedT {
032:
033: /** The element type. */
034: private Type type;
035:
036: /** The flag for whether the array is variable length. */
037: private boolean varlength;
038:
039: /** The length. */
040: private long length;
041:
042: /**
043: * Create a new, incomplete array type.
044: *
045: * @param type The element type.
046: */
047: public ArrayT(Type type) {
048: this (type, -1);
049: }
050:
051: /**
052: * Create a new variable length array.
053: *
054: * @param type The element type.
055: * @param varlength The flag for whether this array is of variable
056: * length, which must be <code>true</code>.
057: */
058: public ArrayT(Type type, boolean varlength) {
059: this .type = type;
060: this .varlength = varlength;
061: this .length = -1;
062: }
063:
064: /**
065: * Create a new array type.
066: *
067: * @param type The element type.
068: * @param length The length.
069: */
070: public ArrayT(Type type, long length) {
071: this .type = type;
072: this .varlength = false;
073: this .length = length;
074: }
075:
076: /**
077: * Create a new array type.
078: *
079: * @param template The type whose annotations to copy.
080: * @param type The element type.
081: * @param varlength The flag for whether this array is variable.
082: * @param length The length.
083: */
084: public ArrayT(Type template, Type type, boolean varlength,
085: long length) {
086: super (template);
087: this .type = type;
088: this .varlength = varlength;
089: this .length = length;
090: }
091:
092: public Type seal() {
093: if (!isSealed()) {
094: super .seal();
095: type.seal();
096: }
097: return this ;
098: }
099:
100: public ArrayT copy() {
101: return new ArrayT(this , type, varlength, length);
102: }
103:
104: public Type.Tag tag() {
105: return Type.Tag.ARRAY;
106: }
107:
108: public boolean isArray() {
109: return true;
110: }
111:
112: public ArrayT toArray() {
113: return this ;
114: }
115:
116: /**
117: * Get the element type.
118: *
119: * @return The element type.
120: */
121: public Type getType() {
122: return type;
123: }
124:
125: /**
126: * Determine whether the array is of variable length.
127: *
128: * @return <code>true</code> if this array is variable length.
129: */
130: public boolean isVarLength() {
131: return varlength;
132: }
133:
134: /**
135: * Set the variable length flag.
136: *
137: * @param varlength The variable length flag.
138: * @throws IllegalStateException Signals that this type is sealed.
139: */
140: public void setVarLength(boolean varlength) {
141: checkNotSealed();
142: this .varlength = varlength;
143: }
144:
145: /**
146: * Determine whether this array has a length.
147: *
148: * @return <code>true</code> if this array has a length.
149: */
150: public boolean hasLength() {
151: return -1 != length;
152: }
153:
154: /**
155: * Get the length.
156: *
157: * @return The length or <code>-1</code> if this type is either of
158: * variable length or incomplete.
159: */
160: public long getLength() {
161: return length;
162: }
163:
164: /**
165: * Set the length.
166: *
167: * @param length The length.
168: * @throws IllegalStateException Signals that this type is sealed.
169: */
170: public void setLength(long length) {
171: checkNotSealed();
172: this .length = length;
173: }
174:
175: public int hashCode() {
176: return type.hashCode();
177: }
178:
179: public boolean equals(Object o) {
180: if (!(o instanceof Type))
181: return false;
182: Type t = resolve(o);
183:
184: if (this == t)
185: return true;
186: if (!t.isArray())
187: return false;
188: ArrayT other = (ArrayT) t;
189:
190: if (this .varlength != other.varlength)
191: return false;
192: if (this .length != other.length)
193: return false;
194: return this .type.equals(other.type);
195: }
196:
197: public void write(Appendable out) throws IOException {
198: out.append("array(");
199: type.write(out);
200: if (varlength) {
201: out.append(", *");
202: } else if (-1 != length) {
203: out.append(", ");
204: out.append(Long.toString(length));
205: }
206: out.append(')');
207: }
208:
209: }
|