| Index: third_party/go/src/golang.org/x/mobile/bind/genjava.go
|
| diff --git a/third_party/go/src/golang.org/x/mobile/bind/genjava.go b/third_party/go/src/golang.org/x/mobile/bind/genjava.go
|
| deleted file mode 100644
|
| index 61575d9afe6a8c152ee0b6cc907f3d18ca5e71fa..0000000000000000000000000000000000000000
|
| --- a/third_party/go/src/golang.org/x/mobile/bind/genjava.go
|
| +++ /dev/null
|
| @@ -1,598 +0,0 @@
|
| -// 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
|
| -
|
| -import (
|
| - "bytes"
|
| - "fmt"
|
| - "go/token"
|
| - "io"
|
| - "regexp"
|
| - "unicode"
|
| - "unicode/utf8"
|
| -
|
| - "golang.org/x/tools/go/types"
|
| -)
|
| -
|
| -// TODO(crawshaw): disallow basic android java type names in exported symbols.
|
| -// TODO(crawshaw): generate all relevant "implements" relationships for interfaces.
|
| -// TODO(crawshaw): consider introducing Java functions for casting to and from interfaces at runtime.
|
| -
|
| -type ErrorList []error
|
| -
|
| -func (list ErrorList) Error() string {
|
| - buf := new(bytes.Buffer)
|
| - for i, err := range list {
|
| - if i > 0 {
|
| - buf.WriteRune('\n')
|
| - }
|
| - io.WriteString(buf, err.Error())
|
| - }
|
| - return buf.String()
|
| -}
|
| -
|
| -type javaGen struct {
|
| - *printer
|
| - nextCode int
|
| - fset *token.FileSet
|
| - pkg *types.Package
|
| - err ErrorList
|
| -}
|
| -
|
| -func (g *javaGen) genStruct(obj *types.TypeName, T *types.Struct) {
|
| - fields := exportedFields(T)
|
| - methods := exportedMethodSet(types.NewPointer(obj.Type()))
|
| -
|
| - g.Printf("public static final class %s implements go.Seq.Object {\n", obj.Name())
|
| - g.Indent()
|
| - g.Printf("private static final String DESCRIPTOR = \"go.%s.%s\";\n", g.pkg.Name(), obj.Name())
|
| - for i, f := range fields {
|
| - g.Printf("private static final int FIELD_%s_GET = 0x%x0f;\n", f.Name(), i)
|
| - g.Printf("private static final int FIELD_%s_SET = 0x%x1f;\n", f.Name(), i)
|
| - }
|
| - for i, m := range methods {
|
| - g.Printf("private static final int CALL_%s = 0x%x0c;\n", m.Name(), i)
|
| - }
|
| - g.Printf("\n")
|
| -
|
| - g.Printf("private go.Seq.Ref ref;\n\n")
|
| -
|
| - n := obj.Name()
|
| - g.Printf("private %s(go.Seq.Ref ref) { this.ref = ref; }\n\n", n)
|
| - g.Printf(`public go.Seq.Ref ref() { return ref; }
|
| -
|
| -public void call(int code, go.Seq in, go.Seq out) {
|
| - throw new RuntimeException("internal error: cycle: cannot call concrete proxy");
|
| -}
|
| -
|
| -`)
|
| -
|
| - for _, f := range fields {
|
| - g.Printf("public %s get%s() {\n", g.javaType(f.Type()), f.Name())
|
| - g.Indent()
|
| - g.Printf("Seq in = new Seq();\n")
|
| - g.Printf("Seq out = new Seq();\n")
|
| - g.Printf("in.writeRef(ref);\n")
|
| - g.Printf("Seq.send(DESCRIPTOR, FIELD_%s_GET, in, out);\n", f.Name())
|
| - g.Printf("return out.read%s;\n", seqRead(f.Type()))
|
| - g.Outdent()
|
| - g.Printf("}\n\n")
|
| -
|
| - g.Printf("public void set%s(%s v) {\n", f.Name(), g.javaType(f.Type()))
|
| - g.Indent()
|
| - g.Printf("Seq in = new Seq();\n")
|
| - g.Printf("Seq out = new Seq();\n")
|
| - g.Printf("in.writeRef(ref);\n")
|
| - g.Printf("in.write%s;\n", seqWrite(f.Type(), "v"))
|
| - g.Printf("Seq.send(DESCRIPTOR, FIELD_%s_SET, in, out);\n", f.Name())
|
| - g.Outdent()
|
| - g.Printf("}\n")
|
| - }
|
| - g.Printf("\n")
|
| -
|
| - for _, m := range methods {
|
| - g.genFunc(m, true)
|
| - }
|
| -
|
| - g.Printf("@Override public boolean equals(Object o) {\n")
|
| - g.Indent()
|
| - g.Printf("if (o == null || !(o instanceof %s)) {\n return false;\n}\n", n)
|
| - g.Printf("%s that = (%s)o;\n", n, n)
|
| - for _, f := range fields {
|
| - nf := f.Name()
|
| - g.Printf("%s this%s = get%s();\n", g.javaType(f.Type()), nf, nf)
|
| - g.Printf("%s that%s = that.get%s();\n", g.javaType(f.Type()), nf, nf)
|
| - if isJavaPrimitive(f.Type()) {
|
| - g.Printf("if (this%s != that%s) {\n return false;\n}\n", nf, nf)
|
| - } else {
|
| - g.Printf("if (this%s == null) {\n", nf)
|
| - g.Indent()
|
| - g.Printf("if (that%s != null) {\n return false;\n}\n", nf)
|
| - g.Outdent()
|
| - g.Printf("} else if (!this%s.equals(that%s)) {\n return false;\n}\n", nf, nf)
|
| - }
|
| - }
|
| - g.Printf("return true;\n")
|
| - g.Outdent()
|
| - g.Printf("}\n\n")
|
| -
|
| - g.Printf("@Override public int hashCode() {\n")
|
| - g.Printf(" return java.util.Arrays.hashCode(new Object[] {")
|
| - for i, f := range fields {
|
| - if i > 0 {
|
| - g.Printf(", ")
|
| - }
|
| - g.Printf("get%s()", f.Name())
|
| - }
|
| - g.Printf("});\n")
|
| - g.Printf("}\n\n")
|
| -
|
| - // TODO(crawshaw): use String() string if it is defined.
|
| - g.Printf("@Override public String toString() {\n")
|
| - g.Indent()
|
| - g.Printf("StringBuilder b = new StringBuilder();\n")
|
| - g.Printf(`b.append("%s").append("{");`, obj.Name())
|
| - g.Printf("\n")
|
| - for _, f := range fields {
|
| - n := f.Name()
|
| - g.Printf(`b.append("%s:").append(get%s()).append(",");`, n, n)
|
| - g.Printf("\n")
|
| - }
|
| - g.Printf(`return b.append("}").toString();`)
|
| - g.Printf("\n")
|
| - g.Outdent()
|
| - g.Printf("}\n\n")
|
| -
|
| - g.Outdent()
|
| - g.Printf("}\n\n")
|
| -}
|
| -
|
| -func (g *javaGen) genInterfaceStub(o *types.TypeName, m *types.Interface) {
|
| - g.Printf("public static abstract class Stub implements %s {\n", o.Name())
|
| - g.Indent()
|
| -
|
| - g.Printf("static final String DESCRIPTOR = \"go.%s.%s\";\n\n", g.pkg.Name(), o.Name())
|
| - g.Printf("private final go.Seq.Ref ref;\n")
|
| - g.Printf("public Stub() {\n ref = go.Seq.createRef(this);\n}\n\n")
|
| - g.Printf("public go.Seq.Ref ref() { return ref; }\n\n")
|
| -
|
| - g.Printf("public void call(int code, go.Seq in, go.Seq out) {\n")
|
| - g.Indent()
|
| - g.Printf("switch (code) {\n")
|
| -
|
| - for i := 0; i < m.NumMethods(); i++ {
|
| - f := m.Method(i)
|
| - g.Printf("case Proxy.CALL_%s: {\n", f.Name())
|
| - g.Indent()
|
| -
|
| - sig := f.Type().(*types.Signature)
|
| - for i := 0; i < sig.Params().Len(); i++ {
|
| - p := sig.Params().At(i)
|
| - jt := g.javaType(p.Type())
|
| - g.Printf("%s param_%s = in.read%s;\n", jt, p.Name(), seqRead(p.Type()))
|
| - }
|
| -
|
| - res := sig.Results()
|
| - var returnsError bool
|
| - var numRes = res.Len()
|
| - if (res.Len() == 1 && isErrorType(res.At(0).Type())) ||
|
| - (res.Len() == 2 && isErrorType(res.At(1).Type())) {
|
| - numRes -= 1
|
| - returnsError = true
|
| - }
|
| -
|
| - if returnsError {
|
| - g.Printf("try {\n")
|
| - g.Indent()
|
| - }
|
| -
|
| - if numRes > 0 {
|
| - g.Printf("%s result = ", g.javaType(res.At(0).Type()))
|
| - }
|
| -
|
| - g.Printf("this.%s(", f.Name())
|
| - for i := 0; i < sig.Params().Len(); i++ {
|
| - if i > 0 {
|
| - g.Printf(", ")
|
| - }
|
| - g.Printf("param_%s", sig.Params().At(i).Name())
|
| - }
|
| - g.Printf(");\n")
|
| -
|
| - if numRes > 0 {
|
| - g.Printf("out.write%s;\n", seqWrite(res.At(0).Type(), "result"))
|
| - }
|
| - if returnsError {
|
| - g.Printf("out.writeUTF16(null);\n")
|
| - g.Outdent()
|
| - g.Printf("} catch (Exception e) {\n")
|
| - g.Indent()
|
| - if numRes > 0 {
|
| - resTyp := res.At(0).Type()
|
| - g.Printf("%s result = %s;\n", g.javaType(resTyp), g.javaTypeDefault(resTyp))
|
| - g.Printf("out.write%s;\n", seqWrite(resTyp, "result"))
|
| - }
|
| - g.Printf("out.writeUTF16(e.getMessage());\n")
|
| - g.Outdent()
|
| - g.Printf("}\n")
|
| - }
|
| - g.Printf("return;\n")
|
| - g.Outdent()
|
| - g.Printf("}\n")
|
| - }
|
| -
|
| - g.Printf("default:\n throw new RuntimeException(\"unknown code: \"+ code);\n")
|
| - g.Printf("}\n")
|
| - g.Outdent()
|
| - g.Printf("}\n")
|
| -
|
| - g.Outdent()
|
| - g.Printf("}\n\n")
|
| -}
|
| -
|
| -const javaProxyPreamble = `static final class Proxy implements %s {
|
| - static final String DESCRIPTOR = Stub.DESCRIPTOR;
|
| -
|
| - private go.Seq.Ref ref;
|
| -
|
| - Proxy(go.Seq.Ref ref) { this.ref = ref; }
|
| -
|
| - public go.Seq.Ref ref() { return ref; }
|
| -
|
| - public void call(int code, go.Seq in, go.Seq out) {
|
| - throw new RuntimeException("cycle: cannot call proxy");
|
| - }
|
| -
|
| -`
|
| -
|
| -func (g *javaGen) genInterface(o *types.TypeName) {
|
| - iface := o.Type().(*types.Named).Underlying().(*types.Interface)
|
| -
|
| - g.Printf("public interface %s extends go.Seq.Object {\n", o.Name())
|
| - g.Indent()
|
| -
|
| - methodSigErr := false
|
| - for i := 0; i < iface.NumMethods(); i++ {
|
| - if err := g.funcSignature(iface.Method(i), false); err != nil {
|
| - methodSigErr = true
|
| - g.errorf("%v", err)
|
| - }
|
| - g.Printf(";\n\n")
|
| - }
|
| - if methodSigErr {
|
| - return // skip stub generation, more of the same errors
|
| - }
|
| -
|
| - g.genInterfaceStub(o, iface)
|
| -
|
| - g.Printf(javaProxyPreamble, o.Name())
|
| - g.Indent()
|
| -
|
| - for i := 0; i < iface.NumMethods(); i++ {
|
| - g.genFunc(iface.Method(i), true)
|
| - }
|
| - for i := 0; i < iface.NumMethods(); i++ {
|
| - g.Printf("static final int CALL_%s = 0x%x0a;\n", iface.Method(i).Name(), i+1)
|
| - }
|
| -
|
| - g.Outdent()
|
| - g.Printf("}\n")
|
| -
|
| - g.Outdent()
|
| - g.Printf("}\n\n")
|
| -}
|
| -
|
| -func isErrorType(T types.Type) bool {
|
| - return T == types.Universe.Lookup("error").Type()
|
| -}
|
| -
|
| -func isJavaPrimitive(T types.Type) bool {
|
| - b, ok := T.(*types.Basic)
|
| - if !ok {
|
| - return false
|
| - }
|
| - switch b.Kind() {
|
| - case types.Bool, types.Uint8, types.Float32, types.Float64,
|
| - types.Int, types.Int8, types.Int16, types.Int32, types.Int64:
|
| - return true
|
| - }
|
| - return false
|
| -}
|
| -
|
| -// javaType returns a string that can be used as a Java type.
|
| -func (g *javaGen) javaType(T types.Type) string {
|
| - switch T := T.(type) {
|
| - case *types.Basic:
|
| - switch T.Kind() {
|
| - case types.Bool:
|
| - return "boolean"
|
| - case types.Int:
|
| - return "long"
|
| - case types.Int8:
|
| - return "byte"
|
| - case types.Int16:
|
| - return "short"
|
| - case types.Int32:
|
| - return "int"
|
| - case types.Int64:
|
| - return "long"
|
| - case types.Uint8:
|
| - // TODO(crawshaw): Java bytes are signed, so this is
|
| - // questionable, but vital.
|
| - return "byte"
|
| - // TODO(crawshaw): case types.Uint, types.Uint16, types.Uint32, types.Uint64:
|
| - case types.Float32:
|
| - return "float"
|
| - case types.Float64:
|
| - return "double"
|
| - case types.String:
|
| - return "String"
|
| - default:
|
| - g.errorf("unsupported return type: %s", T)
|
| - return "TODO"
|
| - }
|
| - case *types.Slice:
|
| - elem := g.javaType(T.Elem())
|
| - return elem + "[]"
|
| -
|
| - case *types.Pointer:
|
| - if _, ok := T.Elem().(*types.Named); ok {
|
| - return g.javaType(T.Elem())
|
| - }
|
| - panic(fmt.Sprintf("unsupporter pointer to type: %s", T))
|
| - case *types.Named:
|
| - n := T.Obj()
|
| - if n.Pkg() != g.pkg {
|
| - panic(fmt.Sprintf("type %s is in package %s, must be defined in package %s", n.Name(), n.Pkg().Name(), g.pkg.Name()))
|
| - }
|
| - // TODO(crawshaw): more checking here
|
| - return n.Name()
|
| - default:
|
| - g.errorf("unsupported javaType: %#+v, %s\n", T, T)
|
| - return "TODO"
|
| - }
|
| -}
|
| -
|
| -// javaTypeDefault returns a string that represents the default value of the mapped java type.
|
| -// TODO(hyangah): Combine javaType and javaTypeDefault?
|
| -func (g *javaGen) javaTypeDefault(T types.Type) string {
|
| - switch T := T.(type) {
|
| - case *types.Basic:
|
| - switch T.Kind() {
|
| - case types.Bool:
|
| - return "false"
|
| - case types.Int, types.Int8, types.Int16, types.Int32,
|
| - types.Int64, types.Uint8, types.Float32, types.Float64:
|
| - return "0"
|
| - case types.String:
|
| - return "null"
|
| - default:
|
| - g.errorf("unsupported return type: %s", T)
|
| - return "TODO"
|
| - }
|
| - case *types.Slice, *types.Pointer, *types.Named:
|
| - return "null"
|
| -
|
| - default:
|
| - g.errorf("unsupported javaType: %#+v, %s\n", T, T)
|
| - return "TODO"
|
| - }
|
| -}
|
| -
|
| -var paramRE = regexp.MustCompile(`^p[0-9]+$`)
|
| -
|
| -// paramName replaces incompatible name with a p0-pN name.
|
| -// Missing names, or existing names of the form p[0-9] are incompatible.
|
| -// TODO(crawshaw): Replace invalid unicode names.
|
| -func paramName(params *types.Tuple, pos int) string {
|
| - name := params.At(pos).Name()
|
| - if name == "" || paramRE.MatchString(name) {
|
| - name = fmt.Sprintf("p%d", pos)
|
| - }
|
| - return name
|
| -}
|
| -
|
| -func (g *javaGen) funcSignature(o *types.Func, static bool) error {
|
| - sig := o.Type().(*types.Signature)
|
| - res := sig.Results()
|
| -
|
| - var returnsError bool
|
| - var ret string
|
| - switch res.Len() {
|
| - case 2:
|
| - if !isErrorType(res.At(1).Type()) {
|
| - return fmt.Errorf("second result value must be of type error: %s", o)
|
| - }
|
| - returnsError = true
|
| - ret = g.javaType(res.At(0).Type())
|
| - case 1:
|
| - if isErrorType(res.At(0).Type()) {
|
| - returnsError = true
|
| - ret = "void"
|
| - } else {
|
| - ret = g.javaType(res.At(0).Type())
|
| - }
|
| - case 0:
|
| - ret = "void"
|
| - default:
|
| - return fmt.Errorf("too many result values: %s", o)
|
| - }
|
| -
|
| - g.Printf("public ")
|
| - if static {
|
| - g.Printf("static ")
|
| - }
|
| - g.Printf("%s %s(", ret, o.Name())
|
| - params := sig.Params()
|
| - for i := 0; i < params.Len(); i++ {
|
| - if i > 0 {
|
| - g.Printf(", ")
|
| - }
|
| - v := sig.Params().At(i)
|
| - name := paramName(params, i)
|
| - jt := g.javaType(v.Type())
|
| - g.Printf("%s %s", jt, name)
|
| - }
|
| - g.Printf(")")
|
| - if returnsError {
|
| - g.Printf(" throws Exception")
|
| - }
|
| - return nil
|
| -}
|
| -
|
| -func (g *javaGen) genFunc(o *types.Func, method bool) {
|
| - if err := g.funcSignature(o, !method); err != nil {
|
| - g.errorf("%v", err)
|
| - return
|
| - }
|
| - sig := o.Type().(*types.Signature)
|
| - res := sig.Results()
|
| -
|
| - g.Printf(" {\n")
|
| - g.Indent()
|
| - g.Printf("go.Seq _in = new go.Seq();\n")
|
| - g.Printf("go.Seq _out = new go.Seq();\n")
|
| -
|
| - returnsError := false
|
| - var resultType types.Type
|
| - if res.Len() > 0 {
|
| - if !isErrorType(res.At(0).Type()) {
|
| - resultType = res.At(0).Type()
|
| - }
|
| - if res.Len() > 1 || isErrorType(res.At(0).Type()) {
|
| - returnsError = true
|
| - }
|
| - }
|
| - if resultType != nil {
|
| - t := g.javaType(resultType)
|
| - g.Printf("%s _result;\n", t)
|
| - }
|
| -
|
| - if method {
|
| - g.Printf("_in.writeRef(ref);\n")
|
| - }
|
| - params := sig.Params()
|
| - for i := 0; i < params.Len(); i++ {
|
| - p := params.At(i)
|
| - g.Printf("_in.write%s;\n", seqWrite(p.Type(), p.Name()))
|
| - }
|
| - g.Printf("Seq.send(DESCRIPTOR, CALL_%s, _in, _out);\n", o.Name())
|
| - if resultType != nil {
|
| - g.genRead("_result", "_out", resultType)
|
| - }
|
| - if returnsError {
|
| - g.Printf(`String _err = _out.readUTF16();
|
| -if (_err != null) {
|
| - throw new Exception(_err);
|
| -}
|
| -`)
|
| - }
|
| - if resultType != nil {
|
| - g.Printf("return _result;\n")
|
| - }
|
| - g.Outdent()
|
| - g.Printf("}\n\n")
|
| -}
|
| -
|
| -func (g *javaGen) genRead(resName, seqName string, T types.Type) {
|
| - switch T := T.(type) {
|
| - case *types.Pointer:
|
| - // TODO(crawshaw): test *int
|
| - // 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 package %s", T, g.pkg)
|
| - return
|
| - }
|
| - g.Printf("%s = new %s(%s.readRef());\n", resName, o.Name(), seqName)
|
| - 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 package %s", T, g.pkg)
|
| - return
|
| - }
|
| - g.Printf("%s = new %s.Proxy(%s.readRef());\n", resName, o.Name(), seqName)
|
| - default:
|
| - g.errorf("unsupported, direct named type %s", T)
|
| - }
|
| - default:
|
| - g.Printf("%s = %s.read%s();\n", resName, seqName, seqType(T))
|
| - }
|
| -}
|
| -
|
| -func (g *javaGen) errorf(format string, args ...interface{}) {
|
| - g.err = append(g.err, fmt.Errorf(format, args...))
|
| -}
|
| -
|
| -const javaPreamble = `// Java Package %s is a proxy for talking to a Go program.
|
| -// gobind -lang=java %s
|
| -//
|
| -// File is generated by gobind. Do not edit.
|
| -package go.%s;
|
| -
|
| -import go.Seq;
|
| -
|
| -`
|
| -
|
| -func (g *javaGen) gen() error {
|
| - g.Printf(javaPreamble, g.pkg.Name(), g.pkg.Path(), g.pkg.Name())
|
| -
|
| - firstRune, size := utf8.DecodeRuneInString(g.pkg.Name())
|
| - className := string(unicode.ToUpper(firstRune)) + g.pkg.Name()[size:]
|
| -
|
| - g.Printf("public abstract class %s {\n", className)
|
| - g.Indent()
|
| - g.Printf("private %s() {} // uninstantiable\n\n", className)
|
| - scope := g.pkg.Scope()
|
| - names := scope.Names()
|
| - var funcs []string
|
| - for _, name := range names {
|
| - obj := scope.Lookup(name)
|
| - if !obj.Exported() {
|
| - continue
|
| - }
|
| -
|
| - switch o := obj.(type) {
|
| - // TODO(crawshaw): case *types.Const:
|
| - // TODO(crawshaw): case *types.Var:
|
| - case *types.Func:
|
| - g.genFunc(o, false)
|
| - funcs = append(funcs, o.Name())
|
| - case *types.TypeName:
|
| - named := o.Type().(*types.Named)
|
| - switch t := named.Underlying().(type) {
|
| - case *types.Struct:
|
| - g.genStruct(o, t)
|
| - case *types.Interface:
|
| - g.genInterface(o)
|
| - default:
|
| - g.errorf("%s: cannot generate binding for %s: %T", g.fset.Position(o.Pos()), o.Name(), t)
|
| - continue
|
| - }
|
| - default:
|
| - g.errorf("unsupported exported type: ", obj)
|
| - }
|
| - }
|
| -
|
| - for i, name := range funcs {
|
| - g.Printf("private static final int CALL_%s = %d;\n", name, i+1)
|
| - }
|
| -
|
| - g.Printf("private static final String DESCRIPTOR = %q;\n", g.pkg.Name())
|
| - g.Outdent()
|
| - g.Printf("}\n")
|
| -
|
| - if len(g.err) > 0 {
|
| - return g.err
|
| - }
|
| - return nil
|
| -}
|
|
|