aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/google/go-cmp/cmp/cmpopts
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2020-07-04 10:38:29 +0200
committerDmitry Vyukov <dvyukov@google.com>2020-07-04 15:05:30 +0200
commitdcff124efb2ea4a834b74ac0974aa2f2fd000b40 (patch)
tree8d49a1e0849baa283d09c7227ec9d2311a34258a /vendor/github.com/google/go-cmp/cmp/cmpopts
parent4f739670f77d37168a44be2139f4005b748a825d (diff)
go.mod: switch to modules for dependency management
Godep is long deprecated and modules is the future. Updating dependencies with godep is painful and non-transparent. This will hopefully help to create custom golangci-lint linters. The change was created with: go mod init rm -rf vendor go mod vendor Fixes #1247
Diffstat (limited to 'vendor/github.com/google/go-cmp/cmp/cmpopts')
-rw-r--r--vendor/github.com/google/go-cmp/cmp/cmpopts/equate.go89
-rw-r--r--vendor/github.com/google/go-cmp/cmp/cmpopts/ignore.go207
-rw-r--r--vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go147
-rw-r--r--vendor/github.com/google/go-cmp/cmp/cmpopts/struct_filter.go182
-rw-r--r--vendor/github.com/google/go-cmp/cmp/cmpopts/xform.go35
5 files changed, 0 insertions, 660 deletions
diff --git a/vendor/github.com/google/go-cmp/cmp/cmpopts/equate.go b/vendor/github.com/google/go-cmp/cmp/cmpopts/equate.go
deleted file mode 100644
index 41bbddc61..000000000
--- a/vendor/github.com/google/go-cmp/cmp/cmpopts/equate.go
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2017, 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.md file.
-
-// Package cmpopts provides common options for the cmp package.
-package cmpopts
-
-import (
- "math"
- "reflect"
-
- "github.com/google/go-cmp/cmp"
-)
-
-func equateAlways(_, _ interface{}) bool { return true }
-
-// EquateEmpty returns a Comparer option that determines all maps and slices
-// with a length of zero to be equal, regardless of whether they are nil.
-//
-// EquateEmpty can be used in conjunction with SortSlices and SortMaps.
-func EquateEmpty() cmp.Option {
- return cmp.FilterValues(isEmpty, cmp.Comparer(equateAlways))
-}
-
-func isEmpty(x, y interface{}) bool {
- vx, vy := reflect.ValueOf(x), reflect.ValueOf(y)
- return (x != nil && y != nil && vx.Type() == vy.Type()) &&
- (vx.Kind() == reflect.Slice || vx.Kind() == reflect.Map) &&
- (vx.Len() == 0 && vy.Len() == 0)
-}
-
-// EquateApprox returns a Comparer option that determines float32 or float64
-// values to be equal if they are within a relative fraction or absolute margin.
-// This option is not used when either x or y is NaN or infinite.
-//
-// The fraction determines that the difference of two values must be within the
-// smaller fraction of the two values, while the margin determines that the two
-// values must be within some absolute margin.
-// To express only a fraction or only a margin, use 0 for the other parameter.
-// The fraction and margin must be non-negative.
-//
-// The mathematical expression used is equivalent to:
-// |x-y| ≤ max(fraction*min(|x|, |y|), margin)
-//
-// EquateApprox can be used in conjunction with EquateNaNs.
-func EquateApprox(fraction, margin float64) cmp.Option {
- if margin < 0 || fraction < 0 || math.IsNaN(margin) || math.IsNaN(fraction) {
- panic("margin or fraction must be a non-negative number")
- }
- a := approximator{fraction, margin}
- return cmp.Options{
- cmp.FilterValues(areRealF64s, cmp.Comparer(a.compareF64)),
- cmp.FilterValues(areRealF32s, cmp.Comparer(a.compareF32)),
- }
-}
-
-type approximator struct{ frac, marg float64 }
-
-func areRealF64s(x, y float64) bool {
- return !math.IsNaN(x) && !math.IsNaN(y) && !math.IsInf(x, 0) && !math.IsInf(y, 0)
-}
-func areRealF32s(x, y float32) bool {
- return areRealF64s(float64(x), float64(y))
-}
-func (a approximator) compareF64(x, y float64) bool {
- relMarg := a.frac * math.Min(math.Abs(x), math.Abs(y))
- return math.Abs(x-y) <= math.Max(a.marg, relMarg)
-}
-func (a approximator) compareF32(x, y float32) bool {
- return a.compareF64(float64(x), float64(y))
-}
-
-// EquateNaNs returns a Comparer option that determines float32 and float64
-// NaN values to be equal.
-//
-// EquateNaNs can be used in conjunction with EquateApprox.
-func EquateNaNs() cmp.Option {
- return cmp.Options{
- cmp.FilterValues(areNaNsF64s, cmp.Comparer(equateAlways)),
- cmp.FilterValues(areNaNsF32s, cmp.Comparer(equateAlways)),
- }
-}
-
-func areNaNsF64s(x, y float64) bool {
- return math.IsNaN(x) && math.IsNaN(y)
-}
-func areNaNsF32s(x, y float32) bool {
- return areNaNsF64s(float64(x), float64(y))
-}
diff --git a/vendor/github.com/google/go-cmp/cmp/cmpopts/ignore.go b/vendor/github.com/google/go-cmp/cmp/cmpopts/ignore.go
deleted file mode 100644
index ff8e785d4..000000000
--- a/vendor/github.com/google/go-cmp/cmp/cmpopts/ignore.go
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright 2017, 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.md file.
-
-package cmpopts
-
-import (
- "fmt"
- "reflect"
- "unicode"
- "unicode/utf8"
-
- "github.com/google/go-cmp/cmp"
- "github.com/google/go-cmp/cmp/internal/function"
-)
-
-// IgnoreFields returns an Option that ignores exported fields of the
-// given names on a single struct type.
-// The struct type is specified by passing in a value of that type.
-//
-// The name may be a dot-delimited string (e.g., "Foo.Bar") to ignore a
-// specific sub-field that is embedded or nested within the parent struct.
-//
-// This does not handle unexported fields; use IgnoreUnexported instead.
-func IgnoreFields(typ interface{}, names ...string) cmp.Option {
- sf := newStructFilter(typ, names...)
- return cmp.FilterPath(sf.filter, cmp.Ignore())
-}
-
-// IgnoreTypes returns an Option that ignores all values assignable to
-// certain types, which are specified by passing in a value of each type.
-func IgnoreTypes(typs ...interface{}) cmp.Option {
- tf := newTypeFilter(typs...)
- return cmp.FilterPath(tf.filter, cmp.Ignore())
-}
-
-type typeFilter []reflect.Type
-
-func newTypeFilter(typs ...interface{}) (tf typeFilter) {
- for _, typ := range typs {
- t := reflect.TypeOf(typ)
- if t == nil {
- // This occurs if someone tries to pass in sync.Locker(nil)
- panic("cannot determine type; consider using IgnoreInterfaces")
- }
- tf = append(tf, t)
- }
- return tf
-}
-func (tf typeFilter) filter(p cmp.Path) bool {
- if len(p) < 1 {
- return false
- }
- t := p.Last().Type()
- for _, ti := range tf {
- if t.AssignableTo(ti) {
- return true
- }
- }
- return false
-}
-
-// IgnoreInterfaces returns an Option that ignores all values or references of
-// values assignable to certain interface types. These interfaces are specified
-// by passing in an anonymous struct with the interface types embedded in it.
-// For example, to ignore sync.Locker, pass in struct{sync.Locker}{}.
-func IgnoreInterfaces(ifaces interface{}) cmp.Option {
- tf := newIfaceFilter(ifaces)
- return cmp.FilterPath(tf.filter, cmp.Ignore())
-}
-
-type ifaceFilter []reflect.Type
-
-func newIfaceFilter(ifaces interface{}) (tf ifaceFilter) {
- t := reflect.TypeOf(ifaces)
- if ifaces == nil || t.Name() != "" || t.Kind() != reflect.Struct {
- panic("input must be an anonymous struct")
- }
- for i := 0; i < t.NumField(); i++ {
- fi := t.Field(i)
- switch {
- case !fi.Anonymous:
- panic("struct cannot have named fields")
- case fi.Type.Kind() != reflect.Interface:
- panic("embedded field must be an interface type")
- case fi.Type.NumMethod() == 0:
- // This matches everything; why would you ever want this?
- panic("cannot ignore empty interface")
- default:
- tf = append(tf, fi.Type)
- }
- }
- return tf
-}
-func (tf ifaceFilter) filter(p cmp.Path) bool {
- if len(p) < 1 {
- return false
- }
- t := p.Last().Type()
- for _, ti := range tf {
- if t.AssignableTo(ti) {
- return true
- }
- if t.Kind() != reflect.Ptr && reflect.PtrTo(t).AssignableTo(ti) {
- return true
- }
- }
- return false
-}
-
-// IgnoreUnexported returns an Option that only ignores the immediate unexported
-// fields of a struct, including anonymous fields of unexported types.
-// In particular, unexported fields within the struct's exported fields
-// of struct types, including anonymous fields, will not be ignored unless the
-// type of the field itself is also passed to IgnoreUnexported.
-//
-// Avoid ignoring unexported fields of a type which you do not control (i.e. a
-// type from another repository), as changes to the implementation of such types
-// may change how the comparison behaves. Prefer a custom Comparer instead.
-func IgnoreUnexported(typs ...interface{}) cmp.Option {
- ux := newUnexportedFilter(typs...)
- return cmp.FilterPath(ux.filter, cmp.Ignore())
-}
-
-type unexportedFilter struct{ m map[reflect.Type]bool }
-
-func newUnexportedFilter(typs ...interface{}) unexportedFilter {
- ux := unexportedFilter{m: make(map[reflect.Type]bool)}
- for _, typ := range typs {
- t := reflect.TypeOf(typ)
- if t == nil || t.Kind() != reflect.Struct {
- panic(fmt.Sprintf("invalid struct type: %T", typ))
- }
- ux.m[t] = true
- }
- return ux
-}
-func (xf unexportedFilter) filter(p cmp.Path) bool {
- sf, ok := p.Index(-1).(cmp.StructField)
- if !ok {
- return false
- }
- return xf.m[p.Index(-2).Type()] && !isExported(sf.Name())
-}
-
-// isExported reports whether the identifier is exported.
-func isExported(id string) bool {
- r, _ := utf8.DecodeRuneInString(id)
- return unicode.IsUpper(r)
-}
-
-// IgnoreSliceElements returns an Option that ignores elements of []V.
-// The discard function must be of the form "func(T) bool" which is used to
-// ignore slice elements of type V, where V is assignable to T.
-// Elements are ignored if the function reports true.
-func IgnoreSliceElements(discardFunc interface{}) cmp.Option {
- vf := reflect.ValueOf(discardFunc)
- if !function.IsType(vf.Type(), function.ValuePredicate) || vf.IsNil() {
- panic(fmt.Sprintf("invalid discard function: %T", discardFunc))
- }
- return cmp.FilterPath(func(p cmp.Path) bool {
- si, ok := p.Index(-1).(cmp.SliceIndex)
- if !ok {
- return false
- }
- if !si.Type().AssignableTo(vf.Type().In(0)) {
- return false
- }
- vx, vy := si.Values()
- if vx.IsValid() && vf.Call([]reflect.Value{vx})[0].Bool() {
- return true
- }
- if vy.IsValid() && vf.Call([]reflect.Value{vy})[0].Bool() {
- return true
- }
- return false
- }, cmp.Ignore())
-}
-
-// IgnoreMapEntries returns an Option that ignores entries of map[K]V.
-// The discard function must be of the form "func(T, R) bool" which is used to
-// ignore map entries of type K and V, where K and V are assignable to T and R.
-// Entries are ignored if the function reports true.
-func IgnoreMapEntries(discardFunc interface{}) cmp.Option {
- vf := reflect.ValueOf(discardFunc)
- if !function.IsType(vf.Type(), function.KeyValuePredicate) || vf.IsNil() {
- panic(fmt.Sprintf("invalid discard function: %T", discardFunc))
- }
- return cmp.FilterPath(func(p cmp.Path) bool {
- mi, ok := p.Index(-1).(cmp.MapIndex)
- if !ok {
- return false
- }
- if !mi.Key().Type().AssignableTo(vf.Type().In(0)) || !mi.Type().AssignableTo(vf.Type().In(1)) {
- return false
- }
- k := mi.Key()
- vx, vy := mi.Values()
- if vx.IsValid() && vf.Call([]reflect.Value{k, vx})[0].Bool() {
- return true
- }
- if vy.IsValid() && vf.Call([]reflect.Value{k, vy})[0].Bool() {
- return true
- }
- return false
- }, cmp.Ignore())
-}
diff --git a/vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go b/vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go
deleted file mode 100644
index 3a4804621..000000000
--- a/vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2017, 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.md file.
-
-package cmpopts
-
-import (
- "fmt"
- "reflect"
- "sort"
-
- "github.com/google/go-cmp/cmp"
- "github.com/google/go-cmp/cmp/internal/function"
-)
-
-// SortSlices returns a Transformer option that sorts all []V.
-// The less function must be of the form "func(T, T) bool" which is used to
-// sort any slice with element type V that is assignable to T.
-//
-// The less function must be:
-// • Deterministic: less(x, y) == less(x, y)
-// • Irreflexive: !less(x, x)
-// • Transitive: if !less(x, y) and !less(y, z), then !less(x, z)
-//
-// The less function does not have to be "total". That is, if !less(x, y) and
-// !less(y, x) for two elements x and y, their relative order is maintained.
-//
-// SortSlices can be used in conjunction with EquateEmpty.
-func SortSlices(lessFunc interface{}) cmp.Option {
- vf := reflect.ValueOf(lessFunc)
- if !function.IsType(vf.Type(), function.Less) || vf.IsNil() {
- panic(fmt.Sprintf("invalid less function: %T", lessFunc))
- }
- ss := sliceSorter{vf.Type().In(0), vf}
- return cmp.FilterValues(ss.filter, cmp.Transformer("cmpopts.SortSlices", ss.sort))
-}
-
-type sliceSorter struct {
- in reflect.Type // T
- fnc reflect.Value // func(T, T) bool
-}
-
-func (ss sliceSorter) filter(x, y interface{}) bool {
- vx, vy := reflect.ValueOf(x), reflect.ValueOf(y)
- if !(x != nil && y != nil && vx.Type() == vy.Type()) ||
- !(vx.Kind() == reflect.Slice && vx.Type().Elem().AssignableTo(ss.in)) ||
- (vx.Len() <= 1 && vy.Len() <= 1) {
- return false
- }
- // Check whether the slices are already sorted to avoid an infinite
- // recursion cycle applying the same transform to itself.
- ok1 := sort.SliceIsSorted(x, func(i, j int) bool { return ss.less(vx, i, j) })
- ok2 := sort.SliceIsSorted(y, func(i, j int) bool { return ss.less(vy, i, j) })
- return !ok1 || !ok2
-}
-func (ss sliceSorter) sort(x interface{}) interface{} {
- src := reflect.ValueOf(x)
- dst := reflect.MakeSlice(src.Type(), src.Len(), src.Len())
- for i := 0; i < src.Len(); i++ {
- dst.Index(i).Set(src.Index(i))
- }
- sort.SliceStable(dst.Interface(), func(i, j int) bool { return ss.less(dst, i, j) })
- ss.checkSort(dst)
- return dst.Interface()
-}
-func (ss sliceSorter) checkSort(v reflect.Value) {
- start := -1 // Start of a sequence of equal elements.
- for i := 1; i < v.Len(); i++ {
- if ss.less(v, i-1, i) {
- // Check that first and last elements in v[start:i] are equal.
- if start >= 0 && (ss.less(v, start, i-1) || ss.less(v, i-1, start)) {
- panic(fmt.Sprintf("incomparable values detected: want equal elements: %v", v.Slice(start, i)))
- }
- start = -1
- } else if start == -1 {
- start = i
- }
- }
-}
-func (ss sliceSorter) less(v reflect.Value, i, j int) bool {
- vx, vy := v.Index(i), v.Index(j)
- return ss.fnc.Call([]reflect.Value{vx, vy})[0].Bool()
-}
-
-// SortMaps returns a Transformer option that flattens map[K]V types to be a
-// sorted []struct{K, V}. The less function must be of the form
-// "func(T, T) bool" which is used to sort any map with key K that is
-// assignable to T.
-//
-// Flattening the map into a slice has the property that cmp.Equal is able to
-// use Comparers on K or the K.Equal method if it exists.
-//
-// The less function must be:
-// • Deterministic: less(x, y) == less(x, y)
-// • Irreflexive: !less(x, x)
-// • Transitive: if !less(x, y) and !less(y, z), then !less(x, z)
-// • Total: if x != y, then either less(x, y) or less(y, x)
-//
-// SortMaps can be used in conjunction with EquateEmpty.
-func SortMaps(lessFunc interface{}) cmp.Option {
- vf := reflect.ValueOf(lessFunc)
- if !function.IsType(vf.Type(), function.Less) || vf.IsNil() {
- panic(fmt.Sprintf("invalid less function: %T", lessFunc))
- }
- ms := mapSorter{vf.Type().In(0), vf}
- return cmp.FilterValues(ms.filter, cmp.Transformer("cmpopts.SortMaps", ms.sort))
-}
-
-type mapSorter struct {
- in reflect.Type // T
- fnc reflect.Value // func(T, T) bool
-}
-
-func (ms mapSorter) filter(x, y interface{}) bool {
- vx, vy := reflect.ValueOf(x), reflect.ValueOf(y)
- return (x != nil && y != nil && vx.Type() == vy.Type()) &&
- (vx.Kind() == reflect.Map && vx.Type().Key().AssignableTo(ms.in)) &&
- (vx.Len() != 0 || vy.Len() != 0)
-}
-func (ms mapSorter) sort(x interface{}) interface{} {
- src := reflect.ValueOf(x)
- outType := reflect.StructOf([]reflect.StructField{
- {Name: "K", Type: src.Type().Key()},
- {Name: "V", Type: src.Type().Elem()},
- })
- dst := reflect.MakeSlice(reflect.SliceOf(outType), src.Len(), src.Len())
- for i, k := range src.MapKeys() {
- v := reflect.New(outType).Elem()
- v.Field(0).Set(k)
- v.Field(1).Set(src.MapIndex(k))
- dst.Index(i).Set(v)
- }
- sort.Slice(dst.Interface(), func(i, j int) bool { return ms.less(dst, i, j) })
- ms.checkSort(dst)
- return dst.Interface()
-}
-func (ms mapSorter) checkSort(v reflect.Value) {
- for i := 1; i < v.Len(); i++ {
- if !ms.less(v, i-1, i) {
- panic(fmt.Sprintf("partial order detected: want %v < %v", v.Index(i-1), v.Index(i)))
- }
- }
-}
-func (ms mapSorter) less(v reflect.Value, i, j int) bool {
- vx, vy := v.Index(i).Field(0), v.Index(j).Field(0)
- return ms.fnc.Call([]reflect.Value{vx, vy})[0].Bool()
-}
diff --git a/vendor/github.com/google/go-cmp/cmp/cmpopts/struct_filter.go b/vendor/github.com/google/go-cmp/cmp/cmpopts/struct_filter.go
deleted file mode 100644
index 97f707983..000000000
--- a/vendor/github.com/google/go-cmp/cmp/cmpopts/struct_filter.go
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2017, 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.md file.
-
-package cmpopts
-
-import (
- "fmt"
- "reflect"
- "strings"
-
- "github.com/google/go-cmp/cmp"
-)
-
-// filterField returns a new Option where opt is only evaluated on paths that
-// include a specific exported field on a single struct type.
-// The struct type is specified by passing in a value of that type.
-//
-// The name may be a dot-delimited string (e.g., "Foo.Bar") to select a
-// specific sub-field that is embedded or nested within the parent struct.
-func filterField(typ interface{}, name string, opt cmp.Option) cmp.Option {
- // TODO: This is currently unexported over concerns of how helper filters
- // can be composed together easily.
- // TODO: Add tests for FilterField.
-
- sf := newStructFilter(typ, name)
- return cmp.FilterPath(sf.filter, opt)
-}
-
-type structFilter struct {
- t reflect.Type // The root struct type to match on
- ft fieldTree // Tree of fields to match on
-}
-
-func newStructFilter(typ interface{}, names ...string) structFilter {
- // TODO: Perhaps allow * as a special identifier to allow ignoring any
- // number of path steps until the next field match?
- // This could be useful when a concrete struct gets transformed into
- // an anonymous struct where it is not possible to specify that by type,
- // but the transformer happens to provide guarantees about the names of
- // the transformed fields.
-
- t := reflect.TypeOf(typ)
- if t == nil || t.Kind() != reflect.Struct {
- panic(fmt.Sprintf("%T must be a struct", typ))
- }
- var ft fieldTree
- for _, name := range names {
- cname, err := canonicalName(t, name)
- if err != nil {
- panic(fmt.Sprintf("%s: %v", strings.Join(cname, "."), err))
- }
- ft.insert(cname)
- }
- return structFilter{t, ft}
-}
-
-func (sf structFilter) filter(p cmp.Path) bool {
- for i, ps := range p {
- if ps.Type().AssignableTo(sf.t) && sf.ft.matchPrefix(p[i+1:]) {
- return true
- }
- }
- return false
-}
-
-// fieldTree represents a set of dot-separated identifiers.
-//
-// For example, inserting the following selectors:
-// Foo
-// Foo.Bar.Baz
-// Foo.Buzz
-// Nuka.Cola.Quantum
-//
-// Results in a tree of the form:
-// {sub: {
-// "Foo": {ok: true, sub: {
-// "Bar": {sub: {
-// "Baz": {ok: true},
-// }},
-// "Buzz": {ok: true},
-// }},
-// "Nuka": {sub: {
-// "Cola": {sub: {
-// "Quantum": {ok: true},
-// }},
-// }},
-// }}
-type fieldTree struct {
- ok bool // Whether this is a specified node
- sub map[string]fieldTree // The sub-tree of fields under this node
-}
-
-// insert inserts a sequence of field accesses into the tree.
-func (ft *fieldTree) insert(cname []string) {
- if ft.sub == nil {
- ft.sub = make(map[string]fieldTree)
- }
- if len(cname) == 0 {
- ft.ok = true
- return
- }
- sub := ft.sub[cname[0]]
- sub.insert(cname[1:])
- ft.sub[cname[0]] = sub
-}
-
-// matchPrefix reports whether any selector in the fieldTree matches
-// the start of path p.
-func (ft fieldTree) matchPrefix(p cmp.Path) bool {
- for _, ps := range p {
- switch ps := ps.(type) {
- case cmp.StructField:
- ft = ft.sub[ps.Name()]
- if ft.ok {
- return true
- }
- if len(ft.sub) == 0 {
- return false
- }
- case cmp.Indirect:
- default:
- return false
- }
- }
- return false
-}
-
-// canonicalName returns a list of identifiers where any struct field access
-// through an embedded field is expanded to include the names of the embedded
-// types themselves.
-//
-// For example, suppose field "Foo" is not directly in the parent struct,
-// but actually from an embedded struct of type "Bar". Then, the canonical name
-// of "Foo" is actually "Bar.Foo".
-//
-// Suppose field "Foo" is not directly in the parent struct, but actually
-// a field in two different embedded structs of types "Bar" and "Baz".
-// Then the selector "Foo" causes a panic since it is ambiguous which one it
-// refers to. The user must specify either "Bar.Foo" or "Baz.Foo".
-func canonicalName(t reflect.Type, sel string) ([]string, error) {
- var name string
- sel = strings.TrimPrefix(sel, ".")
- if sel == "" {
- return nil, fmt.Errorf("name must not be empty")
- }
- if i := strings.IndexByte(sel, '.'); i < 0 {
- name, sel = sel, ""
- } else {
- name, sel = sel[:i], sel[i:]
- }
-
- // Type must be a struct or pointer to struct.
- if t.Kind() == reflect.Ptr {
- t = t.Elem()
- }
- if t.Kind() != reflect.Struct {
- return nil, fmt.Errorf("%v must be a struct", t)
- }
-
- // Find the canonical name for this current field name.
- // If the field exists in an embedded struct, then it will be expanded.
- if !isExported(name) {
- // Disallow unexported fields:
- // * To discourage people from actually touching unexported fields
- // * FieldByName is buggy (https://golang.org/issue/4876)
- return []string{name}, fmt.Errorf("name must be exported")
- }
- sf, ok := t.FieldByName(name)
- if !ok {
- return []string{name}, fmt.Errorf("does not exist")
- }
- var ss []string
- for i := range sf.Index {
- ss = append(ss, t.FieldByIndex(sf.Index[:i+1]).Name)
- }
- if sel == "" {
- return ss, nil
- }
- ssPost, err := canonicalName(sf.Type, sel)
- return append(ss, ssPost...), err
-}
diff --git a/vendor/github.com/google/go-cmp/cmp/cmpopts/xform.go b/vendor/github.com/google/go-cmp/cmp/cmpopts/xform.go
deleted file mode 100644
index 9d651553d..000000000
--- a/vendor/github.com/google/go-cmp/cmp/cmpopts/xform.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018, 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.md file.
-
-package cmpopts
-
-import (
- "github.com/google/go-cmp/cmp"
-)
-
-type xformFilter struct{ xform cmp.Option }
-
-func (xf xformFilter) filter(p cmp.Path) bool {
- for _, ps := range p {
- if t, ok := ps.(cmp.Transform); ok && t.Option() == xf.xform {
- return false
- }
- }
- return true
-}
-
-// AcyclicTransformer returns a Transformer with a filter applied that ensures
-// that the transformer cannot be recursively applied upon its own output.
-//
-// An example use case is a transformer that splits a string by lines:
-// AcyclicTransformer("SplitLines", func(s string) []string{
-// return strings.Split(s, "\n")
-// })
-//
-// Had this been an unfiltered Transformer instead, this would result in an
-// infinite cycle converting a string to []string to [][]string and so on.
-func AcyclicTransformer(name string, xformFunc interface{}) cmp.Option {
- xf := xformFilter{cmp.Transformer(name, xformFunc)}
- return cmp.FilterPath(xf.filter, xf.xform)
-}