func (s methodSet) add(list []*Func, index []int, indirect bool, multiples bool) methodSet {
	if len(list) == 0 {
		return s
	}
	if s == nil {
		s = make(methodSet)
	}
	for i, f := range list {
		key := f.Id()
		if !multiples {
			if _, found := s[key]; !found && (indirect || !ptrRecv(f)) {
				s[key] = &Selection{MethodVal, nil, f, concat(index, i), indirect}
				continue
			}
		}
		s[key] = nil  
	}
	return s
}
Add adds all functions in list to the method set s.
If multiples is set, every function in list appears multiple times
and is treated as a collision.
package types
import (
	"bytes"
	"fmt"
	"sort"
	"sync"
)
type MethodSet struct {
	list []*Selection
}
func (s *MethodSet) String() string {
	if s.Len() == 0 {
		return "MethodSet {}"
	}
	var buf bytes.Buffer
	fmt.Fprintln(&buf, "MethodSet {")
	for _, f := range s.list {
		fmt.Fprintf(&buf, "\t%s\n", f)
	}
	fmt.Fprintln(&buf, "}")
	return buf.String()
}
func (s *MethodSet) Len() int { return len(s.list) }
func (s *MethodSet) At(i int) *Selection { return s.list[i] }
func (s *MethodSet) Lookup(pkg *Package, name string) *Selection {
	if s.Len() == 0 {
		return nil
	}
	key := Id(pkg, name)
	i := sort.Search(len(s.list), func(i int) bool {
		m := s.list[i]
		return m.obj.Id() >= key
	})
	if i < len(s.list) {
		m := s.list[i]
		if m.obj.Id() == key {
			return m
		}
	}
	return nil
}
var emptyMethodSet MethodSet
type cachedMethodSet struct {
	mset *MethodSet
	mu   sync.RWMutex  
}
func (c *cachedMethodSet) of(typ Type) *MethodSet {
	c.mu.RLock()
	mset := c.mset
	c.mu.RUnlock()
	if mset == nil {
		mset = NewMethodSet(typ)
		c.mu.Lock()
		c.mset = mset
		c.mu.Unlock()
	}
	return mset
}
func NewMethodSet(T Type) *MethodSet {
	var base methodSet
	typ, isPtr := deref(T)
	named, _ := typ.(*Named)
	if isPtr {
		utyp := typ
		if named != nil {
			utyp = named.underlying
		}
		if _, ok := utyp.(*Interface); ok {
			return &emptyMethodSet
		}
	}
	current := []embeddedType{{named, nil, isPtr, false}}
	var seen map[*Named]bool
	for len(current) > 0 {
		var next []embeddedType  
		var fset fieldSet
		var mset methodSet
		for _, e := range current {
			if e.typ != nil {
				if seen[e.typ] {
					continue
				}
				if seen == nil {
					seen = make(map[*Named]bool)
				}
				seen[e.typ] = true
				mset = mset.add(e.typ.methods, e.index, e.indirect, e.multiples)
				typ = e.typ.underlying
			}
			switch t := typ.(type) {
			case *Struct:
				for i, f := range t.fields {
					fset = fset.add(f, e.multiples)
					if f.anonymous {
						typ, isPtr := deref(f.typ)
						if t, _ := typ.(*Named); t != nil {
							next = append(next, embeddedType{t, concat(e.index, i), e.indirect || isPtr, e.multiples})
						}
					}
				}
			case *Interface:
				mset = mset.add(t.allMethods, e.index, true, e.multiples)
			}
		}
		for k, m := range mset {
			if _, found := base[k]; !found {
				if _, found := fset[k]; found {
					m = nil  
				}
				if base == nil {
					base = make(methodSet)
				}
				base[k] = m
			}
		}
		for k, f := range fset {
			if f == nil {
				if _, found := base[k]; !found {
					if base == nil {
						base = make(methodSet)
					}
					base[k] = nil  
				}
			}
		}
		current = consolidateMultiples(next)
	}
	if len(base) == 0 {
		return &emptyMethodSet
	}
	var list []*Selection
	for _, m := range base {
		if m != nil {
			m.recv = T
			list = append(list, m)
		}
	}
	sort.Sort(byUniqueName(list))
	return &MethodSet{list}
}
type fieldSet map[string]*Var  
func (s fieldSet) add(f *Var, multiples bool) fieldSet {
	if s == nil {
		s = make(fieldSet)
	}
	key := f.Id()
	if !multiples {
		if _, found := s[key]; !found {
			s[key] = f
			return s
		}
	}
	s[key] = nil  
	return s
}
type methodSet map[string]*Selection  