]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blame - vendor/github.com/google/go-cmp/cmp/internal/function/func.go
update vendor and go.mod
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / google / go-cmp / cmp / internal / function / func.go
CommitLineData
107c1cdb
ND
1// Copyright 2017, The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE.md file.
4
863486a6 5// Package function provides functionality for identifying function types.
107c1cdb
ND
6package function
7
863486a6
AG
8import (
9 "reflect"
10 "regexp"
11 "runtime"
12 "strings"
13)
107c1cdb
ND
14
15type funcType int
16
17const (
18 _ funcType = iota
19
863486a6 20 tbFunc // func(T) bool
107c1cdb 21 ttbFunc // func(T, T) bool
863486a6 22 trbFunc // func(T, R) bool
107c1cdb
ND
23 tibFunc // func(T, I) bool
24 trFunc // func(T) R
25
863486a6
AG
26 Equal = ttbFunc // func(T, T) bool
27 EqualAssignable = tibFunc // func(T, I) bool; encapsulates func(T, T) bool
28 Transformer = trFunc // func(T) R
29 ValueFilter = ttbFunc // func(T, T) bool
30 Less = ttbFunc // func(T, T) bool
31 ValuePredicate = tbFunc // func(T) bool
32 KeyValuePredicate = trbFunc // func(T, R) bool
107c1cdb
ND
33)
34
35var boolType = reflect.TypeOf(true)
36
37// IsType reports whether the reflect.Type is of the specified function type.
38func IsType(t reflect.Type, ft funcType) bool {
39 if t == nil || t.Kind() != reflect.Func || t.IsVariadic() {
40 return false
41 }
42 ni, no := t.NumIn(), t.NumOut()
43 switch ft {
863486a6
AG
44 case tbFunc: // func(T) bool
45 if ni == 1 && no == 1 && t.Out(0) == boolType {
46 return true
47 }
107c1cdb
ND
48 case ttbFunc: // func(T, T) bool
49 if ni == 2 && no == 1 && t.In(0) == t.In(1) && t.Out(0) == boolType {
50 return true
51 }
863486a6
AG
52 case trbFunc: // func(T, R) bool
53 if ni == 2 && no == 1 && t.Out(0) == boolType {
54 return true
55 }
107c1cdb
ND
56 case tibFunc: // func(T, I) bool
57 if ni == 2 && no == 1 && t.In(0).AssignableTo(t.In(1)) && t.Out(0) == boolType {
58 return true
59 }
60 case trFunc: // func(T) R
61 if ni == 1 && no == 1 {
62 return true
63 }
64 }
65 return false
66}
863486a6
AG
67
68var lastIdentRx = regexp.MustCompile(`[_\p{L}][_\p{L}\p{N}]*$`)
69
70// NameOf returns the name of the function value.
71func NameOf(v reflect.Value) string {
72 fnc := runtime.FuncForPC(v.Pointer())
73 if fnc == nil {
74 return "<unknown>"
75 }
76 fullName := fnc.Name() // e.g., "long/path/name/mypkg.(*MyType).(long/path/name/mypkg.myMethod)-fm"
77
78 // Method closures have a "-fm" suffix.
79 fullName = strings.TrimSuffix(fullName, "-fm")
80
81 var name string
82 for len(fullName) > 0 {
83 inParen := strings.HasSuffix(fullName, ")")
84 fullName = strings.TrimSuffix(fullName, ")")
85
86 s := lastIdentRx.FindString(fullName)
87 if s == "" {
88 break
89 }
90 name = s + "." + name
91 fullName = strings.TrimSuffix(fullName, s)
92
93 if i := strings.LastIndexByte(fullName, '('); inParen && i >= 0 {
94 fullName = fullName[:i]
95 }
96 fullName = strings.TrimSuffix(fullName, ".")
97 }
98 return strings.TrimSuffix(name, ".")
99}