Add generated file
This PR adds generated files under pkg/client and vendor folder.
This commit is contained in:
313
vendor/golang.org/x/tools/go/pointer/util.go
generated
vendored
Normal file
313
vendor/golang.org/x/tools/go/pointer/util.go
generated
vendored
Normal file
@@ -0,0 +1,313 @@
|
||||
// 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 pointer
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/types"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"golang.org/x/tools/container/intsets"
|
||||
)
|
||||
|
||||
// CanPoint reports whether the type T is pointerlike,
|
||||
// for the purposes of this analysis.
|
||||
func CanPoint(T types.Type) bool {
|
||||
switch T := T.(type) {
|
||||
case *types.Named:
|
||||
if obj := T.Obj(); obj.Name() == "Value" && obj.Pkg().Path() == "reflect" {
|
||||
return true // treat reflect.Value like interface{}
|
||||
}
|
||||
return CanPoint(T.Underlying())
|
||||
case *types.Pointer, *types.Interface, *types.Map, *types.Chan, *types.Signature, *types.Slice:
|
||||
return true
|
||||
}
|
||||
|
||||
return false // array struct tuple builtin basic
|
||||
}
|
||||
|
||||
// CanHaveDynamicTypes reports whether the type T can "hold" dynamic types,
|
||||
// i.e. is an interface (incl. reflect.Type) or a reflect.Value.
|
||||
//
|
||||
func CanHaveDynamicTypes(T types.Type) bool {
|
||||
switch T := T.(type) {
|
||||
case *types.Named:
|
||||
if obj := T.Obj(); obj.Name() == "Value" && obj.Pkg().Path() == "reflect" {
|
||||
return true // reflect.Value
|
||||
}
|
||||
return CanHaveDynamicTypes(T.Underlying())
|
||||
case *types.Interface:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isInterface(T types.Type) bool { return types.IsInterface(T) }
|
||||
|
||||
// mustDeref returns the element type of its argument, which must be a
|
||||
// pointer; panic ensues otherwise.
|
||||
func mustDeref(typ types.Type) types.Type {
|
||||
return typ.Underlying().(*types.Pointer).Elem()
|
||||
}
|
||||
|
||||
// deref returns a pointer's element type; otherwise it returns typ.
|
||||
func deref(typ types.Type) types.Type {
|
||||
if p, ok := typ.Underlying().(*types.Pointer); ok {
|
||||
return p.Elem()
|
||||
}
|
||||
return typ
|
||||
}
|
||||
|
||||
// A fieldInfo describes one subelement (node) of the flattening-out
|
||||
// of a type T: the subelement's type and its path from the root of T.
|
||||
//
|
||||
// For example, for this type:
|
||||
// type line struct{ points []struct{x, y int} }
|
||||
// flatten() of the inner struct yields the following []fieldInfo:
|
||||
// struct{ x, y int } ""
|
||||
// int ".x"
|
||||
// int ".y"
|
||||
// and flatten(line) yields:
|
||||
// struct{ points []struct{x, y int} } ""
|
||||
// struct{ x, y int } ".points[*]"
|
||||
// int ".points[*].x
|
||||
// int ".points[*].y"
|
||||
//
|
||||
type fieldInfo struct {
|
||||
typ types.Type
|
||||
|
||||
// op and tail describe the path to the element (e.g. ".a#2.b[*].c").
|
||||
op interface{} // *Array: true; *Tuple: int; *Struct: *types.Var; *Named: nil
|
||||
tail *fieldInfo
|
||||
}
|
||||
|
||||
// path returns a user-friendly string describing the subelement path.
|
||||
//
|
||||
func (fi *fieldInfo) path() string {
|
||||
var buf bytes.Buffer
|
||||
for p := fi; p != nil; p = p.tail {
|
||||
switch op := p.op.(type) {
|
||||
case bool:
|
||||
fmt.Fprintf(&buf, "[*]")
|
||||
case int:
|
||||
fmt.Fprintf(&buf, "#%d", op)
|
||||
case *types.Var:
|
||||
fmt.Fprintf(&buf, ".%s", op.Name())
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// flatten returns a list of directly contained fields in the preorder
|
||||
// traversal of the type tree of t. The resulting elements are all
|
||||
// scalars (basic types or pointerlike types), except for struct/array
|
||||
// "identity" nodes, whose type is that of the aggregate.
|
||||
//
|
||||
// reflect.Value is considered pointerlike, similar to interface{}.
|
||||
//
|
||||
// Callers must not mutate the result.
|
||||
//
|
||||
func (a *analysis) flatten(t types.Type) []*fieldInfo {
|
||||
fl, ok := a.flattenMemo[t]
|
||||
if !ok {
|
||||
switch t := t.(type) {
|
||||
case *types.Named:
|
||||
u := t.Underlying()
|
||||
if isInterface(u) {
|
||||
// Debuggability hack: don't remove
|
||||
// the named type from interfaces as
|
||||
// they're very verbose.
|
||||
fl = append(fl, &fieldInfo{typ: t})
|
||||
} else {
|
||||
fl = a.flatten(u)
|
||||
}
|
||||
|
||||
case *types.Basic,
|
||||
*types.Signature,
|
||||
*types.Chan,
|
||||
*types.Map,
|
||||
*types.Interface,
|
||||
*types.Slice,
|
||||
*types.Pointer:
|
||||
fl = append(fl, &fieldInfo{typ: t})
|
||||
|
||||
case *types.Array:
|
||||
fl = append(fl, &fieldInfo{typ: t}) // identity node
|
||||
for _, fi := range a.flatten(t.Elem()) {
|
||||
fl = append(fl, &fieldInfo{typ: fi.typ, op: true, tail: fi})
|
||||
}
|
||||
|
||||
case *types.Struct:
|
||||
fl = append(fl, &fieldInfo{typ: t}) // identity node
|
||||
for i, n := 0, t.NumFields(); i < n; i++ {
|
||||
f := t.Field(i)
|
||||
for _, fi := range a.flatten(f.Type()) {
|
||||
fl = append(fl, &fieldInfo{typ: fi.typ, op: f, tail: fi})
|
||||
}
|
||||
}
|
||||
|
||||
case *types.Tuple:
|
||||
// No identity node: tuples are never address-taken.
|
||||
n := t.Len()
|
||||
if n == 1 {
|
||||
// Don't add a fieldInfo link for singletons,
|
||||
// e.g. in params/results.
|
||||
fl = append(fl, a.flatten(t.At(0).Type())...)
|
||||
} else {
|
||||
for i := 0; i < n; i++ {
|
||||
f := t.At(i)
|
||||
for _, fi := range a.flatten(f.Type()) {
|
||||
fl = append(fl, &fieldInfo{typ: fi.typ, op: i, tail: fi})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
panic(fmt.Sprintf("cannot flatten unsupported type %T", t))
|
||||
}
|
||||
|
||||
a.flattenMemo[t] = fl
|
||||
}
|
||||
|
||||
return fl
|
||||
}
|
||||
|
||||
// sizeof returns the number of pointerlike abstractions (nodes) in the type t.
|
||||
func (a *analysis) sizeof(t types.Type) uint32 {
|
||||
return uint32(len(a.flatten(t)))
|
||||
}
|
||||
|
||||
// shouldTrack reports whether object type T contains (recursively)
|
||||
// any fields whose addresses should be tracked.
|
||||
func (a *analysis) shouldTrack(T types.Type) bool {
|
||||
if a.track == trackAll {
|
||||
return true // fast path
|
||||
}
|
||||
track, ok := a.trackTypes[T]
|
||||
if !ok {
|
||||
a.trackTypes[T] = true // break cycles conservatively
|
||||
// NB: reflect.Value, reflect.Type are pre-populated to true.
|
||||
for _, fi := range a.flatten(T) {
|
||||
switch ft := fi.typ.Underlying().(type) {
|
||||
case *types.Interface, *types.Signature:
|
||||
track = true // needed for callgraph
|
||||
case *types.Basic:
|
||||
// no-op
|
||||
case *types.Chan:
|
||||
track = a.track&trackChan != 0 || a.shouldTrack(ft.Elem())
|
||||
case *types.Map:
|
||||
track = a.track&trackMap != 0 || a.shouldTrack(ft.Key()) || a.shouldTrack(ft.Elem())
|
||||
case *types.Slice:
|
||||
track = a.track&trackSlice != 0 || a.shouldTrack(ft.Elem())
|
||||
case *types.Pointer:
|
||||
track = a.track&trackPtr != 0 || a.shouldTrack(ft.Elem())
|
||||
case *types.Array, *types.Struct:
|
||||
// No need to look at field types since they will follow (flattened).
|
||||
default:
|
||||
// Includes *types.Tuple, which are never address-taken.
|
||||
panic(ft)
|
||||
}
|
||||
if track {
|
||||
break
|
||||
}
|
||||
}
|
||||
a.trackTypes[T] = track
|
||||
if !track && a.log != nil {
|
||||
fmt.Fprintf(a.log, "\ttype not tracked: %s\n", T)
|
||||
}
|
||||
}
|
||||
return track
|
||||
}
|
||||
|
||||
// offsetOf returns the (abstract) offset of field index within struct
|
||||
// or tuple typ.
|
||||
func (a *analysis) offsetOf(typ types.Type, index int) uint32 {
|
||||
var offset uint32
|
||||
switch t := typ.Underlying().(type) {
|
||||
case *types.Tuple:
|
||||
for i := 0; i < index; i++ {
|
||||
offset += a.sizeof(t.At(i).Type())
|
||||
}
|
||||
case *types.Struct:
|
||||
offset++ // the node for the struct itself
|
||||
for i := 0; i < index; i++ {
|
||||
offset += a.sizeof(t.Field(i).Type())
|
||||
}
|
||||
default:
|
||||
panic(fmt.Sprintf("offsetOf(%s : %T)", typ, typ))
|
||||
}
|
||||
return offset
|
||||
}
|
||||
|
||||
// sliceToArray returns the type representing the arrays to which
|
||||
// slice type slice points.
|
||||
func sliceToArray(slice types.Type) *types.Array {
|
||||
return types.NewArray(slice.Underlying().(*types.Slice).Elem(), 1)
|
||||
}
|
||||
|
||||
// Node set -------------------------------------------------------------------
|
||||
|
||||
type nodeset struct {
|
||||
intsets.Sparse
|
||||
}
|
||||
|
||||
func (ns *nodeset) String() string {
|
||||
var buf bytes.Buffer
|
||||
buf.WriteRune('{')
|
||||
var space [50]int
|
||||
for i, n := range ns.AppendTo(space[:0]) {
|
||||
if i > 0 {
|
||||
buf.WriteString(", ")
|
||||
}
|
||||
buf.WriteRune('n')
|
||||
fmt.Fprintf(&buf, "%d", n)
|
||||
}
|
||||
buf.WriteRune('}')
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (ns *nodeset) add(n nodeid) bool {
|
||||
return ns.Sparse.Insert(int(n))
|
||||
}
|
||||
|
||||
func (x *nodeset) addAll(y *nodeset) bool {
|
||||
return x.UnionWith(&y.Sparse)
|
||||
}
|
||||
|
||||
// Profiling & debugging -------------------------------------------------------
|
||||
|
||||
var timers = make(map[string]time.Time)
|
||||
|
||||
func start(name string) {
|
||||
if debugTimers {
|
||||
timers[name] = time.Now()
|
||||
log.Printf("%s...\n", name)
|
||||
}
|
||||
}
|
||||
|
||||
func stop(name string) {
|
||||
if debugTimers {
|
||||
log.Printf("%s took %s\n", name, time.Since(timers[name]))
|
||||
}
|
||||
}
|
||||
|
||||
// diff runs the command "diff a b" and reports its success.
|
||||
func diff(a, b string) bool {
|
||||
var cmd *exec.Cmd
|
||||
switch runtime.GOOS {
|
||||
case "plan9":
|
||||
cmd = exec.Command("/bin/diff", "-c", a, b)
|
||||
default:
|
||||
cmd = exec.Command("/usr/bin/diff", "-u", a, b)
|
||||
}
|
||||
cmd.Stdout = os.Stderr
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run() == nil
|
||||
}
|
Reference in New Issue
Block a user