diff --git a/bind/gen.go b/bind/gen.go index 2ad555d..b03277f 100644 --- a/bind/gen.go +++ b/bind/gen.go @@ -234,6 +234,52 @@ func (g *generator) validPkg(pkg *types.Package) bool { return false } +// isSigSupported returns whether the generators can handle a given +// function signature +func (g *generator) isSigSupported(t types.Type) bool { + sig := t.(*types.Signature) + params := sig.Params() + for i := 0; i < params.Len(); i++ { + if !g.isSupported(params.At(i).Type()) { + return false + } + } + res := sig.Results() + for i := 0; i < res.Len(); i++ { + if !g.isSupported(res.At(i).Type()) { + return false + } + } + return true +} + +// isSupported returns whether the generators can handle the type. +func (g *generator) isSupported(t types.Type) bool { + if isErrorType(t) { + return true + } + switch t := t.(type) { + case *types.Basic: + return true + case *types.Slice: + switch e := t.Elem().(type) { + case *types.Basic: + return e.Kind() == types.Uint8 + } + case *types.Pointer: + switch t := t.Elem().(type) { + case *types.Named: + return g.validPkg(t.Obj().Pkg()) + } + case *types.Named: + switch t.Underlying().(type) { + case *types.Interface, *types.Pointer: + return g.validPkg(t.Obj().Pkg()) + } + } + 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 6fb839b..654d5c1 100644 --- a/bind/gengo.go +++ b/bind/gengo.go @@ -180,7 +180,7 @@ func (g *goGen) genFuncSignature(o *types.Func, objName string) { } func (g *goGen) genFunc(o *types.Func) { - if !isSigSupported(o.Type()) { + if !g.isSigSupported(o.Type()) { g.Printf("// skipped function %s with unsupported parameter or result types\n", o.Name()) return } @@ -196,7 +196,7 @@ func (g *goGen) genStruct(obj *types.TypeName, T *types.Struct) { methods := exportedMethodSet(types.NewPointer(obj.Type())) for _, f := range fields { - if t := f.Type(); !isSupported(t) { + if t := f.Type(); !g.isSupported(t) { g.Printf("// skipped field %s.%s with unsupported type: %T\n\n", obj.Name(), f.Name(), t) continue } @@ -221,7 +221,7 @@ func (g *goGen) genStruct(obj *types.TypeName, T *types.Struct) { } for _, m := range methods { - if !isSigSupported(m.Type()) { + if !g.isSigSupported(m.Type()) { g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name()) continue } @@ -236,7 +236,7 @@ func (g *goGen) genStruct(obj *types.TypeName, T *types.Struct) { } func (g *goGen) genVar(o *types.Var) { - if t := o.Type(); !isSupported(t) { + if t := o.Type(); !g.isSupported(t) { g.Printf("// skipped variable %s with unsupported type %T\n\n", o.Name(), t) return } @@ -273,7 +273,7 @@ func (g *goGen) genInterface(obj *types.TypeName) { // Define the entry points. for _, m := range summary.callable { - if !isSigSupported(m.Type()) { + if !g.isSigSupported(m.Type()) { g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name()) continue } @@ -298,7 +298,7 @@ func (g *goGen) genInterface(obj *types.TypeName) { g.Printf("func (p *proxy%s_%s) Bind_proxy_refnum__() int32 { return p.Bind_Num }\n\n", g.pkgPrefix, obj.Name()) for _, m := range summary.callable { - if !isSigSupported(m.Type()) { + if !g.isSigSupported(m.Type()) { g.Printf("// skipped method %s.%s with unsupported parameter or result types\n", obj.Name(), m.Name()) continue } diff --git a/bind/genjava.go b/bind/genjava.go index 2d9c032..d2af44a 100644 --- a/bind/genjava.go +++ b/bind/genjava.go @@ -44,7 +44,7 @@ func (g *javaGen) genStruct(obj *types.TypeName, T *types.Struct) { g.Printf("public final go.Seq.Ref ref() { return ref; }\n\n") for _, f := range fields { - if t := f.Type(); !isSupported(t) { + if t := f.Type(); !g.isSupported(t) { g.Printf("// skipped field %s.%s with unsupported type: %T\n\n", f.Name(), t) continue } @@ -54,7 +54,7 @@ func (g *javaGen) genStruct(obj *types.TypeName, T *types.Struct) { var isStringer bool for _, m := range methods { - if !isSigSupported(m.Type()) { + if !g.isSigSupported(m.Type()) { g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name()) continue } @@ -69,7 +69,7 @@ func (g *javaGen) genStruct(obj *types.TypeName, T *types.Struct) { 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 { - if t := f.Type(); !isSupported(t) { + if t := f.Type(); !g.isSupported(t) { g.Printf("// skipped field %s.%s with unsupported type: %T\n\n", f.Name(), t) continue } @@ -94,7 +94,7 @@ func (g *javaGen) genStruct(obj *types.TypeName, T *types.Struct) { g.Printf(" return java.util.Arrays.hashCode(new Object[] {") idx := 0 for _, f := range fields { - if t := f.Type(); !isSupported(t) { + if t := f.Type(); !g.isSupported(t) { continue } if idx > 0 { @@ -115,7 +115,7 @@ func (g *javaGen) genStruct(obj *types.TypeName, T *types.Struct) { g.Printf(`b.append("%s").append("{");`, obj.Name()) g.Printf("\n") for _, f := range fields { - if t := f.Type(); !isSupported(t) { + if t := f.Type(); !g.isSupported(t) { continue } n := f.Name() @@ -150,7 +150,7 @@ func (g *javaGen) genInterface(iface interfaceInfo) { methodSigErr := false for _, m := range iface.summary.callable { - if !isSigSupported(m.Type()) { + 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 } @@ -168,7 +168,7 @@ func (g *javaGen) genInterface(iface interfaceInfo) { g.Indent() for _, m := range iface.summary.callable { - if !isSigSupported(m.Type()) { + 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 } @@ -425,7 +425,7 @@ func (g *javaGen) genFuncSignature(o *types.Func, static, header bool) { } func (g *javaGen) genVar(o *types.Var) { - if t := o.Type(); !isSupported(t) { + if t := o.Type(); !g.isSupported(t) { g.Printf("// skipped variable %s with unsupported type: %T\n\n", o.Name(), t) return } @@ -615,7 +615,7 @@ func (g *javaGen) genConst(o *types.Const) { } func (g *javaGen) genJNIField(o *types.TypeName, f *types.Var) { - if t := f.Type(); !isSupported(t) { + if t := f.Type(); !g.isSupported(t) { g.Printf("// skipped field %s with unsupported type: %T\n\n", o.Name(), t) return } @@ -644,7 +644,7 @@ func (g *javaGen) genJNIField(o *types.TypeName, f *types.Var) { } func (g *javaGen) genJNIVar(o *types.Var) { - if t := o.Type(); !isSupported(t) { + if t := o.Type(); !g.isSupported(t) { g.Printf("// skipped variable %s with unsupported type: %T\n\n", o.Name(), t) return } @@ -671,7 +671,7 @@ func (g *javaGen) genJNIVar(o *types.Var) { } func (g *javaGen) genJNIFunc(o *types.Func, sName string, proxy bool) { - if !isSigSupported(o.Type()) { + if !g.isSigSupported(o.Type()) { n := o.Name() if sName != "" { n = sName + "." + n @@ -760,7 +760,7 @@ func (g *javaGen) genRelease(varName string, t types.Type, mode varMode) { } func (g *javaGen) genMethodInterfaceProxy(oName string, m *types.Func) { - if !isSigSupported(m.Type()) { + if !g.isSigSupported(m.Type()) { g.Printf("// skipped method %s with unsupported parameter or return types\n\n", oName) return } @@ -827,7 +827,7 @@ func (g *javaGen) genH() error { g.Printf("extern jmethodID proxy_class_%s_%s_cons;\n", g.pkgPrefix, iface.obj.Name()) g.Printf("\n") for _, m := range iface.summary.callable { - if !isSigSupported(m.Type()) { + 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 } @@ -953,7 +953,7 @@ func (g *javaGen) genC() error { 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 _, m := range iface.summary.callable { - if !isSigSupported(m.Type()) { + 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 } @@ -980,7 +980,7 @@ func (g *javaGen) genC() error { 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.jniClassSigType(iface.obj)) for _, m := range iface.summary.callable { - if !isSigSupported(m.Type()) { + 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 } @@ -1066,7 +1066,7 @@ func (g *javaGen) genJava() error { g.genVar(v) } for _, f := range g.funcs { - if !isSigSupported(f.Type()) { + if !g.isSigSupported(f.Type()) { g.Printf("// skipped function %s with unsupported parameter or return types\n\n", f.Name()) continue } diff --git a/bind/genobjc.go b/bind/genobjc.go index e556f33..cf726c4 100644 --- a/bind/genobjc.go +++ b/bind/genobjc.go @@ -66,7 +66,7 @@ func (g *objcGen) genGoH() error { continue } for _, m := range i.summary.callable { - if !isSigSupported(m.Type()) { + if !g.isSigSupported(m.Type()) { g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", i.obj.Name(), m.Name()) continue } @@ -143,7 +143,7 @@ func (g *objcGen) genH() error { if len(g.vars) > 0 { g.Printf("@interface %s : NSObject\n", g.namePrefix) for _, obj := range g.vars { - if t := obj.Type(); !isSupported(t) { + if t := obj.Type(); !g.isSupported(t) { g.Printf("// skipped variable %s with unsupported type: %T\n\n", obj.Name(), t) continue } @@ -235,7 +235,7 @@ func (g *objcGen) genM() error { g.Printf("\n") for _, obj := range g.funcs { - if !isSigSupported(obj.Type()) { + if !g.isSigSupported(obj.Type()) { g.Printf("// skipped function %s with unsupported parameter or return types\n\n", obj.Name()) continue } @@ -245,7 +245,7 @@ func (g *objcGen) genM() error { for _, i := range g.interfaces { for _, m := range i.summary.callable { - if !isSigSupported(m.Type()) { + if !g.isSigSupported(m.Type()) { g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", i.obj.Name(), m.Name()) continue } @@ -267,7 +267,7 @@ func (g *objcGen) genM() error { } func (g *objcGen) genVarM(o *types.Var) { - if t := o.Type(); !isSupported(t) { + if t := o.Type(); !g.isSupported(t) { g.Printf("// skipped variable %s with unsupported type: %T\n\n", o.Name(), t) return } @@ -477,7 +477,7 @@ func (s *funcSummary) returnsVal() bool { } func (g *objcGen) genFuncH(obj *types.Func) { - if !isSigSupported(obj.Type()) { + if !g.isSigSupported(obj.Type()) { g.Printf("// skipped function %s with unsupported parameter or return types\n\n", obj.Name()) return } @@ -712,7 +712,7 @@ func (g *objcGen) genInterfaceInterface(obj *types.TypeName, summary ifaceSummar g.Printf("\n") g.Printf("- (id)initWithRef:(id)ref;\n") for _, m := range summary.callable { - if !isSigSupported(m.Type()) { + if !g.isSigSupported(m.Type()) { g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name()) return } @@ -730,7 +730,7 @@ func (g *objcGen) genInterfaceH(obj *types.TypeName, t *types.Interface) { } g.Printf("@protocol %s%s\n", g.namePrefix, obj.Name()) for _, m := range makeIfaceSummary(t).callable { - if !isSigSupported(m.Type()) { + if !g.isSigSupported(m.Type()) { g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name()) continue } @@ -757,7 +757,7 @@ func (g *objcGen) genInterfaceM(obj *types.TypeName, t *types.Interface) bool { g.Printf("\n") for _, m := range summary.callable { - if !isSigSupported(m.Type()) { + if !g.isSigSupported(m.Type()) { g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name()) continue } @@ -883,7 +883,7 @@ func (g *objcGen) genStructH(obj *types.TypeName, t *types.Struct) { // accessors to exported fields. for _, f := range exportedFields(t) { - if t := f.Type(); !isSupported(t) { + if t := f.Type(); !g.isSupported(t) { g.Printf("// skipped field %s.%s with unsupported type: %T\n\n", obj.Name(), f.Name(), t) continue } @@ -894,7 +894,7 @@ func (g *objcGen) genStructH(obj *types.TypeName, t *types.Struct) { // exported methods for _, m := range exportedMethodSet(types.NewPointer(obj.Type())) { - if !isSigSupported(m.Type()) { + if !g.isSigSupported(m.Type()) { g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name()) continue } @@ -920,7 +920,7 @@ func (g *objcGen) genStructM(obj *types.TypeName, t *types.Struct) { g.Printf("}\n\n") for _, f := range fields { - if !isSupported(f.Type()) { + if !g.isSupported(f.Type()) { g.Printf("// skipped unsupported field %s with type %T\n\n", f.Name(), f) continue } @@ -929,7 +929,7 @@ func (g *objcGen) genStructM(obj *types.TypeName, t *types.Struct) { } for _, m := range methods { - if !isSigSupported(m.Type()) { + if !g.isSigSupported(m.Type()) { g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name()) continue } diff --git a/bind/testpkg/testpkg.go b/bind/testpkg/testpkg.go index 97dd20e..b9ab811 100644 --- a/bind/testpkg/testpkg.go +++ b/bind/testpkg/testpkg.go @@ -23,6 +23,7 @@ import ( "golang.org/x/mobile/bind/testpkg/secondpkg" "golang.org/x/mobile/bind/testpkg/simplepkg" + "golang.org/x/mobile/bind/testpkg/unboundpkg" ) const ( @@ -469,3 +470,9 @@ func CallImportedI(i secondpkg.I) { func NewSimpleS() *simplepkg.S { return nil } + +func UnboundS(_ *unboundpkg.S) { +} + +func UnboundI(_ unboundpkg.I) { +} diff --git a/bind/testpkg/unboundpkg/unboundpkg.go b/bind/testpkg/unboundpkg/unboundpkg.go new file mode 100644 index 0000000..985b2cb --- /dev/null +++ b/bind/testpkg/unboundpkg/unboundpkg.go @@ -0,0 +1,12 @@ +// 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 +// that references to other, unbound packages, are ignored. +package unboundpkg + +type ( + S struct{} + I interface{} +) diff --git a/bind/types.go b/bind/types.go index 5697dbd..2f368dd 100644 --- a/bind/types.go +++ b/bind/types.go @@ -101,52 +101,6 @@ func isErrorType(t types.Type) bool { return types.Identical(t, types.Universe.Lookup("error").Type()) } -// isSigSupported returns whether the generators can handle a given -// function signature -func isSigSupported(t types.Type) bool { - sig := t.(*types.Signature) - params := sig.Params() - for i := 0; i < params.Len(); i++ { - if !isSupported(params.At(i).Type()) { - return false - } - } - res := sig.Results() - for i := 0; i < res.Len(); i++ { - if !isSupported(res.At(i).Type()) { - return false - } - } - return true -} - -// isSupported returns whether the generators can handle the type. -func isSupported(t types.Type) bool { - if isErrorType(t) { - return true - } - switch t := t.(type) { - case *types.Basic: - return true - case *types.Slice: - switch e := t.Elem().(type) { - case *types.Basic: - return e.Kind() == types.Uint8 - } - case *types.Pointer: - switch t.Elem().(type) { - case *types.Named: - return true - } - case *types.Named: - switch t.Underlying().(type) { - case *types.Interface, *types.Pointer: - return true - } - } - return false -} - func isExported(t types.Type) bool { if isErrorType(t) { return true