2
0
mirror of synced 2025-02-23 23:08:14 +00:00
mobile/bind/bind.go
Elias Naur 7df33f4a5c mobile/bind: allow bound packages to refer to imported bound packages
Multiple packages are already supported, but only as if each packages
were bound in isolation. This CL lets a bound package refer to other
bound packages in its exported functions, types and fields.

In Java, the JNI class jclass and constructor jmethodID are exported
so other packages can construct proxies of other packages' interfaces.

In ObjC, the class @interface declarations are moved from the package
.m file to its .h file to allow other packages to constructs its
interface proxies.

Add a supporting test package, secondpkg, and add Java and ObjC tests
for the new cross package functionality. Also add simplepkg for
testing corner cases where the generated Go file must not include its
bound package.

While we're here, stop generating Go proxy types for struct types;
only Go interfaces can be implemented in the foreign language.

Change-Id: Icbfa739c893703867d38a9100ed0928fbd7a660d
Reviewed-on: https://go-review.googlesource.com/20575
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2016-03-12 06:23:01 +00:00

130 lines
2.5 KiB
Go

// Copyright 2014 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 bind implements a code generator for gobind.
//
// See the documentation on the gobind command for usage details
// and the list of currently supported types.
// (http://godoc.org/golang.org/x/mobile/cmd/gobind)
package bind // import "golang.org/x/mobile/bind"
// TODO(crawshaw): slice support
// TODO(crawshaw): channel support
import (
"bytes"
"go/format"
"go/token"
"go/types"
"io"
)
type (
GeneratorConfig struct {
Writer io.Writer
Fset *token.FileSet
Pkg *types.Package
AllPkg []*types.Package
}
fileType int
)
const (
Java fileType = iota
JavaC
JavaH
ObjcM
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,
},
}
g.init()
if err := g.gen(); err != nil {
return err
}
src := buf.Bytes()
srcf, err := format.Source(src)
if err != nil {
conf.Writer.Write(src) // for debugging
return err
}
_, err = conf.Writer.Write(srcf)
return err
}
// GenObjc generates the Objective-C API from a Go package.
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,
},
prefix: prefix,
}
g.init()
var err error
switch ft {
case ObjcH:
err = g.genH()
case ObjcM:
err = g.genM()
case ObjcGoH:
err = g.genGoH()
default:
panic("invalid fileType")
}
if err != nil {
return err
}
_, err = io.Copy(conf.Writer, buf)
return err
}