This repository has been archived by the owner on Jul 7, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
func.go
129 lines (106 loc) · 2.54 KB
/
func.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package humanize
import (
"go/ast"
"strings"
)
// Function is annotation data for a single function
type Function struct {
Name string
Receiver *Variable // Nil means normal function
Docs Docs
Type *FuncType
}
func compareVariable(one, two []*Variable) bool {
if len(one) != len(two) {
return false
}
for i := range one {
if one[i].Type.GetDefinition() != two[i].Type.GetDefinition() {
return false
}
}
return true
}
func removeReceiver(fn string) string {
split := strings.Split(fn, ".")
if len(split) == 2 {
return split[1]
}
return fn
}
func compareFunc(one, two *Function) bool {
// the receiver is not important, since we want to check interface match
if removeReceiver(one.Name) != removeReceiver(two.Name) {
return false
}
if !compareVariable(one.Type.Parameters, two.Type.Parameters) {
return false
}
if !compareVariable(one.Type.Results, two.Type.Results) {
return false
}
return true
}
func compare(one, two []*Function) bool {
bigLoop:
for i := range one {
for j := range two {
if compareFunc(one[i], two[j]) {
continue bigLoop
}
}
return false
}
return true
}
func extractVariableList(f *ast.FieldList, src string, fl *File, p *Package) []*Variable {
var res []*Variable
if f == nil {
return res
}
for i := range f.List {
n := f.List[i].Names
if n != nil {
for in := range n {
p := variableFromExpr(nameFromIdent(n[in]), f.List[i].Type, src, fl, p)
res = append(res, p)
}
} else {
// Its probably without name part (ie return variable)
p := variableFromExpr("", f.List[i].Type, src, fl, p)
res = append(res, p)
}
}
return res
}
// NewFunction return a single function annotation
func NewFunction(f *ast.FuncDecl, src string, fl *File, p *Package) *Function {
res := &Function{}
res.Name = nameFromIdent(f.Name)
res.Docs = docsFromNodeDoc(f.Doc)
if f.Recv != nil {
// Method receiver is only one parameter
for i := range f.Recv.List {
n := ""
if f.Recv.List[i].Names != nil {
n = nameFromIdent(f.Recv.List[i].Names[0])
}
p := variableFromExpr(n, f.Recv.List[i].Type, src, fl, p)
res.Receiver = p
}
}
// Change the name of the function to receiver.func
if res.Receiver != nil {
tmp := res.Receiver.Type
if _, ok := tmp.(*StarType); ok {
tmp = tmp.(*StarType).Target
}
res.Name = tmp.(*IdentType).Ident + "." + res.Name
}
res.Type = &FuncType{
srcBase: srcBase{p, ""},
Parameters: extractVariableList(f.Type.Params, src, fl, p),
Results: extractVariableList(f.Type.Results, src, fl, p),
}
return res
}