Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / go / types / typeutil / map.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/go/types/typeutil/map.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/go/types/typeutil/map.go
new file mode 100644 (file)
index 0000000..c7f7545
--- /dev/null
@@ -0,0 +1,313 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package typeutil defines various utilities for types, such as Map,
+// a mapping from types.Type to interface{} values.
+package typeutil // import "golang.org/x/tools/go/types/typeutil"
+
+import (
+       "bytes"
+       "fmt"
+       "go/types"
+       "reflect"
+)
+
+// Map is a hash-table-based mapping from types (types.Type) to
+// arbitrary interface{} values.  The concrete types that implement
+// the Type interface are pointers.  Since they are not canonicalized,
+// == cannot be used to check for equivalence, and thus we cannot
+// simply use a Go map.
+//
+// Just as with map[K]V, a nil *Map is a valid empty map.
+//
+// Not thread-safe.
+//
+type Map struct {
+       hasher Hasher             // shared by many Maps
+       table  map[uint32][]entry // maps hash to bucket; entry.key==nil means unused
+       length int                // number of map entries
+}
+
+// entry is an entry (key/value association) in a hash bucket.
+type entry struct {
+       key   types.Type
+       value interface{}
+}
+
+// SetHasher sets the hasher used by Map.
+//
+// All Hashers are functionally equivalent but contain internal state
+// used to cache the results of hashing previously seen types.
+//
+// A single Hasher created by MakeHasher() may be shared among many
+// Maps.  This is recommended if the instances have many keys in
+// common, as it will amortize the cost of hash computation.
+//
+// A Hasher may grow without bound as new types are seen.  Even when a
+// type is deleted from the map, the Hasher never shrinks, since other
+// types in the map may reference the deleted type indirectly.
+//
+// Hashers are not thread-safe, and read-only operations such as
+// Map.Lookup require updates to the hasher, so a full Mutex lock (not a
+// read-lock) is require around all Map operations if a shared
+// hasher is accessed from multiple threads.
+//
+// If SetHasher is not called, the Map will create a private hasher at
+// the first call to Insert.
+//
+func (m *Map) SetHasher(hasher Hasher) {
+       m.hasher = hasher
+}
+
+// Delete removes the entry with the given key, if any.
+// It returns true if the entry was found.
+//
+func (m *Map) Delete(key types.Type) bool {
+       if m != nil && m.table != nil {
+               hash := m.hasher.Hash(key)
+               bucket := m.table[hash]
+               for i, e := range bucket {
+                       if e.key != nil && types.Identical(key, e.key) {
+                               // We can't compact the bucket as it
+                               // would disturb iterators.
+                               bucket[i] = entry{}
+                               m.length--
+                               return true
+                       }
+               }
+       }
+       return false
+}
+
+// At returns the map entry for the given key.
+// The result is nil if the entry is not present.
+//
+func (m *Map) At(key types.Type) interface{} {
+       if m != nil && m.table != nil {
+               for _, e := range m.table[m.hasher.Hash(key)] {
+                       if e.key != nil && types.Identical(key, e.key) {
+                               return e.value
+                       }
+               }
+       }
+       return nil
+}
+
+// Set sets the map entry for key to val,
+// and returns the previous entry, if any.
+func (m *Map) Set(key types.Type, value interface{}) (prev interface{}) {
+       if m.table != nil {
+               hash := m.hasher.Hash(key)
+               bucket := m.table[hash]
+               var hole *entry
+               for i, e := range bucket {
+                       if e.key == nil {
+                               hole = &bucket[i]
+                       } else if types.Identical(key, e.key) {
+                               prev = e.value
+                               bucket[i].value = value
+                               return
+                       }
+               }
+
+               if hole != nil {
+                       *hole = entry{key, value} // overwrite deleted entry
+               } else {
+                       m.table[hash] = append(bucket, entry{key, value})
+               }
+       } else {
+               if m.hasher.memo == nil {
+                       m.hasher = MakeHasher()
+               }
+               hash := m.hasher.Hash(key)
+               m.table = map[uint32][]entry{hash: {entry{key, value}}}
+       }
+
+       m.length++
+       return
+}
+
+// Len returns the number of map entries.
+func (m *Map) Len() int {
+       if m != nil {
+               return m.length
+       }
+       return 0
+}
+
+// Iterate calls function f on each entry in the map in unspecified order.
+//
+// If f should mutate the map, Iterate provides the same guarantees as
+// Go maps: if f deletes a map entry that Iterate has not yet reached,
+// f will not be invoked for it, but if f inserts a map entry that
+// Iterate has not yet reached, whether or not f will be invoked for
+// it is unspecified.
+//
+func (m *Map) Iterate(f func(key types.Type, value interface{})) {
+       if m != nil {
+               for _, bucket := range m.table {
+                       for _, e := range bucket {
+                               if e.key != nil {
+                                       f(e.key, e.value)
+                               }
+                       }
+               }
+       }
+}
+
+// Keys returns a new slice containing the set of map keys.
+// The order is unspecified.
+func (m *Map) Keys() []types.Type {
+       keys := make([]types.Type, 0, m.Len())
+       m.Iterate(func(key types.Type, _ interface{}) {
+               keys = append(keys, key)
+       })
+       return keys
+}
+
+func (m *Map) toString(values bool) string {
+       if m == nil {
+               return "{}"
+       }
+       var buf bytes.Buffer
+       fmt.Fprint(&buf, "{")
+       sep := ""
+       m.Iterate(func(key types.Type, value interface{}) {
+               fmt.Fprint(&buf, sep)
+               sep = ", "
+               fmt.Fprint(&buf, key)
+               if values {
+                       fmt.Fprintf(&buf, ": %q", value)
+               }
+       })
+       fmt.Fprint(&buf, "}")
+       return buf.String()
+}
+
+// String returns a string representation of the map's entries.
+// Values are printed using fmt.Sprintf("%v", v).
+// Order is unspecified.
+//
+func (m *Map) String() string {
+       return m.toString(true)
+}
+
+// KeysString returns a string representation of the map's key set.
+// Order is unspecified.
+//
+func (m *Map) KeysString() string {
+       return m.toString(false)
+}
+
+////////////////////////////////////////////////////////////////////////
+// Hasher
+
+// A Hasher maps each type to its hash value.
+// For efficiency, a hasher uses memoization; thus its memory
+// footprint grows monotonically over time.
+// Hashers are not thread-safe.
+// Hashers have reference semantics.
+// Call MakeHasher to create a Hasher.
+type Hasher struct {
+       memo map[types.Type]uint32
+}
+
+// MakeHasher returns a new Hasher instance.
+func MakeHasher() Hasher {
+       return Hasher{make(map[types.Type]uint32)}
+}
+
+// Hash computes a hash value for the given type t such that
+// Identical(t, t') => Hash(t) == Hash(t').
+func (h Hasher) Hash(t types.Type) uint32 {
+       hash, ok := h.memo[t]
+       if !ok {
+               hash = h.hashFor(t)
+               h.memo[t] = hash
+       }
+       return hash
+}
+
+// hashString computes the Fowler–Noll–Vo hash of s.
+func hashString(s string) uint32 {
+       var h uint32
+       for i := 0; i < len(s); i++ {
+               h ^= uint32(s[i])
+               h *= 16777619
+       }
+       return h
+}
+
+// hashFor computes the hash of t.
+func (h Hasher) hashFor(t types.Type) uint32 {
+       // See Identical for rationale.
+       switch t := t.(type) {
+       case *types.Basic:
+               return uint32(t.Kind())
+
+       case *types.Array:
+               return 9043 + 2*uint32(t.Len()) + 3*h.Hash(t.Elem())
+
+       case *types.Slice:
+               return 9049 + 2*h.Hash(t.Elem())
+
+       case *types.Struct:
+               var hash uint32 = 9059
+               for i, n := 0, t.NumFields(); i < n; i++ {
+                       f := t.Field(i)
+                       if f.Anonymous() {
+                               hash += 8861
+                       }
+                       hash += hashString(t.Tag(i))
+                       hash += hashString(f.Name()) // (ignore f.Pkg)
+                       hash += h.Hash(f.Type())
+               }
+               return hash
+
+       case *types.Pointer:
+               return 9067 + 2*h.Hash(t.Elem())
+
+       case *types.Signature:
+               var hash uint32 = 9091
+               if t.Variadic() {
+                       hash *= 8863
+               }
+               return hash + 3*h.hashTuple(t.Params()) + 5*h.hashTuple(t.Results())
+
+       case *types.Interface:
+               var hash uint32 = 9103
+               for i, n := 0, t.NumMethods(); i < n; i++ {
+                       // See go/types.identicalMethods for rationale.
+                       // Method order is not significant.
+                       // Ignore m.Pkg().
+                       m := t.Method(i)
+                       hash += 3*hashString(m.Name()) + 5*h.Hash(m.Type())
+               }
+               return hash
+
+       case *types.Map:
+               return 9109 + 2*h.Hash(t.Key()) + 3*h.Hash(t.Elem())
+
+       case *types.Chan:
+               return 9127 + 2*uint32(t.Dir()) + 3*h.Hash(t.Elem())
+
+       case *types.Named:
+               // Not safe with a copying GC; objects may move.
+               return uint32(reflect.ValueOf(t.Obj()).Pointer())
+
+       case *types.Tuple:
+               return h.hashTuple(t)
+       }
+       panic(t)
+}
+
+func (h Hasher) hashTuple(tuple *types.Tuple) uint32 {
+       // See go/types.identicalTypes for rationale.
+       n := tuple.Len()
+       var hash uint32 = 9137 + 2*uint32(n)
+       for i := 0; i < n; i++ {
+               hash += 3 * h.Hash(tuple.At(i).Type())
+       }
+       return hash
+}