| 93 | } |
| 94 | |
| 95 | func getSelectionsWithReceiverType(p *loader.Program, targetType types.Type) map[token.Pos]selection { |
| 96 | selections := map[token.Pos]selection{} |
| 97 | |
| 98 | for _, z := range p.AllPackages { |
| 99 | for i, t := range z.Selections { |
| 100 | switch o := t.Obj().(type) { |
| 101 | case *types.Func: |
| 102 | // this is not a bug, o.Type() is always *types.Signature, see docs |
| 103 | if vt := o.Type().(*types.Signature).Recv(); vt != nil { |
| 104 | typ := vt.Type() |
| 105 | if pointer, ok := typ.(*types.Pointer); ok { |
| 106 | typ = pointer.Elem() |
| 107 | } |
| 108 | |
| 109 | if typ == targetType { |
| 110 | if s, ok := selections[i.Pos()]; !ok || i.End() > s.End() { |
| 111 | selections[i.Pos()] = selection{i, o, z.Pkg} |
| 112 | } |
| 113 | } |
| 114 | } |
| 115 | default: |
| 116 | // skip |
| 117 | } |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | return selections |
| 122 | } |
| 123 | |
| 124 | func hasBadFinisher(p *loader.Program, s selection) bool { |
| 125 | pkgPath := strings.TrimPrefix(s.pkg.Path(), rootPkg+"/vendor/") |