forked from v2pro/plz.codegen
/
func_signature.go
112 lines (106 loc) · 2.65 KB
/
func_signature.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
102
103
104
105
106
107
108
109
110
111
112
package generic
import (
"strings"
"fmt"
"bytes"
"reflect"
)
func parseSignature(input string) (*funcSignature, error) {
leftBrace := strings.IndexByte(input, '(')
if leftBrace == -1 {
return nil, fmt.Errorf("( not found in " + input)
}
funcName := strings.TrimSpace(input[:leftBrace])
rightBrace := strings.IndexByte(input, ')')
if rightBrace == -1 {
return nil, fmt.Errorf(") not found in " + input)
}
signature := &funcSignature{
funcName: funcName,
}
params := strings.TrimSpace(input[leftBrace+1:rightBrace])
if len(params) > 0 {
for _, param := range strings.Split(params, ",") {
nameAndType := strings.SplitN(strings.TrimSpace(param), " ", 2)
signature.funcParams = append(signature.funcParams, funcParam{
paramName: strings.TrimSpace(nameAndType[0]),
paramType: strings.TrimSpace(nameAndType[1]),
})
}
} else {
signature.funcParams = []funcParam{}
}
returns := strings.TrimFunc(input[rightBrace:], func(r rune) bool {
switch r {
case ' ', '\t', '\r', '\n', '(', ')':
return true
}
return false
})
if len(returns) > 0 {
for _, ret := range strings.Split(returns, ",") {
nameAndType := strings.SplitN(strings.TrimSpace(ret), " ", 2)
if len(nameAndType) == 1 {
nameAndType = []string{"", nameAndType[0]}
}
signature.funcReturns = append(signature.funcReturns, funcReturn{
returnName: strings.TrimSpace(nameAndType[0]),
returnType: strings.TrimSpace(nameAndType[1]),
})
}
} else {
signature.funcReturns = []funcReturn{}
}
return signature, nil
}
type funcSignature struct {
funcName string
funcParams []funcParam
funcReturns []funcReturn
}
type funcParam struct {
paramName string
paramType string
}
type funcReturn struct {
returnName string
returnType string
}
func (signature *funcSignature) expand(out *bytes.Buffer,
expandedFuncName string, argMap map[string]interface{}) {
out.WriteString("\nfunc ")
out.WriteString(expandedFuncName)
out.WriteByte('(')
for i, param := range signature.funcParams {
if i != 0 {
out.WriteByte(',')
}
out.WriteString(param.paramName)
out.WriteByte(' ')
typ, isType := argMap[param.paramType].(reflect.Type)
if isType {
out.WriteString(genName(typ))
} else {
out.WriteString(param.paramType)
}
}
out.WriteByte(')')
if len(signature.funcReturns) > 0 {
out.WriteByte('(')
for i, ret := range signature.funcReturns {
if i != 0 {
out.WriteByte(',')
}
out.WriteString(ret.returnName)
out.WriteByte(' ')
typ, isType := argMap[ret.returnType].(reflect.Type)
if isType {
out.WriteString(genName(typ))
} else {
out.WriteString(ret.returnType)
}
}
out.WriteByte(')')
}
out.WriteByte('{')
}