/
param.go
101 lines (88 loc) · 2.76 KB
/
param.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package python
import (
"fmt"
"github.com/devigned/veil/cgo"
"github.com/devigned/veil/core"
"go/types"
"strconv"
)
const (
STRING_OUTPUT_TRANSFORM = "_CffiHelper.c2py_string(%s)"
STRING_INPUT_TRANSFORM = "%s = _CffiHelper.py2c_string(%s)"
STRUCT_INPUT_TRANSFORM = "%s = _CffiHelper.py2c_veil_object(%s)"
STRUCT_OUTPUT_TRANSFORM = "%s(uuid_ptr=%s, tracked=%s)"
)
type Param struct {
underlying *types.Var
binder *Binder
DefaultName string
}
func (p Param) Name() string {
name := p.DefaultName
if p.underlying.Name() != "" {
name = p.underlying.Name()
}
return core.ToSnake(name)
}
func (p Param) IsError() bool {
return cgo.ImplementsError(p.underlying.Type())
}
func (p Param) ReturnFormatWithName(varName string) string {
return p.ReturnFormatWithNameAndTracked(varName, true)
}
func (p Param) ReturnFormatWithNameAndTracked(varName string, tracked bool) string {
return p.returnFormatWithTypeAndNameAndTracked(p.underlying.Type(), varName, tracked)
}
func (p Param) returnFormatWithTypeAndNameAndTracked(typ types.Type, varName string, tracked bool) string {
trackedBoolStr := core.ToCap(strconv.FormatBool(tracked))
switch t := typ.(type) {
case *types.Basic:
if t.Kind() == types.String {
return fmt.Sprintf(STRING_OUTPUT_TRANSFORM, varName)
}
return varName
case *types.Named:
if cgo.ImplementsError(t) {
return fmt.Sprintf(STRUCT_OUTPUT_TRANSFORM, "VeilError", varName, trackedBoolStr)
} else if _, ok := t.Underlying().(*types.Struct); ok {
class := p.binder.NewClass(cgo.NewStruct(t))
return fmt.Sprintf(STRUCT_OUTPUT_TRANSFORM, class.Name(), varName, trackedBoolStr)
} else {
return varName
}
case *types.Slice:
slice := p.binder.NewList(cgo.NewSlice(t.Elem()))
return fmt.Sprintf(STRUCT_OUTPUT_TRANSFORM, slice.ListTypeName(), varName, trackedBoolStr)
case *types.Pointer:
return p.returnFormatWithTypeAndNameAndTracked(t.Elem(), varName, tracked)
default:
return varName
}
}
func InputFormat(varName string, typ types.Type) string {
switch t := typ.(type) {
case *types.Basic:
if t.Kind() == types.String {
return fmt.Sprintf(STRING_INPUT_TRANSFORM, varName, varName)
}
case *types.Named, *types.Slice, *types.Interface:
return fmt.Sprintf(STRUCT_INPUT_TRANSFORM, varName, varName)
case *types.Pointer:
if _, ok := t.Elem().(*types.Named); ok {
return fmt.Sprintf(STRUCT_INPUT_TRANSFORM, varName, varName)
}
}
return ""
}
func (p Param) ReturnFormatUntracked() string {
return p.ReturnFormatWithNameAndTracked(p.Name(), false)
}
func (p Param) ReturnFormat() string {
return p.ReturnFormatWithName(p.Name())
}
func (p Param) InputFormat() string {
return InputFormat(p.Name(), p.underlying.Type())
}
func (p Param) InputFormatWithName(name string) string {
return InputFormat(name, p.underlying.Type())
}