bind, bind/java: support generating exceptional constructors

In Go type constructors can often return an error type too
beside an instance of the type being created. This is useful
in cases where the parameters might be wrong and instantiaion
cannot succeed. This CL extends the Java generator so that
these methods are also converted into class constructors that
also can throw.

Change-Id: I5e531eec126904a026767a8503968255b9fd833b
Reviewed-on: https://go-review.googlesource.com/31184
Reviewed-by: Elias Naur <elias.naur@gmail.com>
This commit is contained in:
Péter Szilágyi
2016-10-17 14:21:52 +00:00
committed by Elias Naur
parent 4cb3e7f634
commit 2ea7e2cc92
4 changed files with 46 additions and 8 deletions
+13 -2
View File
@@ -941,6 +941,7 @@ func (g *JavaGen) genJNIConstructor(f *types.Func, sName string) {
return
}
sig := f.Type().(*types.Signature)
res := sig.Results()
g.Printf("JNIEXPORT jobject JNICALL\n")
g.Printf("Java_%s_%s_%s(JNIEnv *env, jclass clazz", g.jniPkgName(), sName, java.JNIMangle("__"+f.Name()))
@@ -956,8 +957,12 @@ func (g *JavaGen) genJNIConstructor(f *types.Func, sName string) {
name := g.paramName(params, i)
g.genJavaToC(name, params.At(i).Type(), modeTransient)
}
// Constructors always have one result parameter, a *T.
g.Printf("int32_t refnum = proxy%s__%s(", g.pkgPrefix, f.Name())
// Constructors always return a mandatory *T and an optional error
if res.Len() == 1 {
g.Printf("int32_t refnum = proxy%s__%s(", g.pkgPrefix, f.Name())
} else {
g.Printf("struct proxy%s__%s_return res = proxy%s__%s(", g.pkgPrefix, f.Name(), g.pkgPrefix, f.Name())
}
for i := 0; i < params.Len(); i++ {
if i > 0 {
g.Printf(", ")
@@ -968,6 +973,12 @@ func (g *JavaGen) genJNIConstructor(f *types.Func, sName string) {
for i := 0; i < params.Len(); i++ {
g.genRelease(g.paramName(params, i), params.At(i).Type(), modeTransient)
}
// Extract multi returns and handle errors
if res.Len() == 2 {
g.Printf("int32_t refnum = res.r0;\n")
g.genCToJava("_err", "res.r1", res.At(1).Type(), modeRetained)
g.Printf("go_seq_maybe_throw_exception(env, _err);\n")
}
// Pass no proxy class so that the Seq.Ref is returned instead.
g.Printf("return go_seq_from_refnum(env, refnum, NULL, NULL);\n")
g.Outdent()