github.com/cockroachdb/tools@v0.0.0-20230222021103-a6d27438930d/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 func IntuitiveMethodSet(T types.Type, msets *MethodSetCache) []*types.Selection { 26 isPointerToConcrete := func(T types.Type) bool { 27 ptr, ok := T.(*types.Pointer) 28 return ok && !types.IsInterface(ptr.Elem()) 29 } 30 31 var result []*types.Selection 32 mset := msets.MethodSet(T) 33 if types.IsInterface(T) || isPointerToConcrete(T) { 34 for i, n := 0, mset.Len(); i < n; i++ { 35 result = append(result, mset.At(i)) 36 } 37 } else { 38 // T is some other concrete type. 39 // Report methods of T and *T, preferring those of T. 40 pmset := msets.MethodSet(types.NewPointer(T)) 41 for i, n := 0, pmset.Len(); i < n; i++ { 42 meth := pmset.At(i) 43 if m := mset.Lookup(meth.Obj().Pkg(), meth.Obj().Name()); m != nil { 44 meth = m 45 } 46 result = append(result, meth) 47 } 48 49 } 50 return result 51 }