Tue, 16 Jun 2009 10:46:37 +0100
6638712: Inference with wildcard types causes selection of inapplicable method
Summary: Added global sanity check in order to make sure that return type inference does not violate bounds constraints
Reviewed-by: jjg
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 */
26 package com.sun.tools.javah;
28 import java.io.OutputStream;
29 import java.io.PrintWriter;
30 import java.util.Vector;
31 import java.util.Enumeration;
32 import com.sun.javadoc.*;
35 /**
36 * Header file generator for JNI.
37 *
38 * @author Sucheta Dambalkar(Revised)
39 */
41 public class JNI extends Gen {
43 public JNI(RootDoc root){
44 super(root);
45 }
47 public String getIncludes() {
48 return "#include <jni.h>";
49 }
51 public void write(OutputStream o, ClassDoc clazz)
52 throws ClassNotFoundException {
54 String cname = Mangle.mangle(clazz.qualifiedName(), Mangle.Type.CLASS);
55 PrintWriter pw = wrapWriter(o);
56 pw.println(guardBegin(cname));
57 pw.println(cppGuardBegin());
59 /* Write statics. */
60 FieldDoc[] classfields = getAllFields(clazz);
62 for (int i = 0; i < classfields.length; i++) {
63 if (!classfields[i].isStatic())
64 continue;
65 String s = null;
66 s = defineForStatic(clazz, classfields[i]);
67 if (s != null) {
68 pw.println(s);
69 }
70 }
72 /* Write methods. */
73 MethodDoc[] classmethods = clazz.methods();
74 for (int i = 0; i < classmethods.length; i++) {
75 if(classmethods[i].isNative()){
76 MethodDoc md = classmethods[i];
77 Type mtr = classmethods[i].returnType();
78 String sig = md.signature();
79 TypeSignature newtypesig = new TypeSignature(root);
80 String methodName = md.name();
81 boolean longName = false;
82 for (int j = 0; j < classmethods.length; j++) {
83 if ((classmethods[j] != md)
84 && (methodName.equals(classmethods[j].name()))
85 && (classmethods[j].isNative()))
86 longName = true;
88 }
89 pw.println("/*");
90 pw.println(" * Class: " + cname);
91 pw.println(" * Method: " +
92 Mangle.mangle(methodName, Mangle.Type.FIELDSTUB));
93 pw.println(" * Signature: " + newtypesig.getTypeSignature(sig, mtr));
94 pw.println(" */");
95 pw.println("JNIEXPORT " + jniType(mtr) +
96 " JNICALL " +
97 Mangle.mangleMethod(md, root,clazz,
98 (longName) ?
99 Mangle.Type.METHOD_JNI_LONG :
100 Mangle.Type.METHOD_JNI_SHORT));
101 pw.print(" (JNIEnv *, ");
102 Parameter[] paramargs = md.parameters();
103 Type []args =new Type[ paramargs.length];
104 for(int p = 0; p < paramargs.length; p++){
105 args[p] = paramargs[p].type();
106 }
107 if (md.isStatic())
108 pw.print("jclass");
109 else
110 pw.print("jobject");
111 if (args.length > 0)
112 pw.print(", ");
114 for (int j = 0; j < args.length; j++) {
115 pw.print(jniType(args[j]));
116 if (j != (args.length - 1)) {
117 pw.print(", ");
118 }
119 }
120 pw.println(");" + lineSep);
121 }
122 }
123 pw.println(cppGuardEnd());
124 pw.println(guardEnd(cname));
125 }
128 protected final String jniType(Type t){
130 String elmT = t.typeName();
131 ClassDoc throwable = root.classNamed("java.lang.Throwable");
132 ClassDoc jClass = root.classNamed("java.lang.Class");
133 ClassDoc tclassDoc = t.asClassDoc();
135 if((t.dimension()).indexOf("[]") != -1){
136 if((t.dimension().indexOf("[][]") != -1)
137 || (tclassDoc != null)) return "jobjectArray";
138 else if(elmT.equals("boolean"))return "jbooleanArray";
139 else if(elmT.equals("byte"))return "jbyteArray";
140 else if(elmT.equals("char"))return "jcharArray";
141 else if(elmT.equals("short"))return "jshortArray";
142 else if(elmT.equals("int"))return "jintArray";
143 else if(elmT.equals("long"))return "jlongArray";
144 else if(elmT.equals("float"))return "jfloatArray";
145 else if(elmT.equals("double"))return "jdoubleArray";
146 }else{
147 if(elmT.equals("void"))return "void";
148 else if(elmT.equals("String"))return "jstring";
149 else if(elmT.equals("boolean"))return "jboolean";
150 else if(elmT.equals("byte"))return "jbyte";
151 else if(elmT.equals("char"))return "jchar";
152 else if(elmT.equals("short"))return "jshort";
153 else if(elmT.equals("int"))return "jint";
154 else if(elmT.equals("long"))return "jlong";
155 else if(elmT.equals("float"))return "jfloat";
156 else if(elmT.equals("double"))return "jdouble";
157 else if(tclassDoc != null){
158 if(tclassDoc.subclassOf(throwable)) return "jthrowable";
159 else if(tclassDoc.subclassOf(jClass)) return "jclass";
160 else return "jobject";
161 }
162 }
163 Util.bug("jni.unknown.type");
164 return null; /* dead code. */
165 }
166 }