From f61b769412a04a50c6bd96727eb93bb7671335c8 Mon Sep 17 00:00:00 2001 From: Sebastien Binet Date: Tue, 28 Jul 2015 11:47:55 +0200 Subject: [PATCH] all: consolidate Func+Method --- bind/gencpy.go | 51 ++++++++++++----------- bind/gengo.go | 29 ++++++------- bind/package.go | 106 ++++++++++++++++++++++++------------------------ 3 files changed, 90 insertions(+), 96 deletions(-) diff --git a/bind/gencpy.go b/bind/gencpy.go index 4d51d70..e8a4c0a 100644 --- a/bind/gencpy.go +++ b/bind/gencpy.go @@ -59,10 +59,10 @@ func (g *cpyGen) gen() error { g.impl.Printf("static PyMethodDef cpy_%s_methods[] = {\n", g.pkg.pkg.Name()) g.impl.Indent() for _, f := range g.pkg.funcs { - name := f.typ.Name() + name := f.Name() //obj := scope.Lookup(name) g.impl.Printf("{%[1]q, %[2]s, METH_VARARGS, %[3]q},\n", - name, "gopy_"+f.id, f.doc, + name, "gopy_"+f.ID(), f.Doc(), ) } g.impl.Printf("{NULL, NULL, 0, NULL} /* Sentinel */\n") @@ -74,7 +74,10 @@ func (g *cpyGen) gen() error { g.impl.Printf("PyObject *module = NULL;\n\n") for _, s := range g.pkg.structs { - g.impl.Printf("if (PyType_Ready(&_gopy_%sType) < 0) { return; }\n", s.id) + g.impl.Printf( + "if (PyType_Ready(&_gopy_%sType) < 0) { return; }\n", + s.ID(), + ) } g.impl.Printf("module = Py_InitModule3(%[1]q, cpy_%[1]s_methods, %[2]q);\n\n", @@ -83,10 +86,10 @@ func (g *cpyGen) gen() error { ) for _, s := range g.pkg.structs { - g.impl.Printf("Py_INCREF(&_gopy_%sType);\n", s.id) + g.impl.Printf("Py_INCREF(&_gopy_%sType);\n", s.ID()) g.impl.Printf("PyModule_AddObject(module, %q, (PyObject*)&_gopy_%sType);\n\n", - s.obj.Name(), - s.id, + s.Name(), + s.ID(), ) } g.impl.Outdent() @@ -107,12 +110,12 @@ static PyObject* gopy_%[3]s(PyObject *self, PyObject *args) { `, g.pkg.pkg.Name(), - o.typ.Name(), + o.Name(), o.id, ) g.impl.Indent() - g.genFuncBody(o.id, o.typ.Type().(*types.Signature)) + g.genFuncBody(o.ID(), o.Signature()) g.impl.Outdent() g.impl.Printf("}\n\n") } @@ -477,15 +480,14 @@ func (g *cpyGen) genStructMembers(cpy Struct) { func (g *cpyGen) genStructMethods(cpy Struct) { - obj := cpy.obj - pkgname := obj.Pkg().Name() + pkgname := cpy.Obj().Pkg().Name() - g.decl.Printf("/* methods for %s.%s */\n\n", pkgname, obj.Name()) + g.decl.Printf("/* methods for %s.%s */\n\n", pkgname, cpy.Name()) for _, m := range cpy.meths { g.genMethod(cpy, m) } - g.impl.Printf("static PyMethodDef _gopy_%s_methods[] = {\n", cpy.id) + g.impl.Printf("static PyMethodDef _gopy_%s_methods[] = {\n", cpy.ID()) g.impl.Indent() for _, m := range cpy.meths { margs := "METH_VARARGS" @@ -494,10 +496,10 @@ func (g *cpyGen) genStructMethods(cpy Struct) { } g.impl.Printf( "{%[1]q, (PyCFunction)gopy_%[2]s, %[3]s, %[4]q},\n", - m.sel.Obj().Name(), - m.id, + m.Name(), + m.ID(), margs, - m.doc, + m.Doc(), ) /* {"name", (PyCFunction)Noddy_name, METH_NOARGS, @@ -510,32 +512,29 @@ func (g *cpyGen) genStructMethods(cpy Struct) { g.impl.Printf("};\n\n") } -func (g *cpyGen) genMethod(cpy Struct, m Method) { +func (g *cpyGen) genMethod(cpy Struct, fct Func) { pkgname := g.pkg.pkg.Name() - sobj := cpy.obj - mobj := m.sel.Obj() - g.decl.Printf("/* wrapper of %[1]s.%[2]s */\n", pkgname, - sobj.Name()+"."+mobj.Name(), + cpy.Name()+"."+fct.Name(), ) g.decl.Printf("static PyObject*\n") - g.decl.Printf("gopy_%s(PyObject *self, PyObject *args);\n", m.id) + g.decl.Printf("gopy_%s(PyObject *self, PyObject *args);\n", fct.ID()) g.impl.Printf("/* wrapper of %[1]s.%[2]s */\n", pkgname, - sobj.Name()+"."+mobj.Name(), + cpy.Name()+"."+fct.Name(), ) g.impl.Printf("static PyObject*\n") - g.impl.Printf("gopy_%s(PyObject *self, PyObject *args) {\n", m.id) + g.impl.Printf("gopy_%s(PyObject *self, PyObject *args) {\n", fct.ID()) g.impl.Indent() - g.genMethodBody(cpy, m) + g.genMethodBody(cpy, fct) g.impl.Outdent() g.impl.Printf("}\n\n") } -func (g *cpyGen) genMethodBody(cpy Struct, m Method) { - g.genFuncBody(m.id, m.sel.Type().(*types.Signature)) +func (g *cpyGen) genMethodBody(cpy Struct, fct Func) { + g.genFuncBody(fct.ID(), fct.Signature()) } func (g *cpyGen) genPreamble() { diff --git a/bind/gengo.go b/bind/gengo.go index 83e3da7..8fc829e 100644 --- a/bind/gengo.go +++ b/bind/gengo.go @@ -85,8 +85,7 @@ func (g *goGen) gen() error { } func (g *goGen) genFunc(f Func) { - o := f.typ - sig := o.Type().(*types.Signature) + sig := f.Signature() params := "(" + g.tupleString(sig.Params()) + ")" ret := g.tupleString(sig.Results()) @@ -103,7 +102,7 @@ func (g *goGen) genFunc(f Func) { func GoPy_%[1]s%[3]v%[4]v{ `, f.id, - o.FullName(), + f.Obj().Name(), params, ret, ) @@ -115,8 +114,7 @@ func GoPy_%[1]s%[3]v%[4]v{ } func (g *goGen) genFuncBody(f Func) { - o := f.typ - sig := o.Type().(*types.Signature) + sig := f.Signature() results := newVars(sig.Results()) for i := range results { if i > 0 { @@ -128,7 +126,7 @@ func (g *goGen) genFuncBody(f Func) { g.Printf(" := ") } - g.Printf("%s.%s(", g.pkg.Name(), o.Name()) + g.Printf("%s.%s(", g.pkg.Name(), f.Name()) args := sig.Params() for i := 0; i < args.Len(); i++ { @@ -223,9 +221,9 @@ func (g *goGen) genStruct(s Struct) { g.Printf("}\n\n") } -func (g *goGen) genMethod(s Struct, m Method) { - sig := m.sel.Type().(*types.Signature) - params := "(self GoPy_" + s.id +func (g *goGen) genMethod(s Struct, m Func) { + sig := m.Signature() + params := "(self GoPy_" + s.ID() if sig.Params().Len() > 0 { params += ", " + g.tupleString(sig.Params()) } @@ -238,9 +236,9 @@ func (g *goGen) genMethod(s Struct, m Method) { ret += " " } - g.Printf("//export GoPy_%[1]s\n", m.id) + g.Printf("//export GoPy_%[1]s\n", m.ID()) g.Printf("func GoPy_%[1]s%[2]s%[3]s{\n", - m.id, + m.ID(), params, ret, ) @@ -250,9 +248,8 @@ func (g *goGen) genMethod(s Struct, m Method) { g.Printf("}\n\n") } -func (g *goGen) genMethodBody(s Struct, m Method) { - o := m.sel.Obj() - sig := m.sel.Type().(*types.Signature) +func (g *goGen) genMethodBody(s Struct, m Func) { + sig := m.Signature() results := newVars(sig.Results()) for i := range results { if i > 0 { @@ -265,8 +262,8 @@ func (g *goGen) genMethodBody(s Struct, m Method) { } g.Printf("(*%s.%s)(unsafe.Pointer(self)).%s(", - g.pkg.Name(), s.obj.Name(), - o.Name(), + g.pkg.Name(), s.Name(), + m.Name(), ) args := sig.Params() diff --git a/bind/package.go b/bind/package.go index f3eff61..775447d 100644 --- a/bind/package.go +++ b/bind/package.go @@ -157,7 +157,7 @@ func (p *Package) process() error { p.addVar(obj) case *types.Func: - funcs[name], err = newFunc(p, obj) + funcs[name], err = newFunc(p, "", obj, obj) if err != nil { return err } @@ -204,7 +204,7 @@ func (p *Package) process() error { if !meth.Obj().Exported() { continue } - m, err := newMethod(p, &s, meth) + m, err := newFunc(p, sname, meth.Obj(), meth.Obj().(*types.Func)) if err != nil { return err } @@ -238,7 +238,7 @@ type Struct struct { id string doc string ctors []Func - meths []Method + meths []Func } func newStruct(p *Package, obj *types.TypeName, typ *types.Struct) (Struct, error) { @@ -251,58 +251,30 @@ func newStruct(p *Package, obj *types.TypeName, typ *types.Struct) (Struct, erro return s, nil } -// Method collects informations about a go method. -type Method struct { - sel *types.Selection - - id string - doc string - ret types.Type // return type, if any - err bool // true if original go method has comma-error +func (s Struct) ID() string { + return s.id } -func newMethod(p *Package, typ *Struct, sel *types.Selection) (Method, error) { - haserr := false - sig := sel.Type().(*types.Signature) - res := sig.Results() - var ret types.Type - - switch res.Len() { - case 2: - if !isErrorType(res.At(1).Type()) { - return Method{}, fmt.Errorf( - "bind: second result value must be of type error: %s", - sel, - ) - } - haserr = true - ret = res.At(0).Type() - - case 1: - if isErrorType(res.At(0).Type()) { - haserr = true - ret = nil - } else { - ret = res.At(0).Type() - } - case 0: - ret = nil - default: - return Method{}, fmt.Errorf("bind: too many results to return: %v", sel) - } - - return Method{ - sel: sel, - id: typ.obj.Pkg().Name() + "_" + typ.obj.Name() + "_" + sel.Obj().Name(), - doc: p.getDoc(typ.obj.Name(), sel.Obj()), - ret: ret, - err: haserr, - }, nil - +func (s Struct) Doc() string { + return s.doc } -// Func collects informations about a go func. +func (s Struct) GoType() types.Type { + return s.typ +} + +func (s Struct) Obj() types.Object { + return s.obj +} + +func (s Struct) Name() string { + return s.obj.Name() +} + +// Func collects informations about a go func/method. type Func struct { + sig *types.Signature + obj types.Object typ *types.Func id string @@ -311,9 +283,9 @@ type Func struct { err bool // true if original go func has comma-error } -func newFunc(p *Package, obj *types.Func) (Func, error) { +func newFunc(p *Package, parent string, obj types.Object, typ *types.Func) (Func, error) { haserr := false - sig := obj.Type().(*types.Signature) + sig := typ.Type().(*types.Signature) res := sig.Results() var ret types.Type @@ -342,10 +314,36 @@ func newFunc(p *Package, obj *types.Func) (Func, error) { } return Func{ - typ: obj, + sig: sig, + obj: obj, + typ: typ, id: obj.Pkg().Name() + "_" + obj.Name(), - doc: p.getDoc("", obj), + doc: p.getDoc(parent, obj), ret: ret, err: haserr, }, nil } + +func (f Func) ID() string { + return f.id +} + +func (f Func) Doc() string { + return f.doc +} + +func (f Func) GoType() types.Type { + return f.obj.Type() +} + +func (f Func) Obj() types.Object { + return f.obj +} + +func (f Func) Name() string { + return f.obj.Name() +} + +func (f Func) Signature() *types.Signature { + return f.sig +}