in bind/genjava.go [1456:1588]
func (g *JavaGen) GenC() error {
var pkgName, pkgPath string
if g.Pkg != nil {
pkgName = g.Pkg.Name()
pkgPath = g.Pkg.Path()
} else {
pkgName = "universe"
}
g.Printf(cPreamble, g.gobindOpts(), pkgPath)
g.Printf("#include %q\n", pkgName+".h")
if g.Pkg != nil {
for _, pkg := range g.Pkg.Imports() {
if g.validPkg(pkg) {
g.Printf("#include \"%s.h\"\n", pkg.Name())
}
}
}
g.Printf("\n")
for _, iface := range g.interfaces {
g.Printf("jclass proxy_class_%s_%s;\n", g.pkgPrefix, iface.obj.Name())
g.Printf("jmethodID proxy_class_%s_%s_cons;\n", g.pkgPrefix, iface.obj.Name())
for _, m := range iface.summary.callable {
if !g.isSigSupported(m.Type()) {
g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", iface.obj.Name(), m.Name())
continue
}
g.Printf("static jmethodID mid_%s_%s;\n", iface.obj.Name(), m.Name())
}
}
for _, s := range g.structs {
g.Printf("jclass proxy_class_%s_%s;\n", g.pkgPrefix, s.obj.Name())
g.Printf("jmethodID proxy_class_%s_%s_cons;\n", g.pkgPrefix, s.obj.Name())
}
g.Printf("\n")
g.Printf("JNIEXPORT void JNICALL\n")
g.Printf("Java_%s_%s__1init(JNIEnv *env, jclass _unused) {\n", g.jniPkgName(), java.JNIMangle(g.className()))
g.Indent()
g.Printf("jclass clazz;\n")
for _, s := range g.structs {
if jinf, ok := g.jstructs[s.obj]; ok {
// Leave the class and constructor NULL for Java classes with no
// default constructor.
if !jinf.genNoargCon {
continue
}
}
g.Printf("clazz = (*env)->FindClass(env, %q);\n", g.jniClassSigPrefix(s.obj.Pkg())+g.javaTypeName(s.obj.Name()))
g.Printf("proxy_class_%s_%s = (*env)->NewGlobalRef(env, clazz);\n", g.pkgPrefix, s.obj.Name())
g.Printf("proxy_class_%s_%s_cons = (*env)->GetMethodID(env, clazz, \"<init>\", \"(I)V\");\n", g.pkgPrefix, s.obj.Name())
}
for _, iface := range g.interfaces {
pkg := iface.obj.Pkg()
g.Printf("clazz = (*env)->FindClass(env, %q);\n", g.jniClassSigPrefix(pkg)+JavaClassName(pkg)+"$proxy"+iface.obj.Name())
g.Printf("proxy_class_%s_%s = (*env)->NewGlobalRef(env, clazz);\n", g.pkgPrefix, iface.obj.Name())
g.Printf("proxy_class_%s_%s_cons = (*env)->GetMethodID(env, clazz, \"<init>\", \"(I)V\");\n", g.pkgPrefix, iface.obj.Name())
if isErrorType(iface.obj.Type()) {
// As a special case, Java Exceptions are passed to Go pretending to implement the Go error interface.
// To complete the illusion, use the Throwable.getMessage method for proxied calls to the error.Error method.
g.Printf("clazz = (*env)->FindClass(env, \"java/lang/Throwable\");\n")
g.Printf("mid_error_Error = (*env)->GetMethodID(env, clazz, \"getMessage\", \"()Ljava/lang/String;\");\n")
continue
}
g.Printf("clazz = (*env)->FindClass(env, %q);\n", g.jniClassSigPrefix(pkg)+g.javaTypeName(iface.obj.Name()))
for _, m := range iface.summary.callable {
if !g.isSigSupported(m.Type()) {
g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", iface.obj.Name(), m.Name())
continue
}
sig := m.Type().(*types.Signature)
res := sig.Results()
retSig := "V"
if res.Len() > 0 {
if t := res.At(0).Type(); !isErrorType(t) {
retSig = g.jniSigType(t)
}
}
var jniParams string
params := sig.Params()
for i := 0; i < params.Len(); i++ {
jniParams += g.jniSigType(params.At(i).Type())
}
g.Printf("mid_%s_%s = (*env)->GetMethodID(env, clazz, %q, \"(%s)%s\");\n",
iface.obj.Name(), m.Name(), javaNameReplacer(lowerFirst(m.Name())), jniParams, retSig)
}
g.Printf("\n")
}
g.Outdent()
g.Printf("}\n\n")
for _, f := range g.funcs {
g.genJNIFunc(f, "", nil, false, false)
}
for _, s := range g.structs {
sName := s.obj.Name()
cons := g.constructors[s.obj]
jinf := g.jstructs[s.obj]
for _, f := range cons {
g.genJNIConstructor(f, sName)
}
if len(cons) == 0 && (jinf == nil || jinf.genNoargCon) {
g.Printf("JNIEXPORT jint JNICALL\n")
g.Printf("Java_%s_%s_%s(JNIEnv *env, jclass clazz) {\n", g.jniPkgName(), java.JNIMangle(g.javaTypeName(sName)), java.JNIMangle("__New"))
g.Indent()
g.Printf("return new_%s_%s();\n", g.pkgPrefix, sName)
g.Outdent()
g.Printf("}\n\n")
}
for _, m := range exportedMethodSet(types.NewPointer(s.obj.Type())) {
var jm *java.Func
if jinf != nil {
jm = jinf.lookupMethod(m, g.hasThis(s.obj.Name(), m))
}
g.genJNIFunc(m, sName, jm, false, jinf != nil)
}
for _, f := range exportedFields(s.t) {
g.genJNIField(s.obj, f)
}
}
for _, iface := range g.interfaces {
for _, m := range iface.summary.callable {
g.genJNIFunc(m, iface.obj.Name(), nil, true, false)
g.genMethodInterfaceProxy(iface.obj.Name(), m)
}
}
for _, v := range g.vars {
g.genJNIVar(v)
}
if len(g.err) > 0 {
return g.err
}
return nil
}