diff --git a/bind/bind.go b/bind/bind.go index 2990e0c..63ca719 100644 --- a/bind/bind.go +++ b/bind/bind.go @@ -20,7 +20,16 @@ import ( "io" ) -type fileType int +type ( + GeneratorConfig struct { + Writer io.Writer + Fset *token.FileSet + Pkg *types.Package + AllPkg []*types.Package + } + + fileType int +) const ( Java fileType = iota @@ -33,17 +42,15 @@ const ( ) // GenJava generates a Java API from a Go package. -func GenJava(w io.Writer, fset *token.FileSet, pkg *types.Package, javaPkg string, ft fileType) error { - if javaPkg == "" { - javaPkg = javaPkgName(pkg.Name()) - } +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: fset, - pkg: pkg, + fset: conf.Fset, + allPkg: conf.AllPkg, + pkg: conf.Pkg, }, } g.init() @@ -61,18 +68,19 @@ func GenJava(w io.Writer, fset *token.FileSet, pkg *types.Package, javaPkg strin if err != nil { return err } - _, err = io.Copy(w, buf) + _, err = io.Copy(conf.Writer, buf) return err } // GenGo generates a Go stub to support foreign language APIs. -func GenGo(w io.Writer, fset *token.FileSet, pkg *types.Package) error { +func GenGo(conf *GeneratorConfig) error { buf := new(bytes.Buffer) g := &goGen{ - &generator{ + generator: &generator{ printer: &printer{buf: buf, indentEach: []byte("\t")}, - fset: fset, - pkg: pkg, + fset: conf.Fset, + allPkg: conf.AllPkg, + pkg: conf.Pkg, }, } g.init() @@ -82,25 +90,22 @@ func GenGo(w io.Writer, fset *token.FileSet, pkg *types.Package) error { src := buf.Bytes() srcf, err := format.Source(src) if err != nil { - w.Write(src) // for debugging + conf.Writer.Write(src) // for debugging return err } - _, err = w.Write(srcf) + _, err = conf.Writer.Write(srcf) return err } // GenObjc generates the Objective-C API from a Go package. -func GenObjc(w io.Writer, fset *token.FileSet, pkg *types.Package, prefix string, ft fileType) error { - if prefix == "" { - prefix = "Go" - } - +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: fset, - pkg: pkg, + fset: conf.Fset, + allPkg: conf.AllPkg, + pkg: conf.Pkg, }, prefix: prefix, } @@ -119,6 +124,6 @@ func GenObjc(w io.Writer, fset *token.FileSet, pkg *types.Package, prefix string if err != nil { return err } - _, err = io.Copy(w, buf) + _, err = io.Copy(conf.Writer, buf) return err } diff --git a/bind/bind_test.go b/bind/bind_test.go index 2a9c480..49b9072 100644 --- a/bind/bind_test.go +++ b/bind/bind_test.go @@ -100,7 +100,7 @@ func TestGenObjc(t *testing.T) { for typ, suffix := range suffixes { var buf bytes.Buffer - if err := GenObjc(&buf, fset, pkg, "", typ); err != nil { + if err := GenObjc(&buf, fset, pkg, []*types.Package{pkg}, "", typ); err != nil { t.Errorf("%s: %v", filename, err) continue } @@ -132,7 +132,7 @@ func TestGenJava(t *testing.T) { pkg := typeCheck(t, filename) for typ, suffix := range suffixes { var buf bytes.Buffer - if err := GenJava(&buf, fset, pkg, "", typ); err != nil { + if err := GenJava(&buf, fset, pkg, []*types.Package{pkg}, "", typ); err != nil { t.Errorf("%s: %v", filename, err) continue } @@ -158,7 +158,7 @@ func TestGenGo(t *testing.T) { for _, filename := range tests { var buf bytes.Buffer pkg := typeCheck(t, filename) - if err := GenGo(&buf, fset, pkg); err != nil { + if err := GenGo(&buf, fset, pkg, []*types.Package{pkg}); err != nil { t.Errorf("%s: %v", filename, err) continue } @@ -189,27 +189,27 @@ func TestCustomPrefix(t *testing.T) { }{ { "testdata/customprefix.java.golden", - func(w io.Writer) error { return GenJava(w, fset, pkg, "com.example", Java) }, + func(w io.Writer) error { return GenJava(w, fset, pkg, []*types.Package{pkg}, "com.example", Java) }, }, { "testdata/customprefix.java.h.golden", - func(w io.Writer) error { return GenJava(w, fset, pkg, "com.example", JavaH) }, + func(w io.Writer) error { return GenJava(w, fset, pkg, []*types.Package{pkg}, "com.example", JavaH) }, }, { "testdata/customprefix.java.c.golden", - func(w io.Writer) error { return GenJava(w, fset, pkg, "com.example", JavaC) }, + func(w io.Writer) error { return GenJava(w, fset, pkg, []*types.Package{pkg}, "com.example", JavaC) }, }, { "testdata/customprefix.objc.go.h.golden", - func(w io.Writer) error { return GenObjc(w, fset, pkg, "EX", ObjcGoH) }, + func(w io.Writer) error { return GenObjc(w, fset, pkg, []*types.Package{pkg}, "EX", ObjcGoH) }, }, { "testdata/customprefix.objc.h.golden", - func(w io.Writer) error { return GenObjc(w, fset, pkg, "EX", ObjcH) }, + func(w io.Writer) error { return GenObjc(w, fset, pkg, []*types.Package{pkg}, "EX", ObjcH) }, }, { "testdata/customprefix.objc.m.golden", - func(w io.Writer) error { return GenObjc(w, fset, pkg, "EX", ObjcM) }, + func(w io.Writer) error { return GenObjc(w, fset, pkg, []*types.Package{pkg}, "EX", ObjcM) }, }, } diff --git a/bind/gen.go b/bind/gen.go index 1a4aec8..2b827d1 100644 --- a/bind/gen.go +++ b/bind/gen.go @@ -52,14 +52,13 @@ func (list ErrorList) Error() string { type generator struct { *printer - fset *token.FileSet - pkg *types.Package - err ErrorList + fset *token.FileSet + allPkg []*types.Package + pkg *types.Package + err ErrorList // fields set by init. - pkgName string - // pkgPrefix is a prefix for disambiguating - // function names for binding multiple packages + pkgName string pkgPrefix string funcs []*types.Func constants []*types.Const @@ -70,12 +69,19 @@ type generator struct { otherNames []*types.TypeName } +// pkgPrefix returns a prefix that disambiguates symbol names for binding +// multiple packages. +// +// TODO(elias.naur): Avoid (and test) name clashes from multiple packages +// with the same name. Perhaps use the index from the order the package is +// generated. +func pkgPrefix(pkg *types.Package) string { + return pkg.Name() +} + func (g *generator) init() { g.pkgName = g.pkg.Name() - // TODO(elias.naur): Avoid (and test) name clashes from multiple packages - // with the same name. Perhaps use the index from the order the package is - // generated. - g.pkgPrefix = g.pkgName + g.pkgPrefix = pkgPrefix(g.pkg) scope := g.pkg.Scope() hasExported := false @@ -223,6 +229,15 @@ func (g *generator) genInterfaceMethodSignature(m *types.Func, iName string, hea } } +func (g *generator) validPkg(pkg *types.Package) bool { + for _, p := range g.allPkg { + if p.Path() == pkg.Path() { + return true + } + } + return false +} + var paramRE = regexp.MustCompile(`^p[0-9]*$`) // paramName replaces incompatible name with a p0-pN name. diff --git a/bind/gengo.go b/bind/gengo.go index 805b559..5544350 100644 --- a/bind/gengo.go +++ b/bind/gengo.go @@ -5,6 +5,7 @@ package bind import ( + "bytes" "fmt" "go/types" "strings" @@ -12,6 +13,7 @@ import ( type goGen struct { *generator + imports map[string]struct{} } const ( @@ -30,14 +32,6 @@ package gomobile_bind */ import "C" -import ( - _seq "golang.org/x/mobile/bind/seq" - %[2]q -) - -// suppress the error if seq ends up unused -var _ = _seq.FromRefNum - ` ) @@ -129,11 +123,6 @@ func (g *goGen) genWrite(toVar, fromVar string, t types.Type, mode varMode) { // TODO(crawshaw): test **Generator switch t := t.Elem().(type) { case *types.Named: - obj := t.Obj() - if obj.Pkg() != g.pkg { - g.errorf("type %s not defined in %s", t, g.pkg) - return - } g.genToRefNum(toVar, fromVar) default: g.errorf("unsupported type %s", t) @@ -193,7 +182,7 @@ func (g *goGen) genFuncSignature(o *types.Func, objName string) { func (g *goGen) genFunc(o *types.Func) { g.genFuncSignature(o, "") g.Indent() - g.genFuncBody(o, g.pkg.Name()) + g.genFuncBody(o, g.pkgName(g.pkg)) g.Outdent() g.Printf("}\n\n") } @@ -202,15 +191,13 @@ func (g *goGen) genStruct(obj *types.TypeName, T *types.Struct) { fields := exportedFields(T) methods := exportedMethodSet(types.NewPointer(obj.Type())) - g.Printf("type proxy%s _seq.Ref\n\n", obj.Name()) - for _, f := range fields { g.Printf("//export proxy%s_%s_%s_Set\n", g.pkgPrefix, obj.Name(), f.Name()) g.Printf("func proxy%s_%s_%s_Set(refnum C.int32_t, v C.%s) {\n", g.pkgPrefix, obj.Name(), f.Name(), g.cgoType(f.Type())) 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.pkg.Name(), 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") @@ -218,7 +205,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.pkg.Name(), 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() @@ -229,7 +216,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.pkg.Name(), 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") @@ -239,7 +226,7 @@ func (g *goGen) genStruct(obj *types.TypeName, T *types.Struct) { func (g *goGen) genVar(o *types.Var) { // TODO(hyangah): non-struct pointer types (*int), struct type. - v := fmt.Sprintf("%s.%s", g.pkg.Name(), o.Name()) + v := fmt.Sprintf("%s.%s", g.pkgName(g.pkg), o.Name()) // var I int // @@ -273,7 +260,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.pkg.Name(), 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") @@ -383,13 +370,14 @@ func (g *goGen) genRead(toVar, fromVar string, typ types.Type, mode varMode) { switch u := t.Elem().(type) { case *types.Named: o := u.Obj() - if o.Pkg() != g.pkg { - g.errorf("type %s not defined in %s", u, g.pkg) + oPkg := o.Pkg() + if !g.validPkg(oPkg) { + g.errorf("type %s is defined in %s, which is not bound", u, oPkg) return } g.Printf("// Must be a Go object\n") g.Printf("%s_ref := _seq.FromRefNum(int32(%s))\n", toVar, fromVar) - g.Printf("%s := %s_ref.Get().(*%s.%s)\n", toVar, toVar, g.pkg.Name(), o.Name()) + g.Printf("%s := %s_ref.Get().(*%s.%s)\n", toVar, toVar, g.pkgName(oPkg), o.Name()) default: g.errorf("unsupported pointer type %s", t) } @@ -401,18 +389,19 @@ func (g *goGen) genRead(toVar, fromVar string, typ types.Type, mode varMode) { hasProxy = makeIfaceSummary(iface).implementable } o := t.Obj() - if o.Pkg() != g.pkg { - g.errorf("type %s not defined in %s", t, g.pkg) + oPkg := o.Pkg() + if !g.validPkg(oPkg) { + g.errorf("type %s is defined in %s, which is not bound", t, oPkg) return } g.Printf("var %s %s\n", toVar, g.typeString(t)) g.Printf("%s_ref := _seq.FromRefNum(int32(%s))\n", toVar, fromVar) g.Printf("if %s_ref != nil {\n", toVar) g.Printf(" if %s_ref.Num < 0 { // go object \n", toVar) - g.Printf(" %s = %s_ref.Get().(%s.%s)\n", toVar, toVar, g.pkg.Name(), o.Name()) + g.Printf(" %s = %s_ref.Get().(%s.%s)\n", toVar, toVar, g.pkgName(oPkg), o.Name()) if hasProxy { g.Printf(" } else { // foreign object \n") - g.Printf(" %s = (*proxy%s_%s)(%s_ref)\n", toVar, g.pkgPrefix, o.Name(), toVar) + g.Printf(" %s = (*proxy%s_%s)(%s_ref)\n", toVar, pkgPrefix(oPkg), o.Name(), toVar) } g.Printf(" }\n") g.Printf("}\n") @@ -433,13 +422,15 @@ func (g *goGen) typeString(typ types.Type) string { if obj.Pkg() == nil { // e.g. error type is *types.Named. return types.TypeString(typ, types.RelativeTo(pkg)) } - if obj.Pkg() != g.pkg { - g.errorf("type %s not defined in %s", t, g.pkg) + oPkg := obj.Pkg() + if !g.validPkg(oPkg) { + g.errorf("type %s is defined in %s, which is not bound", t, oPkg) + return "TODO" } switch t.Underlying().(type) { case *types.Interface, *types.Struct: - return fmt.Sprintf("%s.%s", pkg.Name(), types.TypeString(typ, types.RelativeTo(pkg))) + return fmt.Sprintf("%s.%s", g.pkgName(oPkg), types.TypeString(typ, types.RelativeTo(oPkg))) default: g.errorf("unsupported named type %s / %T", t, t) } @@ -456,8 +447,30 @@ func (g *goGen) typeString(typ types.Type) string { return "" } -func (g *goGen) gen() error { +// genPreamble generates the preamble. It is generated after everything +// else, where we know which bound packages to import. +func (g *goGen) genPreamble() { g.Printf(goPreamble, g.pkg.Name(), g.pkg.Path()) + g.Printf("import (\n") + g.Indent() + g.Printf("_seq \"golang.org/x/mobile/bind/seq\"\n") + for path := range g.imports { + g.Printf("%q\n", path) + } + g.Outdent() + g.Printf(")\n\n") +} + +func (g *goGen) gen() error { + g.imports = make(map[string]struct{}) + + // Switch to a temporary buffer so the preamble can be + // written last. + oldBuf := g.printer.buf + newBuf := new(bytes.Buffer) + g.printer.buf = newBuf + g.Printf("// suppress the error if seq ends up unused\n") + g.Printf("var _ = _seq.FromRefNum\n") for _, s := range g.structs { g.genStruct(s.obj, s.t) @@ -471,8 +484,20 @@ func (g *goGen) gen() error { for _, f := range g.funcs { g.genFunc(f) } + // Switch to the original buffer, write the preamble + // and append the rest of the file. + g.printer.buf = oldBuf + g.genPreamble() + g.printer.buf.Write(newBuf.Bytes()) if len(g.err) > 0 { return g.err } return nil } + +// pkgName retuns the package name and adds the package to the list of +// imports. +func (g *goGen) pkgName(pkg *types.Package) string { + g.imports[pkg.Path()] = struct{}{} + return pkg.Name() +} diff --git a/bind/genjava.go b/bind/genjava.go index 3749bc2..9603780 100644 --- a/bind/genjava.go +++ b/bind/genjava.go @@ -16,6 +16,8 @@ import ( // TODO(crawshaw): consider introducing Java functions for casting to and from interfaces at runtime. 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 *generator @@ -262,22 +264,24 @@ func (g *javaGen) javaType(T types.Type) string { if _, ok := T.Elem().(*types.Named); ok { return g.javaType(T.Elem()) } - panic(fmt.Sprintf("unsupported pointer to type: %s", T)) + g.errorf("unsupported pointer to type: %s", T) case *types.Named: n := T.Obj() - if n.Pkg() != g.pkg { - nPkgName := "" - if nPkg := n.Pkg(); nPkg != nil { - nPkgName = nPkg.Name() - } - panic(fmt.Sprintf("type %s is in package %s, must be defined in package %s", n.Name(), nPkgName, g.pkg.Name())) + nPkg := n.Pkg() + if !g.validPkg(nPkg) { + g.errorf("type %s is in %s, which is not bound", n.Name(), nPkg) + break } // TODO(crawshaw): more checking here - return n.Name() + if nPkg != g.pkg { + return fmt.Sprintf("%s.%s.%s", g.javaPkgName(nPkg), className(nPkg), n.Name()) + } else { + return n.Name() + } default: g.errorf("unsupported javaType: %#+v, %s\n", T, T) - return "TODO" } + return "TODO" } func (g *javaGen) genJNIFuncSignature(o *types.Func, sName string, proxy bool) { @@ -328,7 +332,7 @@ func (g *javaGen) genJNIFuncSignature(o *types.Func, sName string, proxy bool) { } func (g *javaGen) jniPkgName() string { - return strings.Replace(g.javaPkg, ".", "_", -1) + return strings.Replace(g.javaPkgName(g.pkg), ".", "_", -1) } func (g *javaGen) genFuncSignature(o *types.Func, static, header bool) { @@ -466,24 +470,14 @@ func (g *javaGen) genCToJava(toName, fromName string, t types.Type, mode varMode // TODO(crawshaw): test **Generator switch t := t.Elem().(type) { case *types.Named: - o := t.Obj() - if o.Pkg() != g.pkg { - g.errorf("type %s not defined in %s", t, g.pkg) - return - } - g.Printf("jobject %s = go_seq_from_refnum(env, %s, proxy_class_%s_%s, proxy_class_%s_%s_cons);\n", toName, fromName, g.pkgPrefix, o.Name(), g.pkgPrefix, o.Name()) + g.genFromRefnum(toName, fromName, t, t.Obj()) default: g.errorf("unsupported type %s", t) } case *types.Named: switch t.Underlying().(type) { case *types.Interface, *types.Pointer: - o := t.Obj() - if o.Pkg() != g.pkg { - g.errorf("type %s not defined in %s", t, g.pkg) - return - } - g.Printf("jobject %s = go_seq_from_refnum(env, %s, proxy_class_%s_%s, proxy_class_%s_%s_cons);\n", toName, fromName, g.pkgPrefix, o.Name(), g.pkgPrefix, o.Name()) + g.genFromRefnum(toName, fromName, t, t.Obj()) default: g.errorf("unsupported, direct named type %s", t) } @@ -492,9 +486,19 @@ 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) { + oPkg := o.Pkg() + if !g.validPkg(oPkg) { + g.errorf("type %s is defined in package %s, which is not bound", t, oPkg) + return + } + p := pkgPrefix(oPkg) + 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 { opts := []string{"-lang=java"} - if g.javaPkg != javaPkgName(g.pkg.Name()) { + if g.javaPkg != "" { opts = append(opts, "-javapkg="+g.javaPkg) } return strings.Join(opts, " ") @@ -505,8 +509,11 @@ var javaNameReplacer = strings.NewReplacer( ".", "_", ) -func javaPkgName(pkgName string) string { - s := javaNameReplacer.Replace(pkgName) +func (g *javaGen) javaPkgName(pkg *types.Package) string { + 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. // @@ -528,7 +535,11 @@ func javaPkgName(pkgName string) string { } func (g *javaGen) className() string { - return strings.Title(javaNameReplacer.Replace(g.pkg.Name())) + return className(g.pkg) +} + +func className(pkg *types.Package) string { + return strings.Title(javaNameReplacer.Replace(pkg.Name())) } func (g *javaGen) genConst(o *types.Const) { @@ -749,11 +760,18 @@ func (g *javaGen) genMethodInterfaceProxy(oName string, m *types.Func) { func (g *javaGen) genH() error { g.Printf(hPreamble, g.gobindOpts(), g.pkg.Path(), g.className()) for _, iface := range g.interfaces { + g.Printf("extern jclass proxy_class_%s_%s;\n", g.pkgPrefix, iface.obj.Name()) + g.Printf("extern jmethodID proxy_class_%s_%s_cons;\n", g.pkgPrefix, iface.obj.Name()) + g.Printf("\n") for _, m := range iface.summary.callable { g.genInterfaceMethodSignature(m, iface.obj.Name(), true) g.Printf("\n") } } + for _, s := range g.structs { + g.Printf("extern jclass proxy_class_%s_%s;\n", g.pkgPrefix, s.obj.Name()) + g.Printf("extern jmethodID proxy_class_%s_%s_cons;\n", g.pkgPrefix, s.obj.Name()) + } g.Printf("#endif\n") if len(g.err) > 0 { return g.err @@ -805,7 +823,7 @@ func (g *javaGen) jniCallType(t types.Type) string { } func (g *javaGen) jniClassSigType(className string) string { - return strings.Replace(g.javaPkg, ".", "/", -1) + "/" + g.className() + "$" + className + return strings.Replace(g.javaPkgName(g.pkg), ".", "/", -1) + "/" + g.className() + "$" + className } func (g *javaGen) jniSigType(T types.Type) string { @@ -856,16 +874,24 @@ func (g *javaGen) jniSigType(T types.Type) string { func (g *javaGen) genC() error { g.Printf(cPreamble, g.gobindOpts(), g.pkg.Path(), g.pkg.Name()) + g.Printf("#include %q\n", g.pkg.Name()+".h") + 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("static jclass proxy_class_%s_%s;\n", g.pkgPrefix, iface.obj.Name()) - g.Printf("static jmethodID proxy_class_%s_%s_cons;\n", g.pkgPrefix, iface.obj.Name()) + 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 i := 0; i < iface.t.NumMethods(); i++ { g.Printf("static jmethodID mid_%s_%s;\n", iface.obj.Name(), iface.t.Method(i).Name()) } } for _, s := range g.structs { - g.Printf("static jclass proxy_class_%s_%s;\n", g.pkgPrefix, s.obj.Name()) - g.Printf("static jmethodID proxy_class_%s_%s_cons;\n", g.pkgPrefix, s.obj.Name()) + 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") @@ -931,7 +957,7 @@ func (g *javaGen) genC() error { } func (g *javaGen) genJava() error { - g.Printf(javaPreamble, g.javaPkg, g.className(), g.gobindOpts(), g.pkg.Path()) + g.Printf(javaPreamble, g.javaPkgName(g.pkg), g.className(), g.gobindOpts(), g.pkg.Path()) g.Printf("public abstract class %s {\n", g.className()) g.Indent() @@ -996,11 +1022,9 @@ import go.Seq; #include #include #include "seq.h" -#include "%[3]s.h" #include "_cgo_export.h" - - ` + hPreamble = `// JNI function headers for the Go <=> Java bridge. // gobind %[1]s %[2]s // diff --git a/bind/genobjc.go b/bind/genobjc.go index ab0fee2..824f6ce 100644 --- a/bind/genobjc.go +++ b/bind/genobjc.go @@ -43,7 +43,15 @@ type structInfo struct { func (g *objcGen) init() { g.generator.init() - g.namePrefix = g.prefix + strings.Title(g.pkgName) + g.namePrefix = g.namePrefixOf(g.pkg) +} + +func (g *objcGen) namePrefixOf(pkg *types.Package) string { + p := g.prefix + if p == "" { + p = "Go" + } + return p + strings.Title(pkg.Name()) } func (g *objcGen) genGoH() error { @@ -73,10 +81,15 @@ func (g *objcGen) genGoH() error { func (g *objcGen) genH() error { g.Printf(objcPreamble, g.pkg.Path(), g.gobindOpts(), g.pkg.Path()) - g.Printf("#ifndef __%s%s_H__\n", g.prefix, strings.Title(g.pkgName)) - g.Printf("#define __%s%s_H__\n", g.prefix, strings.Title(g.pkgName)) + g.Printf("#ifndef __%s_H__\n", g.namePrefix) + g.Printf("#define __%s_H__\n", g.namePrefix) g.Printf("\n") g.Printf("#include \n") + for _, pkg := range g.pkg.Imports() { + if g.validPkg(pkg) { + g.Printf("#include %q\n", g.namePrefixOf(pkg)+".h") + } + } g.Printf("\n") // Forward declaration of @class and @protocol @@ -136,39 +149,6 @@ func (g *objcGen) genH() error { g.Printf("\n") } - // declare all named types first. - g.Printf("#endif\n") - - if len(g.err) > 0 { - return g.err - } - return nil -} - -func (g *objcGen) gobindOpts() string { - opts := []string{"-lang=objc"} - if g.prefix != "Go" { - opts = append(opts, "-prefix="+g.prefix) - } - return strings.Join(opts, " ") -} - -func (g *objcGen) genM() error { - g.Printf(objcPreamble, g.pkg.Path(), g.gobindOpts(), g.pkg.Path()) - g.Printf("#include %q\n", g.namePrefix+".h") - g.Printf("#include \n") - g.Printf("#include \"seq.h\"\n") - g.Printf("#include \"_cgo_export.h\"\n") - g.Printf("\n") - g.Printf("static NSString* errDomain = @\"go.%s\";\n", g.pkg.Path()) - g.Printf("\n") - g.Printf(`@protocol goSeqRefInterface --(GoSeqRef*) _ref; -@end - -`) - - // forward declarations skipped from genH for _, i := range g.interfaces { if i.summary.implementable { g.Printf("@class %s%s;\n\n", g.namePrefix, i.obj.Name()) @@ -182,6 +162,37 @@ func (g *objcGen) genM() error { } } + g.Printf("#endif\n") + + if len(g.err) > 0 { + return g.err + } + return nil +} + +func (g *objcGen) gobindOpts() string { + opts := []string{"-lang=objc"} + if g.prefix != "" { + opts = append(opts, "-prefix="+g.prefix) + } + return strings.Join(opts, " ") +} + +func (g *objcGen) genM() error { + g.Printf(objcPreamble, g.pkg.Path(), g.gobindOpts(), g.pkg.Path()) + g.Printf("#include \n") + g.Printf("#include \"seq.h\"\n") + g.Printf("#include \"_cgo_export.h\"\n") + g.Printf("#include %q\n", g.namePrefix+".h") + g.Printf("\n") + g.Printf("static NSString* errDomain = @\"go.%s\";\n", g.pkg.Path()) + g.Printf("\n") + g.Printf(`@protocol goSeqRefInterface +-(GoSeqRef*) _ref; +@end + +`) + // struct for _, s := range g.structs { g.genStructM(s.obj, s.t) @@ -889,10 +900,10 @@ func (g *objcGen) refTypeBase(typ types.Type) string { } case *types.Named: n := typ.Obj() - if n.Pkg() == g.pkg { + if g.validPkg(n.Pkg()) { switch typ.Underlying().(type) { case *types.Interface, *types.Struct: - return g.namePrefix + n.Name() + return g.namePrefixOf(n.Pkg()) + n.Name() } } } @@ -965,19 +976,19 @@ func (g *objcGen) objcType(typ types.Type) string { return "TODO" case *types.Named: n := typ.Obj() - if n.Pkg() != g.pkg { - g.errorf("type %s is in package %s; only types defined in package %s is supported", n.Name(), n.Pkg().Name(), g.pkg.Name()) + if !g.validPkg(n.Pkg()) { + g.errorf("type %s is in package %s, which is not bound", n.Name(), n.Pkg().Name()) return "TODO" } switch t := typ.Underlying().(type) { case *types.Interface: if makeIfaceSummary(t).implementable { - return "id<" + g.namePrefix + n.Name() + ">" + return "id<" + g.namePrefixOf(n.Pkg()) + n.Name() + ">" } else { - return g.namePrefix + n.Name() + "*" + return g.namePrefixOf(n.Pkg()) + n.Name() + "*" } case *types.Struct: - return g.namePrefix + n.Name() + return g.namePrefixOf(n.Pkg()) + n.Name() } g.errorf("unsupported, named type %s", typ) return "TODO" diff --git a/bind/java/SeqTest.java b/bind/java/SeqTest.java index 474591a..1647508 100644 --- a/bind/java/SeqTest.java +++ b/bind/java/SeqTest.java @@ -11,6 +11,7 @@ import java.util.Arrays; import java.util.Random; import go.testpkg.Testpkg; +import go.secondpkg.Secondpkg; public class SeqTest extends InstrumentationTestCase { public SeqTest() { @@ -472,4 +473,23 @@ public class SeqTest extends InstrumentationTestCase { } }); } + + public void testImportedPkg() { + assertEquals("imported string should match", Secondpkg.HelloString, Secondpkg.Hello()); + Secondpkg.I i = Testpkg.NewImportedI(); + 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(); + i = fields.getI(); + s = fields.getS(); + fields.setI(i); + fields.setS(s); + Testpkg.WithImportedI(i); + Testpkg.WithImportedS(s); + } } diff --git a/bind/java/seq_test.go b/bind/java/seq_test.go index 1c39c89..5535fcb 100644 --- a/bind/java/seq_test.go +++ b/bind/java/seq_test.go @@ -20,7 +20,11 @@ import ( // This requires the gradle command in PATH and // the Android SDK whose path is available through ANDROID_HOME environment variable. func TestJavaSeqTest(t *testing.T) { - runTest(t, "golang.org/x/mobile/bind/testpkg", "SeqTest") + runTest(t, []string{ + "golang.org/x/mobile/bind/testpkg", + "golang.org/x/mobile/bind/testpkg/secondpkg", + "golang.org/x/mobile/bind/testpkg/simplepkg", + }, "SeqTest") } // TestJavaSeqBench runs java test SeqBench.java, with the same @@ -34,10 +38,10 @@ func TestJavaSeqTest(t *testing.T) { // // while running the benchmark to see the results. func TestJavaSeqBench(t *testing.T) { - runTest(t, "golang.org/x/mobile/bind/benchmark", "SeqBench") + runTest(t, []string{"golang.org/x/mobile/bind/benchmark"}, "SeqBench") } -func runTest(t *testing.T, pkgName, javaCls string) { +func runTest(t *testing.T, pkgNames []string, javaCls string) { if _, err := run("which gradle"); err != nil { t.Skip("command gradle not found, skipping") } @@ -80,7 +84,7 @@ func runTest(t *testing.T, pkgName, javaCls string) { } } - buf, err := run("gomobile bind -o pkg.aar " + pkgName) + buf, err := run("gomobile bind -o pkg.aar " + strings.Join(pkgNames, " ")) if err != nil { t.Logf("%s", buf) t.Fatalf("failed to run gomobile bind: %v", err) diff --git a/bind/objc/SeqTest.m b/bind/objc/SeqTest.m index 69bda57..89b2d4f 100644 --- a/bind/objc/SeqTest.m +++ b/bind/objc/SeqTest.m @@ -348,4 +348,23 @@ static int numI = 0; XCTAssertEqualObjects(got, want, @"want %@\nGoTestpkgReturnsError(TRUE) = (%@, %@)", want, value, got); } +- (void)testImportedPkg { + XCTAssertEqualObjects(GoSecondpkgHelloString, GoSecondpkgHello(), @"imported string should match"); + id i = GoTestpkgNewImportedI(); + GoSecondpkgS *s = GoTestpkgNewImportedS(); + XCTAssertEqual(8, [i f:8], @"numbers should match"); + XCTAssertEqual(8, [s f:8], @"numbers should match"); + i = GoTestpkgWithImportedI(i); + s = GoTestpkgWithImportedS(s); + i = [GoTestpkg importedVarI]; + s = [GoTestpkg importedVarS]; + [GoTestpkg setImportedVarI:i]; + [GoTestpkg setImportedVarS:s]; + GoTestpkgImportedFields *fields = GoTestpkgNewImportedFields(); + i = [fields i]; + s = [fields s]; + [fields setI:i]; + [fields setS:s]; +} + @end diff --git a/bind/objc/seq_test.go b/bind/objc/seq_test.go index a143ab1..2a1a014 100644 --- a/bind/objc/seq_test.go +++ b/bind/objc/seq_test.go @@ -38,16 +38,20 @@ var destination = flag.String("device", "platform=iOS Simulator,name=iPhone 6s P // TestObjcSeqTest runs ObjC test SeqTest.m. // This requires the xcode command lines tools. func TestObjcSeqTest(t *testing.T) { - runTest(t, "golang.org/x/mobile/bind/testpkg", "xcodetest", "SeqTest.m", false) + runTest(t, []string{ + "golang.org/x/mobile/bind/testpkg", + "golang.org/x/mobile/bind/testpkg/secondpkg", + "golang.org/x/mobile/bind/testpkg/simplepkg", + }, "xcodetest", "SeqTest.m", false) } // TestObjcSeqBench runs ObjC test SeqBench.m. // This requires the xcode command lines tools. func TestObjcSeqBench(t *testing.T) { - runTest(t, "golang.org/x/mobile/bind/benchmark", "xcodebench", "SeqBench.m", true) + runTest(t, []string{"golang.org/x/mobile/bind/benchmark"}, "xcodebench", "SeqBench.m", true) } -func runTest(t *testing.T, pkgName, project, testfile string, dumpOutput bool) { +func runTest(t *testing.T, pkgNames []string, project, testfile string, dumpOutput bool) { if _, err := run("which xcodebuild"); err != nil { t.Skip("command xcodebuild not found, skipping") } @@ -89,7 +93,7 @@ func runTest(t *testing.T, pkgName, project, testfile string, dumpOutput bool) { } defer os.Chdir(cwd) - buf, err := run("gomobile bind -target=ios " + pkgName) + buf, err := run("gomobile bind -target=ios " + strings.Join(pkgNames, " ")) if err != nil { t.Logf("%s", buf) t.Fatalf("failed to run gomobile bind: %v", err) diff --git a/bind/testdata/basictypes.java.c.golden b/bind/testdata/basictypes.java.c.golden index 5690011..caa1d1e 100644 --- a/bind/testdata/basictypes.java.c.golden +++ b/bind/testdata/basictypes.java.c.golden @@ -6,9 +6,8 @@ #include #include #include "seq.h" -#include "basictypes.h" #include "_cgo_export.h" - +#include "basictypes.h" JNIEXPORT void JNICALL diff --git a/bind/testdata/basictypes.objc.m.golden b/bind/testdata/basictypes.objc.m.golden index d3b7b4e..0c9bcb5 100644 --- a/bind/testdata/basictypes.objc.m.golden +++ b/bind/testdata/basictypes.objc.m.golden @@ -3,10 +3,10 @@ // // File is generated by gobind. Do not edit. -#include "GoBasictypes.h" #include #include "seq.h" #include "_cgo_export.h" +#include "GoBasictypes.h" static NSString* errDomain = @"go.basictypes"; diff --git a/bind/testdata/customprefix.java.c.golden b/bind/testdata/customprefix.java.c.golden index a8ba32b..00074b9 100644 --- a/bind/testdata/customprefix.java.c.golden +++ b/bind/testdata/customprefix.java.c.golden @@ -6,9 +6,8 @@ #include #include #include "seq.h" -#include "customprefix.h" #include "_cgo_export.h" - +#include "customprefix.h" JNIEXPORT void JNICALL diff --git a/bind/testdata/customprefix.objc.m.golden b/bind/testdata/customprefix.objc.m.golden index 59f8583..13041d2 100644 --- a/bind/testdata/customprefix.objc.m.golden +++ b/bind/testdata/customprefix.objc.m.golden @@ -3,10 +3,10 @@ // // File is generated by gobind. Do not edit. -#include "EXCustomprefix.h" #include #include "seq.h" #include "_cgo_export.h" +#include "EXCustomprefix.h" static NSString* errDomain = @"go.customprefix"; diff --git a/bind/testdata/interfaces.java.c.golden b/bind/testdata/interfaces.java.c.golden index 202c1fe..777586a 100644 --- a/bind/testdata/interfaces.java.c.golden +++ b/bind/testdata/interfaces.java.c.golden @@ -6,29 +6,28 @@ #include #include #include "seq.h" -#include "interfaces.h" #include "_cgo_export.h" +#include "interfaces.h" - -static jclass proxy_class_interfaces_Error; -static jmethodID proxy_class_interfaces_Error_cons; +jclass proxy_class_interfaces_Error; +jmethodID proxy_class_interfaces_Error_cons; static jmethodID mid_Error_Err; -static jclass proxy_class_interfaces_I; -static jmethodID proxy_class_interfaces_I_cons; +jclass proxy_class_interfaces_I; +jmethodID proxy_class_interfaces_I_cons; static jmethodID mid_I_Rand; -static jclass proxy_class_interfaces_I1; -static jmethodID proxy_class_interfaces_I1_cons; +jclass proxy_class_interfaces_I1; +jmethodID proxy_class_interfaces_I1_cons; static jmethodID mid_I1_H; static jmethodID mid_I1_J; -static jclass proxy_class_interfaces_I2; -static jmethodID proxy_class_interfaces_I2_cons; +jclass proxy_class_interfaces_I2; +jmethodID proxy_class_interfaces_I2_cons; static jmethodID mid_I2_G; static jmethodID mid_I2_f; -static jclass proxy_class_interfaces_I3; -static jmethodID proxy_class_interfaces_I3_cons; +jclass proxy_class_interfaces_I3; +jmethodID proxy_class_interfaces_I3_cons; static jmethodID mid_I3_F; -static jclass proxy_class_interfaces_WithParam; -static jmethodID proxy_class_interfaces_WithParam_cons; +jclass proxy_class_interfaces_WithParam; +jmethodID proxy_class_interfaces_WithParam_cons; static jmethodID mid_WithParam_HasParam; JNIEXPORT void JNICALL diff --git a/bind/testdata/interfaces.java.h.golden b/bind/testdata/interfaces.java.h.golden index 6e05bd7..df496ea 100644 --- a/bind/testdata/interfaces.java.h.golden +++ b/bind/testdata/interfaces.java.h.golden @@ -8,16 +8,34 @@ #include +extern jclass proxy_class_interfaces_Error; +extern jmethodID proxy_class_interfaces_Error_cons; + nstring cproxyinterfaces_Error_Err(int32_t refnum); +extern jclass proxy_class_interfaces_I; +extern jmethodID proxy_class_interfaces_I_cons; + int32_t cproxyinterfaces_I_Rand(int32_t refnum); +extern jclass proxy_class_interfaces_I1; +extern jmethodID proxy_class_interfaces_I1_cons; + void cproxyinterfaces_I1_J(int32_t refnum); +extern jclass proxy_class_interfaces_I2; +extern jmethodID proxy_class_interfaces_I2_cons; + void cproxyinterfaces_I2_G(int32_t refnum); +extern jclass proxy_class_interfaces_I3; +extern jmethodID proxy_class_interfaces_I3_cons; + int32_t cproxyinterfaces_I3_F(int32_t refnum); +extern jclass proxy_class_interfaces_WithParam; +extern jmethodID proxy_class_interfaces_WithParam_cons; + void cproxyinterfaces_WithParam_HasParam(int32_t refnum, char p0); #endif diff --git a/bind/testdata/interfaces.objc.h.golden b/bind/testdata/interfaces.objc.h.golden index bdf25ea..9e75266 100644 --- a/bind/testdata/interfaces.objc.h.golden +++ b/bind/testdata/interfaces.objc.h.golden @@ -57,4 +57,44 @@ FOUNDATION_EXPORT BOOL GoInterfacesCallErr(id e, NSError** er FOUNDATION_EXPORT id GoInterfacesSeven(); +@class GoInterfacesError; + +@class GoInterfacesI; + +@class GoInterfacesI3; + +@class GoInterfacesWithParam; + +@interface GoInterfacesError : NSObject { +} +@property(strong, readonly) id _ref; + +- (id)initWithRef:(id)ref; +- (BOOL)err:(NSError**)error; +@end + +@interface GoInterfacesI : NSObject { +} +@property(strong, readonly) id _ref; + +- (id)initWithRef:(id)ref; +- (int32_t)rand; +@end + +@interface GoInterfacesI3 : NSObject { +} +@property(strong, readonly) id _ref; + +- (id)initWithRef:(id)ref; +- (GoInterfacesI1*)f; +@end + +@interface GoInterfacesWithParam : NSObject { +} +@property(strong, readonly) id _ref; + +- (id)initWithRef:(id)ref; +- (void)hasParam:(BOOL)p0; +@end + #endif diff --git a/bind/testdata/interfaces.objc.m.golden b/bind/testdata/interfaces.objc.m.golden index c112f60..d89926d 100644 --- a/bind/testdata/interfaces.objc.m.golden +++ b/bind/testdata/interfaces.objc.m.golden @@ -3,10 +3,10 @@ // // File is generated by gobind. Do not edit. -#include "GoInterfaces.h" #include #include "seq.h" #include "_cgo_export.h" +#include "GoInterfaces.h" static NSString* errDomain = @"go.interfaces"; @@ -14,46 +14,6 @@ static NSString* errDomain = @"go.interfaces"; -(GoSeqRef*) _ref; @end -@class GoInterfacesError; - -@class GoInterfacesI; - -@class GoInterfacesI3; - -@class GoInterfacesWithParam; - -@interface GoInterfacesError : NSObject { -} -@property(strong, readonly) id _ref; - -- (id)initWithRef:(id)ref; -- (BOOL)err:(NSError**)error; -@end - -@interface GoInterfacesI : NSObject { -} -@property(strong, readonly) id _ref; - -- (id)initWithRef:(id)ref; -- (int32_t)rand; -@end - -@interface GoInterfacesI3 : NSObject { -} -@property(strong, readonly) id _ref; - -- (id)initWithRef:(id)ref; -- (GoInterfacesI1*)f; -@end - -@interface GoInterfacesWithParam : NSObject { -} -@property(strong, readonly) id _ref; - -- (id)initWithRef:(id)ref; -- (void)hasParam:(BOOL)p0; -@end - @implementation GoInterfacesError { } diff --git a/bind/testdata/issue10788.go.golden b/bind/testdata/issue10788.go.golden index 0981a16..19c86dd 100644 --- a/bind/testdata/issue10788.go.golden +++ b/bind/testdata/issue10788.go.golden @@ -21,8 +21,6 @@ import ( // suppress the error if seq ends up unused var _ = _seq.FromRefNum -type proxyTestStruct _seq.Ref - //export proxyissue10788_TestStruct_Value_Set func proxyissue10788_TestStruct_Value_Set(refnum C.int32_t, v C.nstring) { ref := _seq.FromRefNum(int32(refnum)) diff --git a/bind/testdata/issue10788.java.c.golden b/bind/testdata/issue10788.java.c.golden index 9d63edc..48e179f 100644 --- a/bind/testdata/issue10788.java.c.golden +++ b/bind/testdata/issue10788.java.c.golden @@ -6,16 +6,15 @@ #include #include #include "seq.h" -#include "issue10788.h" #include "_cgo_export.h" +#include "issue10788.h" - -static jclass proxy_class_issue10788_TestInterface; -static jmethodID proxy_class_issue10788_TestInterface_cons; +jclass proxy_class_issue10788_TestInterface; +jmethodID proxy_class_issue10788_TestInterface_cons; static jmethodID mid_TestInterface_DoSomeWork; static jmethodID mid_TestInterface_MultipleUnnamedParams; -static jclass proxy_class_issue10788_TestStruct; -static jmethodID proxy_class_issue10788_TestStruct_cons; +jclass proxy_class_issue10788_TestStruct; +jmethodID proxy_class_issue10788_TestStruct_cons; JNIEXPORT void JNICALL Java_go_issue10788_Issue10788_init(JNIEnv *env, jclass _unused) { diff --git a/bind/testdata/issue10788.java.h.golden b/bind/testdata/issue10788.java.h.golden index 895f15f..f8206d3 100644 --- a/bind/testdata/issue10788.java.h.golden +++ b/bind/testdata/issue10788.java.h.golden @@ -8,8 +8,13 @@ #include +extern jclass proxy_class_issue10788_TestInterface; +extern jmethodID proxy_class_issue10788_TestInterface_cons; + void cproxyissue10788_TestInterface_DoSomeWork(int32_t refnum, int32_t s); void cproxyissue10788_TestInterface_MultipleUnnamedParams(int32_t refnum, nint p0, nstring p1, int64_t p2); +extern jclass proxy_class_issue10788_TestStruct; +extern jmethodID proxy_class_issue10788_TestStruct_cons; #endif diff --git a/bind/testdata/issue10788.objc.h.golden b/bind/testdata/issue10788.objc.h.golden index eea9159..c391329 100644 --- a/bind/testdata/issue10788.objc.h.golden +++ b/bind/testdata/issue10788.objc.h.golden @@ -26,4 +26,15 @@ - (void)multipleUnnamedParams:(int)p0 p1:(NSString*)p1 p2:(int64_t)p2; @end +@class GoIssue10788TestInterface; + +@interface GoIssue10788TestInterface : NSObject { +} +@property(strong, readonly) id _ref; + +- (id)initWithRef:(id)ref; +- (void)doSomeWork:(GoIssue10788TestStruct*)s; +- (void)multipleUnnamedParams:(int)p0 p1:(NSString*)p1 p2:(int64_t)p2; +@end + #endif diff --git a/bind/testdata/issue10788.objc.m.golden b/bind/testdata/issue10788.objc.m.golden index 7671140..d48e481 100644 --- a/bind/testdata/issue10788.objc.m.golden +++ b/bind/testdata/issue10788.objc.m.golden @@ -3,10 +3,10 @@ // // File is generated by gobind. Do not edit. -#include "GoIssue10788.h" #include #include "seq.h" #include "_cgo_export.h" +#include "GoIssue10788.h" static NSString* errDomain = @"go.issue10788"; @@ -14,17 +14,6 @@ static NSString* errDomain = @"go.issue10788"; -(GoSeqRef*) _ref; @end -@class GoIssue10788TestInterface; - -@interface GoIssue10788TestInterface : NSObject { -} -@property(strong, readonly) id _ref; - -- (id)initWithRef:(id)ref; -- (void)doSomeWork:(GoIssue10788TestStruct*)s; -- (void)multipleUnnamedParams:(int)p0 p1:(NSString*)p1 p2:(int64_t)p2; -@end - @implementation GoIssue10788TestStruct { } diff --git a/bind/testdata/issue12328.go.golden b/bind/testdata/issue12328.go.golden index 65ce4c8..4a238f7 100644 --- a/bind/testdata/issue12328.go.golden +++ b/bind/testdata/issue12328.go.golden @@ -21,8 +21,6 @@ import ( // suppress the error if seq ends up unused var _ = _seq.FromRefNum -type proxyT _seq.Ref - //export proxyissue12328_T_Err_Set func proxyissue12328_T_Err_Set(refnum C.int32_t, v C.nstring) { ref := _seq.FromRefNum(int32(refnum)) diff --git a/bind/testdata/issue12328.java.c.golden b/bind/testdata/issue12328.java.c.golden index 8aca32a..52b110d 100644 --- a/bind/testdata/issue12328.java.c.golden +++ b/bind/testdata/issue12328.java.c.golden @@ -6,12 +6,11 @@ #include #include #include "seq.h" -#include "issue12328.h" #include "_cgo_export.h" +#include "issue12328.h" - -static jclass proxy_class_issue12328_T; -static jmethodID proxy_class_issue12328_T_cons; +jclass proxy_class_issue12328_T; +jmethodID proxy_class_issue12328_T_cons; JNIEXPORT void JNICALL Java_go_issue12328_Issue12328_init(JNIEnv *env, jclass _unused) { diff --git a/bind/testdata/issue12328.java.h.golden b/bind/testdata/issue12328.java.h.golden index 0d54708..14debbb 100644 --- a/bind/testdata/issue12328.java.h.golden +++ b/bind/testdata/issue12328.java.h.golden @@ -8,4 +8,6 @@ #include +extern jclass proxy_class_issue12328_T; +extern jmethodID proxy_class_issue12328_T_cons; #endif diff --git a/bind/testdata/issue12328.objc.m.golden b/bind/testdata/issue12328.objc.m.golden index 05095e8..860a132 100644 --- a/bind/testdata/issue12328.objc.m.golden +++ b/bind/testdata/issue12328.objc.m.golden @@ -3,10 +3,10 @@ // // File is generated by gobind. Do not edit. -#include "GoIssue12328.h" #include #include "seq.h" #include "_cgo_export.h" +#include "GoIssue12328.h" static NSString* errDomain = @"go.issue12328"; diff --git a/bind/testdata/issue12403.java.c.golden b/bind/testdata/issue12403.java.c.golden index b8d9e98..569a5ba 100644 --- a/bind/testdata/issue12403.java.c.golden +++ b/bind/testdata/issue12403.java.c.golden @@ -6,12 +6,11 @@ #include #include #include "seq.h" -#include "issue12403.h" #include "_cgo_export.h" +#include "issue12403.h" - -static jclass proxy_class_issue12403_Parsable; -static jmethodID proxy_class_issue12403_Parsable_cons; +jclass proxy_class_issue12403_Parsable; +jmethodID proxy_class_issue12403_Parsable_cons; static jmethodID mid_Parsable_FromJSON; static jmethodID mid_Parsable_ToJSON; diff --git a/bind/testdata/issue12403.java.h.golden b/bind/testdata/issue12403.java.h.golden index a2f7fbb..1b79ac5 100644 --- a/bind/testdata/issue12403.java.h.golden +++ b/bind/testdata/issue12403.java.h.golden @@ -8,6 +8,9 @@ #include +extern jclass proxy_class_issue12403_Parsable; +extern jmethodID proxy_class_issue12403_Parsable_cons; + nstring cproxyissue12403_Parsable_FromJSON(int32_t refnum, nstring jstr); typedef struct cproxyissue12403_Parsable_ToJSON_return { diff --git a/bind/testdata/issue12403.objc.h.golden b/bind/testdata/issue12403.objc.h.golden index 5e7eba5..cb81a42 100644 --- a/bind/testdata/issue12403.objc.h.golden +++ b/bind/testdata/issue12403.objc.h.golden @@ -16,4 +16,15 @@ - (BOOL)toJSON:(NSString**)ret0_ error:(NSError**)error; @end +@class GoIssue12403Parsable; + +@interface GoIssue12403Parsable : NSObject { +} +@property(strong, readonly) id _ref; + +- (id)initWithRef:(id)ref; +- (NSString*)fromJSON:(NSString*)jstr; +- (BOOL)toJSON:(NSString**)ret0_ error:(NSError**)error; +@end + #endif diff --git a/bind/testdata/issue12403.objc.m.golden b/bind/testdata/issue12403.objc.m.golden index c568668..35a4cf0 100644 --- a/bind/testdata/issue12403.objc.m.golden +++ b/bind/testdata/issue12403.objc.m.golden @@ -3,10 +3,10 @@ // // File is generated by gobind. Do not edit. -#include "GoIssue12403.h" #include #include "seq.h" #include "_cgo_export.h" +#include "GoIssue12403.h" static NSString* errDomain = @"go.issue12403"; @@ -14,17 +14,6 @@ static NSString* errDomain = @"go.issue12403"; -(GoSeqRef*) _ref; @end -@class GoIssue12403Parsable; - -@interface GoIssue12403Parsable : NSObject { -} -@property(strong, readonly) id _ref; - -- (id)initWithRef:(id)ref; -- (NSString*)fromJSON:(NSString*)jstr; -- (BOOL)toJSON:(NSString**)ret0_ error:(NSError**)error; -@end - @implementation GoIssue12403Parsable { } diff --git a/bind/testdata/structs.go.golden b/bind/testdata/structs.go.golden index 4ec9ca0..9a8eb37 100644 --- a/bind/testdata/structs.go.golden +++ b/bind/testdata/structs.go.golden @@ -21,8 +21,6 @@ import ( // suppress the error if seq ends up unused var _ = _seq.FromRefNum -type proxyS _seq.Ref - //export proxystructs_S_X_Set func proxystructs_S_X_Set(refnum C.int32_t, v C.double) { ref := _seq.FromRefNum(int32(refnum)) @@ -81,8 +79,6 @@ func proxystructs_S_Sum(refnum C.int32_t) C.double { return _res_0 } -type proxyS2 _seq.Ref - //export proxystructs_S2_M func proxystructs_S2_M(refnum C.int32_t) { ref := _seq.FromRefNum(int32(refnum)) diff --git a/bind/testdata/structs.java.c.golden b/bind/testdata/structs.java.c.golden index a54d17f..9710738 100644 --- a/bind/testdata/structs.java.c.golden +++ b/bind/testdata/structs.java.c.golden @@ -6,17 +6,16 @@ #include #include #include "seq.h" -#include "structs.h" #include "_cgo_export.h" +#include "structs.h" - -static jclass proxy_class_structs_I; -static jmethodID proxy_class_structs_I_cons; +jclass proxy_class_structs_I; +jmethodID proxy_class_structs_I_cons; static jmethodID mid_I_M; -static jclass proxy_class_structs_S; -static jmethodID proxy_class_structs_S_cons; -static jclass proxy_class_structs_S2; -static jmethodID proxy_class_structs_S2_cons; +jclass proxy_class_structs_S; +jmethodID proxy_class_structs_S_cons; +jclass proxy_class_structs_S2; +jmethodID proxy_class_structs_S2_cons; JNIEXPORT void JNICALL Java_go_structs_Structs_init(JNIEnv *env, jclass _unused) { diff --git a/bind/testdata/structs.java.h.golden b/bind/testdata/structs.java.h.golden index 25ea098..b80a847 100644 --- a/bind/testdata/structs.java.h.golden +++ b/bind/testdata/structs.java.h.golden @@ -8,6 +8,13 @@ #include +extern jclass proxy_class_structs_I; +extern jmethodID proxy_class_structs_I_cons; + void cproxystructs_I_M(int32_t refnum); +extern jclass proxy_class_structs_S; +extern jmethodID proxy_class_structs_S_cons; +extern jclass proxy_class_structs_S2; +extern jmethodID proxy_class_structs_S2_cons; #endif diff --git a/bind/testdata/structs.objc.h.golden b/bind/testdata/structs.objc.h.golden index cfc9f75..7b0a834 100644 --- a/bind/testdata/structs.objc.h.golden +++ b/bind/testdata/structs.objc.h.golden @@ -42,4 +42,14 @@ FOUNDATION_EXPORT GoStructsS* GoStructsIdentity(GoStructsS* s); FOUNDATION_EXPORT BOOL GoStructsIdentityWithError(GoStructsS* s, GoStructsS** ret0_, NSError** error); +@class GoStructsI; + +@interface GoStructsI : NSObject { +} +@property(strong, readonly) id _ref; + +- (id)initWithRef:(id)ref; +- (void)m; +@end + #endif diff --git a/bind/testdata/structs.objc.m.golden b/bind/testdata/structs.objc.m.golden index e15d42b..6e8e7df 100644 --- a/bind/testdata/structs.objc.m.golden +++ b/bind/testdata/structs.objc.m.golden @@ -3,10 +3,10 @@ // // File is generated by gobind. Do not edit. -#include "GoStructs.h" #include #include "seq.h" #include "_cgo_export.h" +#include "GoStructs.h" static NSString* errDomain = @"go.structs"; @@ -14,16 +14,6 @@ static NSString* errDomain = @"go.structs"; -(GoSeqRef*) _ref; @end -@class GoStructsI; - -@interface GoStructsI : NSObject { -} -@property(strong, readonly) id _ref; - -- (id)initWithRef:(id)ref; -- (void)m; -@end - @implementation GoStructsS { } diff --git a/bind/testdata/try.java.c.golden b/bind/testdata/try.java.c.golden index 8107f1d..f83c963 100644 --- a/bind/testdata/try.java.c.golden +++ b/bind/testdata/try.java.c.golden @@ -6,9 +6,8 @@ #include #include #include "seq.h" -#include "try.h" #include "_cgo_export.h" - +#include "try.h" JNIEXPORT void JNICALL diff --git a/bind/testdata/try.objc.m.golden b/bind/testdata/try.objc.m.golden index cecba96..8bf633e 100644 --- a/bind/testdata/try.objc.m.golden +++ b/bind/testdata/try.objc.m.golden @@ -3,10 +3,10 @@ // // File is generated by gobind. Do not edit. -#include "GoTry.h" #include #include "seq.h" #include "_cgo_export.h" +#include "GoTry.h" static NSString* errDomain = @"go.try"; diff --git a/bind/testdata/vars.go.golden b/bind/testdata/vars.go.golden index 0f9c16e..f830109 100644 --- a/bind/testdata/vars.go.golden +++ b/bind/testdata/vars.go.golden @@ -21,8 +21,6 @@ import ( // suppress the error if seq ends up unused var _ = _seq.FromRefNum -type proxyS _seq.Ref - type proxyvars_I _seq.Ref //export var_setvars_ABool diff --git a/bind/testdata/vars.java.c.golden b/bind/testdata/vars.java.c.golden index 7bbda6d..5a4a4f3 100644 --- a/bind/testdata/vars.java.c.golden +++ b/bind/testdata/vars.java.c.golden @@ -6,14 +6,13 @@ #include #include #include "seq.h" -#include "vars.h" #include "_cgo_export.h" +#include "vars.h" - -static jclass proxy_class_vars_I; -static jmethodID proxy_class_vars_I_cons; -static jclass proxy_class_vars_S; -static jmethodID proxy_class_vars_S_cons; +jclass proxy_class_vars_I; +jmethodID proxy_class_vars_I_cons; +jclass proxy_class_vars_S; +jmethodID proxy_class_vars_S_cons; JNIEXPORT void JNICALL Java_go_vars_Vars_init(JNIEnv *env, jclass _unused) { diff --git a/bind/testdata/vars.java.h.golden b/bind/testdata/vars.java.h.golden index 6ef9a45..f707a99 100644 --- a/bind/testdata/vars.java.h.golden +++ b/bind/testdata/vars.java.h.golden @@ -8,4 +8,9 @@ #include +extern jclass proxy_class_vars_I; +extern jmethodID proxy_class_vars_I_cons; + +extern jclass proxy_class_vars_S; +extern jmethodID proxy_class_vars_S_cons; #endif diff --git a/bind/testdata/vars.objc.h.golden b/bind/testdata/vars.objc.h.golden index 6a9645f..e5b24ef 100644 --- a/bind/testdata/vars.objc.h.golden +++ b/bind/testdata/vars.objc.h.golden @@ -61,4 +61,13 @@ @end +@class GoVarsI; + +@interface GoVarsI : NSObject { +} +@property(strong, readonly) id _ref; + +- (id)initWithRef:(id)ref; +@end + #endif diff --git a/bind/testdata/vars.objc.m.golden b/bind/testdata/vars.objc.m.golden index 5d87788..bb84cae 100644 --- a/bind/testdata/vars.objc.m.golden +++ b/bind/testdata/vars.objc.m.golden @@ -3,10 +3,10 @@ // // File is generated by gobind. Do not edit. -#include "GoVars.h" #include #include "seq.h" #include "_cgo_export.h" +#include "GoVars.h" static NSString* errDomain = @"go.vars"; @@ -14,15 +14,6 @@ static NSString* errDomain = @"go.vars"; -(GoSeqRef*) _ref; @end -@class GoVarsI; - -@interface GoVarsI : NSObject { -} -@property(strong, readonly) id _ref; - -- (id)initWithRef:(id)ref; -@end - @implementation GoVarsS { } diff --git a/bind/testpkg/secondpkg/secondpkg.go b/bind/testpkg/secondpkg/secondpkg.go new file mode 100644 index 0000000..ae87e11 --- /dev/null +++ b/bind/testpkg/secondpkg/secondpkg.go @@ -0,0 +1,25 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package secondpkg is imported by bind tests that verify +// that a bound package can reference another bound package. +package secondpkg + +type ( + I interface { + F(i int) int + } + + S struct{} +) + +func (_ *S) F(i int) int { + return i +} + +const HelloString = "secondpkg string" + +func Hello() string { + return HelloString +} diff --git a/bind/testpkg/simplepkg/simplepkg.go b/bind/testpkg/simplepkg/simplepkg.go new file mode 100644 index 0000000..730c1be --- /dev/null +++ b/bind/testpkg/simplepkg/simplepkg.go @@ -0,0 +1,16 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package simplepkg is imported from testpkg and tests two +// corner cases. +// First: simplepkg itself contains no (exported) functions +// or methods and so its generated Go package must not import +// it. +// +// Second: even though testpkg imports simplepkg, testpkg's +// generated Go package ends up not referencing simplepkg and +// must not import it. +package simplepkg + +type S struct{} diff --git a/bind/testpkg/testpkg.go b/bind/testpkg/testpkg.go index 2333b24..9599d54 100644 --- a/bind/testpkg/testpkg.go +++ b/bind/testpkg/testpkg.go @@ -20,6 +20,9 @@ import ( "time" "golang.org/x/mobile/asset" + + "golang.org/x/mobile/bind/testpkg/secondpkg" + "golang.org/x/mobile/bind/testpkg/simplepkg" ) const ( @@ -411,3 +414,40 @@ type NullFieldStruct struct { func NewNullFieldStruct() *NullFieldStruct { return &NullFieldStruct{} } + +var ( + ImportedVarI secondpkg.I = NewImportedI() + ImportedVarS *secondpkg.S = NewImportedS() +) + +type ImportedFields struct { + I secondpkg.I + S *secondpkg.S +} + +func NewImportedFields() *ImportedFields { + return &ImportedFields{ + I: NewImportedI(), + S: NewImportedS(), + } +} + +func NewImportedI() secondpkg.I { + return NewImportedS() +} + +func NewImportedS() *secondpkg.S { + return new(secondpkg.S) +} + +func WithImportedI(i secondpkg.I) secondpkg.I { + return i +} + +func WithImportedS(s *secondpkg.S) *secondpkg.S { + return s +} + +func NewSimpleS() *simplepkg.S { + return nil +} diff --git a/cmd/gobind/gen.go b/cmd/gobind/gen.go index 6b7624f..5dd1d05 100644 --- a/cmd/gobind/gen.go +++ b/cmd/gobind/gen.go @@ -16,36 +16,48 @@ import ( "golang.org/x/mobile/bind" ) -func genPkg(p *types.Package) { +func genPkg(p *types.Package, allPkg []*types.Package) { fname := defaultFileName(*lang, p) + conf := &bind.GeneratorConfig{ + Fset: fset, + Pkg: p, + AllPkg: allPkg, + } switch *lang { case "java": w, closer := writer(fname) - processErr(bind.GenJava(w, fset, p, *javaPkg, bind.Java)) + conf.Writer = w + processErr(bind.GenJava(conf, *javaPkg, bind.Java)) closer() cname := "java_" + p.Name() + ".c" w, closer = writer(cname) - processErr(bind.GenJava(w, fset, p, *javaPkg, bind.JavaC)) + conf.Writer = w + processErr(bind.GenJava(conf, *javaPkg, bind.JavaC)) closer() hname := p.Name() + ".h" w, closer = writer(hname) - processErr(bind.GenJava(w, fset, p, *javaPkg, bind.JavaH)) + conf.Writer = w + processErr(bind.GenJava(conf, *javaPkg, bind.JavaH)) closer() case "go": w, closer := writer(fname) - processErr(bind.GenGo(w, fset, p)) + conf.Writer = w + processErr(bind.GenGo(conf)) closer() case "objc": gohname := p.Name() + ".h" w, closer := writer(gohname) - processErr(bind.GenObjc(w, fset, p, *prefix, bind.ObjcGoH)) + conf.Writer = w + processErr(bind.GenObjc(conf, *prefix, bind.ObjcGoH)) closer() hname := fname[:len(fname)-2] + ".h" w, closer = writer(hname) - processErr(bind.GenObjc(w, fset, p, *prefix, bind.ObjcH)) + conf.Writer = w + processErr(bind.GenObjc(conf, *prefix, bind.ObjcH)) closer() w, closer = writer(fname) - processErr(bind.GenObjc(w, fset, p, *prefix, bind.ObjcM)) + conf.Writer = w + processErr(bind.GenObjc(conf, *prefix, bind.ObjcM)) closer() default: errorf("unknown target language: %q", *lang) diff --git a/cmd/gobind/main.go b/cmd/gobind/main.go index 8dd5172..a4c4f98 100644 --- a/cmd/gobind/main.go +++ b/cmd/gobind/main.go @@ -8,6 +8,7 @@ import ( "flag" "fmt" "go/importer" + "go/types" "log" "os" "os/exec" @@ -46,13 +47,17 @@ func main() { os.Exit(1) } + var allPkg []*types.Package for _, arg := range flag.Args() { pkg, err := importer.Default().Import(arg) if err != nil { fmt.Fprintf(os.Stderr, "could not import package %s: %v", arg, err) os.Exit(1) } - genPkg(pkg) + allPkg = append(allPkg, pkg) + } + for _, pkg := range allPkg { + genPkg(pkg, allPkg) } os.Exit(exitStatus) } diff --git a/cmd/gomobile/bind.go b/cmd/gomobile/bind.go index 41cacb5..5b2b62c 100644 --- a/cmd/gomobile/bind.go +++ b/cmd/gomobile/bind.go @@ -160,7 +160,7 @@ func (b *binder) GenObjcSupport(outdir string) error { return copyFile(filepath.Join(outdir, "seq.h"), filepath.Join(objcPkg.Dir, "seq.h")) } -func (b *binder) GenObjc(pkg *types.Package, outdir string) (string, error) { +func (b *binder) GenObjc(pkg *types.Package, allPkg []*types.Package, outdir string) (string, error) { const bindPrefixDefault = "Go" if bindPrefix == "" { bindPrefix = bindPrefixDefault @@ -176,6 +176,11 @@ func (b *binder) GenObjc(pkg *types.Package, outdir string) (string, error) { hfile := filepath.Join(outdir, fileBase+".h") gohfile := filepath.Join(outdir, pkg.Name()+".h") + conf := &bind.GeneratorConfig{ + Fset: b.fset, + Pkg: pkg, + AllPkg: allPkg, + } generate := func(w io.Writer) error { if buildX { printcmd("gobind %s -outdir=%s %s", bindOption, outdir, pkg.Path()) @@ -183,7 +188,8 @@ func (b *binder) GenObjc(pkg *types.Package, outdir string) (string, error) { if buildN { return nil } - return bind.GenObjc(w, b.fset, pkg, bindPrefix, bind.ObjcM) + conf.Writer = w + return bind.GenObjc(conf, bindPrefix, bind.ObjcM) } if err := writeFile(mfile, generate); err != nil { return "", err @@ -192,7 +198,8 @@ func (b *binder) GenObjc(pkg *types.Package, outdir string) (string, error) { if buildN { return nil } - return bind.GenObjc(w, b.fset, pkg, bindPrefix, bind.ObjcH) + conf.Writer = w + return bind.GenObjc(conf, bindPrefix, bind.ObjcH) } if err := writeFile(hfile, generate); err != nil { return "", err @@ -201,7 +208,8 @@ func (b *binder) GenObjc(pkg *types.Package, outdir string) (string, error) { if buildN { return nil } - return bind.GenObjc(w, b.fset, pkg, bindPrefix, bind.ObjcGoH) + conf.Writer = w + return bind.GenObjc(conf, bindPrefix, bind.ObjcGoH) } if err := writeFile(gohfile, generate); err != nil { return "", err @@ -224,7 +232,7 @@ func (b *binder) GenJavaSupport(outdir string) error { return copyFile(filepath.Join(outdir, "seq.h"), filepath.Join(javaPkg.Dir, "seq.h")) } -func (b *binder) GenJava(pkg *types.Package, outdir, javadir string) error { +func (b *binder) GenJava(pkg *types.Package, allPkg []*types.Package, outdir, javadir string) error { className := strings.Title(pkg.Name()) javaFile := filepath.Join(javadir, className+".java") cFile := filepath.Join(outdir, "java_"+pkg.Name()+".c") @@ -234,6 +242,11 @@ func (b *binder) GenJava(pkg *types.Package, outdir, javadir string) error { bindOption += " -javapkg=" + bindJavaPkg } + conf := &bind.GeneratorConfig{ + Fset: b.fset, + Pkg: pkg, + AllPkg: allPkg, + } generate := func(w io.Writer) error { if buildX { printcmd("gobind %s -outdir=%s %s", bindOption, javadir, pkg.Path()) @@ -241,7 +254,8 @@ func (b *binder) GenJava(pkg *types.Package, outdir, javadir string) error { if buildN { return nil } - return bind.GenJava(w, b.fset, pkg, bindJavaPkg, bind.Java) + conf.Writer = w + return bind.GenJava(conf, bindJavaPkg, bind.Java) } if err := writeFile(javaFile, generate); err != nil { return err @@ -250,7 +264,8 @@ func (b *binder) GenJava(pkg *types.Package, outdir, javadir string) error { if buildN { return nil } - return bind.GenJava(w, b.fset, pkg, bindJavaPkg, bind.JavaC) + conf.Writer = w + return bind.GenJava(conf, bindJavaPkg, bind.JavaC) } if err := writeFile(cFile, generate); err != nil { return err @@ -259,12 +274,13 @@ func (b *binder) GenJava(pkg *types.Package, outdir, javadir string) error { if buildN { return nil } - return bind.GenJava(w, b.fset, pkg, bindJavaPkg, bind.JavaH) + conf.Writer = w + return bind.GenJava(conf, bindJavaPkg, bind.JavaH) } return writeFile(hFile, generate) } -func (b *binder) GenGo(pkg *types.Package, outdir string) error { +func (b *binder) GenGo(pkg *types.Package, allPkg []*types.Package, outdir string) error { pkgName := "go_" + pkg.Name() goFile := filepath.Join(outdir, pkgName+"main.go") @@ -275,7 +291,13 @@ func (b *binder) GenGo(pkg *types.Package, outdir string) error { if buildN { return nil } - return bind.GenGo(w, b.fset, pkg) + conf := &bind.GeneratorConfig{ + Writer: w, + Fset: b.fset, + Pkg: pkg, + AllPkg: allPkg, + } + return bind.GenGo(conf) } if err := writeFile(goFile, generate); err != nil { return err diff --git a/cmd/gomobile/bind_androidapp.go b/cmd/gomobile/bind_androidapp.go index bd86a1a..e6d8568 100644 --- a/cmd/gomobile/bind_androidapp.go +++ b/cmd/gomobile/bind_androidapp.go @@ -71,8 +71,8 @@ func goAndroidBind(pkgs []*build.Package, androidArchs []string) error { } srcDir := filepath.Join(tmpdir, "gomobile_bind") - for _, pkg := range typesPkgs { - if err := binder.GenGo(pkg, srcDir); err != nil { + for _, pkg := range binder.pkgs { + if err := binder.GenGo(pkg, binder.pkgs, srcDir); err != nil { return err } } @@ -96,7 +96,7 @@ func goAndroidBind(pkgs []*build.Package, androidArchs []string) error { if bindJavaPkg == "" { pkgpath = "go/" + pkg.Name() } - if err := binder.GenJava(pkg, srcDir, filepath.Join(androidDir, "src/main/java/"+pkgpath)); err != nil { + if err := binder.GenJava(pkg, binder.pkgs, srcDir, filepath.Join(androidDir, "src/main/java/"+pkgpath)); err != nil { return err } } diff --git a/cmd/gomobile/bind_iosapp.go b/cmd/gomobile/bind_iosapp.go index 0c706a7..1ec010c 100644 --- a/cmd/gomobile/bind_iosapp.go +++ b/cmd/gomobile/bind_iosapp.go @@ -36,8 +36,8 @@ func goIOSBind(pkgs []*build.Package) error { } srcDir := filepath.Join(tmpdir, "src", "gomobile_bind") - for _, pkg := range typesPkgs { - if err := binder.GenGo(pkg, srcDir); err != nil { + for _, pkg := range binder.pkgs { + if err := binder.GenGo(pkg, binder.pkgs, srcDir); err != nil { return err } } @@ -51,8 +51,8 @@ func goIOSBind(pkgs []*build.Package) error { } fileBases := make([]string, len(typesPkgs)) - for i, pkg := range typesPkgs { - if fileBases[i], err = binder.GenObjc(pkg, srcDir); err != nil { + for i, pkg := range binder.pkgs { + if fileBases[i], err = binder.GenObjc(pkg, binder.pkgs, srcDir); err != nil { return err } }