Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201028153306-37f0764111ff / go / ssa / interp / value.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201028153306-37f0764111ff/go/ssa/interp/value.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201028153306-37f0764111ff/go/ssa/interp/value.go
new file mode 100644 (file)
index 0000000..94018b5
--- /dev/null
@@ -0,0 +1,525 @@
+// Copyright 2013 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 interp
+
+// Values
+//
+// All interpreter values are "boxed" in the empty interface, value.
+// The range of possible dynamic types within value are:
+//
+// - bool
+// - numbers (all built-in int/float/complex types are distinguished)
+// - string
+// - map[value]value --- maps for which  usesBuiltinMap(keyType)
+//   *hashmap        --- maps for which !usesBuiltinMap(keyType)
+// - chan value
+// - []value --- slices
+// - iface --- interfaces.
+// - structure --- structs.  Fields are ordered and accessed by numeric indices.
+// - array --- arrays.
+// - *value --- pointers.  Careful: *value is a distinct type from *array etc.
+// - *ssa.Function \
+//   *ssa.Builtin   } --- functions.  A nil 'func' is always of type *ssa.Function.
+//   *closure      /
+// - tuple --- as returned by Return, Next, "value,ok" modes, etc.
+// - iter --- iterators from 'range' over map or string.
+// - bad --- a poison pill for locals that have gone out of scope.
+// - rtype -- the interpreter's concrete implementation of reflect.Type
+//
+// Note that nil is not on this list.
+//
+// Pay close attention to whether or not the dynamic type is a pointer.
+// The compiler cannot help you since value is an empty interface.
+
+import (
+       "bytes"
+       "fmt"
+       "go/types"
+       "io"
+       "reflect"
+       "strings"
+       "sync"
+       "unsafe"
+
+       "golang.org/x/tools/go/ssa"
+       "golang.org/x/tools/go/types/typeutil"
+)
+
+type value interface{}
+
+type tuple []value
+
+type array []value
+
+type iface struct {
+       t types.Type // never an "untyped" type
+       v value
+}
+
+type structure []value
+
+// For map, array, *array, slice, string or channel.
+type iter interface {
+       // next returns a Tuple (key, value, ok).
+       // key and value are unaliased, e.g. copies of the sequence element.
+       next() tuple
+}
+
+type closure struct {
+       Fn  *ssa.Function
+       Env []value
+}
+
+type bad struct{}
+
+type rtype struct {
+       t types.Type
+}
+
+// Hash functions and equivalence relation:
+
+// hashString computes the FNV hash of s.
+func hashString(s string) int {
+       var h uint32
+       for i := 0; i < len(s); i++ {
+               h ^= uint32(s[i])
+               h *= 16777619
+       }
+       return int(h)
+}
+
+var (
+       mu     sync.Mutex
+       hasher = typeutil.MakeHasher()
+)
+
+// hashType returns a hash for t such that
+// types.Identical(x, y) => hashType(x) == hashType(y).
+func hashType(t types.Type) int {
+       mu.Lock()
+       h := int(hasher.Hash(t))
+       mu.Unlock()
+       return h
+}
+
+// usesBuiltinMap returns true if the built-in hash function and
+// equivalence relation for type t are consistent with those of the
+// interpreter's representation of type t.  Such types are: all basic
+// types (bool, numbers, string), pointers and channels.
+//
+// usesBuiltinMap returns false for types that require a custom map
+// implementation: interfaces, arrays and structs.
+//
+// Panic ensues if t is an invalid map key type: function, map or slice.
+func usesBuiltinMap(t types.Type) bool {
+       switch t := t.(type) {
+       case *types.Basic, *types.Chan, *types.Pointer:
+               return true
+       case *types.Named:
+               return usesBuiltinMap(t.Underlying())
+       case *types.Interface, *types.Array, *types.Struct:
+               return false
+       }
+       panic(fmt.Sprintf("invalid map key type: %T", t))
+}
+
+func (x array) eq(t types.Type, _y interface{}) bool {
+       y := _y.(array)
+       tElt := t.Underlying().(*types.Array).Elem()
+       for i, xi := range x {
+               if !equals(tElt, xi, y[i]) {
+                       return false
+               }
+       }
+       return true
+}
+
+func (x array) hash(t types.Type) int {
+       h := 0
+       tElt := t.Underlying().(*types.Array).Elem()
+       for _, xi := range x {
+               h += hash(tElt, xi)
+       }
+       return h
+}
+
+func (x structure) eq(t types.Type, _y interface{}) bool {
+       y := _y.(structure)
+       tStruct := t.Underlying().(*types.Struct)
+       for i, n := 0, tStruct.NumFields(); i < n; i++ {
+               if f := tStruct.Field(i); !f.Anonymous() {
+                       if !equals(f.Type(), x[i], y[i]) {
+                               return false
+                       }
+               }
+       }
+       return true
+}
+
+func (x structure) hash(t types.Type) int {
+       tStruct := t.Underlying().(*types.Struct)
+       h := 0
+       for i, n := 0, tStruct.NumFields(); i < n; i++ {
+               if f := tStruct.Field(i); !f.Anonymous() {
+                       h += hash(f.Type(), x[i])
+               }
+       }
+       return h
+}
+
+// nil-tolerant variant of types.Identical.
+func sameType(x, y types.Type) bool {
+       if x == nil {
+               return y == nil
+       }
+       return y != nil && types.Identical(x, y)
+}
+
+func (x iface) eq(t types.Type, _y interface{}) bool {
+       y := _y.(iface)
+       return sameType(x.t, y.t) && (x.t == nil || equals(x.t, x.v, y.v))
+}
+
+func (x iface) hash(_ types.Type) int {
+       return hashType(x.t)*8581 + hash(x.t, x.v)
+}
+
+func (x rtype) hash(_ types.Type) int {
+       return hashType(x.t)
+}
+
+func (x rtype) eq(_ types.Type, y interface{}) bool {
+       return types.Identical(x.t, y.(rtype).t)
+}
+
+// equals returns true iff x and y are equal according to Go's
+// linguistic equivalence relation for type t.
+// In a well-typed program, the dynamic types of x and y are
+// guaranteed equal.
+func equals(t types.Type, x, y value) bool {
+       switch x := x.(type) {
+       case bool:
+               return x == y.(bool)
+       case int:
+               return x == y.(int)
+       case int8:
+               return x == y.(int8)
+       case int16:
+               return x == y.(int16)
+       case int32:
+               return x == y.(int32)
+       case int64:
+               return x == y.(int64)
+       case uint:
+               return x == y.(uint)
+       case uint8:
+               return x == y.(uint8)
+       case uint16:
+               return x == y.(uint16)
+       case uint32:
+               return x == y.(uint32)
+       case uint64:
+               return x == y.(uint64)
+       case uintptr:
+               return x == y.(uintptr)
+       case float32:
+               return x == y.(float32)
+       case float64:
+               return x == y.(float64)
+       case complex64:
+               return x == y.(complex64)
+       case complex128:
+               return x == y.(complex128)
+       case string:
+               return x == y.(string)
+       case *value:
+               return x == y.(*value)
+       case chan value:
+               return x == y.(chan value)
+       case structure:
+               return x.eq(t, y)
+       case array:
+               return x.eq(t, y)
+       case iface:
+               return x.eq(t, y)
+       case rtype:
+               return x.eq(t, y)
+       }
+
+       // Since map, func and slice don't support comparison, this
+       // case is only reachable if one of x or y is literally nil
+       // (handled in eqnil) or via interface{} values.
+       panic(fmt.Sprintf("comparing uncomparable type %s", t))
+}
+
+// Returns an integer hash of x such that equals(x, y) => hash(x) == hash(y).
+func hash(t types.Type, x value) int {
+       switch x := x.(type) {
+       case bool:
+               if x {
+                       return 1
+               }
+               return 0
+       case int:
+               return x
+       case int8:
+               return int(x)
+       case int16:
+               return int(x)
+       case int32:
+               return int(x)
+       case int64:
+               return int(x)
+       case uint:
+               return int(x)
+       case uint8:
+               return int(x)
+       case uint16:
+               return int(x)
+       case uint32:
+               return int(x)
+       case uint64:
+               return int(x)
+       case uintptr:
+               return int(x)
+       case float32:
+               return int(x)
+       case float64:
+               return int(x)
+       case complex64:
+               return int(real(x))
+       case complex128:
+               return int(real(x))
+       case string:
+               return hashString(x)
+       case *value:
+               return int(uintptr(unsafe.Pointer(x)))
+       case chan value:
+               return int(uintptr(reflect.ValueOf(x).Pointer()))
+       case structure:
+               return x.hash(t)
+       case array:
+               return x.hash(t)
+       case iface:
+               return x.hash(t)
+       case rtype:
+               return x.hash(t)
+       }
+       panic(fmt.Sprintf("%T is unhashable", x))
+}
+
+// reflect.Value struct values don't have a fixed shape, since the
+// payload can be a scalar or an aggregate depending on the instance.
+// So store (and load) can't simply use recursion over the shape of the
+// rhs value, or the lhs, to copy the value; we need the static type
+// information.  (We can't make reflect.Value a new basic data type
+// because its "structness" is exposed to Go programs.)
+
+// load returns the value of type T in *addr.
+func load(T types.Type, addr *value) value {
+       switch T := T.Underlying().(type) {
+       case *types.Struct:
+               v := (*addr).(structure)
+               a := make(structure, len(v))
+               for i := range a {
+                       a[i] = load(T.Field(i).Type(), &v[i])
+               }
+               return a
+       case *types.Array:
+               v := (*addr).(array)
+               a := make(array, len(v))
+               for i := range a {
+                       a[i] = load(T.Elem(), &v[i])
+               }
+               return a
+       default:
+               return *addr
+       }
+}
+
+// store stores value v of type T into *addr.
+func store(T types.Type, addr *value, v value) {
+       switch T := T.Underlying().(type) {
+       case *types.Struct:
+               lhs := (*addr).(structure)
+               rhs := v.(structure)
+               for i := range lhs {
+                       store(T.Field(i).Type(), &lhs[i], rhs[i])
+               }
+       case *types.Array:
+               lhs := (*addr).(array)
+               rhs := v.(array)
+               for i := range lhs {
+                       store(T.Elem(), &lhs[i], rhs[i])
+               }
+       default:
+               *addr = v
+       }
+}
+
+// Prints in the style of built-in println.
+// (More or less; in gc println is actually a compiler intrinsic and
+// can distinguish println(1) from println(interface{}(1)).)
+func writeValue(buf *bytes.Buffer, v value) {
+       switch v := v.(type) {
+       case nil, bool, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr, float32, float64, complex64, complex128, string:
+               fmt.Fprintf(buf, "%v", v)
+
+       case map[value]value:
+               buf.WriteString("map[")
+               sep := ""
+               for k, e := range v {
+                       buf.WriteString(sep)
+                       sep = " "
+                       writeValue(buf, k)
+                       buf.WriteString(":")
+                       writeValue(buf, e)
+               }
+               buf.WriteString("]")
+
+       case *hashmap:
+               buf.WriteString("map[")
+               sep := " "
+               for _, e := range v.entries() {
+                       for e != nil {
+                               buf.WriteString(sep)
+                               sep = " "
+                               writeValue(buf, e.key)
+                               buf.WriteString(":")
+                               writeValue(buf, e.value)
+                               e = e.next
+                       }
+               }
+               buf.WriteString("]")
+
+       case chan value:
+               fmt.Fprintf(buf, "%v", v) // (an address)
+
+       case *value:
+               if v == nil {
+                       buf.WriteString("<nil>")
+               } else {
+                       fmt.Fprintf(buf, "%p", v)
+               }
+
+       case iface:
+               fmt.Fprintf(buf, "(%s, ", v.t)
+               writeValue(buf, v.v)
+               buf.WriteString(")")
+
+       case structure:
+               buf.WriteString("{")
+               for i, e := range v {
+                       if i > 0 {
+                               buf.WriteString(" ")
+                       }
+                       writeValue(buf, e)
+               }
+               buf.WriteString("}")
+
+       case array:
+               buf.WriteString("[")
+               for i, e := range v {
+                       if i > 0 {
+                               buf.WriteString(" ")
+                       }
+                       writeValue(buf, e)
+               }
+               buf.WriteString("]")
+
+       case []value:
+               buf.WriteString("[")
+               for i, e := range v {
+                       if i > 0 {
+                               buf.WriteString(" ")
+                       }
+                       writeValue(buf, e)
+               }
+               buf.WriteString("]")
+
+       case *ssa.Function, *ssa.Builtin, *closure:
+               fmt.Fprintf(buf, "%p", v) // (an address)
+
+       case rtype:
+               buf.WriteString(v.t.String())
+
+       case tuple:
+               // Unreachable in well-formed Go programs
+               buf.WriteString("(")
+               for i, e := range v {
+                       if i > 0 {
+                               buf.WriteString(", ")
+                       }
+                       writeValue(buf, e)
+               }
+               buf.WriteString(")")
+
+       default:
+               fmt.Fprintf(buf, "<%T>", v)
+       }
+}
+
+// Implements printing of Go values in the style of built-in println.
+func toString(v value) string {
+       var b bytes.Buffer
+       writeValue(&b, v)
+       return b.String()
+}
+
+// ------------------------------------------------------------------------
+// Iterators
+
+type stringIter struct {
+       *strings.Reader
+       i int
+}
+
+func (it *stringIter) next() tuple {
+       okv := make(tuple, 3)
+       ch, n, err := it.ReadRune()
+       ok := err != io.EOF
+       okv[0] = ok
+       if ok {
+               okv[1] = it.i
+               okv[2] = ch
+       }
+       it.i += n
+       return okv
+}
+
+type mapIter struct {
+       iter *reflect.MapIter
+       ok   bool
+}
+
+func (it *mapIter) next() tuple {
+       it.ok = it.iter.Next()
+       if !it.ok {
+               return []value{false, nil, nil}
+       }
+       k, v := it.iter.Key().Interface(), it.iter.Value().Interface()
+       return []value{true, k, v}
+}
+
+type hashmapIter struct {
+       iter *reflect.MapIter
+       ok   bool
+       cur  *entry
+}
+
+func (it *hashmapIter) next() tuple {
+       for {
+               if it.cur != nil {
+                       k, v := it.cur.key, it.cur.value
+                       it.cur = it.cur.next
+                       return []value{true, k, v}
+               }
+               it.ok = it.iter.Next()
+               if !it.ok {
+                       return []value{false, nil, nil}
+               }
+               it.cur = it.iter.Value().Interface().(*entry)
+       }
+}