all: consolidate Func+Method

This commit is contained in:
Sebastien Binet 2015-07-28 11:47:55 +02:00
parent b7b84b89bc
commit f61b769412
3 changed files with 90 additions and 96 deletions

View File

@ -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() {

View File

@ -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()

View File

@ -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)
func (s Struct) Doc() string {
return s.doc
}
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) GoType() types.Type {
return s.typ
}
// Func collects informations about a go func.
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
}