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
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/honnef.co/go/tools@v0.0.1-2020.1.5/unused/implements.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/honnef.co/go/tools@v0.0.1-2020.1.5/unused/implements.go
new file mode 100644 (file)
index 0000000..835baac
--- /dev/null
@@ -0,0 +1,82 @@
+package unused
+
+import "go/types"
+
+// lookupMethod returns the index of and method with matching package and name, or (-1, nil).
+func lookupMethod(T *types.Interface, pkg *types.Package, name string) (int, *types.Func) {
+       if name != "_" {
+               for i := 0; i < T.NumMethods(); i++ {
+                       m := T.Method(i)
+                       if sameId(m, pkg, name) {
+                               return i, m
+                       }
+               }
+       }
+       return -1, nil
+}
+
+func sameId(obj types.Object, pkg *types.Package, name string) bool {
+       // spec:
+       // "Two identifiers are different if they are spelled differently,
+       // or if they appear in different packages and are not exported.
+       // Otherwise, they are the same."
+       if name != obj.Name() {
+               return false
+       }
+       // obj.Name == name
+       if obj.Exported() {
+               return true
+       }
+       // not exported, so packages must be the same (pkg == nil for
+       // fields in Universe scope; this can only happen for types
+       // introduced via Eval)
+       if pkg == nil || obj.Pkg() == nil {
+               return pkg == obj.Pkg()
+       }
+       // pkg != nil && obj.pkg != nil
+       return pkg.Path() == obj.Pkg().Path()
+}
+
+func (g *Graph) implements(V types.Type, T *types.Interface, msV *types.MethodSet) ([]*types.Selection, bool) {
+       // fast path for common case
+       if T.Empty() {
+               return nil, true
+       }
+
+       if ityp, _ := V.Underlying().(*types.Interface); ityp != nil {
+               // TODO(dh): is this code reachable?
+               for i := 0; i < T.NumMethods(); i++ {
+                       m := T.Method(i)
+                       _, obj := lookupMethod(ityp, m.Pkg(), m.Name())
+                       switch {
+                       case obj == nil:
+                               return nil, false
+                       case !types.Identical(obj.Type(), m.Type()):
+                               return nil, false
+                       }
+               }
+               return nil, true
+       }
+
+       // A concrete type implements T if it implements all methods of T.
+       var sels []*types.Selection
+       for i := 0; i < T.NumMethods(); i++ {
+               m := T.Method(i)
+               sel := msV.Lookup(m.Pkg(), m.Name())
+               if sel == nil {
+                       return nil, false
+               }
+
+               f, _ := sel.Obj().(*types.Func)
+               if f == nil {
+                       return nil, false
+               }
+
+               if !types.Identical(f.Type(), m.Type()) {
+                       return nil, false
+               }
+
+               sels = append(sels, sel)
+       }
+       return sels, true
+}