001: /* Soot - a J*va Optimization Framework
002: * Copyright (C) 1997-1999 Raja Vallee-Rai
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library 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 GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the
016: * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
017: * Boston, MA 02111-1307, USA.
018: */
019:
020: /*
021: * Modified by the Sable Research Group and others 1997-1999.
022: * See the 'credits' file distributed with Soot for the complete list of
023: * contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
024: */
025:
026: package soot;
027:
028: import soot.util.*;
029:
030: /**
031: * A class that models Java's array types. ArrayTypes are parametrized by a Type and
032: * and an integer representing the array's dimension count..
033: * Two ArrayType are 'equal' if they are parametrized equally.
034: *
035: *
036: *
037: */
038: public class ArrayType extends RefLikeType {
039: /**
040: * baseType can be any type except for an array type, null and void
041: *
042: * What is the base type of the array? That is, for an array of type
043: * A[][][], how do I find out what the A is? The accepted way of
044: * doing this has always been to look at the public field baseType
045: * in ArrayType, ever since the very beginning of Soot.
046: */
047: public final Type baseType;
048:
049: /** dimension count for the array type*/
050: public final int numDimensions;
051:
052: private ArrayType(Type baseType, int numDimensions) {
053: if (!(baseType instanceof PrimType || baseType instanceof RefType))
054: throw new RuntimeException("oops");
055: if (numDimensions < 1)
056: throw new RuntimeException("attempt to create array with "
057: + numDimensions + " dimensions");
058: this .baseType = baseType;
059: this .numDimensions = numDimensions;
060: }
061:
062: /**
063: * Creates an ArrayType parametrized by a given Type and dimension count.
064: * @param baseType a Type to parametrize the ArrayType
065: * @param numDimensions the dimension count to parametrize the ArrayType.
066: * @return an ArrayType parametrized accrodingly.
067: */
068: public static ArrayType v(Type baseType, int numDimensions) {
069: if (numDimensions < 1)
070: throw new RuntimeException("attempt to create array with "
071: + numDimensions + " dimensions");
072: ArrayType ret;
073: Type elementType;
074: if (numDimensions == 1) {
075: elementType = baseType;
076: } else {
077: elementType = ArrayType.v(baseType, numDimensions - 1);
078: }
079: ret = elementType.getArrayType();
080: if (ret == null) {
081: ret = new ArrayType(baseType, numDimensions);
082: elementType.setArrayType(ret);
083: }
084: return ret;
085: }
086:
087: /**
088: * Two ArrayType are 'equal' if they are parametrized identically.
089: * (ie have same Type and dimension count.
090: * @param t object to test for equality
091: * @return true if t is an ArrayType and is parametrized identically to this.
092: */
093: public boolean equals(Object t) {
094: return t == this ;
095: /*
096: if(t instanceof ArrayType)
097: {
098: ArrayType arrayType = (ArrayType) t;
099:
100: return this.numDimensions == arrayType.numDimensions &&
101: this.baseType.equals(arrayType.baseType);
102: }
103: else
104: return false;
105: */
106: }
107:
108: public void toString(UnitPrinter up) {
109: up.type(baseType);
110:
111: for (int i = 0; i < numDimensions; i++)
112: up.literal("[]");
113: }
114:
115: public String toString() {
116: StringBuffer buffer = new StringBuffer();
117:
118: buffer.append(baseType.toString());
119:
120: for (int i = 0; i < numDimensions; i++)
121: buffer.append("[]");
122:
123: return buffer.toString();
124: }
125:
126: public int hashCode() {
127: return baseType.hashCode() + 0x432E0341 * numDimensions;
128: }
129:
130: public void apply(Switch sw) {
131: ((TypeSwitch) sw).caseArrayType(this );
132: }
133:
134: /**
135: * If I have a variable x of declared type t, what is a good
136: * declared type for the expression ((Object[]) x)[i]? The
137: * getArrayElementType() method in RefLikeType was introduced to
138: * answer this question for all classes implementing RefLikeType. If
139: * t is an array, then the answer is the same as getElementType().
140: * But t could also be Object, Serializable, or Cloneable, which can
141: * all hold any array, so then the answer is Object.
142: */
143: public Type getArrayElementType() {
144: return getElementType();
145: }
146:
147: /**
148: * If I get an element of the array, what will be its type? That
149: * is, if I have an array a of type A[][][], what is the type of
150: * a[] (it's A[][])? The getElementType() method in ArrayType was
151: * introduced to answer this question.
152: */
153: public Type getElementType() {
154: if (numDimensions > 1) {
155: return ArrayType.v(baseType, numDimensions - 1);
156: } else {
157: return baseType;
158: }
159: }
160:
161: public ArrayType makeArrayType() {
162: return ArrayType.v(baseType, numDimensions + 1);
163: }
164: }
|