Tue, 13 Oct 2009 15:26:30 -0700
6891079: Compiler allows invalid binary literals 0b and oBL
Reviewed-by: darcy
1 /*
2 * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
26 package com.sun.tools.classfile;
28 import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info;
29 import com.sun.tools.classfile.ConstantPool.CONSTANT_Double_info;
30 import com.sun.tools.classfile.ConstantPool.CONSTANT_Fieldref_info;
31 import com.sun.tools.classfile.ConstantPool.CONSTANT_Float_info;
32 import com.sun.tools.classfile.ConstantPool.CONSTANT_Integer_info;
33 import com.sun.tools.classfile.ConstantPool.CONSTANT_InterfaceMethodref_info;
34 import com.sun.tools.classfile.ConstantPool.CONSTANT_Long_info;
35 import com.sun.tools.classfile.ConstantPool.CONSTANT_Methodref_info;
36 import com.sun.tools.classfile.ConstantPool.CONSTANT_NameAndType_info;
37 import com.sun.tools.classfile.ConstantPool.CONSTANT_String_info;
38 import com.sun.tools.classfile.ConstantPool.CONSTANT_Utf8_info;
39 import com.sun.tools.classfile.ConstantPool.CPInfo;
40 import java.util.Map;
42 /**
43 * Rewrites a class file using a map of translations.
44 *
45 * <p><b>This is NOT part of any API supported by Sun Microsystems. If
46 * you write code that depends on this, you do so at your own risk.
47 * This code and its internal interfaces are subject to change or
48 * deletion without notice.</b>
49 */
50 public class ClassTranslator
51 implements ConstantPool.Visitor<ConstantPool.CPInfo,Map<Object,Object>> {
52 /**
53 * Create a new ClassFile from {@code cf}, such that for all entries
54 * {@code k -\> v} in {@code translations},
55 * each occurrence of {@code k} in {@code cf} will be replaced by {@code v}.
56 * in
57 * @param cf the class file to be processed
58 * @param translations the set of translations to be applied
59 * @return a copy of {@code} with the values in {@code translations} substituted
60 */
61 public ClassFile translate(ClassFile cf, Map<Object,Object> translations) {
62 ClassFile cf2 = (ClassFile) translations.get(cf);
63 if (cf2 == null) {
64 ConstantPool constant_pool2 = translate(cf.constant_pool, translations);
65 Field[] fields2 = translate(cf.fields, cf.constant_pool, translations);
66 Method[] methods2 = translateMethods(cf.methods, cf.constant_pool, translations);
67 Attributes attributes2 = translateAttributes(cf.attributes, cf.constant_pool,
68 translations);
70 if (constant_pool2 == cf.constant_pool &&
71 fields2 == cf.fields &&
72 methods2 == cf.methods &&
73 attributes2 == cf.attributes)
74 cf2 = cf;
75 else
76 cf2 = new ClassFile(
77 cf.magic,
78 cf.minor_version,
79 cf.major_version,
80 constant_pool2,
81 cf.access_flags,
82 cf.this_class,
83 cf.super_class,
84 cf.interfaces,
85 fields2,
86 methods2,
87 attributes2);
88 translations.put(cf, cf2);
89 }
90 return cf2;
91 }
93 ConstantPool translate(ConstantPool cp, Map<Object,Object> translations) {
94 ConstantPool cp2 = (ConstantPool) translations.get(cp);
95 if (cp2 == null) {
96 ConstantPool.CPInfo[] pool2 = new ConstantPool.CPInfo[cp.size()];
97 boolean eq = true;
98 for (int i = 0; i < cp.size(); ) {
99 ConstantPool.CPInfo cpInfo;
100 try {
101 cpInfo = cp.get(i);
102 } catch (ConstantPool.InvalidIndex e) {
103 throw new IllegalStateException(e);
104 }
105 ConstantPool.CPInfo cpInfo2 = translate(cpInfo, translations);
106 eq &= (cpInfo == cpInfo2);
107 pool2[i] = cpInfo2;
108 if (cpInfo.getTag() != cpInfo2.getTag())
109 throw new IllegalStateException();
110 i += cpInfo.size();
111 }
113 if (eq)
114 cp2 = cp;
115 else
116 cp2 = new ConstantPool(pool2);
118 translations.put(cp, cp2);
119 }
120 return cp2;
121 }
123 ConstantPool.CPInfo translate(ConstantPool.CPInfo cpInfo, Map<Object,Object> translations) {
124 ConstantPool.CPInfo cpInfo2 = (ConstantPool.CPInfo) translations.get(cpInfo);
125 if (cpInfo2 == null) {
126 cpInfo2 = cpInfo.accept(this, translations);
127 translations.put(cpInfo, cpInfo2);
128 }
129 return cpInfo2;
130 }
132 Field[] translate(Field[] fields, ConstantPool constant_pool, Map<Object,Object> translations) {
133 Field[] fields2 = (Field[]) translations.get(fields);
134 if (fields2 == null) {
135 fields2 = new Field[fields.length];
136 for (int i = 0; i < fields.length; i++)
137 fields2[i] = translate(fields[i], constant_pool, translations);
138 if (equal(fields, fields2))
139 fields2 = fields;
140 translations.put(fields, fields2);
141 }
142 return fields2;
143 }
145 Field translate(Field field, ConstantPool constant_pool, Map<Object,Object> translations) {
146 Field field2 = (Field) translations.get(field);
147 if (field2 == null) {
148 Attributes attributes2 = translateAttributes(field.attributes, constant_pool,
149 translations);
151 if (attributes2 == field.attributes)
152 field2 = field;
153 else
154 field2 = new Field(
155 field.access_flags,
156 field.name_index,
157 field.descriptor,
158 attributes2);
159 translations.put(field, field2);
160 }
161 return field2;
162 }
164 Method[] translateMethods(Method[] methods, ConstantPool constant_pool, Map<Object,Object> translations) {
165 Method[] methods2 = (Method[]) translations.get(methods);
166 if (methods2 == null) {
167 methods2 = new Method[methods.length];
168 for (int i = 0; i < methods.length; i++)
169 methods2[i] = translate(methods[i], constant_pool, translations);
170 if (equal(methods, methods2))
171 methods2 = methods;
172 translations.put(methods, methods2);
173 }
174 return methods2;
175 }
177 Method translate(Method method, ConstantPool constant_pool, Map<Object,Object> translations) {
178 Method method2 = (Method) translations.get(method);
179 if (method2 == null) {
180 Attributes attributes2 = translateAttributes(method.attributes, constant_pool,
181 translations);
183 if (attributes2 == method.attributes)
184 method2 = method;
185 else
186 method2 = new Method(
187 method.access_flags,
188 method.name_index,
189 method.descriptor,
190 attributes2);
191 translations.put(method, method2);
192 }
193 return method2;
194 }
196 Attributes translateAttributes(Attributes attributes,
197 ConstantPool constant_pool, Map<Object,Object> translations) {
198 Attributes attributes2 = (Attributes) translations.get(attributes);
199 if (attributes2 == null) {
200 Attribute[] attrArray2 = new Attribute[attributes.size()];
201 ConstantPool constant_pool2 = translate(constant_pool, translations);
202 boolean attrsEqual = true;
203 for (int i = 0; i < attributes.size(); i++) {
204 Attribute attr = attributes.get(i);
205 Attribute attr2 = translate(attr, translations);
206 if (attr2 != attr)
207 attrsEqual = false;
208 attrArray2[i] = attr2;
209 }
210 if ((constant_pool2 == constant_pool) && attrsEqual)
211 attributes2 = attributes;
212 else
213 attributes2 = new Attributes(constant_pool2, attrArray2);
214 translations.put(attributes, attributes2);
215 }
216 return attributes2;
217 }
219 Attribute translate(Attribute attribute, Map<Object,Object> translations) {
220 Attribute attribute2 = (Attribute) translations.get(attribute);
221 if (attribute2 == null) {
222 attribute2 = attribute; // don't support translation within attributes yet
223 // (what about Code attribute)
224 translations.put(attribute, attribute2);
225 }
226 return attribute2;
227 }
229 private static <T> boolean equal(T[] a1, T[] a2) {
230 if (a1 == null || a2 == null)
231 return (a1 == a2);
232 if (a1.length != a2.length)
233 return false;
234 for (int i = 0; i < a1.length; i++) {
235 if (a1[i] != a2[i])
236 return false;
237 }
238 return true;
239 }
241 public CPInfo visitClass(CONSTANT_Class_info info, Map<Object, Object> translations) {
242 CONSTANT_Class_info info2 = (CONSTANT_Class_info) translations.get(info);
243 if (info2 == null) {
244 ConstantPool cp2 = translate(info.cp, translations);
245 if (cp2 == info.cp)
246 info2 = info;
247 else
248 info2 = new CONSTANT_Class_info(cp2, info.name_index);
249 translations.put(info, info2);
250 }
251 return info;
252 }
254 public CPInfo visitDouble(CONSTANT_Double_info info, Map<Object, Object> translations) {
255 CONSTANT_Double_info info2 = (CONSTANT_Double_info) translations.get(info);
256 if (info2 == null) {
257 info2 = info;
258 translations.put(info, info2);
259 }
260 return info;
261 }
263 public CPInfo visitFieldref(CONSTANT_Fieldref_info info, Map<Object, Object> translations) {
264 CONSTANT_Fieldref_info info2 = (CONSTANT_Fieldref_info) translations.get(info);
265 if (info2 == null) {
266 ConstantPool cp2 = translate(info.cp, translations);
267 if (cp2 == info.cp)
268 info2 = info;
269 else
270 info2 = new CONSTANT_Fieldref_info(cp2, info.class_index, info.name_and_type_index);
271 translations.put(info, info2);
272 }
273 return info;
274 }
276 public CPInfo visitFloat(CONSTANT_Float_info info, Map<Object, Object> translations) {
277 CONSTANT_Float_info info2 = (CONSTANT_Float_info) translations.get(info);
278 if (info2 == null) {
279 info2 = info;
280 translations.put(info, info2);
281 }
282 return info;
283 }
285 public CPInfo visitInteger(CONSTANT_Integer_info info, Map<Object, Object> translations) {
286 CONSTANT_Integer_info info2 = (CONSTANT_Integer_info) translations.get(info);
287 if (info2 == null) {
288 info2 = info;
289 translations.put(info, info2);
290 }
291 return info;
292 }
294 public CPInfo visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Map<Object, Object> translations) {
295 CONSTANT_InterfaceMethodref_info info2 = (CONSTANT_InterfaceMethodref_info) translations.get(info);
296 if (info2 == null) {
297 ConstantPool cp2 = translate(info.cp, translations);
298 if (cp2 == info.cp)
299 info2 = info;
300 else
301 info2 = new CONSTANT_InterfaceMethodref_info(cp2, info.class_index, info.name_and_type_index);
302 translations.put(info, info2);
303 }
304 return info;
305 }
307 public CPInfo visitLong(CONSTANT_Long_info info, Map<Object, Object> translations) {
308 CONSTANT_Long_info info2 = (CONSTANT_Long_info) translations.get(info);
309 if (info2 == null) {
310 info2 = info;
311 translations.put(info, info2);
312 }
313 return info;
314 }
316 public CPInfo visitNameAndType(CONSTANT_NameAndType_info info, Map<Object, Object> translations) {
317 CONSTANT_NameAndType_info info2 = (CONSTANT_NameAndType_info) translations.get(info);
318 if (info2 == null) {
319 ConstantPool cp2 = translate(info.cp, translations);
320 if (cp2 == info.cp)
321 info2 = info;
322 else
323 info2 = new CONSTANT_NameAndType_info(cp2, info.name_index, info.type_index);
324 translations.put(info, info2);
325 }
326 return info;
327 }
329 public CPInfo visitMethodref(CONSTANT_Methodref_info info, Map<Object, Object> translations) {
330 CONSTANT_Methodref_info info2 = (CONSTANT_Methodref_info) translations.get(info);
331 if (info2 == null) {
332 ConstantPool cp2 = translate(info.cp, translations);
333 if (cp2 == info.cp)
334 info2 = info;
335 else
336 info2 = new CONSTANT_Methodref_info(cp2, info.class_index, info.name_and_type_index);
337 translations.put(info, info2);
338 }
339 return info;
340 }
342 public CPInfo visitString(CONSTANT_String_info info, Map<Object, Object> translations) {
343 CONSTANT_String_info info2 = (CONSTANT_String_info) translations.get(info);
344 if (info2 == null) {
345 ConstantPool cp2 = translate(info.cp, translations);
346 if (cp2 == info.cp)
347 info2 = info;
348 else
349 info2 = new CONSTANT_String_info(cp2, info.string_index);
350 translations.put(info, info2);
351 }
352 return info;
353 }
355 public CPInfo visitUtf8(CONSTANT_Utf8_info info, Map<Object, Object> translations) {
356 CONSTANT_Utf8_info info2 = (CONSTANT_Utf8_info) translations.get(info);
357 if (info2 == null) {
358 info2 = info;
359 translations.put(info, info2);
360 }
361 return info;
362 }
364 }