/
reflect.go
101 lines (80 loc) · 2.49 KB
/
reflect.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 cli
import (
"fmt"
"reflect"
"strings"
)
func (p *pluginStructure) getVariableSignature(variable reflect.Type, isVariadic bool) string {
if variable.Name() != "" {
if isVariadic {
return fmt.Sprintf("...%s%s", p.getNamedPkgImport(variable.PkgPath()), variable.Name())
}
return fmt.Sprintf("%s%s", p.getNamedPkgImport(variable.PkgPath()), variable.Name())
}
switch variable.Kind() {
case reflect.Func:
return p.getFunctionSignature(variable, false)
case reflect.Array:
return fmt.Sprintf("[%d]%s", variable.Len(), p.getVariableSignature(variable.Elem(), false))
case reflect.Slice:
if isVariadic {
return fmt.Sprintf("...%s", p.getVariableSignature(variable.Elem(), false))
}
return fmt.Sprintf("[]%s", p.getVariableSignature(variable.Elem(), false))
case reflect.Chan:
return fmt.Sprintf("%s %s", variable.ChanDir().String(), p.getVariableSignature(variable.Elem(), false))
case reflect.Map:
return fmt.Sprintf("map[%s]%s", p.getVariableSignature(variable.Key(), false), p.getVariableSignature(variable.Elem(), false))
case reflect.Ptr:
return fmt.Sprintf("*%s", p.getVariableSignature(variable.Elem(), false))
}
return variable.String()
}
func (p *pluginStructure) getNamedPkgImport(pkg string) string {
if pkg == "" {
return ""
}
if pkg == "main" {
pkg = p.Package
}
importName := pkg[strings.LastIndex(pkg, "/")+1:]
nextIndex := 0
for {
var nextImportName string
if nextIndex == 0 {
nextImportName = importName
} else {
nextImportName = fmt.Sprintf("%s_%d", importName, nextIndex)
}
if current, ok := p.importsNames[nextImportName]; ok {
// We already have this package
if current == pkg {
return nextImportName + "."
}
nextIndex++
continue
} else {
p.importsNames[nextImportName] = pkg
return nextImportName + "."
}
}
}
func (p *pluginStructure) getFunctionSignature(fun reflect.Type, namedParams bool) string {
var in []string
var out []string
for i := 0; i < fun.NumIn(); i++ {
if namedParams {
in = append(in, fmt.Sprintf("in%d %s", i, p.getVariableSignature(fun.In(i), fun.IsVariadic() && i == fun.NumIn()-1)))
} else {
in = append(in, p.getVariableSignature(fun.In(i), fun.IsVariadic() && i == fun.NumIn()-1))
}
}
for i := 0; i < fun.NumOut(); i++ {
out = append(out, p.getVariableSignature(fun.Out(i), false))
}
var outParams string
if fun.NumOut() > 0 {
outParams = fmt.Sprintf(" (%s)", strings.Join(out, ", "))
}
return fmt.Sprintf("func(%s)%s", strings.Join(in, ", "), outParams)
}