Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
kardolus
GitHub Repository: kardolus/chatgpt-cli
Path: blob/main/vendor/github.com/google/go-cmp/cmp/internal/function/func.go
2898 views
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 file.
4
5
// Package function provides functionality for identifying function types.
6
package function
7
8
import (
9
"reflect"
10
"regexp"
11
"runtime"
12
"strings"
13
)
14
15
type funcType int
16
17
const (
18
_ funcType = iota
19
20
tbFunc // func(T) bool
21
ttbFunc // func(T, T) bool
22
ttiFunc // func(T, T) int
23
trbFunc // func(T, R) bool
24
tibFunc // func(T, I) bool
25
trFunc // func(T) R
26
27
Equal = ttbFunc // func(T, T) bool
28
EqualAssignable = tibFunc // func(T, I) bool; encapsulates func(T, T) bool
29
Transformer = trFunc // func(T) R
30
ValueFilter = ttbFunc // func(T, T) bool
31
Less = ttbFunc // func(T, T) bool
32
Compare = ttiFunc // func(T, T) int
33
ValuePredicate = tbFunc // func(T) bool
34
KeyValuePredicate = trbFunc // func(T, R) bool
35
)
36
37
var boolType = reflect.TypeOf(true)
38
var intType = reflect.TypeOf(0)
39
40
// IsType reports whether the reflect.Type is of the specified function type.
41
func IsType(t reflect.Type, ft funcType) bool {
42
if t == nil || t.Kind() != reflect.Func || t.IsVariadic() {
43
return false
44
}
45
ni, no := t.NumIn(), t.NumOut()
46
switch ft {
47
case tbFunc: // func(T) bool
48
if ni == 1 && no == 1 && t.Out(0) == boolType {
49
return true
50
}
51
case ttbFunc: // func(T, T) bool
52
if ni == 2 && no == 1 && t.In(0) == t.In(1) && t.Out(0) == boolType {
53
return true
54
}
55
case ttiFunc: // func(T, T) int
56
if ni == 2 && no == 1 && t.In(0) == t.In(1) && t.Out(0) == intType {
57
return true
58
}
59
case trbFunc: // func(T, R) bool
60
if ni == 2 && no == 1 && t.Out(0) == boolType {
61
return true
62
}
63
case tibFunc: // func(T, I) bool
64
if ni == 2 && no == 1 && t.In(0).AssignableTo(t.In(1)) && t.Out(0) == boolType {
65
return true
66
}
67
case trFunc: // func(T) R
68
if ni == 1 && no == 1 {
69
return true
70
}
71
}
72
return false
73
}
74
75
var lastIdentRx = regexp.MustCompile(`[_\p{L}][_\p{L}\p{N}]*$`)
76
77
// NameOf returns the name of the function value.
78
func NameOf(v reflect.Value) string {
79
fnc := runtime.FuncForPC(v.Pointer())
80
if fnc == nil {
81
return "<unknown>"
82
}
83
fullName := fnc.Name() // e.g., "long/path/name/mypkg.(*MyType).(long/path/name/mypkg.myMethod)-fm"
84
85
// Method closures have a "-fm" suffix.
86
fullName = strings.TrimSuffix(fullName, "-fm")
87
88
var name string
89
for len(fullName) > 0 {
90
inParen := strings.HasSuffix(fullName, ")")
91
fullName = strings.TrimSuffix(fullName, ")")
92
93
s := lastIdentRx.FindString(fullName)
94
if s == "" {
95
break
96
}
97
name = s + "." + name
98
fullName = strings.TrimSuffix(fullName, s)
99
100
if i := strings.LastIndexByte(fullName, '('); inParen && i >= 0 {
101
fullName = fullName[:i]
102
}
103
fullName = strings.TrimSuffix(fullName, ".")
104
}
105
return strings.TrimSuffix(name, ".")
106
}
107
108