gopy/bind/vars.go

169 lines
3.2 KiB
Go
Raw Normal View History

2015-07-24 14:16:31 +00:00
// Copyright 2015 The go-python 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 (
"fmt"
"golang.org/x/tools/go/types"
)
type Var struct {
2015-07-28 14:00:18 +00:00
pkg *Package
id string
doc string
name string
2015-07-29 09:44:06 +00:00
typ types.Type
2015-07-24 14:16:31 +00:00
dtype typedesc
}
2015-07-28 14:00:18 +00:00
func (v *Var) Name() string {
return v.name
}
2015-07-29 09:44:06 +00:00
func newVar(p *Package, typ types.Type, objname, name, doc string) *Var {
2015-07-28 14:00:18 +00:00
return &Var{
pkg: p,
2015-07-29 09:44:06 +00:00
id: p.Name() + "_" + objname,
2015-07-28 14:00:18 +00:00
doc: doc,
name: name,
2015-07-29 09:44:06 +00:00
typ: typ,
dtype: getTypedesc(typ),
2015-07-28 14:00:18 +00:00
}
}
func newVarsFrom(p *Package, tuple *types.Tuple) []*Var {
2015-07-24 14:16:31 +00:00
vars := make([]*Var, 0, tuple.Len())
for i := 0; i < tuple.Len(); i++ {
2015-07-28 14:00:18 +00:00
vars = append(vars, newVarFrom(p, tuple.At(i)))
2015-07-24 14:16:31 +00:00
}
return vars
}
2015-07-28 14:00:18 +00:00
func newVarFrom(p *Package, v *types.Var) *Var {
2015-07-29 09:44:06 +00:00
return newVar(p, v.Type(), v.Name(), v.Name(), p.getDoc("", v))
2015-07-24 14:16:31 +00:00
}
func getTypedesc(t types.Type) typedesc {
switch typ := t.(type) {
case *types.Basic:
dtype, ok := typedescr[typ.Kind()]
if ok {
return dtype
}
case *types.Named:
switch typ.Underlying().(type) {
case *types.Struct:
2015-07-28 08:05:13 +00:00
obj := typ.Obj()
pkgname := obj.Pkg().Name()
id := pkgname + "_" + obj.Name()
2015-07-24 14:16:31 +00:00
return typedesc{
2015-07-28 08:05:13 +00:00
ctype: "GoPy_" + id,
cgotype: "GoPy_" + id,
2015-07-24 14:16:31 +00:00
pyfmt: "N",
}
2015-07-29 12:15:11 +00:00
case *types.Interface:
return typedesc{
ctype: "GoInterface",
cgotype: "GoInterface",
pyfmt: "?",
}
default:
panic(fmt.Errorf("unhandled type: %#v", typ))
2015-07-24 14:16:31 +00:00
}
case *types.Pointer:
elem := typ.Elem()
return getTypedesc(elem)
case *types.Signature:
return typedesc{
ctype: "GoFunction",
cgotype: "GoFunction",
pyfmt: "?",
}
case *types.Slice:
return typedesc{
ctype: "GoSlice",
cgotype: "GoSlice",
pyfmt: "?",
}
2015-07-24 14:16:31 +00:00
default:
panic(fmt.Errorf("unhandled type: %#v\n", typ))
}
return typedesc{}
}
func (v *Var) GoType() types.Type {
2015-07-29 09:44:06 +00:00
return v.typ
2015-07-24 14:16:31 +00:00
}
func (v *Var) CType() string {
return v.dtype.ctype
}
func (v *Var) CGoType() string {
return v.dtype.cgotype
}
func (v *Var) PyCode() string {
return v.dtype.pyfmt
}
func (v *Var) isGoString() bool {
switch typ := v.GoType().(type) {
case *types.Basic:
return typ.Kind() == types.String
}
return false
}
func (v *Var) genDecl(g *printer) {
if v.isGoString() {
2015-07-28 14:00:18 +00:00
g.Printf("const char* cgopy_%s;\n", v.Name())
2015-07-24 14:16:31 +00:00
}
2015-07-28 14:00:18 +00:00
g.Printf("%[1]s c_%[2]s;\n", v.CGoType(), v.Name())
2015-07-24 14:16:31 +00:00
}
2015-07-28 08:04:36 +00:00
func (v *Var) genRecvDecl(g *printer) {
2015-07-28 14:00:18 +00:00
g.Printf("%[1]s c_%[2]s;\n", v.CGoType(), v.Name())
2015-07-28 08:04:36 +00:00
}
func (v *Var) genRecvImpl(g *printer) {
n := string(v.CGoType()[len("GoPy_"):])
2015-07-28 14:00:18 +00:00
g.Printf("c_%[1]s = ((_gopy_%[2]s*)self)->cgopy;\n", v.Name(), n)
2015-07-28 08:04:36 +00:00
}
2015-07-24 14:16:31 +00:00
func (v *Var) genRetDecl(g *printer) {
if v.isGoString() {
g.Printf("const char* cgopy_gopy_ret;\n")
}
g.Printf("%[1]s c_gopy_ret;\n", v.CGoType())
}
func (v *Var) getArgParse() (string, string) {
2015-07-28 14:00:18 +00:00
addr := "&c_" + v.Name()
2015-07-24 14:16:31 +00:00
if v.isGoString() {
2015-07-28 14:00:18 +00:00
addr = "&cgopy_" + v.Name()
2015-07-24 14:16:31 +00:00
}
return v.dtype.pyfmt, addr
}
func (v *Var) genFuncPreamble(g *printer) {
if v.isGoString() {
2015-07-28 14:00:18 +00:00
g.Printf("c_%[1]s = CGoPy_GoString((char*)cgopy_%[1]s);\n", v.Name())
2015-07-24 14:16:31 +00:00
}
}
func (v *Var) getFuncArg() string {
2015-07-28 14:00:18 +00:00
return "c_" + v.Name()
2015-07-24 14:16:31 +00:00
}
func (v *Var) needWrap() bool {
typ := v.GoType()
return needWrapType(typ)
}