github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/types/typeutil/ui.go (about) 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 }