Tue, 13 Jan 2009 13:27:14 +0000
6765045: Remove rawtypes warnings from langtools
Summary: Removed all occurrences of rawtypes warnings from langtools
Reviewed-by: jjg, bpatel
1 /*
2 * Copyright 2002-2005 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 */
27 package com.sun.tools.javah;
29 import java.io.File;
30 import java.io.OutputStream;
31 import java.io.PrintWriter;
32 import java.util.Hashtable;
33 import com.sun.javadoc.*;
35 /*
36 * @author Sucheta Dambalkar(Revised)
37 */
38 public class LLNI extends Gen {
40 protected final char pathChar = File.separatorChar;
41 protected final char innerDelim = '$'; /* For inner classes */
42 protected Hashtable<Object, Object> doneHandleTypes;
43 MemberDoc []fields;
44 MemberDoc [] methods;
45 private boolean doubleAlign;
46 private int padFieldNum = 0;
49 LLNI(boolean doubleAlign, RootDoc root) {
50 super(root);
51 this.doubleAlign = doubleAlign;
52 }
55 protected String getIncludes() {
56 return "";
57 }
59 protected void write(OutputStream o, ClassDoc clazz)
60 throws ClassNotFoundException {
61 String cname = mangleClassName(clazz.qualifiedName());
62 PrintWriter pw = wrapWriter(o);
63 fields = clazz.fields();
64 methods = clazz.methods();
65 generateDeclsForClass(pw, clazz, cname);
66 }
68 protected void generateDeclsForClass(PrintWriter pw,
69 ClassDoc clazz, String cname)
70 throws ClassNotFoundException {
71 doneHandleTypes = new Hashtable<Object, Object>();
72 /* The following handle types are predefined in "typedefs.h". Suppress
73 inclusion in the output by generating them "into the blue" here. */
74 genHandleType(null, "java.lang.Class");
75 genHandleType(null, "java.lang.ClassLoader");
76 genHandleType(null, "java.lang.Object");
77 genHandleType(null, "java.lang.String");
78 genHandleType(null, "java.lang.Thread");
79 genHandleType(null, "java.lang.ThreadGroup");
80 genHandleType(null, "java.lang.Throwable");
82 pw.println("/* LLNI Header for class " + clazz.qualifiedName() + " */" + lineSep);
83 pw.println("#ifndef _Included_" + cname);
84 pw.println("#define _Included_" + cname);
85 pw.println("#include \"typedefs.h\"");
86 pw.println("#include \"llni.h\"");
87 pw.println("#include \"jni.h\"" + lineSep);
89 forwardDecls(pw, clazz);
90 structSectionForClass(pw, clazz, cname);
91 methodSectionForClass(pw, clazz, cname);
92 pw.println("#endif");
93 }
95 protected void genHandleType(PrintWriter pw, String clazzname) {
96 String cname = mangleClassName(clazzname);
97 if (!doneHandleTypes.containsKey(cname)) {
98 doneHandleTypes.put(cname, cname);
99 if (pw != null) {
100 pw.println("#ifndef DEFINED_" + cname);
101 pw.println(" #define DEFINED_" + cname);
102 pw.println(" GEN_HANDLE_TYPES(" + cname + ");");
103 pw.println("#endif" + lineSep);
104 }
105 }
106 }
108 protected String mangleClassName(String s) {
109 return s.replace('.', '_')
110 .replace(pathChar, '_')
111 .replace(innerDelim, '_');
112 }
114 protected void forwardDecls(PrintWriter pw, ClassDoc clazz)
115 throws ClassNotFoundException {
116 ClassDoc clazzfield = null;
118 if (clazz.qualifiedName().equals("java.lang.Object"))
119 return;
120 genHandleType(pw, clazz.qualifiedName());
121 ClassDoc superClass = clazz.superclass();
123 if(superClass != null){
124 String superClassName = superClass.qualifiedName();
125 forwardDecls(pw, superClass);
126 }
128 for (int i = 0; i < fields.length; i++) {
129 FieldDoc field = (FieldDoc)fields[i];
131 if (!field.isStatic()) {
132 Type t = field.type();
133 String tname = t.qualifiedTypeName();
134 TypeSignature newTypeSig = new TypeSignature(root);
135 String sig = newTypeSig.getTypeSignature(tname);
137 if (sig.charAt(0) != '[')
138 forwardDeclsFromSig(pw, sig);
139 }
140 }
142 for (int i = 0; i < methods.length; i++) {
143 MethodDoc method = (MethodDoc)methods[i];
145 if (method.isNative()) {
146 Type retType = method.returnType();
147 String typesig = method.signature();
148 TypeSignature newTypeSig = new TypeSignature(root);
149 String sig = newTypeSig.getTypeSignature(typesig, retType);
151 if (sig.charAt(0) != '[')
152 forwardDeclsFromSig(pw, sig);
154 }
155 }
156 }
158 protected void forwardDeclsFromSig(PrintWriter pw, String sig) {
159 int len = sig.length();
160 int i = sig.charAt(0) == '(' ? 1 : 0;
162 /* Skip the initial "(". */
163 while (i < len) {
164 if (sig.charAt(i) == 'L') {
165 int j = i + 1;
166 while (sig.charAt(j) != ';') j++;
167 genHandleType(pw, sig.substring(i + 1, j));
168 i = j + 1;
169 } else {
170 i++;
171 }
172 }
173 }
175 protected void structSectionForClass(PrintWriter pw,
176 ClassDoc jclazz, String cname)
177 throws ClassNotFoundException {
179 String jname = jclazz.qualifiedName();
181 if (cname.equals("java_lang_Object")) {
182 pw.println("/* struct java_lang_Object is defined in typedefs.h. */");
183 pw.println();
184 return;
185 }
186 pw.println("#if !defined(__i386)");
187 pw.println("#pragma pack(4)");
188 pw.println("#endif");
189 pw.println();
190 pw.println("struct " + cname + " {");
191 pw.println(" ObjHeader h;");
192 pw.print(fieldDefs(jclazz, cname));
194 if (jname.equals("java.lang.Class"))
195 pw.println(" Class *LLNI_mask(cClass);" +
196 " /* Fake field; don't access (see oobj.h) */");
197 pw.println("};" + lineSep + lineSep + "#pragma pack()");
198 pw.println();
199 return;
200 }
202 private static class FieldDefsRes {
203 public String className; /* Name of the current class. */
204 public FieldDefsRes parent;
205 public String s;
206 public int byteSize;
207 public boolean bottomMost;
208 public boolean printedOne = false;
210 FieldDefsRes(ClassDoc clazz, FieldDefsRes parent, boolean bottomMost) {
211 this.className = clazz.qualifiedName();
212 this.parent = parent;
213 this.bottomMost = bottomMost;
214 int byteSize = 0;
215 if (parent == null) this.s = "";
216 else this.s = parent.s;
217 }
218 }
220 /* Returns "true" iff added a field. */
221 private boolean doField(FieldDefsRes res, FieldDoc field,
222 String cname, boolean padWord)
223 throws ClassNotFoundException {
225 String fieldDef = addStructMember(field, cname, padWord);
226 if (fieldDef != null) {
227 if (!res.printedOne) { /* add separator */
228 if (res.bottomMost) {
229 if (res.s.length() != 0)
230 res.s = res.s + " /* local members: */" + lineSep;
231 } else {
232 res.s = res.s + " /* inherited members from " +
233 res.className + ": */" + lineSep;
234 }
235 res.printedOne = true;
236 }
237 res.s = res.s + fieldDef;
238 return true;
239 }
241 // Otherwise.
242 return false;
243 }
245 private int doTwoWordFields(FieldDefsRes res, ClassDoc clazz,
246 int offset, String cname, boolean padWord)
247 throws ClassNotFoundException {
248 boolean first = true;
249 FieldDoc[] fields = clazz.fields();
251 for (int i = 0; i <fields.length; i++) {
252 FieldDoc field = fields[i];
253 String tc =field.type().typeName();
254 boolean twoWords = (tc.equals("long") || tc.equals("double"));
255 if (twoWords && doField(res, field, cname, first && padWord)) {
256 offset += 8; first = false;
257 }
258 }
259 return offset;
260 }
262 protected String fieldDefs(ClassDoc clazz, String cname)
263 throws ClassNotFoundException {
264 FieldDefsRes res = fieldDefs(clazz, cname, true);
265 return res.s;
266 }
268 protected FieldDefsRes fieldDefs(ClassDoc clazz, String cname,
269 boolean bottomMost)
270 throws ClassNotFoundException {
271 FieldDefsRes res;
272 int offset;
273 boolean didTwoWordFields = false;
274 ClassDoc superclazz = clazz.superclass();
276 if (superclazz != null) {
277 String supername = superclazz.qualifiedName();
278 res = new FieldDefsRes(clazz,
279 fieldDefs(superclazz, cname, false),
280 bottomMost);
281 offset = res.parent.byteSize;
282 } else {
283 res = new FieldDefsRes(clazz, null, bottomMost);
284 offset = 0;
285 }
287 FieldDoc[] fields = clazz.fields();
289 for (int i = 0; i < fields.length; i++) {
290 FieldDoc field = fields[i];
292 if (doubleAlign && !didTwoWordFields && (offset % 8) == 0) {
293 offset = doTwoWordFields(res, clazz, offset, cname, false);
294 didTwoWordFields = true;
295 }
297 String tc = field.type().typeName();
298 boolean twoWords = (tc.equals("long") ||tc.equals("double"));
300 if (!doubleAlign || !twoWords) {
301 if (doField(res, field, cname, false)) offset += 4;
302 }
304 }
306 if (doubleAlign && !didTwoWordFields) {
307 if ((offset % 8) != 0) offset += 4;
308 offset = doTwoWordFields(res, clazz, offset, cname, true);
309 }
311 res.byteSize = offset;
312 return res;
313 }
315 /* OVERRIDE: This method handles instance fields */
316 protected String addStructMember(FieldDoc member, String cname,
317 boolean padWord)
318 throws ClassNotFoundException {
319 String res = null;
321 if (member.isStatic()) {
322 res = addStaticStructMember(member, cname);
323 // if (res == null) /* JNI didn't handle it, print comment. */
324 // res = " /* Inaccessible static: " + member + " */" + lineSep;
325 } else {
326 if (padWord) res = " java_int padWord" + padFieldNum++ + ";" + lineSep;
327 res = " " + llniType(member.type(), false, false) + " " + llniFieldName(member);
328 if (isLongOrDouble(member.type())) res = res + "[2]";
329 res = res + ";" + lineSep;
330 }
331 return res;
332 }
334 static private final boolean isWindows =
335 System.getProperty("os.name").startsWith("Windows");
337 /*
338 * This method only handles static final fields.
339 */
340 protected String addStaticStructMember(FieldDoc field, String cname)
341 throws ClassNotFoundException {
342 String res = null;
343 Object exp = null;
345 if (!field.isStatic())
346 return res;
347 if (!field.isFinal())
348 return res;
350 exp = field.constantValue();
352 if (exp != null) {
353 /* Constant. */
355 String cn = cname + "_" + field.name();
356 String suffix = null;
357 long val = 0;
358 /* Can only handle int, long, float, and double fields. */
359 if (exp instanceof Integer) {
360 suffix = "L";
361 val = ((Integer)exp).intValue();
362 }
363 if (exp instanceof Long) {
364 // Visual C++ supports the i64 suffix, not LL
365 suffix = isWindows ? "i64" : "LL";
366 val = ((Long)exp).longValue();
367 }
368 if (exp instanceof Float) suffix = "f";
369 if (exp instanceof Double) suffix = "";
370 if (suffix != null) {
371 // Some compilers will generate a spurious warning
372 // for the integer constants for Integer.MIN_VALUE
373 // and Long.MIN_VALUE so we handle them specially.
374 if ((suffix.equals("L") && (val == Integer.MIN_VALUE)) ||
375 (suffix.equals("LL") && (val == Long.MIN_VALUE))) {
376 res = " #undef " + cn + lineSep
377 + " #define " + cn
378 + " (" + (val + 1) + suffix + "-1)" + lineSep;
379 } else {
380 res = " #undef " + cn + lineSep
381 + " #define " + cn + " "+ exp.toString() + suffix + lineSep;
382 }
383 }
384 }
385 return res;
386 }
388 protected void methodSectionForClass(PrintWriter pw,
389 ClassDoc clazz, String cname)
390 throws ClassNotFoundException {
391 String methods = methodDecls(clazz, cname);
393 if (methods.length() != 0) {
394 pw.println("/* Native method declarations: */" + lineSep);
395 pw.println("#ifdef __cplusplus");
396 pw.println("extern \"C\" {");
397 pw.println("#endif" + lineSep);
398 pw.println(methods);
399 pw.println("#ifdef __cplusplus");
400 pw.println("}");
401 pw.println("#endif");
402 }
403 }
405 protected String methodDecls(ClassDoc clazz, String cname)
406 throws ClassNotFoundException {
408 String res = "";
409 for (int i = 0; i < methods.length; i++) {
410 MethodDoc method = (MethodDoc)methods[i];
411 if (method.isNative())
412 res = res + methodDecl(method, clazz, cname);
413 }
414 return res;
415 }
417 protected String methodDecl(MethodDoc method,
418 ClassDoc clazz, String cname)
419 throws ClassNotFoundException {
420 String res = null;
422 Type retType = method.returnType();
423 String typesig = method.signature();
424 TypeSignature newTypeSig = new TypeSignature(root);
425 String sig = newTypeSig.getTypeSignature(typesig, retType);
426 boolean longName = needLongName(method, clazz);
428 if (sig.charAt(0) != '(')
429 Util.error("invalid.method.signature", sig);
432 res = "JNIEXPORT " + jniType(retType) + " JNICALL" + lineSep + jniMethodName(method, cname, longName)
433 + "(JNIEnv *, " + cRcvrDecl(method, cname);
434 Parameter[] params = method.parameters();
435 Type argTypes[] = new Type[params.length];
436 for(int p = 0; p < params.length; p++){
437 argTypes[p] = params[p].type();
438 }
440 /* It would have been nice to include the argument names in the
441 declaration, but there seems to be a bug in the "BinaryField"
442 class, causing the getArguments() method to return "null" for
443 most (non-constructor) methods. */
444 for (int i = 0; i < argTypes.length; i++)
445 res = res + ", " + jniType(argTypes[i]);
446 res = res + ");" + lineSep;
447 return res;
448 }
450 protected final boolean needLongName(MethodDoc method,
451 ClassDoc clazz)
452 throws ClassNotFoundException {
453 String methodName = method.name();
454 for (int i = 0; i < methods.length; i++) {
455 MethodDoc memberMethod = (MethodDoc) methods[i];
456 if ((memberMethod != method) &&
457 memberMethod.isNative() && (methodName == memberMethod.name()))
458 return true;
459 }
460 return false;
461 }
463 protected final String jniMethodName(MethodDoc method, String cname,
464 boolean longName) {
465 String res = "Java_" + cname + "_" + method.name();
467 if (longName) {
468 Type mType = method.returnType();
469 Parameter[] params = method.parameters();
470 Type argTypes[] = new Type[params.length];
471 for(int p = 0; p < params.length; p++){
472 argTypes[p] = params[p].type();
473 }
475 res = res + "__";
476 for (int i = 0; i < argTypes.length; i++){
477 Type t = argTypes[i];
478 String tname = t.typeName();
479 TypeSignature newTypeSig = new TypeSignature(root);
480 String sig = newTypeSig.getTypeSignature(tname);
481 res = res + nameToIdentifier(sig);
482 }
483 }
484 return res;
485 }
487 protected final String jniType(Type t) {
488 String elmT =t.typeName();
489 if (t.dimension().indexOf("[]") != -1) {
490 if(elmT.equals("boolean"))return "jbooleanArray";
491 else if(elmT.equals("byte"))return "jbyteArray";
492 else if(elmT.equals("char"))return "jcharArray";
493 else if(elmT.equals("short"))return "jshortArray";
494 else if(elmT.equals("int"))return "jintArray";
495 else if(elmT.equals("long"))return "jlongArray";
496 else if(elmT.equals("float"))return "jfloatArray";
497 else if(elmT.equals("double"))return "jdoubleArray";
498 else if((t.dimension().indexOf("[][]") != -1) || (t.asClassDoc() != null)) return "jobjectArray";
499 } else {
500 if(elmT.equals("void"))return "void";
501 else if(elmT.equals("boolean"))return "jboolean";
502 else if(elmT.equals("byte"))return "jbyte";
503 else if(elmT.equals("char"))return "jchar";
504 else if(elmT.equals("short"))return "jshort";
505 else if(elmT.equals("int"))return "jint";
506 else if(elmT.equals("long"))return "jlong";
507 else if(elmT.equals("float"))return "jfloat";
508 else if(elmT.equals("double"))return "jdouble";
509 else if (t.asClassDoc() != null) {
510 if (elmT.equals("String"))
511 return "jstring";
512 else if (t.asClassDoc().subclassOf(root.classNamed("java.lang.Class")))
513 return "jclass";
514 else
515 return "jobject";
516 }
517 }
518 Util.bug("jni.unknown.type");
519 return null; /* dead code. */
520 }
522 protected String llniType(Type t, boolean handleize, boolean longDoubleOK) {
523 String res = null;
524 String elmt = t.typeName();
525 if (t.dimension().indexOf("[]") != -1) {
526 if((t.dimension().indexOf("[][]") != -1)
527 || (t.asClassDoc() != null)) res = "IArrayOfRef";
528 else if(elmt.equals("boolean")) res = "IArrayOfBoolean";
529 else if(elmt.equals("byte")) res = "IArrayOfByte";
530 else if(elmt.equals("char")) res = "IArrayOfChar";
531 else if(elmt.equals("int")) res = "IArrayOfInt";
532 else if(elmt.equals("long")) res = "IArrayOfLong";
533 else if(elmt.equals("float")) res = "IArrayOfFloat";
534 else if(elmt.equals("double")) res = "IArrayOfDouble";
535 if (!handleize) res = "DEREFERENCED_" + res;
536 } else {
537 if(elmt.equals("void")) res = "void";
538 else if( (elmt.equals("boolean")) || (elmt.equals("byte"))
539 ||(elmt.equals("char")) || (elmt.equals("short"))
540 || (elmt.equals("int"))) res = "java_int";
541 else if(elmt.equals("long")) res = longDoubleOK
542 ? "java_long" : "val32 /* java_long */";
543 else if(elmt.equals("float")) res = "java_float";
544 else if(elmt.equals("double")) res = res = longDoubleOK
545 ? "java_double" : "val32 /* java_double */";
546 else if(t.asClassDoc() != null) {
547 res = "I" + mangleClassName(t.asClassDoc().qualifiedName());
548 if (!handleize) res = "DEREFERENCED_" + res;
549 }
550 }
551 return res;
552 }
554 protected final String cRcvrDecl(MemberDoc field, String cname) {
555 return (field.isStatic() ? "jclass" : "jobject");
556 }
558 protected String maskName(String s) {
559 return "LLNI_mask(" + s + ")";
560 }
562 protected String llniFieldName(MemberDoc field) {
563 return maskName(field.name());
564 }
566 protected final boolean isLongOrDouble(Type t) {
567 String tc = t.typeName();
568 return (tc.equals("long") || tc.equals("double"));
569 }
571 /* Do unicode to ansi C identifier conversion.
572 %%% This may not be right, but should be called more often. */
573 protected final String nameToIdentifier(String name) {
574 int len = name.length();
575 StringBuffer buf = new StringBuffer(len);
576 for (int i = 0; i < len; i++) {
577 char c = name.charAt(i);
578 if (isASCIILetterOrDigit(c))
579 buf.append(c);
580 else if (c == '/')
581 buf.append('_');
582 else if (c == '.')
583 buf.append('_');
584 else if (c == '_')
585 buf.append("_1");
586 else if (c == ';')
587 buf.append("_2");
588 else if (c == '[')
589 buf.append("_3");
590 else
591 buf.append("_0" + ((int)c));
592 }
593 return new String(buf);
594 }
596 protected final boolean isASCIILetterOrDigit(char c) {
597 if (((c >= 'A') && (c <= 'Z')) ||
598 ((c >= 'a') && (c <= 'z')) ||
599 ((c >= '0') && (c <= '9')))
600 return true;
601 else
602 return false;
603 }
604 }