Skip to content

Commit 26c080e

Browse files
committed
Add emulation for java.lang.reflect.Array.
Change-Id: Ie6c4b232d2d4c582cc0b8bfd6d00f86700f03c6d Review-Link: https://gwt-review.googlesource.com/#/c/19260/
1 parent 391075f commit 26c080e

File tree

3 files changed

+718
-0
lines changed

3 files changed

+718
-0
lines changed
Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
/*
2+
* Copyright 2017 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
package java.lang.reflect;
17+
18+
import static javaemul.internal.InternalPreconditions.checkArgument;
19+
import static javaemul.internal.InternalPreconditions.checkNotNull;
20+
21+
import javaemul.internal.ArrayHelper;
22+
23+
/**
24+
* See <a
25+
* href="http://java.sun.com/javase/6/docs/api/java/lang/reflect/Array.html">the
26+
* official Java API doc</a> for details.
27+
*/
28+
public final class Array {
29+
30+
public static Object get(Object array, int index) {
31+
if (array instanceof boolean[]) {
32+
return getBooleanImpl(array, index);
33+
} else if (array instanceof byte[]) {
34+
return getByteImpl(array, index);
35+
} else if (array instanceof char[]) {
36+
return getCharImpl(array, index);
37+
} else if (array instanceof double[]) {
38+
return getDoubleImpl(array, index);
39+
} else if (array instanceof float[]) {
40+
return getFloatImpl(array, index);
41+
} else if (array instanceof int[]) {
42+
return getIntImpl(array, index);
43+
} else if (array instanceof long[]) {
44+
return getLongImpl(array, index);
45+
} else if (array instanceof short[]) {
46+
return getShortImpl(array, index);
47+
} else {
48+
checkArgument(array instanceof Object[]);
49+
Object[] typedArray = (Object[]) array;
50+
return typedArray[index];
51+
}
52+
}
53+
54+
public static boolean getBoolean(Object array, int index) {
55+
checkArgument(array instanceof boolean[]);
56+
return getBooleanImpl(array, index);
57+
}
58+
59+
private static boolean getBooleanImpl(Object array, int index) {
60+
boolean[] typedArray = (boolean[]) array;
61+
return typedArray[index];
62+
}
63+
64+
public static byte getByte(Object array, int index) {
65+
checkArgument(array instanceof byte[]);
66+
return getByteImpl(array, index);
67+
}
68+
69+
private static byte getByteImpl(Object array, int index) {
70+
byte[] typedArray = (byte[]) array;
71+
return typedArray[index];
72+
}
73+
74+
public static char getChar(Object array, int index) {
75+
checkArgument(array instanceof char[]);
76+
return getCharImpl(array, index);
77+
}
78+
79+
private static char getCharImpl(Object array, int index) {
80+
char[] typedArray = (char[]) array;
81+
return typedArray[index];
82+
}
83+
84+
public static double getDouble(Object array, int index) {
85+
checkArgument(array instanceof double[]);
86+
return getDoubleImpl(array, index);
87+
}
88+
89+
private static double getDoubleImpl(Object array, int index) {
90+
double[] typedArray = (double[]) array;
91+
return typedArray[index];
92+
}
93+
94+
public static float getFloat(Object array, int index) {
95+
checkArgument(array instanceof float[]);
96+
return getFloatImpl(array, index);
97+
}
98+
99+
private static float getFloatImpl(Object array, int index) {
100+
float[] typedArray = (float[]) array;
101+
return typedArray[index];
102+
}
103+
104+
public static int getInt(Object array, int index) {
105+
checkArgument(array instanceof int[]);
106+
return getIntImpl(array, index);
107+
}
108+
109+
private static int getIntImpl(Object array, int index) {
110+
int[] typedArray = (int[]) array;
111+
return typedArray[index];
112+
}
113+
114+
public static int getLength(Object array) {
115+
checkNotNull(array);
116+
return ArrayHelper.getLength(array);
117+
}
118+
119+
public static long getLong(Object array, int index) {
120+
checkArgument(array instanceof long[]);
121+
return getLongImpl(array, index);
122+
}
123+
124+
private static long getLongImpl(Object array, int index) {
125+
long[] typedArray = (long[]) array;
126+
return typedArray[index];
127+
}
128+
129+
public static short getShort(Object array, int index) {
130+
checkArgument(array instanceof short[]);
131+
return getShortImpl(array, index);
132+
}
133+
134+
private static short getShortImpl(Object array, int index) {
135+
short[] typedArray = (short[]) array;
136+
return typedArray[index];
137+
}
138+
139+
public static void set(Object array, int index, Object value) {
140+
if (array instanceof boolean[]) {
141+
setBooleanImpl(array, index, (Boolean) value);
142+
} else if (array instanceof byte[]) {
143+
setByteImpl(array, index, (Byte) value);
144+
} else if (array instanceof char[]) {
145+
setCharImpl(array, index, (Character) value);
146+
} else if (array instanceof double[]) {
147+
setDoubleImpl(array, index, (Double) value);
148+
} else if (array instanceof float[]) {
149+
setFloatImpl(array, index, (Float) value);
150+
} else if (array instanceof int[]) {
151+
setIntImpl(array, index, (Integer) value);
152+
} else if (array instanceof long[]) {
153+
setLongImpl(array, index, (Long) value);
154+
} else if (array instanceof short[]) {
155+
setShortImpl(array, index, (Short) value);
156+
} else {
157+
checkArgument(array instanceof Object[]);
158+
Object[] typedArray = (Object[]) array;
159+
typedArray[index] = value;
160+
}
161+
}
162+
163+
public static void setBoolean(Object array, int index, boolean value) {
164+
checkArgument(array instanceof boolean[]);
165+
setBooleanImpl(array, index, value);
166+
}
167+
168+
private static void setBooleanImpl(Object array, int index, boolean value) {
169+
boolean[] typedArray = (boolean[]) array;
170+
typedArray[index] = value;
171+
}
172+
173+
public static void setByte(Object array, int index, byte value) {
174+
checkArgument(array instanceof byte[]);
175+
setByteImpl(array, index, value);
176+
}
177+
178+
private static void setByteImpl(Object array, int index, byte value) {
179+
byte[] typedArray = (byte[]) array;
180+
typedArray[index] = value;
181+
}
182+
183+
public static void setChar(Object array, int index, char value) {
184+
checkArgument(array instanceof char[]);
185+
setCharImpl(array, index, value);
186+
}
187+
188+
private static void setCharImpl(Object array, int index, char value) {
189+
char[] typedArray = (char[]) array;
190+
typedArray[index] = value;
191+
}
192+
193+
public static void setDouble(Object array, int index, double value) {
194+
checkArgument(array instanceof double[]);
195+
setDoubleImpl(array, index, value);
196+
}
197+
198+
private static void setDoubleImpl(Object array,int index, double value) {
199+
double[] typedArray = (double[]) array;
200+
typedArray[index] = value;
201+
}
202+
203+
public static void setFloat(Object array, int index, float value) {
204+
checkArgument(array instanceof float[]);
205+
setFloatImpl(array, index, value);
206+
}
207+
208+
private static void setFloatImpl(Object array, int index, float value) {
209+
float[] typedArray = (float[]) array;
210+
typedArray[index] = value;
211+
}
212+
213+
public static void setInt(Object array, int index, int value) {
214+
checkArgument(array instanceof int[]);
215+
setIntImpl(array, index, value);
216+
}
217+
218+
private static void setIntImpl(Object array, int index, int value) {
219+
int[] typedArray = (int[]) array;
220+
typedArray[index] = value;
221+
}
222+
223+
public static void setLong(Object array, int index, long value) {
224+
checkArgument(array instanceof long[]);
225+
setLongImpl(array, index, value);
226+
}
227+
228+
private static void setLongImpl(Object array, int index, long value) {
229+
long[] typedArray = (long[]) array;
230+
typedArray[index] = value;
231+
}
232+
233+
public static void setShort(Object array, int index, short value) {
234+
checkArgument(array instanceof short[]);
235+
setShortImpl(array, index, value);
236+
}
237+
238+
private static void setShortImpl(Object array, int index, short value) {
239+
short[] typedArray = (short[]) array;
240+
typedArray[index] = value;
241+
}
242+
243+
// There is a good reason to not implement the generic newInstance methods:
244+
//
245+
// In GWT we would need access from a class literal to the castable type map, which
246+
// could be done, but would require some serious work.
247+
// But it would also mean that we can not compute all Array types being instantiated anymore and
248+
// thus would have to retain more castable type information (bloat).
249+
//
250+
// In J2CL the problem is slightly different. Most checking is deferred to runtime in J2CL and
251+
// we retain constructor functions of leaf types. To ensure that we are not just retaining
252+
// all constructors in a program we make sure that access to these always gets inlined with
253+
// array creation. By allowing a generic method we would not be able to ensure this anymore
254+
// and might cause serious bloat in a program.
255+
// A middle ground for J2CL could be to treat this method special in the compiler and fail the
256+
// compile if its not called with a compile time constant for the class literal.
257+
258+
// Not implemented:
259+
// public static Object newInstance(Class<?> componentType, int... dimensions)
260+
// public static Object newInstance(Class<?> componentType, int length)
261+
262+
private Array() {
263+
}
264+
}

user/test/com/google/gwt/emultest/EmulSuite.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import com.google.gwt.emultest.java.lang.ThrowableStackTraceEmulTest;
4242
import com.google.gwt.emultest.java.lang.ThrowableTest;
4343
import com.google.gwt.emultest.java.lang.TypeTest;
44+
import com.google.gwt.emultest.java.lang.reflect.ArrayTest;
4445
import com.google.gwt.emultest.java.math.MathContextTest;
4546
import com.google.gwt.emultest.java.math.MathContextWithObfuscatedEnumsTest;
4647
import com.google.gwt.emultest.java.math.RoundingModeTest;
@@ -91,6 +92,9 @@
9192
ThrowableStackTraceEmulTest.class,
9293
TypeTest.class,
9394

95+
// java.lang.reflect
96+
ArrayTest.class,
97+
9498
//-- java.math
9599
// BigDecimal is tested in {@link BigDecimalSuite}
96100
// BigInteger is tested in {@link BigIntegerSuite}

0 commit comments

Comments
 (0)