Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / honnef.co / go / tools@v0.0.1-2020.1.5 / unused / implements.go
1 package unused
2
3 import "go/types"
4
5 // lookupMethod returns the index of and method with matching package and name, or (-1, nil).
6 func lookupMethod(T *types.Interface, pkg *types.Package, name string) (int, *types.Func) {
7         if name != "_" {
8                 for i := 0; i < T.NumMethods(); i++ {
9                         m := T.Method(i)
10                         if sameId(m, pkg, name) {
11                                 return i, m
12                         }
13                 }
14         }
15         return -1, nil
16 }
17
18 func sameId(obj types.Object, pkg *types.Package, name string) bool {
19         // spec:
20         // "Two identifiers are different if they are spelled differently,
21         // or if they appear in different packages and are not exported.
22         // Otherwise, they are the same."
23         if name != obj.Name() {
24                 return false
25         }
26         // obj.Name == name
27         if obj.Exported() {
28                 return true
29         }
30         // not exported, so packages must be the same (pkg == nil for
31         // fields in Universe scope; this can only happen for types
32         // introduced via Eval)
33         if pkg == nil || obj.Pkg() == nil {
34                 return pkg == obj.Pkg()
35         }
36         // pkg != nil && obj.pkg != nil
37         return pkg.Path() == obj.Pkg().Path()
38 }
39
40 func (g *Graph) implements(V types.Type, T *types.Interface, msV *types.MethodSet) ([]*types.Selection, bool) {
41         // fast path for common case
42         if T.Empty() {
43                 return nil, true
44         }
45
46         if ityp, _ := V.Underlying().(*types.Interface); ityp != nil {
47                 // TODO(dh): is this code reachable?
48                 for i := 0; i < T.NumMethods(); i++ {
49                         m := T.Method(i)
50                         _, obj := lookupMethod(ityp, m.Pkg(), m.Name())
51                         switch {
52                         case obj == nil:
53                                 return nil, false
54                         case !types.Identical(obj.Type(), m.Type()):
55                                 return nil, false
56                         }
57                 }
58                 return nil, true
59         }
60
61         // A concrete type implements T if it implements all methods of T.
62         var sels []*types.Selection
63         for i := 0; i < T.NumMethods(); i++ {
64                 m := T.Method(i)
65                 sel := msV.Lookup(m.Pkg(), m.Name())
66                 if sel == nil {
67                         return nil, false
68                 }
69
70                 f, _ := sel.Obj().(*types.Func)
71                 if f == nil {
72                         return nil, false
73                 }
74
75                 if !types.Identical(f.Type(), m.Type()) {
76                         return nil, false
77                 }
78
79                 sels = append(sels, sel)
80         }
81         return sels, true
82 }