forked from soot-oss/soot
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathArrayType.java
More file actions
173 lines (153 loc) · 5.3 KB
/
ArrayType.java
File metadata and controls
173 lines (153 loc) · 5.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package soot;
/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 1997 - 1999 Raja Vallee-Rai
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* 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 Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
* #L%
*/
import soot.util.Switch;
/**
* A class that models Java's array types. ArrayTypes are parameterized by a Type and and an integer representing the array's
* dimension count. Two ArrayType are 'equal' if they are parameterized equally.
*/
@SuppressWarnings("serial")
public class ArrayType extends RefLikeType {
/**
* baseType can be any type except for an array type, null and void
*
* What is the base type of the array? That is, for an array of type A[][][], how do I find out what the A is? The accepted
* way of doing this has always been to look at the public field baseType in ArrayType, ever since the very beginning of
* Soot.
*/
public final Type baseType;
/**
* dimension count for the array type
*/
public final int numDimensions;
private ArrayType(Type baseType, int numDimensions) {
if (!(baseType instanceof PrimType || baseType instanceof RefType || baseType instanceof NullType)) {
throw new RuntimeException("oops, base type must be PrimType or RefType but not '" + baseType + "'");
}
if (numDimensions < 1) {
throw new RuntimeException("attempt to create array with " + numDimensions + " dimensions");
}
this.baseType = baseType;
this.numDimensions = numDimensions;
}
/**
* Creates an ArrayType parameterized by a given Type and dimension count.
*
* @param baseType
* a Type to parameterize the ArrayType
* @param numDimensions
* the dimension count to parameterize the ArrayType.
* @return an ArrayType parameterized accordingly.
*/
public static ArrayType v(Type baseType, int numDimensions) {
if (numDimensions < 0) {
throw new RuntimeException("Invalid number of array dimensions: " + numDimensions);
}
final int orgDimensions = numDimensions;
Type elementType = baseType;
while (numDimensions > 0) {
ArrayType ret = elementType.getArrayType();
if (ret == null) {
ret = new ArrayType(baseType, orgDimensions - numDimensions + 1);
elementType.setArrayType(ret);
}
elementType = ret;
numDimensions--;
}
return (ArrayType) elementType;
}
/**
* Two ArrayType are 'equal' if they are parameterized identically. (ie have same Type and dimension count.
*
* @param t
* object to test for equality
* @return true if t is an ArrayType and is parameterized identically to this.
*/
@Override
public boolean equals(Object t) {
return t == this;
}
public void toString(UnitPrinter up) {
up.type(baseType);
for (int i = 0; i < numDimensions; i++) {
up.literal("[]");
}
}
@Override
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append(baseType.toString());
for (int i = 0; i < numDimensions; i++) {
buffer.append("[]");
}
return buffer.toString();
}
/**
* Returns a textual representation, quoted as needed, of this type for serialization, e.g. to .jimple format
*/
@Override
public String toQuotedString() {
StringBuilder buffer = new StringBuilder();
buffer.append(baseType.toQuotedString());
for (int i = 0; i < numDimensions; i++) {
buffer.append("[]");
}
return buffer.toString();
}
@Override
public int hashCode() {
return baseType.hashCode() + 0x432E0341 * numDimensions;
}
@Override
public void apply(Switch sw) {
((TypeSwitch) sw).caseArrayType(this);
}
/**
* If I have a variable x of declared type t, what is a good declared type for the expression ((Object[]) x)[i]? The
* getArrayElementType() method in RefLikeType was introduced to answer this question for all classes implementing
* RefLikeType. If t is an array, then the answer is the same as getElementType(). But t could also be Object,
* Serializable, or Cloneable, which can all hold any array, so then the answer is Object.
*/
@Override
public Type getArrayElementType() {
return getElementType();
}
/**
* If I get an element of the array, what will be its type? That is, if I have an array a of type A[][][], what is the type
* of a[] (it's A[][])? The getElementType() method in ArrayType was introduced to answer this question.
*/
public Type getElementType() {
if (numDimensions > 1) {
return ArrayType.v(baseType, numDimensions - 1);
} else {
return baseType;
}
}
@Override
public ArrayType makeArrayType() {
return ArrayType.v(baseType, numDimensions + 1);
}
@Override
public boolean isAllowedInFinalCode() {
return true;
}
}