diff --git a/bind/bind.go b/bind/bind.go index 63ca719..1b844e1 100644 --- a/bind/bind.go +++ b/bind/bind.go @@ -32,58 +32,23 @@ type ( ) const ( - Java fileType = iota - JavaC - JavaH - - ObjcM + ObjcM = iota ObjcH ObjcGoH ) -// GenJava generates a Java API from a Go package. -func GenJava(conf *GeneratorConfig, javaPkg string, ft fileType) error { - buf := new(bytes.Buffer) - g := &javaGen{ - javaPkg: javaPkg, - generator: &generator{ - printer: &printer{buf: buf, indentEach: []byte(" ")}, - fset: conf.Fset, - allPkg: conf.AllPkg, - pkg: conf.Pkg, - }, - } - g.init() - var err error - switch ft { - case Java: - err = g.genJava() - case JavaC: - err = g.genC() - case JavaH: - err = g.genH() - default: - panic("invalid fileType") - } - if err != nil { - return err - } - _, err = io.Copy(conf.Writer, buf) - return err -} - // GenGo generates a Go stub to support foreign language APIs. func GenGo(conf *GeneratorConfig) error { buf := new(bytes.Buffer) g := &goGen{ - generator: &generator{ - printer: &printer{buf: buf, indentEach: []byte("\t")}, - fset: conf.Fset, - allPkg: conf.AllPkg, - pkg: conf.Pkg, + Generator: &Generator{ + Printer: &Printer{Buf: buf, IndentEach: []byte("\t")}, + Fset: conf.Fset, + AllPkg: conf.AllPkg, + Pkg: conf.Pkg, }, } - g.init() + g.Init() if err := g.gen(); err != nil { return err } @@ -101,11 +66,11 @@ func GenGo(conf *GeneratorConfig) error { func GenObjc(conf *GeneratorConfig, prefix string, ft fileType) error { buf := new(bytes.Buffer) g := &objcGen{ - generator: &generator{ - printer: &printer{buf: buf, indentEach: []byte("\t")}, - fset: conf.Fset, - allPkg: conf.AllPkg, - pkg: conf.Pkg, + Generator: &Generator{ + Printer: &Printer{Buf: buf, IndentEach: []byte("\t")}, + Fset: conf.Fset, + AllPkg: conf.AllPkg, + Pkg: conf.Pkg, }, prefix: prefix, } diff --git a/bind/bind_test.go b/bind/bind_test.go index e4b7621..afbdaf7 100644 --- a/bind/bind_test.go +++ b/bind/bind_test.go @@ -129,29 +129,52 @@ func TestGenObjc(t *testing.T) { } func TestGenJava(t *testing.T) { - var suffixes = map[fileType]string{ - Java: ".java.golden", - JavaC: ".java.c.golden", - JavaH: ".java.h.golden", - } - for _, filename := range tests { pkg := typeCheck(t, filename) - for typ, suffix := range suffixes { - var buf bytes.Buffer - conf := &GeneratorConfig{ - Writer: &buf, - Fset: fset, - Pkg: pkg, - AllPkg: []*types.Package{pkg}, - } - if err := GenJava(conf, "", typ); err != nil { + var buf bytes.Buffer + g := &JavaGen{ + Generator: &Generator{ + Printer: &Printer{Buf: &buf, IndentEach: []byte(" ")}, + Fset: fset, + AllPkg: []*types.Package{pkg}, + Pkg: pkg, + }, + } + g.Init() + testCases := []struct { + suffix string + gen func() error + }{ + { + ".java.golden", + func() error { + for i := range g.ClassNames() { + if err := g.GenClass(i); err != nil { + return err + } + } + return g.GenJava() + }, + }, + { + ".java.c.golden", + func() error { return g.GenC() }, + }, + { + ".java.h.golden", + func() error { return g.GenH() }, + }, + } + + for _, tc := range testCases { + buf.Reset() + if err := tc.gen(); err != nil { t.Errorf("%s: %v", filename, err) continue } - out := writeTempFile(t, "generated"+suffix, buf.Bytes()) + out := writeTempFile(t, "generated"+tc.suffix, buf.Bytes()) defer os.Remove(out) - golden := filename[:len(filename)-len(".go")] + suffix + golden := filename[:len(filename)-len(".go")] + tc.suffix if diffstr := diff(golden, out); diffstr != "" { t.Errorf("%s: does not match Java golden:\n%s", filename, diffstr) @@ -207,21 +230,58 @@ func TestCustomPrefix(t *testing.T) { Pkg: pkg, AllPkg: []*types.Package{pkg}, } + var buf bytes.Buffer + g := &JavaGen{ + JavaPkg: "com.example", + Generator: &Generator{ + Printer: &Printer{Buf: &buf, IndentEach: []byte(" ")}, + Fset: fset, + AllPkg: []*types.Package{pkg}, + Pkg: pkg, + }, + } + g.Init() testCases := []struct { golden string gen func(w io.Writer) error }{ { "testdata/customprefix.java.golden", - func(w io.Writer) error { conf.Writer = w; return GenJava(conf, "com.example", Java) }, + func(w io.Writer) error { + buf.Reset() + for i := range g.ClassNames() { + if err := g.GenClass(i); err != nil { + return err + } + } + if err := g.GenJava(); err != nil { + return err + } + _, err := io.Copy(w, &buf) + return err + }, }, { "testdata/customprefix.java.h.golden", - func(w io.Writer) error { conf.Writer = w; return GenJava(conf, "com.example", JavaH) }, + func(w io.Writer) error { + buf.Reset() + if err := g.GenH(); err != nil { + return err + } + _, err := io.Copy(w, &buf) + return err + }, }, { "testdata/customprefix.java.c.golden", - func(w io.Writer) error { conf.Writer = w; return GenJava(conf, "com.example", JavaC) }, + func(w io.Writer) error { + buf.Reset() + if err := g.GenC(); err != nil { + return err + } + _, err := io.Copy(w, &buf) + return err + }, }, { "testdata/customprefix.objc.go.h.golden", diff --git a/bind/gen.go b/bind/gen.go index 3d618c3..dcf3a9a 100644 --- a/bind/gen.go +++ b/bind/gen.go @@ -50,14 +50,20 @@ func (list ErrorList) Error() string { return buf.String() } -type generator struct { - *printer - fset *token.FileSet - allPkg []*types.Package - pkg *types.Package +// Generator contains the common Go package information +// needed for the specific Go, Java, ObjC generators. +// +// After setting Printer, Fset, AllPkg, Pkg, the Init +// method is used to initialize the auxiliary information +// about the package to be generated, Pkg. +type Generator struct { + *Printer + Fset *token.FileSet + AllPkg []*types.Package + Pkg *types.Package err ErrorList - // fields set by init. + // fields set by Init. pkgName string pkgPrefix string funcs []*types.Func @@ -85,14 +91,14 @@ func pkgPrefix(pkg *types.Package) string { return pkg.Name() } -func (g *generator) init() { - if g.pkg != nil { - g.pkgName = g.pkg.Name() +func (g *Generator) Init() { + if g.Pkg != nil { + g.pkgName = g.Pkg.Name() } - g.pkgPrefix = pkgPrefix(g.pkg) + g.pkgPrefix = pkgPrefix(g.Pkg) - if g.pkg != nil { - scope := g.pkg.Scope() + if g.Pkg != nil { + scope := g.Pkg.Scope() hasExported := false for _, name := range scope.Names() { obj := scope.Lookup(name) @@ -124,7 +130,7 @@ func (g *generator) init() { } } if !hasExported { - g.errorf("no exported names in the package %q", g.pkg.Path()) + g.errorf("no exported names in the package %q", g.Pkg.Path()) } } else { // Bind the single supported type from the universe scope, error. @@ -132,7 +138,7 @@ func (g *generator) init() { t := errType.Type().Underlying().(*types.Interface) g.interfaces = append(g.interfaces, interfaceInfo{errType, t, makeIfaceSummary(t)}) } - for _, p := range g.allPkg { + for _, p := range g.AllPkg { scope := p.Scope() for _, name := range scope.Names() { obj := scope.Lookup(name) @@ -149,20 +155,20 @@ func (g *generator) init() { } } -func (_ *generator) toCFlag(v bool) int { +func (_ *Generator) toCFlag(v bool) int { if v { return 1 } return 0 } -func (g *generator) errorf(format string, args ...interface{}) { +func (g *Generator) errorf(format string, args ...interface{}) { g.err = append(g.err, fmt.Errorf(format, args...)) } // cgoType returns the name of a Cgo type suitable for converting a value of // the given type. -func (g *generator) cgoType(t types.Type) string { +func (g *Generator) cgoType(t types.Type) string { switch t := t.(type) { case *types.Basic: switch t.Kind() { @@ -215,7 +221,7 @@ func (g *generator) cgoType(t types.Type) string { return "TODO" } -func (g *generator) genInterfaceMethodSignature(m *types.Func, iName string, header bool) { +func (g *Generator) genInterfaceMethodSignature(m *types.Func, iName string, header bool) { sig := m.Type().(*types.Signature) params := sig.Params() res := sig.Results() @@ -252,8 +258,8 @@ func (g *generator) genInterfaceMethodSignature(m *types.Func, iName string, hea } } -func (g *generator) validPkg(pkg *types.Package) bool { - for _, p := range g.allPkg { +func (g *Generator) validPkg(pkg *types.Package) bool { + for _, p := range g.AllPkg { if p == pkg { return true } @@ -263,7 +269,7 @@ func (g *generator) validPkg(pkg *types.Package) bool { // isSigSupported returns whether the generators can handle a given // function signature -func (g *generator) isSigSupported(t types.Type) bool { +func (g *Generator) isSigSupported(t types.Type) bool { sig := t.(*types.Signature) params := sig.Params() for i := 0; i < params.Len(); i++ { @@ -281,7 +287,7 @@ func (g *generator) isSigSupported(t types.Type) bool { } // isSupported returns whether the generators can handle the type. -func (g *generator) isSupported(t types.Type) bool { +func (g *Generator) isSupported(t types.Type) bool { if isErrorType(t) { return true } diff --git a/bind/gengo.go b/bind/gengo.go index 6353a39..b4200f3 100644 --- a/bind/gengo.go +++ b/bind/gengo.go @@ -12,7 +12,7 @@ import ( ) type goGen struct { - *generator + *Generator imports map[string]struct{} } @@ -176,7 +176,7 @@ func (g *goGen) genFunc(o *types.Func) { } g.genFuncSignature(o, "") g.Indent() - g.genFuncBody(o, g.pkgName(g.pkg)) + g.genFuncBody(o, g.pkgName(g.Pkg)) g.Outdent() g.Printf("}\n\n") } @@ -195,7 +195,7 @@ func (g *goGen) genStruct(obj *types.TypeName, T *types.Struct) { g.Indent() g.Printf("ref := _seq.FromRefNum(int32(refnum))\n") g.genRead("_v", "v", f.Type(), modeRetained) - g.Printf("ref.Get().(*%s%s).%s = _v\n", g.pkgName(g.pkg), obj.Name(), f.Name()) + g.Printf("ref.Get().(*%s%s).%s = _v\n", g.pkgName(g.Pkg), obj.Name(), f.Name()) g.Outdent() g.Printf("}\n\n") @@ -203,7 +203,7 @@ func (g *goGen) genStruct(obj *types.TypeName, T *types.Struct) { g.Printf("func proxy%s_%s_%s_Get(refnum C.int32_t) C.%s {\n", g.pkgPrefix, obj.Name(), f.Name(), g.cgoType(f.Type())) g.Indent() g.Printf("ref := _seq.FromRefNum(int32(refnum))\n") - g.Printf("v := ref.Get().(*%s%s).%s\n", g.pkgName(g.pkg), obj.Name(), f.Name()) + g.Printf("v := ref.Get().(*%s%s).%s\n", g.pkgName(g.Pkg), obj.Name(), f.Name()) g.genWrite("_v", "v", f.Type(), modeRetained) g.Printf("return _v\n") g.Outdent() @@ -218,7 +218,7 @@ func (g *goGen) genStruct(obj *types.TypeName, T *types.Struct) { g.genFuncSignature(m, obj.Name()) g.Indent() g.Printf("ref := _seq.FromRefNum(int32(refnum))\n") - g.Printf("v := ref.Get().(*%s%s)\n", g.pkgName(g.pkg), obj.Name()) + g.Printf("v := ref.Get().(*%s%s)\n", g.pkgName(g.Pkg), obj.Name()) g.genFuncBody(m, "v.") g.Outdent() g.Printf("}\n\n") @@ -232,7 +232,7 @@ func (g *goGen) genVar(o *types.Var) { } // TODO(hyangah): non-struct pointer types (*int), struct type. - v := fmt.Sprintf("%s%s", g.pkgName(g.pkg), o.Name()) + v := fmt.Sprintf("%s%s", g.pkgName(g.Pkg), o.Name()) // var I int // @@ -270,7 +270,7 @@ func (g *goGen) genInterface(obj *types.TypeName) { g.genFuncSignature(m, obj.Name()) g.Indent() g.Printf("ref := _seq.FromRefNum(int32(refnum))\n") - g.Printf("v := ref.Get().(%s%s)\n", g.pkgName(g.pkg), obj.Name()) + g.Printf("v := ref.Get().(%s%s)\n", g.pkgName(g.Pkg), obj.Name()) g.genFuncBody(m, "v.") g.Outdent() g.Printf("}\n\n") @@ -425,7 +425,7 @@ func (g *goGen) genRead(toVar, fromVar string, typ types.Type, mode varMode) { } func (g *goGen) typeString(typ types.Type) string { - pkg := g.pkg + pkg := g.Pkg switch t := typ.(type) { case *types.Named: @@ -463,9 +463,9 @@ func (g *goGen) typeString(typ types.Type) string { func (g *goGen) genPreamble() { pkgName := "" pkgPath := "" - if g.pkg != nil { - pkgName = g.pkg.Name() - pkgPath = g.pkg.Path() + if g.Pkg != nil { + pkgName = g.Pkg.Name() + pkgPath = g.Pkg.Path() } else { pkgName = "universe" } @@ -485,9 +485,9 @@ func (g *goGen) gen() error { // Switch to a temporary buffer so the preamble can be // written last. - oldBuf := g.printer.buf + oldBuf := g.Printer.Buf newBuf := new(bytes.Buffer) - g.printer.buf = newBuf + g.Printer.Buf = newBuf g.Printf("// suppress the error if seq ends up unused\n") g.Printf("var _ = _seq.FromRefNum\n") @@ -505,9 +505,9 @@ func (g *goGen) gen() error { } // Switch to the original buffer, write the preamble // and append the rest of the file. - g.printer.buf = oldBuf + g.Printer.Buf = oldBuf g.genPreamble() - g.printer.buf.Write(newBuf.Bytes()) + g.Printer.Buf.Write(newBuf.Bytes()) if len(g.err) > 0 { return g.err } diff --git a/bind/genjava.go b/bind/genjava.go index 8632e66..7053abb 100644 --- a/bind/genjava.go +++ b/bind/genjava.go @@ -15,15 +15,48 @@ import ( // TODO(crawshaw): disallow basic android java type names in exported symbols. // TODO(crawshaw): consider introducing Java functions for casting to and from interfaces at runtime. -type javaGen struct { +type JavaGen struct { // javaPkg is the custom name of the Java pkg that contains the generated classes. If empty, // use a package name generated from the Go package name. - javaPkg string + JavaPkg string - *generator + *Generator } -func (g *javaGen) genStruct(obj *types.TypeName, T *types.Struct) { +// ClassNames returns the list of names of the generated Java classes and interfaces. +func (g *JavaGen) ClassNames() []string { + var names []string + for _, s := range g.structs { + names = append(names, s.obj.Name()) + } + for _, iface := range g.interfaces { + names = append(names, iface.obj.Name()) + } + return names +} + +func (g *JavaGen) GenClass(idx int) error { + ns := len(g.structs) + if idx < ns { + s := g.structs[idx] + g.genStruct(s.obj, s.t) + } else { + iface := g.interfaces[idx-ns] + g.genInterface(iface) + } + if len(g.err) > 0 { + return g.err + } + return nil +} + +func (g *JavaGen) genStruct(obj *types.TypeName, T *types.Struct) { + pkgPath := "" + if g.Pkg != nil { + pkgPath = g.Pkg.Path() + } + g.Printf(javaPreamble, g.javaPkgName(g.Pkg), obj.Name(), g.gobindOpts(), pkgPath) + fields := exportedFields(T) methods := exportedMethodSet(types.NewPointer(obj.Type())) @@ -32,13 +65,13 @@ func (g *javaGen) genStruct(obj *types.TypeName, T *types.Struct) { for _, iface := range g.allIntf { if types.AssignableTo(pT, iface.obj.Type()) { n := iface.obj.Name() - if p := iface.obj.Pkg(); p != g.pkg { - n = fmt.Sprintf("%s.%s.%s", g.javaPkgName(p), className(p), n) + if p := iface.obj.Pkg(); p != g.Pkg { + n = fmt.Sprintf("%s.%s", g.javaPkgName(p), n) } impls = append(impls, n) } } - g.Printf("public static final class %s extends Seq.Proxy", obj.Name()) + g.Printf("public final class %s extends Seq.Proxy", obj.Name()) if len(impls) > 0 { g.Printf(" implements %s", strings.Join(impls, ", ")) } @@ -137,15 +170,21 @@ func (g *javaGen) genStruct(obj *types.TypeName, T *types.Struct) { g.Printf("}\n\n") } -func (g *javaGen) genInterface(iface interfaceInfo) { +func (g *JavaGen) genInterface(iface interfaceInfo) { + pkgPath := "" + if g.Pkg != nil { + pkgPath = g.Pkg.Path() + } + g.Printf(javaPreamble, g.javaPkgName(g.Pkg), iface.obj.Name(), g.gobindOpts(), pkgPath) + var exts []string numM := iface.t.NumMethods() for _, other := range g.allIntf { // Only extend interfaces with fewer methods to avoid circular references if other.t.NumMethods() < numM && types.AssignableTo(iface.t, other.t) { n := other.obj.Name() - if p := other.obj.Pkg(); p != g.pkg { - n = fmt.Sprintf("%s.%s.%s", g.javaPkgName(p), className(p), n) + if p := other.obj.Pkg(); p != g.Pkg { + n = fmt.Sprintf("%s.%s", g.javaPkgName(p), n) } exts = append(exts, n) } @@ -165,20 +204,7 @@ func (g *javaGen) genInterface(iface interfaceInfo) { g.genFuncSignature(m, false, true) } - g.Outdent() - g.Printf("}\n") - g.Printf("\n") - g.Printf(javaProxyPreamble, iface.obj.Name()) - g.Indent() - - 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.genFuncSignature(m, false, false) - } g.Outdent() g.Printf("}\n\n") @@ -198,7 +224,7 @@ func isJavaPrimitive(T types.Type) bool { } // jniType returns a string that can be used as a JNI type. -func (g *javaGen) jniType(T types.Type) string { +func (g *JavaGen) jniType(T types.Type) string { switch T := T.(type) { case *types.Basic: switch T.Kind() { @@ -245,7 +271,7 @@ func (g *javaGen) jniType(T types.Type) string { return "TODO" } -func (g *javaGen) javaBasicType(T *types.Basic) string { +func (g *JavaGen) javaBasicType(T *types.Basic) string { switch T.Kind() { case types.Bool, types.UntypedBool: return "boolean" @@ -277,7 +303,7 @@ func (g *javaGen) javaBasicType(T *types.Basic) string { } // javaType returns a string that can be used as a Java type. -func (g *javaGen) javaType(T types.Type) string { +func (g *JavaGen) javaType(T types.Type) string { if isErrorType(T) { // The error type is usually translated into an exception in // Java, however the type can be exposed in other ways, such @@ -304,8 +330,8 @@ func (g *javaGen) javaType(T types.Type) string { break } // TODO(crawshaw): more checking here - if nPkg != g.pkg { - return fmt.Sprintf("%s.%s.%s", g.javaPkgName(nPkg), className(nPkg), n.Name()) + if nPkg != g.Pkg { + return fmt.Sprintf("%s.%s", g.javaPkgName(nPkg), n.Name()) } else { return n.Name() } @@ -315,7 +341,7 @@ func (g *javaGen) javaType(T types.Type) string { return "TODO" } -func (g *javaGen) genJNIFuncSignature(o *types.Func, sName string, proxy bool) { +func (g *JavaGen) genJNIFuncSignature(o *types.Func, sName string, proxy bool) { sig := o.Type().(*types.Signature) res := sig.Results() @@ -337,14 +363,17 @@ func (g *javaGen) genJNIFuncSignature(o *types.Func, sName string, proxy bool) { } g.Printf("JNIEXPORT %s JNICALL\n", ret) - g.Printf("Java_%s_%s", g.jniPkgName(), g.className()) + g.Printf("Java_%s_", g.jniPkgName()) if sName != "" { - // 0024 is the mangled form of $, for naming inner classes. - g.Printf("_00024") if proxy { + g.Printf(g.className()) + // 0024 is the mangled form of $, for naming inner classes. + g.Printf("_00024") g.Printf("proxy") } g.Printf("%s", sName) + } else { + g.Printf(g.className()) } g.Printf("_%s(JNIEnv* env, ", o.Name()) if sName != "" { @@ -363,11 +392,11 @@ func (g *javaGen) genJNIFuncSignature(o *types.Func, sName string, proxy bool) { g.Printf(")") } -func (g *javaGen) jniPkgName() string { - return strings.Replace(g.javaPkgName(g.pkg), ".", "_", -1) +func (g *JavaGen) jniPkgName() string { + return strings.Replace(g.javaPkgName(g.Pkg), ".", "_", -1) } -func (g *javaGen) genFuncSignature(o *types.Func, static, header bool) { +func (g *JavaGen) genFuncSignature(o *types.Func, static, header bool) { sig := o.Type().(*types.Signature) res := sig.Results() @@ -421,7 +450,7 @@ func (g *javaGen) genFuncSignature(o *types.Func, static, header bool) { g.Printf(";\n") } -func (g *javaGen) genVar(o *types.Var) { +func (g *JavaGen) genVar(o *types.Var) { if t := o.Type(); !g.isSupported(t) { g.Printf("// skipped variable %s with unsupported type: %T\n\n", o.Name(), t) return @@ -435,7 +464,7 @@ func (g *javaGen) genVar(o *types.Var) { g.Printf("public static native %s get%s();\n\n", jType, o.Name()) } -func (g *javaGen) genJavaToC(varName string, t types.Type, mode varMode) { +func (g *JavaGen) genJavaToC(varName string, t types.Type, mode varMode) { switch t := t.(type) { case *types.Basic: switch t.Kind() { @@ -470,7 +499,7 @@ func (g *javaGen) genJavaToC(varName string, t types.Type, mode varMode) { } } -func (g *javaGen) genCToJava(toName, fromName string, t types.Type, mode varMode) { +func (g *JavaGen) genCToJava(toName, fromName string, t types.Type, mode varMode) { switch t := t.(type) { case *types.Basic: switch t.Kind() { @@ -514,7 +543,7 @@ func (g *javaGen) genCToJava(toName, fromName string, t types.Type, mode varMode } } -func (g *javaGen) genFromRefnum(toName, fromName string, t types.Type, o *types.TypeName) { +func (g *JavaGen) genFromRefnum(toName, fromName string, t types.Type, o *types.TypeName) { oPkg := o.Pkg() if !isErrorType(o.Type()) && !g.validPkg(oPkg) { g.errorf("type %s is defined in package %s, which is not bound", t, oPkg) @@ -524,10 +553,10 @@ func (g *javaGen) genFromRefnum(toName, fromName string, t types.Type, o *types. g.Printf("jobject %s = go_seq_from_refnum(env, %s, proxy_class_%s_%s, proxy_class_%s_%s_cons);\n", toName, fromName, p, o.Name(), p, o.Name()) } -func (g *javaGen) gobindOpts() string { +func (g *JavaGen) gobindOpts() string { opts := []string{"-lang=java"} - if g.javaPkg != "" { - opts = append(opts, "-javapkg="+g.javaPkg) + if g.JavaPkg != "" { + opts = append(opts, "-javapkg="+g.JavaPkg) } return strings.Join(opts, " ") } @@ -537,13 +566,10 @@ var javaNameReplacer = strings.NewReplacer( ".", "_", ) -func (g *javaGen) javaPkgName(pkg *types.Package) string { +func (g *JavaGen) javaPkgName(pkg *types.Package) string { if pkg == nil { return "go" } - if g.javaPkg != "" { - return g.javaPkg - } s := javaNameReplacer.Replace(pkg.Name()) // Look for Java keywords that are not Go keywords, and avoid using // them as a package name. @@ -562,11 +588,15 @@ func (g *javaGen) javaPkgName(pkg *types.Package) string { "void", "volatile", "while": s += "_" } - return "go." + s + if g.JavaPkg != "" { + return g.JavaPkg + "." + s + } else { + return "go." + s + } } -func (g *javaGen) className() string { - return className(g.pkg) +func (g *JavaGen) className() string { + return className(g.Pkg) } func className(pkg *types.Package) string { @@ -576,7 +606,7 @@ func className(pkg *types.Package) string { return strings.Title(javaNameReplacer.Replace(pkg.Name())) } -func (g *javaGen) genConst(o *types.Const) { +func (g *JavaGen) genConst(o *types.Const) { if _, ok := o.Type().(*types.Basic); !ok { g.Printf("// skipped const %s with unsupported type: %T\n\n", o.Name(), o) return @@ -609,14 +639,14 @@ func (g *javaGen) genConst(o *types.Const) { g.Printf("public static final %s %s = %s;\n", g.javaType(o.Type()), o.Name(), val) } -func (g *javaGen) genJNIField(o *types.TypeName, f *types.Var) { +func (g *JavaGen) genJNIField(o *types.TypeName, f *types.Var) { if t := f.Type(); !g.isSupported(t) { g.Printf("// skipped field %s with unsupported type: %T\n\n", o.Name(), t) return } // setter g.Printf("JNIEXPORT void JNICALL\n") - g.Printf("Java_%s_%s_00024%s_set%s(JNIEnv *env, jobject this, %s v) {\n", g.jniPkgName(), g.className(), o.Name(), f.Name(), g.jniType(f.Type())) + g.Printf("Java_%s_%s_set%s(JNIEnv *env, jobject this, %s v) {\n", g.jniPkgName(), o.Name(), f.Name(), g.jniType(f.Type())) g.Indent() g.Printf("int32_t o = go_seq_to_refnum(env, this);\n") g.genJavaToC("v", f.Type(), modeRetained) @@ -627,7 +657,7 @@ func (g *javaGen) genJNIField(o *types.TypeName, f *types.Var) { // getter g.Printf("JNIEXPORT %s JNICALL\n", g.jniType(f.Type())) - g.Printf("Java_%s_%s_00024%s_get%s(JNIEnv *env, jobject this) {\n", g.jniPkgName(), g.className(), o.Name(), f.Name()) + g.Printf("Java_%s_%s_get%s(JNIEnv *env, jobject this) {\n", g.jniPkgName(), o.Name(), f.Name()) g.Indent() g.Printf("int32_t o = go_seq_to_refnum(env, this);\n") g.Printf("%s r0 = ", g.cgoType(f.Type())) @@ -638,7 +668,7 @@ func (g *javaGen) genJNIField(o *types.TypeName, f *types.Var) { g.Printf("}\n\n") } -func (g *javaGen) genJNIVar(o *types.Var) { +func (g *JavaGen) genJNIVar(o *types.Var) { if t := o.Type(); !g.isSupported(t) { g.Printf("// skipped variable %s with unsupported type: %T\n\n", o.Name(), t) return @@ -665,7 +695,7 @@ func (g *javaGen) genJNIVar(o *types.Var) { g.Printf("}\n\n") } -func (g *javaGen) genJNIFunc(o *types.Func, sName string, proxy bool) { +func (g *JavaGen) genJNIFunc(o *types.Func, sName string, proxy bool) { if !g.isSigSupported(o.Type()) { n := o.Name() if sName != "" { @@ -732,7 +762,7 @@ func (g *javaGen) genJNIFunc(o *types.Func, sName string, proxy bool) { } // genRelease cleans up arguments that weren't copied in genJavaToC. -func (g *javaGen) genRelease(varName string, t types.Type, mode varMode) { +func (g *JavaGen) genRelease(varName string, t types.Type, mode varMode) { switch t := t.(type) { case *types.Basic: case *types.Slice: @@ -750,7 +780,7 @@ func (g *javaGen) genRelease(varName string, t types.Type, mode varMode) { } } -func (g *javaGen) genMethodInterfaceProxy(oName string, m *types.Func) { +func (g *JavaGen) genMethodInterfaceProxy(oName string, m *types.Func) { if !g.isSigSupported(m.Type()) { g.Printf("// skipped method %s with unsupported parameter or return types\n\n", oName) return @@ -811,10 +841,10 @@ func (g *javaGen) genMethodInterfaceProxy(oName string, m *types.Func) { g.Printf("}\n\n") } -func (g *javaGen) genH() error { +func (g *JavaGen) GenH() error { pkgPath := "" - if g.pkg != nil { - pkgPath = g.pkg.Path() + if g.Pkg != nil { + pkgPath = g.Pkg.Path() } g.Printf(hPreamble, g.gobindOpts(), pkgPath, g.className()) for _, iface := range g.interfaces { @@ -841,7 +871,7 @@ func (g *javaGen) genH() error { return nil } -func (g *javaGen) jniCallType(t types.Type) string { +func (g *JavaGen) jniCallType(t types.Type) string { switch t := t.(type) { case *types.Basic: switch t.Kind() { @@ -881,11 +911,11 @@ func (g *javaGen) jniCallType(t types.Type) string { return "TODO" } -func (g *javaGen) jniClassSigPrefix(pkg *types.Package) string { - return strings.Replace(g.javaPkgName(pkg), ".", "/", -1) + "/" + className(pkg) + "$" +func (g *JavaGen) jniClassSigPrefix(pkg *types.Package) string { + return strings.Replace(g.javaPkgName(pkg), ".", "/", -1) + "/" } -func (g *javaGen) jniSigType(T types.Type) string { +func (g *JavaGen) jniSigType(T types.Type) string { switch T := T.(type) { case *types.Basic: switch T.Kind() { @@ -928,18 +958,18 @@ func (g *javaGen) jniSigType(T types.Type) string { return "TODO" } -func (g *javaGen) genC() error { +func (g *JavaGen) GenC() error { var pkgName, pkgPath string - if g.pkg != nil { - pkgName = g.pkg.Name() - pkgPath = g.pkg.Path() + 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.Pkg != nil { + for _, pkg := range g.Pkg.Imports() { if g.validPkg(pkg) { g.Printf("#include \"%s.h\"\n", pkg.Name()) } @@ -973,10 +1003,11 @@ func (g *javaGen) genC() error { g.Printf("proxy_class_%s_%s_cons = (*env)->GetMethodID(env, clazz, \"\", \"(Lgo/Seq$Ref;)V\");\n", g.pkgPrefix, s.obj.Name()) } for _, iface := range g.interfaces { - g.Printf("clazz = (*env)->FindClass(env, %q);\n", g.jniClassSigPrefix(iface.obj.Pkg())+"proxy"+iface.obj.Name()) + pkg := iface.obj.Pkg() + g.Printf("clazz = (*env)->FindClass(env, %q);\n", g.jniClassSigPrefix(pkg)+className(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, \"\", \"(Lgo/Seq$Ref;)V\");\n", g.pkgPrefix, iface.obj.Name()) - g.Printf("clazz = (*env)->FindClass(env, %q);\n", g.jniClassSigPrefix(iface.obj.Pkg())+iface.obj.Name()) + g.Printf("clazz = (*env)->FindClass(env, %q);\n", g.jniClassSigPrefix(pkg)+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()) @@ -1029,20 +1060,20 @@ func (g *javaGen) genC() error { return nil } -func (g *javaGen) genJava() error { +func (g *JavaGen) GenJava() error { pkgPath := "" - if g.pkg != nil { - pkgPath = g.pkg.Path() + if g.Pkg != nil { + pkgPath = g.Pkg.Path() } - g.Printf(javaPreamble, g.javaPkgName(g.pkg), g.className(), g.gobindOpts(), pkgPath) + g.Printf(javaPreamble, g.javaPkgName(g.Pkg), g.className(), g.gobindOpts(), pkgPath) g.Printf("public abstract class %s {\n", g.className()) g.Indent() g.Printf("static {\n") g.Indent() g.Printf("Seq.touch(); // for loading the native library\n") - if g.pkg != nil { - for _, p := range g.pkg.Imports() { + if g.Pkg != nil { + for _, p := range g.Pkg.Imports() { if g.validPkg(p) { g.Printf("%s.%s.touch();\n", g.javaPkgName(p), className(p)) } @@ -1056,12 +1087,24 @@ func (g *javaGen) genJava() error { g.Printf("public static void touch() {}\n\n") g.Printf("private static native void init();\n\n") - for _, s := range g.structs { - g.genStruct(s.obj, s.t) - } for _, iface := range g.interfaces { - g.genInterface(iface) + g.Printf(javaProxyPreamble, iface.obj.Name()) + g.Indent() + + 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.genFuncSignature(m, false, false) + } + + g.Outdent() + g.Printf("}\n") } + + g.Printf("\n") + for _, c := range g.constants { g.genConst(c) } diff --git a/bind/genobjc.go b/bind/genobjc.go index d743c0e..f067c03 100644 --- a/bind/genobjc.go +++ b/bind/genobjc.go @@ -27,7 +27,7 @@ type objcGen struct { // fields set by init. namePrefix string - *generator + *Generator } type interfaceInfo struct { @@ -42,8 +42,8 @@ type structInfo struct { } func (g *objcGen) init() { - g.generator.init() - g.namePrefix = g.namePrefixOf(g.pkg) + g.Generator.Init() + g.namePrefix = g.namePrefixOf(g.Pkg) } func (g *objcGen) namePrefixOf(pkg *types.Package) string { @@ -59,8 +59,8 @@ func (g *objcGen) namePrefixOf(pkg *types.Package) string { func (g *objcGen) genGoH() error { var pkgPath string - if g.pkg != nil { - pkgPath = g.pkg.Path() + if g.Pkg != nil { + pkgPath = g.Pkg.Path() } g.Printf(objcPreamble, pkgPath, g.gobindOpts(), pkgPath) g.Printf("#ifndef __%s_H__\n", g.pkgName) @@ -92,8 +92,8 @@ func (g *objcGen) genGoH() error { func (g *objcGen) genH() error { var pkgPath string - if g.pkg != nil { - pkgPath = g.pkg.Path() + if g.Pkg != nil { + pkgPath = g.Pkg.Path() } g.Printf(objcPreamble, pkgPath, g.gobindOpts(), pkgPath) g.Printf("#ifndef __%s_H__\n", g.namePrefix) @@ -101,8 +101,8 @@ func (g *objcGen) genH() error { g.Printf("\n") g.Printf("#include \n") g.Printf("#include \"GoUniverse.h\"\n") - if g.pkg != nil { - for _, pkg := range g.pkg.Imports() { + if g.Pkg != nil { + for _, pkg := range g.Pkg.Imports() { if g.validPkg(pkg) { g.Printf("#include %q\n", g.namePrefixOf(pkg)+".h") } @@ -207,8 +207,8 @@ func (g *objcGen) gobindOpts() string { func (g *objcGen) genM() error { var pkgPath string var errDomain string - if g.pkg != nil { - pkgPath = g.pkg.Path() + if g.Pkg != nil { + pkgPath = g.Pkg.Path() errDomain = "go." + pkgPath } else { errDomain = "go" diff --git a/bind/java/CustomPkgTest.java b/bind/java/CustomPkgTest.java index 723389c..5dd6abc 100644 --- a/bind/java/CustomPkgTest.java +++ b/bind/java/CustomPkgTest.java @@ -6,7 +6,7 @@ package go; import android.test.InstrumentationTestCase; -import org.golang.custompkg.Testpkg; +import org.golang.custompkg.testpkg.Testpkg; public class CustomPkgTest extends InstrumentationTestCase { public void testHi() { diff --git a/bind/java/Seq.java b/bind/java/Seq.java index 564dd08..40012c7 100644 --- a/bind/java/Seq.java +++ b/bind/java/Seq.java @@ -9,6 +9,7 @@ import java.util.IdentityHashMap; import java.util.logging.Logger; import go.Universe; +import go.error; // Seq is a sequence of machine-dependent encoded values. // Used by automatically generated language bindings to talk to Go. @@ -47,12 +48,12 @@ public class Seq { private Seq() { } - private static void throwException(Universe.error err) throws Exception { + private static void throwException(error err) throws Exception { throw new Exception(err.Error()); } - private static Universe.error wrapThrowable(final Throwable t) { - return new Universe.error() { + private static error wrapThrowable(final Throwable t) { + return new error() { @Override public String Error() { return t.getMessage(); } diff --git a/bind/java/SeqBench.java b/bind/java/SeqBench.java index e28754f..d06964d 100644 --- a/bind/java/SeqBench.java +++ b/bind/java/SeqBench.java @@ -13,16 +13,16 @@ import java.util.HashMap; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; -import go.benchmark.Benchmark; +import go.benchmark.*; public class SeqBench extends InstrumentationTestCase { - public static class AnI implements Benchmark.I { + public static class AnI implements I { @Override public void F() { } } - private static class Benchmarks implements Benchmark.Benchmarks { + private static class Benchmarks implements go.benchmark.Benchmarks { private static Map benchmarks; private static ExecutorService executor = Executors.newSingleThreadExecutor(); @@ -52,13 +52,13 @@ public class SeqBench extends InstrumentationTestCase { Benchmark.Oneret(); } }); - final Benchmark.I javaRef = new AnI(); + final I javaRef = new AnI(); benchmarks.put("Refforeign", new Runnable() { @Override public void run() { Benchmark.Ref(javaRef); } }); - final Benchmark.I goRef = Benchmark.NewI(); + final I goRef = Benchmark.NewI(); benchmarks.put("Refgo", new Runnable() { @Override public void run() { Benchmark.Ref(goRef); @@ -130,10 +130,10 @@ public class SeqBench extends InstrumentationTestCase { } } - @Override public Benchmark.I NewI() { + @Override public I NewI() { return new AnI(); } - @Override public void Ref(Benchmark.I i) { + @Override public void Ref(I i) { } @Override public void Noargs() { } diff --git a/bind/java/SeqTest.java b/bind/java/SeqTest.java index bab54cf..340b93e 100644 --- a/bind/java/SeqTest.java +++ b/bind/java/SeqTest.java @@ -10,7 +10,7 @@ import android.test.MoreAsserts; import java.util.Arrays; import java.util.Random; -import go.testpkg.Testpkg; +import go.testpkg.*; import go.secondpkg.Secondpkg; public class SeqTest extends InstrumentationTestCase { @@ -63,9 +63,9 @@ public class SeqTest extends InstrumentationTestCase { Testpkg.setIntVar(newIntVar); assertEquals("var IntVar", newIntVar, Testpkg.getIntVar()); - Testpkg.S s0 = Testpkg.getStructVar(); + S s0 = Testpkg.getStructVar(); assertEquals("var StructVar", "a struct var", s0.String()); - Testpkg.S s1 = Testpkg.New(); + S s1 = Testpkg.New(); Testpkg.setStructVar(s1); assertEquals("var StructVar", s1.String(), Testpkg.getStructVar().String()); @@ -205,7 +205,7 @@ public class SeqTest extends InstrumentationTestCase { } public void testGoRefGC() { - Testpkg.S s = Testpkg.New(); + S s = Testpkg.New(); runGC(); long collected = Testpkg.NumSCollected(); assertEquals("Only S should be pinned", 0, collected); @@ -216,7 +216,7 @@ public class SeqTest extends InstrumentationTestCase { assertEquals("S should be collected", 1, collected); } - private class AnI implements Testpkg.I { + private class AnI implements I { public void E() throws Exception { throw new Exception("my exception from E"); } @@ -226,15 +226,15 @@ public class SeqTest extends InstrumentationTestCase { calledF = true; } - public Testpkg.I I() { + public I I() { return this; } - public Testpkg.S S() { + public S S() { return Testpkg.New(); } - public String StoString(Testpkg.S s) { + public String StoString(S s) { return s.String(); } @@ -275,7 +275,7 @@ public class SeqTest extends InstrumentationTestCase { public void testInterfaceMethodReturnsInterface() { AnI obj = new AnI(); obj.name = "testing AnI.I"; - Testpkg.I i = Testpkg.CallI(obj); + I i = Testpkg.CallI(obj); assertEquals("Want AnI.I to return itself", i.String(), obj.String()); runGC(); @@ -287,14 +287,14 @@ public class SeqTest extends InstrumentationTestCase { public void testInterfaceMethodReturnsStructPointer() { final AnI obj = new AnI(); for (int i = 0; i < 5; i++) { - Testpkg.S s = Testpkg.CallS(obj); + S s = Testpkg.CallS(obj); runGC(); } } public void testInterfaceMethodTakesStructPointer() { final AnI obj = new AnI(); - Testpkg.S s = Testpkg.CallS(obj); + S s = Testpkg.CallS(obj); String got = obj.StoString(s); String want = s.String(); assertEquals("Want AnI.StoString(s) to call s's String", want, got); @@ -355,13 +355,13 @@ public class SeqTest extends InstrumentationTestCase { private int countI = 0; - private class CountI implements Testpkg.I { + private class CountI implements I { public void F() { countI++; } public void E() throws Exception {} - public Testpkg.I I() { return null; } - public Testpkg.S S() { return null; } - public String StoString(Testpkg.S s) { return ""; } + public I I() { return null; } + public S S() { return null; } + public String StoString(S s) { return ""; } public long V() { return 0; } public long VE() throws Exception { return 0; } public String String() { return ""; } @@ -404,20 +404,20 @@ public class SeqTest extends InstrumentationTestCase { } public void testPointerToStructAsField() { - Testpkg.Node a = Testpkg.NewNode("A"); - Testpkg.Node b = Testpkg.NewNode("B"); + Node a = Testpkg.NewNode("A"); + Node b = Testpkg.NewNode("B"); a.setNext(b); String got = a.String(); assertEquals("want Node A points to Node B", "A:B:", got); } public void testImplementsInterface() { - Testpkg.Interface intf = Testpkg.NewConcrete(); + Interface intf = Testpkg.NewConcrete(); } public void testErrorField() { final String want = "an error message"; - Testpkg.Node n = Testpkg.NewNode("ErrTest"); + Node n = Testpkg.NewNode("ErrTest"); n.setErr(want); String got = n.getErr(); assertEquals("want back the error message we set", want, got); @@ -425,7 +425,7 @@ public class SeqTest extends InstrumentationTestCase { //test if we have JNI local reference table overflow error public void testLocalReferenceOverflow() { - Testpkg.CallWithCallback(new Testpkg.GoCallback() { + Testpkg.CallWithCallback(new GoCallback() { @Override public void VarUpdate() { @@ -435,8 +435,8 @@ public class SeqTest extends InstrumentationTestCase { } public void testNullReferences() { - assertTrue(Testpkg.CallWithNull(null, new Testpkg.NullTest() { - public Testpkg.NullTest Null() { + assertTrue(Testpkg.CallWithNull(null, new NullTest() { + public NullTest Null() { return null; } })); @@ -445,7 +445,7 @@ public class SeqTest extends InstrumentationTestCase { } public void testPassByteArray() { - Testpkg.PassByteArray(new Testpkg.B() { + Testpkg.PassByteArray(new B() { @Override public void B(byte[] b) { byte[] want = new byte[]{1, 2, 3, 4}; MoreAsserts.assertEquals("bytes should match", want, b); @@ -468,28 +468,28 @@ public class SeqTest extends InstrumentationTestCase { } public void testGoroutineCallback() { - Testpkg.GoroutineCallback(new Testpkg.Receiver() { + Testpkg.GoroutineCallback(new Receiver() { @Override public void Hello(String msg) { } }); } public void testImportedPkg() { - Testpkg.CallImportedI(new Secondpkg.I() { + Testpkg.CallImportedI(new go.secondpkg.I() { @Override public long F(long i) { return i; } }); assertEquals("imported string should match", Secondpkg.HelloString, Secondpkg.Hello()); - Secondpkg.I i = Testpkg.NewImportedI(); - Secondpkg.S s = Testpkg.NewImportedS(); + go.secondpkg.I i = Testpkg.NewImportedI(); + go.secondpkg.S s = Testpkg.NewImportedS(); i = Testpkg.getImportedVarI(); s = Testpkg.getImportedVarS(); assertEquals("numbers should match", 8, i.F(8)); assertEquals("numbers should match", 8, s.F(8)); Testpkg.setImportedVarI(i); Testpkg.setImportedVarS(s); - Testpkg.ImportedFields fields = Testpkg.NewImportedFields(); + ImportedFields fields = Testpkg.NewImportedFields(); i = fields.getI(); s = fields.getS(); fields.setI(i); @@ -497,22 +497,22 @@ public class SeqTest extends InstrumentationTestCase { Testpkg.WithImportedI(i); Testpkg.WithImportedS(s); - Secondpkg.IF f = new AnI(); + go.secondpkg.IF f = new AnI(); f = Testpkg.New(); - Secondpkg.Ser ser = Testpkg.NewSer(); + go.secondpkg.Ser ser = Testpkg.NewSer(); } public void testRoundtripEquality() { - Testpkg.I want = new AnI(); + I want = new AnI(); assertTrue("java object passed through Go should not be wrapped", want == Testpkg.IDup(want)); - Testpkg.InterfaceDupper idup = new Testpkg.InterfaceDupper(){ - @Override public Testpkg.Interface IDup(Testpkg.Interface i) { + InterfaceDupper idup = new InterfaceDupper(){ + @Override public Interface IDup(Interface i) { return i; } }; assertTrue("Go interface passed through Java should not be wrapped", Testpkg.CallIDupper(idup)); - Testpkg.ConcreteDupper cdup = new Testpkg.ConcreteDupper(){ - @Override public Testpkg.Concrete CDup(Testpkg.Concrete c) { + ConcreteDupper cdup = new ConcreteDupper(){ + @Override public Concrete CDup(Concrete c) { return c; } }; @@ -525,7 +525,7 @@ public class SeqTest extends InstrumentationTestCase { fail("Empty error wasn't caught"); } catch (Exception e) { } - Testpkg.EmptyErrorer empty = new Testpkg.EmptyErrorer() { + EmptyErrorer empty = new EmptyErrorer() { @Override public void EmptyError() throws Exception { throw new Exception(""); } diff --git a/bind/java/seq_android.c.support b/bind/java/seq_android.c.support index 2bc1c6a..4539f9c 100644 --- a/bind/java/seq_android.c.support +++ b/bind/java/seq_android.c.support @@ -291,7 +291,7 @@ Java_go_Seq_init(JNIEnv *env, jclass clazz) { } seq_class = (*env)->NewGlobalRef(env, clazz); - seq_throw_exc = (*env)->GetStaticMethodID(env, seq_class, "throwException", "(Lgo/Universe$error;)V"); + seq_throw_exc = (*env)->GetStaticMethodID(env, seq_class, "throwException", "(Lgo/error;)V"); if (seq_throw_exc == NULL) { LOG_FATAL("failed to find method Seq.throwException"); } @@ -312,7 +312,7 @@ Java_go_Seq_init(JNIEnv *env, jclass clazz) { if (seq_incRef == NULL) { LOG_FATAL("failed to find method Seq.incRef"); } - seq_wrapThrowable = (*env)->GetStaticMethodID(env, seq_class, "wrapThrowable", "(Ljava/lang/Throwable;)Lgo/Universe$error;"); + seq_wrapThrowable = (*env)->GetStaticMethodID(env, seq_class, "wrapThrowable", "(Ljava/lang/Throwable;)Lgo/error;"); if (seq_wrapThrowable == NULL) { LOG_FATAL("failed to find method Seq.wrapThrowable"); } diff --git a/bind/printer.go b/bind/printer.go index 39cb809..3d24ea0 100644 --- a/bind/printer.go +++ b/bind/printer.go @@ -9,23 +9,23 @@ import ( "fmt" ) -type printer struct { - buf *bytes.Buffer - indentEach []byte +type Printer struct { + Buf *bytes.Buffer + IndentEach []byte indentText []byte needIndent bool } -func (p *printer) writeIndent() error { +func (p *Printer) writeIndent() error { if !p.needIndent { return nil } p.needIndent = false - _, err := p.buf.Write(p.indentText) + _, err := p.Buf.Write(p.indentText) return err } -func (p *printer) Write(b []byte) (n int, err error) { +func (p *Printer) Write(b []byte) (n int, err error) { wrote := 0 for len(b) > 0 { if err := p.writeIndent(); err != nil { @@ -35,7 +35,7 @@ func (p *printer) Write(b []byte) (n int, err error) { if i < 0 { break } - n, err = p.buf.Write(b[0 : i+1]) + n, err = p.Buf.Write(b[0 : i+1]) wrote += n if err != nil { return wrote, err @@ -44,24 +44,24 @@ func (p *printer) Write(b []byte) (n int, err error) { p.needIndent = true } if len(b) > 0 { - n, err = p.buf.Write(b) + n, err = p.Buf.Write(b) wrote += n } return wrote, err } -func (p *printer) Printf(format string, args ...interface{}) { +func (p *Printer) Printf(format string, args ...interface{}) { if _, err := fmt.Fprintf(p, format, args...); err != nil { panic(fmt.Sprintf("printer: %v", err)) } } -func (p *printer) Indent() { - p.indentText = append(p.indentText, p.indentEach...) +func (p *Printer) Indent() { + p.indentText = append(p.indentText, p.IndentEach...) } -func (p *printer) Outdent() { - if len(p.indentText) > len(p.indentEach)-1 { - p.indentText = p.indentText[len(p.indentEach):] +func (p *Printer) Outdent() { + if len(p.indentText) > len(p.IndentEach)-1 { + p.indentText = p.indentText[len(p.IndentEach):] } } diff --git a/bind/testdata/basictypes.java.golden b/bind/testdata/basictypes.java.golden index 887acca..d8986a2 100644 --- a/bind/testdata/basictypes.java.golden +++ b/bind/testdata/basictypes.java.golden @@ -19,6 +19,7 @@ public abstract class Basictypes { private static native void init(); + public static final boolean ABool = true; public static final double AFloat = 0.2015; public static final String ALongString = "LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString"; diff --git a/bind/testdata/customprefix.java.c.golden b/bind/testdata/customprefix.java.c.golden index 00074b9..456fcf7 100644 --- a/bind/testdata/customprefix.java.c.golden +++ b/bind/testdata/customprefix.java.c.golden @@ -11,12 +11,12 @@ JNIEXPORT void JNICALL -Java_com_example_Customprefix_init(JNIEnv *env, jclass _unused) { +Java_com_example_customprefix_Customprefix_init(JNIEnv *env, jclass _unused) { jclass clazz; } JNIEXPORT void JNICALL -Java_com_example_Customprefix_F(JNIEnv* env, jclass clazz) { +Java_com_example_customprefix_Customprefix_F(JNIEnv* env, jclass clazz) { proxycustomprefix__F(); } diff --git a/bind/testdata/customprefix.java.golden b/bind/testdata/customprefix.java.golden index 04693ed..05f2282 100644 --- a/bind/testdata/customprefix.java.golden +++ b/bind/testdata/customprefix.java.golden @@ -1,8 +1,8 @@ -// Java class com.example.Customprefix is a proxy for talking to a Go program. +// Java class com.example.customprefix.Customprefix is a proxy for talking to a Go program. // gobind -lang=java -javapkg=com.example customprefix // // File is generated by gobind. Do not edit. -package com.example; +package com.example.customprefix; import go.Seq; @@ -20,5 +20,6 @@ public abstract class Customprefix { private static native void init(); + public static native void F(); } diff --git a/bind/testdata/ignore.java.c.golden b/bind/testdata/ignore.java.c.golden index 8b3c5a5..6ef3b36 100644 --- a/bind/testdata/ignore.java.c.golden +++ b/bind/testdata/ignore.java.c.golden @@ -21,13 +21,13 @@ jmethodID proxy_class_ignore_S_cons; JNIEXPORT void JNICALL Java_go_ignore_Ignore_init(JNIEnv *env, jclass _unused) { jclass clazz; - clazz = (*env)->FindClass(env, "go/ignore/Ignore$S"); + clazz = (*env)->FindClass(env, "go/ignore/S"); proxy_class_ignore_S = (*env)->NewGlobalRef(env, clazz); proxy_class_ignore_S_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); clazz = (*env)->FindClass(env, "go/ignore/Ignore$proxyI"); proxy_class_ignore_I = (*env)->NewGlobalRef(env, clazz); proxy_class_ignore_I_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); - clazz = (*env)->FindClass(env, "go/ignore/Ignore$I"); + clazz = (*env)->FindClass(env, "go/ignore/I"); // skipped method I.Argument with unsupported parameter or return types // skipped method I.Result with unsupported parameter or return types diff --git a/bind/testdata/ignore.java.golden b/bind/testdata/ignore.java.golden index ef385ff..065b7d7 100644 --- a/bind/testdata/ignore.java.golden +++ b/bind/testdata/ignore.java.golden @@ -1,3 +1,57 @@ +// Java class go.ignore.S is a proxy for talking to a Go program. +// gobind -lang=java ignore +// +// File is generated by gobind. Do not edit. +package go.ignore; + +import go.Seq; + +public final class S extends Seq.Proxy implements I { + private S(go.Seq.Ref ref) { super(ref); } + + // skipped field S.F with unsupported type: *types.Interface + + // skipped method S.Argument with unsupported parameter or return types + + // skipped method S.Result with unsupported parameter or return types + + @Override public boolean equals(Object o) { + if (o == null || !(o instanceof S)) { + return false; + } + S that = (S)o; + // skipped field S.F with unsupported type: *types.Interface + + return true; + } + + @Override public int hashCode() { + return java.util.Arrays.hashCode(new Object[] {}); + } + + @Override public String toString() { + StringBuilder b = new StringBuilder(); + b.append("S").append("{"); + return b.append("}").toString(); + } +} + +// Java class go.ignore.I is a proxy for talking to a Go program. +// gobind -lang=java ignore +// +// File is generated by gobind. Do not edit. +package go.ignore; + +import go.Seq; + +public interface I { + // skipped method I.Argument with unsupported parameter or return types + + // skipped method I.Result with unsupported parameter or return types + + +} + // Java class go.ignore.Ignore is a proxy for talking to a Go program. // gobind -lang=java ignore // @@ -19,43 +73,6 @@ public abstract class Ignore { private static native void init(); - public static final class S extends Seq.Proxy implements I { - private S(go.Seq.Ref ref) { super(ref); } - - // skipped field S.F with unsupported type: *types.Interface - - // skipped method S.Argument with unsupported parameter or return types - - // skipped method S.Result with unsupported parameter or return types - - @Override public boolean equals(Object o) { - if (o == null || !(o instanceof S)) { - return false; - } - S that = (S)o; - // skipped field S.F with unsupported type: *types.Interface - - return true; - } - - @Override public int hashCode() { - return java.util.Arrays.hashCode(new Object[] {}); - } - - @Override public String toString() { - StringBuilder b = new StringBuilder(); - b.append("S").append("{"); - return b.append("}").toString(); - } - } - - public interface I { - // skipped method I.Argument with unsupported parameter or return types - - // skipped method I.Result with unsupported parameter or return types - - } - private static final class proxyI extends Seq.Proxy implements I { proxyI(Seq.Ref ref) { super(ref); } diff --git a/bind/testdata/interfaces.java.c.golden b/bind/testdata/interfaces.java.c.golden index f151ded..444f86a 100644 --- a/bind/testdata/interfaces.java.c.golden +++ b/bind/testdata/interfaces.java.c.golden @@ -41,50 +41,50 @@ Java_go_interfaces_Interfaces_init(JNIEnv *env, jclass _unused) { clazz = (*env)->FindClass(env, "go/interfaces/Interfaces$proxyError"); proxy_class_interfaces_Error = (*env)->NewGlobalRef(env, clazz); proxy_class_interfaces_Error_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); - clazz = (*env)->FindClass(env, "go/interfaces/Interfaces$Error"); + clazz = (*env)->FindClass(env, "go/interfaces/Error"); mid_Error_Err = (*env)->GetMethodID(env, clazz, "Err", "()V"); clazz = (*env)->FindClass(env, "go/interfaces/Interfaces$proxyI"); proxy_class_interfaces_I = (*env)->NewGlobalRef(env, clazz); proxy_class_interfaces_I_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); - clazz = (*env)->FindClass(env, "go/interfaces/Interfaces$I"); + clazz = (*env)->FindClass(env, "go/interfaces/I"); mid_I_Rand = (*env)->GetMethodID(env, clazz, "Rand", "()I"); clazz = (*env)->FindClass(env, "go/interfaces/Interfaces$proxyI1"); proxy_class_interfaces_I1 = (*env)->NewGlobalRef(env, clazz); proxy_class_interfaces_I1_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); - clazz = (*env)->FindClass(env, "go/interfaces/Interfaces$I1"); + clazz = (*env)->FindClass(env, "go/interfaces/I1"); mid_I1_J = (*env)->GetMethodID(env, clazz, "J", "()V"); clazz = (*env)->FindClass(env, "go/interfaces/Interfaces$proxyI2"); proxy_class_interfaces_I2 = (*env)->NewGlobalRef(env, clazz); proxy_class_interfaces_I2_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); - clazz = (*env)->FindClass(env, "go/interfaces/Interfaces$I2"); + clazz = (*env)->FindClass(env, "go/interfaces/I2"); mid_I2_G = (*env)->GetMethodID(env, clazz, "G", "()V"); clazz = (*env)->FindClass(env, "go/interfaces/Interfaces$proxyI3"); proxy_class_interfaces_I3 = (*env)->NewGlobalRef(env, clazz); proxy_class_interfaces_I3_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); - clazz = (*env)->FindClass(env, "go/interfaces/Interfaces$I3"); - mid_I3_F = (*env)->GetMethodID(env, clazz, "F", "()Lgo/interfaces/Interfaces$I1;"); + clazz = (*env)->FindClass(env, "go/interfaces/I3"); + mid_I3_F = (*env)->GetMethodID(env, clazz, "F", "()Lgo/interfaces/I1;"); clazz = (*env)->FindClass(env, "go/interfaces/Interfaces$proxyLargerI"); proxy_class_interfaces_LargerI = (*env)->NewGlobalRef(env, clazz); proxy_class_interfaces_LargerI_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); - clazz = (*env)->FindClass(env, "go/interfaces/Interfaces$LargerI"); + clazz = (*env)->FindClass(env, "go/interfaces/LargerI"); mid_LargerI_AnotherFunc = (*env)->GetMethodID(env, clazz, "AnotherFunc", "()V"); mid_LargerI_Rand = (*env)->GetMethodID(env, clazz, "Rand", "()I"); clazz = (*env)->FindClass(env, "go/interfaces/Interfaces$proxySameI"); proxy_class_interfaces_SameI = (*env)->NewGlobalRef(env, clazz); proxy_class_interfaces_SameI_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); - clazz = (*env)->FindClass(env, "go/interfaces/Interfaces$SameI"); + clazz = (*env)->FindClass(env, "go/interfaces/SameI"); mid_SameI_Rand = (*env)->GetMethodID(env, clazz, "Rand", "()I"); clazz = (*env)->FindClass(env, "go/interfaces/Interfaces$proxyWithParam"); proxy_class_interfaces_WithParam = (*env)->NewGlobalRef(env, clazz); proxy_class_interfaces_WithParam_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); - clazz = (*env)->FindClass(env, "go/interfaces/Interfaces$WithParam"); + clazz = (*env)->FindClass(env, "go/interfaces/WithParam"); mid_WithParam_HasParam = (*env)->GetMethodID(env, clazz, "HasParam", "(Z)V"); } diff --git a/bind/testdata/interfaces.java.golden b/bind/testdata/interfaces.java.golden index a5717f9..9d55c30 100644 --- a/bind/testdata/interfaces.java.golden +++ b/bind/testdata/interfaces.java.golden @@ -1,3 +1,108 @@ +// Java class go.interfaces.Error is a proxy for talking to a Go program. +// gobind -lang=java interfaces +// +// File is generated by gobind. Do not edit. +package go.interfaces; + +import go.Seq; + +public interface Error { + public void Err() throws Exception; + +} + +// Java class go.interfaces.I is a proxy for talking to a Go program. +// gobind -lang=java interfaces +// +// File is generated by gobind. Do not edit. +package go.interfaces; + +import go.Seq; + +public interface I { + public int Rand(); + +} + +// Java class go.interfaces.I1 is a proxy for talking to a Go program. +// gobind -lang=java interfaces +// +// File is generated by gobind. Do not edit. +package go.interfaces; + +import go.Seq; + +public interface I1 { + public void J(); + +} + +// Java class go.interfaces.I2 is a proxy for talking to a Go program. +// gobind -lang=java interfaces +// +// File is generated by gobind. Do not edit. +package go.interfaces; + +import go.Seq; + +public interface I2 { + public void G(); + +} + +// Java class go.interfaces.I3 is a proxy for talking to a Go program. +// gobind -lang=java interfaces +// +// File is generated by gobind. Do not edit. +package go.interfaces; + +import go.Seq; + +public interface I3 { + public I1 F(); + +} + +// Java class go.interfaces.LargerI is a proxy for talking to a Go program. +// gobind -lang=java interfaces +// +// File is generated by gobind. Do not edit. +package go.interfaces; + +import go.Seq; + +public interface LargerI extends I, SameI { + public void AnotherFunc(); + public int Rand(); + +} + +// Java class go.interfaces.SameI is a proxy for talking to a Go program. +// gobind -lang=java interfaces +// +// File is generated by gobind. Do not edit. +package go.interfaces; + +import go.Seq; + +public interface SameI { + public int Rand(); + +} + +// Java class go.interfaces.WithParam is a proxy for talking to a Go program. +// gobind -lang=java interfaces +// +// File is generated by gobind. Do not edit. +package go.interfaces; + +import go.Seq; + +public interface WithParam { + public void HasParam(boolean p0); + +} + // Java class go.interfaces.Interfaces is a proxy for talking to a Go program. // gobind -lang=java interfaces // @@ -19,82 +124,42 @@ public abstract class Interfaces { private static native void init(); - public interface Error { - public void Err() throws Exception; - } - private static final class proxyError extends Seq.Proxy implements Error { proxyError(Seq.Ref ref) { super(ref); } public native void Err() throws Exception; } - - public interface I { - public int Rand(); - } - private static final class proxyI extends Seq.Proxy implements I { proxyI(Seq.Ref ref) { super(ref); } public native int Rand(); } - - public interface I1 { - public void J(); - } - private static final class proxyI1 extends Seq.Proxy implements I1 { proxyI1(Seq.Ref ref) { super(ref); } public native void J(); } - - public interface I2 { - public void G(); - } - private static final class proxyI2 extends Seq.Proxy implements I2 { proxyI2(Seq.Ref ref) { super(ref); } public native void G(); } - - public interface I3 { - public I1 F(); - } - private static final class proxyI3 extends Seq.Proxy implements I3 { proxyI3(Seq.Ref ref) { super(ref); } public native I1 F(); } - - public interface LargerI extends I, SameI { - public void AnotherFunc(); - public int Rand(); - } - private static final class proxyLargerI extends Seq.Proxy implements LargerI { proxyLargerI(Seq.Ref ref) { super(ref); } public native void AnotherFunc(); public native int Rand(); } - - public interface SameI { - public int Rand(); - } - private static final class proxySameI extends Seq.Proxy implements SameI { proxySameI(Seq.Ref ref) { super(ref); } public native int Rand(); } - - public interface WithParam { - public void HasParam(boolean p0); - } - private static final class proxyWithParam extends Seq.Proxy implements WithParam { proxyWithParam(Seq.Ref ref) { super(ref); } diff --git a/bind/testdata/issue10788.java.c.golden b/bind/testdata/issue10788.java.c.golden index 96ed481..3a32f2e 100644 --- a/bind/testdata/issue10788.java.c.golden +++ b/bind/testdata/issue10788.java.c.golden @@ -19,27 +19,27 @@ jmethodID proxy_class_issue10788_TestStruct_cons; JNIEXPORT void JNICALL Java_go_issue10788_Issue10788_init(JNIEnv *env, jclass _unused) { jclass clazz; - clazz = (*env)->FindClass(env, "go/issue10788/Issue10788$TestStruct"); + clazz = (*env)->FindClass(env, "go/issue10788/TestStruct"); proxy_class_issue10788_TestStruct = (*env)->NewGlobalRef(env, clazz); proxy_class_issue10788_TestStruct_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); clazz = (*env)->FindClass(env, "go/issue10788/Issue10788$proxyTestInterface"); proxy_class_issue10788_TestInterface = (*env)->NewGlobalRef(env, clazz); proxy_class_issue10788_TestInterface_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); - clazz = (*env)->FindClass(env, "go/issue10788/Issue10788$TestInterface"); - mid_TestInterface_DoSomeWork = (*env)->GetMethodID(env, clazz, "DoSomeWork", "(Lgo/issue10788/Issue10788$TestStruct;)V"); + clazz = (*env)->FindClass(env, "go/issue10788/TestInterface"); + mid_TestInterface_DoSomeWork = (*env)->GetMethodID(env, clazz, "DoSomeWork", "(Lgo/issue10788/TestStruct;)V"); mid_TestInterface_MultipleUnnamedParams = (*env)->GetMethodID(env, clazz, "MultipleUnnamedParams", "(JLjava/lang/String;J)V"); } JNIEXPORT void JNICALL -Java_go_issue10788_Issue10788_00024TestStruct_setValue(JNIEnv *env, jobject this, jstring v) { +Java_go_issue10788_TestStruct_setValue(JNIEnv *env, jobject this, jstring v) { int32_t o = go_seq_to_refnum(env, this); nstring _v = go_seq_from_java_string(env, v); proxyissue10788_TestStruct_Value_Set(o, _v); } JNIEXPORT jstring JNICALL -Java_go_issue10788_Issue10788_00024TestStruct_getValue(JNIEnv *env, jobject this) { +Java_go_issue10788_TestStruct_getValue(JNIEnv *env, jobject this) { int32_t o = go_seq_to_refnum(env, this); nstring r0 = proxyissue10788_TestStruct_Value_Get(o); jstring _r0 = go_seq_to_java_string(env, r0); diff --git a/bind/testdata/issue10788.java.golden b/bind/testdata/issue10788.java.golden index a41efd6..30aa170 100644 --- a/bind/testdata/issue10788.java.golden +++ b/bind/testdata/issue10788.java.golden @@ -1,3 +1,60 @@ +// Java class go.issue10788.TestStruct is a proxy for talking to a Go program. +// gobind -lang=java issue10788 +// +// File is generated by gobind. Do not edit. +package go.issue10788; + +import go.Seq; + +public final class TestStruct extends Seq.Proxy { + private TestStruct(go.Seq.Ref ref) { super(ref); } + + public final native String getValue(); + public final native void setValue(String v); + + @Override public boolean equals(Object o) { + if (o == null || !(o instanceof TestStruct)) { + return false; + } + TestStruct that = (TestStruct)o; + String thisValue = getValue(); + String thatValue = that.getValue(); + if (thisValue == null) { + if (thatValue != null) { + return false; + } + } else if (!thisValue.equals(thatValue)) { + return false; + } + return true; + } + + @Override public int hashCode() { + return java.util.Arrays.hashCode(new Object[] {getValue()}); + } + + @Override public String toString() { + StringBuilder b = new StringBuilder(); + b.append("TestStruct").append("{"); + b.append("Value:").append(getValue()).append(","); + return b.append("}").toString(); + } +} + +// Java class go.issue10788.TestInterface is a proxy for talking to a Go program. +// gobind -lang=java issue10788 +// +// File is generated by gobind. Do not edit. +package go.issue10788; + +import go.Seq; + +public interface TestInterface { + public void DoSomeWork(TestStruct s); + public void MultipleUnnamedParams(long p0, String p1, long p2); + +} + // Java class go.issue10788.Issue10788 is a proxy for talking to a Go program. // gobind -lang=java issue10788 // @@ -19,46 +76,6 @@ public abstract class Issue10788 { private static native void init(); - public static final class TestStruct extends Seq.Proxy { - private TestStruct(go.Seq.Ref ref) { super(ref); } - - public final native String getValue(); - public final native void setValue(String v); - - @Override public boolean equals(Object o) { - if (o == null || !(o instanceof TestStruct)) { - return false; - } - TestStruct that = (TestStruct)o; - String thisValue = getValue(); - String thatValue = that.getValue(); - if (thisValue == null) { - if (thatValue != null) { - return false; - } - } else if (!thisValue.equals(thatValue)) { - return false; - } - return true; - } - - @Override public int hashCode() { - return java.util.Arrays.hashCode(new Object[] {getValue()}); - } - - @Override public String toString() { - StringBuilder b = new StringBuilder(); - b.append("TestStruct").append("{"); - b.append("Value:").append(getValue()).append(","); - return b.append("}").toString(); - } - } - - public interface TestInterface { - public void DoSomeWork(TestStruct s); - public void MultipleUnnamedParams(long p0, String p1, long p2); - } - private static final class proxyTestInterface extends Seq.Proxy implements TestInterface { proxyTestInterface(Seq.Ref ref) { super(ref); } diff --git a/bind/testdata/issue12328.java.c.golden b/bind/testdata/issue12328.java.c.golden index 9830f6b..ef74476 100644 --- a/bind/testdata/issue12328.java.c.golden +++ b/bind/testdata/issue12328.java.c.golden @@ -15,20 +15,20 @@ jmethodID proxy_class_issue12328_T_cons; JNIEXPORT void JNICALL Java_go_issue12328_Issue12328_init(JNIEnv *env, jclass _unused) { jclass clazz; - clazz = (*env)->FindClass(env, "go/issue12328/Issue12328$T"); + clazz = (*env)->FindClass(env, "go/issue12328/T"); proxy_class_issue12328_T = (*env)->NewGlobalRef(env, clazz); proxy_class_issue12328_T_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); } JNIEXPORT void JNICALL -Java_go_issue12328_Issue12328_00024T_setErr(JNIEnv *env, jobject this, jobject v) { +Java_go_issue12328_T_setErr(JNIEnv *env, jobject this, jobject v) { int32_t o = go_seq_to_refnum(env, this); int32_t _v = go_seq_to_refnum(env, v); proxyissue12328_T_Err_Set(o, _v); } JNIEXPORT jobject JNICALL -Java_go_issue12328_Issue12328_00024T_getErr(JNIEnv *env, jobject this) { +Java_go_issue12328_T_getErr(JNIEnv *env, jobject this) { int32_t o = go_seq_to_refnum(env, this); int32_t r0 = proxyissue12328_T_Err_Get(o); jobject _r0 = go_seq_from_refnum(env, r0, proxy_class__error, proxy_class__error_cons); diff --git a/bind/testdata/issue12328.java.golden b/bind/testdata/issue12328.java.golden index 1a01f48..ce378e1 100644 --- a/bind/testdata/issue12328.java.golden +++ b/bind/testdata/issue12328.java.golden @@ -1,3 +1,46 @@ +// Java class go.issue12328.T is a proxy for talking to a Go program. +// gobind -lang=java issue12328 +// +// File is generated by gobind. Do not edit. +package go.issue12328; + +import go.Seq; + +public final class T extends Seq.Proxy { + private T(go.Seq.Ref ref) { super(ref); } + + public final native String getErr(); + public final native void setErr(String v); + + @Override public boolean equals(Object o) { + if (o == null || !(o instanceof T)) { + return false; + } + T that = (T)o; + String thisErr = getErr(); + String thatErr = that.getErr(); + if (thisErr == null) { + if (thatErr != null) { + return false; + } + } else if (!thisErr.equals(thatErr)) { + return false; + } + return true; + } + + @Override public int hashCode() { + return java.util.Arrays.hashCode(new Object[] {getErr()}); + } + + @Override public String toString() { + StringBuilder b = new StringBuilder(); + b.append("T").append("{"); + b.append("Err:").append(getErr()).append(","); + return b.append("}").toString(); + } +} + // Java class go.issue12328.Issue12328 is a proxy for talking to a Go program. // gobind -lang=java issue12328 // @@ -19,40 +62,6 @@ public abstract class Issue12328 { private static native void init(); - public static final class T extends Seq.Proxy { - private T(go.Seq.Ref ref) { super(ref); } - - public final native String getErr(); - public final native void setErr(String v); - - @Override public boolean equals(Object o) { - if (o == null || !(o instanceof T)) { - return false; - } - T that = (T)o; - String thisErr = getErr(); - String thatErr = that.getErr(); - if (thisErr == null) { - if (thatErr != null) { - return false; - } - } else if (!thisErr.equals(thatErr)) { - return false; - } - return true; - } - - @Override public int hashCode() { - return java.util.Arrays.hashCode(new Object[] {getErr()}); - } - - @Override public String toString() { - StringBuilder b = new StringBuilder(); - b.append("T").append("{"); - b.append("Err:").append(getErr()).append(","); - return b.append("}").toString(); - } - } } diff --git a/bind/testdata/issue12403.java.c.golden b/bind/testdata/issue12403.java.c.golden index f7323f1..64eec04 100644 --- a/bind/testdata/issue12403.java.c.golden +++ b/bind/testdata/issue12403.java.c.golden @@ -20,7 +20,7 @@ Java_go_issue12403_Issue12403_init(JNIEnv *env, jclass _unused) { clazz = (*env)->FindClass(env, "go/issue12403/Issue12403$proxyParsable"); proxy_class_issue12403_Parsable = (*env)->NewGlobalRef(env, clazz); proxy_class_issue12403_Parsable_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); - clazz = (*env)->FindClass(env, "go/issue12403/Issue12403$Parsable"); + clazz = (*env)->FindClass(env, "go/issue12403/Parsable"); mid_Parsable_FromJSON = (*env)->GetMethodID(env, clazz, "FromJSON", "(Ljava/lang/String;)Ljava/lang/String;"); mid_Parsable_ToJSON = (*env)->GetMethodID(env, clazz, "ToJSON", "()Ljava/lang/String;"); diff --git a/bind/testdata/issue12403.java.golden b/bind/testdata/issue12403.java.golden index 1838705..e268ecc 100644 --- a/bind/testdata/issue12403.java.golden +++ b/bind/testdata/issue12403.java.golden @@ -1,3 +1,17 @@ +// Java class go.issue12403.Parsable is a proxy for talking to a Go program. +// gobind -lang=java issue12403 +// +// File is generated by gobind. Do not edit. +package go.issue12403; + +import go.Seq; + +public interface Parsable { + public String FromJSON(String jstr); + public String ToJSON() throws Exception; + +} + // Java class go.issue12403.Issue12403 is a proxy for talking to a Go program. // gobind -lang=java issue12403 // @@ -19,11 +33,6 @@ public abstract class Issue12403 { private static native void init(); - public interface Parsable { - public String FromJSON(String jstr); - public String ToJSON() throws Exception; - } - private static final class proxyParsable extends Seq.Proxy implements Parsable { proxyParsable(Seq.Ref ref) { super(ref); } diff --git a/bind/testdata/structs.java.c.golden b/bind/testdata/structs.java.c.golden index f2417cd..91897d9 100644 --- a/bind/testdata/structs.java.c.golden +++ b/bind/testdata/structs.java.c.golden @@ -20,16 +20,16 @@ jmethodID proxy_class_structs_S2_cons; JNIEXPORT void JNICALL Java_go_structs_Structs_init(JNIEnv *env, jclass _unused) { jclass clazz; - clazz = (*env)->FindClass(env, "go/structs/Structs$S"); + clazz = (*env)->FindClass(env, "go/structs/S"); proxy_class_structs_S = (*env)->NewGlobalRef(env, clazz); proxy_class_structs_S_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); - clazz = (*env)->FindClass(env, "go/structs/Structs$S2"); + clazz = (*env)->FindClass(env, "go/structs/S2"); proxy_class_structs_S2 = (*env)->NewGlobalRef(env, clazz); proxy_class_structs_S2_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); clazz = (*env)->FindClass(env, "go/structs/Structs$proxyI"); proxy_class_structs_I = (*env)->NewGlobalRef(env, clazz); proxy_class_structs_I_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); - clazz = (*env)->FindClass(env, "go/structs/Structs$I"); + clazz = (*env)->FindClass(env, "go/structs/I"); mid_I_M = (*env)->GetMethodID(env, clazz, "M", "()V"); } @@ -53,7 +53,7 @@ Java_go_structs_Structs_IdentityWithError(JNIEnv* env, jclass clazz, jobject s) } JNIEXPORT jobject JNICALL -Java_go_structs_Structs_00024S_Identity(JNIEnv* env, jobject this) { +Java_go_structs_S_Identity(JNIEnv* env, jobject this) { int32_t o = go_seq_to_refnum(env, this); struct proxystructs_S_Identity_return res = proxystructs_S_Identity(o); jobject _r0 = go_seq_from_refnum(env, res.r0, proxy_class_structs_S, proxy_class_structs_S_cons); @@ -63,7 +63,7 @@ Java_go_structs_Structs_00024S_Identity(JNIEnv* env, jobject this) { } JNIEXPORT jdouble JNICALL -Java_go_structs_Structs_00024S_Sum(JNIEnv* env, jobject this) { +Java_go_structs_S_Sum(JNIEnv* env, jobject this) { int32_t o = go_seq_to_refnum(env, this); double r0 = proxystructs_S_Sum(o); jdouble _r0 = (jdouble)r0; @@ -71,14 +71,14 @@ Java_go_structs_Structs_00024S_Sum(JNIEnv* env, jobject this) { } JNIEXPORT void JNICALL -Java_go_structs_Structs_00024S_setX(JNIEnv *env, jobject this, jdouble v) { +Java_go_structs_S_setX(JNIEnv *env, jobject this, jdouble v) { int32_t o = go_seq_to_refnum(env, this); double _v = (double)v; proxystructs_S_X_Set(o, _v); } JNIEXPORT jdouble JNICALL -Java_go_structs_Structs_00024S_getX(JNIEnv *env, jobject this) { +Java_go_structs_S_getX(JNIEnv *env, jobject this) { int32_t o = go_seq_to_refnum(env, this); double r0 = proxystructs_S_X_Get(o); jdouble _r0 = (jdouble)r0; @@ -86,14 +86,14 @@ Java_go_structs_Structs_00024S_getX(JNIEnv *env, jobject this) { } JNIEXPORT void JNICALL -Java_go_structs_Structs_00024S_setY(JNIEnv *env, jobject this, jdouble v) { +Java_go_structs_S_setY(JNIEnv *env, jobject this, jdouble v) { int32_t o = go_seq_to_refnum(env, this); double _v = (double)v; proxystructs_S_Y_Set(o, _v); } JNIEXPORT jdouble JNICALL -Java_go_structs_Structs_00024S_getY(JNIEnv *env, jobject this) { +Java_go_structs_S_getY(JNIEnv *env, jobject this) { int32_t o = go_seq_to_refnum(env, this); double r0 = proxystructs_S_Y_Get(o); jdouble _r0 = (jdouble)r0; @@ -101,13 +101,13 @@ Java_go_structs_Structs_00024S_getY(JNIEnv *env, jobject this) { } JNIEXPORT void JNICALL -Java_go_structs_Structs_00024S2_M(JNIEnv* env, jobject this) { +Java_go_structs_S2_M(JNIEnv* env, jobject this) { int32_t o = go_seq_to_refnum(env, this); proxystructs_S2_M(o); } JNIEXPORT jstring JNICALL -Java_go_structs_Structs_00024S2_String(JNIEnv* env, jobject this) { +Java_go_structs_S2_String(JNIEnv* env, jobject this) { int32_t o = go_seq_to_refnum(env, this); nstring r0 = proxystructs_S2_String(o); jstring _r0 = go_seq_to_java_string(env, r0); diff --git a/bind/testdata/structs.java.golden b/bind/testdata/structs.java.golden index 1f980ed..2b5a877 100644 --- a/bind/testdata/structs.java.golden +++ b/bind/testdata/structs.java.golden @@ -1,3 +1,96 @@ +// Java class go.structs.S is a proxy for talking to a Go program. +// gobind -lang=java structs +// +// File is generated by gobind. Do not edit. +package go.structs; + +import go.Seq; + +public final class S extends Seq.Proxy { + private S(go.Seq.Ref ref) { super(ref); } + + public final native double getX(); + public final native void setX(double v); + + public final native double getY(); + public final native void setY(double v); + + public native S Identity() throws Exception; + public native double Sum(); + @Override public boolean equals(Object o) { + if (o == null || !(o instanceof S)) { + return false; + } + S that = (S)o; + double thisX = getX(); + double thatX = that.getX(); + if (thisX != thatX) { + return false; + } + double thisY = getY(); + double thatY = that.getY(); + if (thisY != thatY) { + return false; + } + return true; + } + + @Override public int hashCode() { + return java.util.Arrays.hashCode(new Object[] {getX(), getY()}); + } + + @Override public String toString() { + StringBuilder b = new StringBuilder(); + b.append("S").append("{"); + b.append("X:").append(getX()).append(","); + b.append("Y:").append(getY()).append(","); + return b.append("}").toString(); + } +} + +// Java class go.structs.S2 is a proxy for talking to a Go program. +// gobind -lang=java structs +// +// File is generated by gobind. Do not edit. +package go.structs; + +import go.Seq; + +public final class S2 extends Seq.Proxy implements I { + private S2(go.Seq.Ref ref) { super(ref); } + + public native void M(); + public native String String(); + @Override public boolean equals(Object o) { + if (o == null || !(o instanceof S2)) { + return false; + } + S2 that = (S2)o; + return true; + } + + @Override public int hashCode() { + return java.util.Arrays.hashCode(new Object[] {}); + } + + @Override public String toString() { + return String(); + } +} + +// Java class go.structs.I is a proxy for talking to a Go program. +// gobind -lang=java structs +// +// File is generated by gobind. Do not edit. +package go.structs; + +import go.Seq; + +public interface I { + public void M(); + +} + // Java class go.structs.Structs is a proxy for talking to a Go program. // gobind -lang=java structs // @@ -19,74 +112,6 @@ public abstract class Structs { private static native void init(); - public static final class S extends Seq.Proxy { - private S(go.Seq.Ref ref) { super(ref); } - - public final native double getX(); - public final native void setX(double v); - - public final native double getY(); - public final native void setY(double v); - - public native S Identity() throws Exception; - public native double Sum(); - @Override public boolean equals(Object o) { - if (o == null || !(o instanceof S)) { - return false; - } - S that = (S)o; - double thisX = getX(); - double thatX = that.getX(); - if (thisX != thatX) { - return false; - } - double thisY = getY(); - double thatY = that.getY(); - if (thisY != thatY) { - return false; - } - return true; - } - - @Override public int hashCode() { - return java.util.Arrays.hashCode(new Object[] {getX(), getY()}); - } - - @Override public String toString() { - StringBuilder b = new StringBuilder(); - b.append("S").append("{"); - b.append("X:").append(getX()).append(","); - b.append("Y:").append(getY()).append(","); - return b.append("}").toString(); - } - } - - public static final class S2 extends Seq.Proxy implements I { - private S2(go.Seq.Ref ref) { super(ref); } - - public native void M(); - public native String String(); - @Override public boolean equals(Object o) { - if (o == null || !(o instanceof S2)) { - return false; - } - S2 that = (S2)o; - return true; - } - - @Override public int hashCode() { - return java.util.Arrays.hashCode(new Object[] {}); - } - - @Override public String toString() { - return String(); - } - } - - public interface I { - public void M(); - } - private static final class proxyI extends Seq.Proxy implements I { proxyI(Seq.Ref ref) { super(ref); } diff --git a/bind/testdata/try.java.golden b/bind/testdata/try.java.golden index 2b0514f..940e67c 100644 --- a/bind/testdata/try.java.golden +++ b/bind/testdata/try.java.golden @@ -20,5 +20,6 @@ public abstract class Try { private static native void init(); + public static native String This(); } diff --git a/bind/testdata/vars.java.c.golden b/bind/testdata/vars.java.c.golden index 539f4e0..8bbdce1 100644 --- a/bind/testdata/vars.java.c.golden +++ b/bind/testdata/vars.java.c.golden @@ -17,13 +17,13 @@ jmethodID proxy_class_vars_S_cons; JNIEXPORT void JNICALL Java_go_vars_Vars_init(JNIEnv *env, jclass _unused) { jclass clazz; - clazz = (*env)->FindClass(env, "go/vars/Vars$S"); + clazz = (*env)->FindClass(env, "go/vars/S"); proxy_class_vars_S = (*env)->NewGlobalRef(env, clazz); proxy_class_vars_S_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); clazz = (*env)->FindClass(env, "go/vars/Vars$proxyI"); proxy_class_vars_I = (*env)->NewGlobalRef(env, clazz); proxy_class_vars_I_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); - clazz = (*env)->FindClass(env, "go/vars/Vars$I"); + clazz = (*env)->FindClass(env, "go/vars/I"); } diff --git a/bind/testdata/vars.java.golden b/bind/testdata/vars.java.golden index 2f0bee7..a7af2db 100644 --- a/bind/testdata/vars.java.golden +++ b/bind/testdata/vars.java.golden @@ -1,3 +1,45 @@ +// Java class go.vars.S is a proxy for talking to a Go program. +// gobind -lang=java vars +// +// File is generated by gobind. Do not edit. +package go.vars; + +import go.Seq; + +public final class S extends Seq.Proxy implements I { + private S(go.Seq.Ref ref) { super(ref); } + + @Override public boolean equals(Object o) { + if (o == null || !(o instanceof S)) { + return false; + } + S that = (S)o; + return true; + } + + @Override public int hashCode() { + return java.util.Arrays.hashCode(new Object[] {}); + } + + @Override public String toString() { + StringBuilder b = new StringBuilder(); + b.append("S").append("{"); + return b.append("}").toString(); + } +} + +// Java class go.vars.I is a proxy for talking to a Go program. +// gobind -lang=java vars +// +// File is generated by gobind. Do not edit. +package go.vars; + +import go.Seq; + +public interface I { + +} + // Java class go.vars.Vars is a proxy for talking to a Go program. // gobind -lang=java vars // @@ -19,31 +61,6 @@ public abstract class Vars { private static native void init(); - public static final class S extends Seq.Proxy implements I { - private S(go.Seq.Ref ref) { super(ref); } - - @Override public boolean equals(Object o) { - if (o == null || !(o instanceof S)) { - return false; - } - S that = (S)o; - return true; - } - - @Override public int hashCode() { - return java.util.Arrays.hashCode(new Object[] {}); - } - - @Override public String toString() { - StringBuilder b = new StringBuilder(); - b.append("S").append("{"); - return b.append("}").toString(); - } - } - - public interface I { - } - private static final class proxyI extends Seq.Proxy implements I { proxyI(Seq.Ref ref) { super(ref); } diff --git a/cmd/gobind/gen.go b/cmd/gobind/gen.go index 5dd1d05..f60b7de 100644 --- a/cmd/gobind/gen.go +++ b/cmd/gobind/gen.go @@ -5,6 +5,7 @@ package main import ( + "bytes" "go/token" "go/types" "io" @@ -25,19 +26,41 @@ func genPkg(p *types.Package, allPkg []*types.Package) { } switch *lang { case "java": + var buf bytes.Buffer + g := &bind.JavaGen{ + JavaPkg: *javaPkg, + Generator: &bind.Generator{ + Printer: &bind.Printer{Buf: &buf, IndentEach: []byte(" ")}, + Fset: conf.Fset, + AllPkg: conf.AllPkg, + Pkg: conf.Pkg, + }, + } + g.Init() + + buf.Reset() w, closer := writer(fname) - conf.Writer = w - processErr(bind.GenJava(conf, *javaPkg, bind.Java)) + processErr(g.GenJava()) + io.Copy(w, &buf) closer() + for i, name := range g.ClassNames() { + buf.Reset() + w, closer := writer(name + ".java") + processErr(g.GenClass(i)) + io.Copy(w, &buf) + closer() + } + buf.Reset() cname := "java_" + p.Name() + ".c" w, closer = writer(cname) - conf.Writer = w - processErr(bind.GenJava(conf, *javaPkg, bind.JavaC)) + processErr(g.GenC()) + io.Copy(w, &buf) closer() + buf.Reset() hname := p.Name() + ".h" w, closer = writer(hname) - conf.Writer = w - processErr(bind.GenJava(conf, *javaPkg, bind.JavaH)) + processErr(g.GenH()) + io.Copy(w, &buf) closer() case "go": w, closer := writer(fname) diff --git a/cmd/gobind/main.go b/cmd/gobind/main.go index 5e4b953..c0d2f9b 100644 --- a/cmd/gobind/main.go +++ b/cmd/gobind/main.go @@ -18,7 +18,7 @@ import ( var ( lang = flag.String("lang", "java", "target language for bindings, either java, go, or objc (experimental).") outdir = flag.String("outdir", "", "result will be written to the directory instead of stdout.") - javaPkg = flag.String("javapkg", "", "custom Java package path used instead of the default 'go.'. Valid only with -lang=java.") + javaPkg = flag.String("javapkg", "", "custom Java package path prefix used instead of the default 'go'. Valid only with -lang=java.") prefix = flag.String("prefix", "", "custom Objective-C name prefix used instead of the default 'Go'. Valid only with -lang=objc.") ) diff --git a/cmd/gomobile/bind.go b/cmd/gomobile/bind.go index 542da96..18de5d0 100644 --- a/cmd/gomobile/bind.go +++ b/cmd/gomobile/bind.go @@ -5,6 +5,7 @@ package main import ( + "bytes" "fmt" "go/ast" "go/build" @@ -139,7 +140,7 @@ var ( func init() { // bind command specific commands. cmdBind.flag.StringVar(&bindJavaPkg, "javapkg", "", - "specifies custom Java package path used instead of the default 'go.'. Valid only with -target=android.") + "specifies custom Java package path prefix used instead of the default 'go'. Valid only with -target=android.") cmdBind.flag.StringVar(&bindPrefix, "prefix", "", "custom Objective-C name prefix used instead of the default 'Go'. Valid only with -lang=ios.") } @@ -273,11 +274,18 @@ func (b *binder) GenJava(pkg *types.Package, allPkg []*types.Package, outdir, ja bindOption += " -javapkg=" + javaPkg } - conf := &bind.GeneratorConfig{ - Fset: b.fset, - Pkg: pkg, - AllPkg: allPkg, + var buf bytes.Buffer + g := &bind.JavaGen{ + JavaPkg: javaPkg, + Generator: &bind.Generator{ + Printer: &bind.Printer{Buf: &buf, IndentEach: []byte(" ")}, + Fset: b.fset, + AllPkg: allPkg, + Pkg: pkg, + }, } + g.Init() + generate := func(w io.Writer) error { if buildX { printcmd("gobind %s -outdir=%s %s", bindOption, javadir, pkgPath) @@ -285,18 +293,43 @@ func (b *binder) GenJava(pkg *types.Package, allPkg []*types.Package, outdir, ja if buildN { return nil } - conf.Writer = w - return bind.GenJava(conf, javaPkg, bind.Java) + buf.Reset() + if err := g.GenJava(); err != nil { + return err + } + _, err := io.Copy(w, &buf) + return err } if err := writeFile(javaFile, generate); err != nil { return err } + for i, name := range g.ClassNames() { + generate := func(w io.Writer) error { + if buildN { + return nil + } + buf.Reset() + if err := g.GenClass(i); err != nil { + return err + } + _, err := io.Copy(w, &buf) + return err + } + classFile := filepath.Join(javadir, name+".java") + if err := writeFile(classFile, generate); err != nil { + return err + } + } generate = func(w io.Writer) error { if buildN { return nil } - conf.Writer = w - return bind.GenJava(conf, bindJavaPkg, bind.JavaC) + buf.Reset() + if err := g.GenC(); err != nil { + return err + } + _, err := io.Copy(w, &buf) + return err } if err := writeFile(cFile, generate); err != nil { return err @@ -305,8 +338,12 @@ func (b *binder) GenJava(pkg *types.Package, allPkg []*types.Package, outdir, ja if buildN { return nil } - conf.Writer = w - return bind.GenJava(conf, bindJavaPkg, bind.JavaH) + buf.Reset() + if err := g.GenH(); err != nil { + return err + } + _, err := io.Copy(w, &buf) + return err } return writeFile(hFile, generate) } diff --git a/cmd/gomobile/bind_test.go b/cmd/gomobile/bind_test.go index 6f2da43..9430537 100644 --- a/cmd/gomobile/bind_test.go +++ b/cmd/gomobile/bind_test.go @@ -117,6 +117,7 @@ mkdir -p $WORK/gomobile_bind mkdir -p $WORK/gomobile_bind mkdir -p $WORK/android/src/main/java/go gobind -lang=java -outdir=$WORK/android/src/main/java/go +mkdir -p $WORK/android/src/main/java/go mkdir -p $WORK/gomobile_bind mkdir -p $WORK/gomobile_bind cp $GOPATH/src/golang.org/x/mobile/bind/java/seq_android.go.support $WORK/gomobile_bind/seq_android.go diff --git a/example/ivy/android/app/src/main/java/org/golang/ivy/Help.java b/example/ivy/android/app/src/main/java/org/golang/ivy/Help.java index 256930b..ccdec2e 100644 --- a/example/ivy/android/app/src/main/java/org/golang/ivy/Help.java +++ b/example/ivy/android/app/src/main/java/org/golang/ivy/Help.java @@ -15,6 +15,8 @@ import android.view.MenuItem; import android.webkit.WebView; import android.webkit.WebViewClient; +import org.golang.mobile.Mobile; + /* * Displays the help message for Ivy. */ diff --git a/example/ivy/android/app/src/main/java/org/golang/ivy/MainActivity.java b/example/ivy/android/app/src/main/java/org/golang/ivy/MainActivity.java index 7142f52..af26876 100644 --- a/example/ivy/android/app/src/main/java/org/golang/ivy/MainActivity.java +++ b/example/ivy/android/app/src/main/java/org/golang/ivy/MainActivity.java @@ -32,6 +32,8 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import org.golang.mobile.Mobile; + /* * Main activity that consists of an edit view to accept the expression * and a web view to display output of the expression. diff --git a/example/ivy/android/ivy/build.gradle b/example/ivy/android/ivy/build.gradle index bf0a5ac..ededcd2 100644 --- a/example/ivy/android/ivy/build.gradle +++ b/example/ivy/android/ivy/build.gradle @@ -10,7 +10,7 @@ gobind { pkg = "robpike.io/ivy/mobile" // -javapkg flag puts the generated java class into the specified package. - GOMOBILEFLAGS="-javapkg=org.golang.ivy" + GOMOBILEFLAGS="-javapkg=org.golang" /* Set the following variable(s):