diff options
Diffstat (limited to 'vendor/honnef.co/go/tools/go/types/typeutil/ui.go')
-rw-r--r-- | vendor/honnef.co/go/tools/go/types/typeutil/ui.go | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/ui.go b/vendor/honnef.co/go/tools/go/types/typeutil/ui.go new file mode 100644 index 0000000..9849c24 --- /dev/null +++ b/vendor/honnef.co/go/tools/go/types/typeutil/ui.go | |||
@@ -0,0 +1,52 @@ | |||
1 | // Copyright 2014 The Go Authors. All rights reserved. | ||
2 | // Use of this source code is governed by a BSD-style | ||
3 | // license that can be found in the LICENSE file. | ||
4 | |||
5 | package typeutil | ||
6 | |||
7 | // This file defines utilities for user interfaces that display types. | ||
8 | |||
9 | import "go/types" | ||
10 | |||
11 | // IntuitiveMethodSet returns the intuitive method set of a type T, | ||
12 | // which is the set of methods you can call on an addressable value of | ||
13 | // that type. | ||
14 | // | ||
15 | // The result always contains MethodSet(T), and is exactly MethodSet(T) | ||
16 | // for interface types and for pointer-to-concrete types. | ||
17 | // For all other concrete types T, the result additionally | ||
18 | // contains each method belonging to *T if there is no identically | ||
19 | // named method on T itself. | ||
20 | // | ||
21 | // This corresponds to user intuition about method sets; | ||
22 | // this function is intended only for user interfaces. | ||
23 | // | ||
24 | // The order of the result is as for types.MethodSet(T). | ||
25 | // | ||
26 | func IntuitiveMethodSet(T types.Type, msets *MethodSetCache) []*types.Selection { | ||
27 | isPointerToConcrete := func(T types.Type) bool { | ||
28 | ptr, ok := T.(*types.Pointer) | ||
29 | return ok && !types.IsInterface(ptr.Elem()) | ||
30 | } | ||
31 | |||
32 | var result []*types.Selection | ||
33 | mset := msets.MethodSet(T) | ||
34 | if types.IsInterface(T) || isPointerToConcrete(T) { | ||
35 | for i, n := 0, mset.Len(); i < n; i++ { | ||
36 | result = append(result, mset.At(i)) | ||
37 | } | ||
38 | } else { | ||
39 | // T is some other concrete type. | ||
40 | // Report methods of T and *T, preferring those of T. | ||
41 | pmset := msets.MethodSet(types.NewPointer(T)) | ||
42 | for i, n := 0, pmset.Len(); i < n; i++ { | ||
43 | meth := pmset.At(i) | ||
44 | if m := mset.Lookup(meth.Obj().Pkg(), meth.Obj().Name()); m != nil { | ||
45 | meth = m | ||
46 | } | ||
47 | result = append(result, meth) | ||
48 | } | ||
49 | |||
50 | } | ||
51 | return result | ||
52 | } | ||