summaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/tools/go/types/typeutil/map.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/tools/go/types/typeutil/map.go')
-rw-r--r--vendor/golang.org/x/tools/go/types/typeutil/map.go313
1 files changed, 0 insertions, 313 deletions
diff --git a/vendor/golang.org/x/tools/go/types/typeutil/map.go b/vendor/golang.org/x/tools/go/types/typeutil/map.go
deleted file mode 100644
index c7f7545..0000000
--- a/vendor/golang.org/x/tools/go/types/typeutil/map.go
+++ /dev/null
@@ -1,313 +0,0 @@
-// 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
-}