-
Notifications
You must be signed in to change notification settings - Fork 3
/
interface.go
103 lines (87 loc) · 2.11 KB
/
interface.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
package humanize
import "go/ast"
// InterfaceType is the interface in go code
type InterfaceType struct {
pkg *Package
Functions []*Function
Embeds []Type // IdentType or SelectorType
}
func (i *InterfaceType) String() string {
if len(i.Embeds) == 0 && len(i.Functions) == 0 {
return "interface{}"
}
res := "interface{\n"
for e := range i.Embeds {
res += "\t" + i.Embeds[e].String() + "\n"
}
for f := range i.Functions {
res += "\t" + i.Functions[f].Type.getDefinitionWithName(i.Functions[f].Name) + "\n"
}
return res + "}"
}
// Equal if both interfaces are equal
func (i *InterfaceType) Equal(t Type) bool {
v, ok := t.(*InterfaceType)
if !ok {
return false
}
if !i.pkg.Equal(v.pkg) {
return false
}
embedLoop:
for e := range i.Embeds {
for ee := range v.Embeds {
if i.Embeds[e].Equal(v.Embeds[ee]) {
continue embedLoop
}
}
return false
}
methodLoop:
for e := range i.Functions {
for ee := range v.Functions {
if i.Functions[e].Equal(v.Functions[ee]) {
continue methodLoop
}
}
return false
}
return true
}
// Package get the interface package
func (i *InterfaceType) Package() *Package {
return i.pkg
}
func (i *InterfaceType) lateBind() error {
for f := range i.Functions {
if err := i.Functions[f].lateBind(); err != nil {
return err
}
}
for f := range i.Embeds {
if err := lateBind(i.Embeds[f]); err != nil {
return err
}
}
return nil
}
func getInterface(p *Package, f *File, t *ast.InterfaceType) Type {
// TODO : interface may refer to itself I need more time to implement this
iface := &InterfaceType{}
for i := range t.Methods.List {
res := Function{}
// The method name is mandatory and always 1
if len(t.Methods.List[i].Names) > 0 {
res.Name = nameFromIdent(t.Methods.List[i].Names[0])
res.Docs = docsFromNodeDoc(t.Methods.List[i].Doc)
typ := newType(p, f, t.Methods.List[i].Type)
res.Type = typ.(*FuncType)
iface.Functions = append(iface.Functions, &res)
} else {
// This is the embedded interface
embed := newType(p, f, t.Methods.List[i].Type)
iface.Embeds = append(iface.Embeds, embed)
}
}
return iface
}