Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / github.com / google / go-cmp@v0.5.1 / cmp / internal / function / func.go
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
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         trbFunc // func(T, R) bool
23         tibFunc // func(T, I) bool
24         trFunc  // func(T) R
25
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
33 )
34
35 var boolType = reflect.TypeOf(true)
36
37 // IsType reports whether the reflect.Type is of the specified function type.
38 func 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 {
44         case tbFunc: // func(T) bool
45                 if ni == 1 && no == 1 && t.Out(0) == boolType {
46                         return true
47                 }
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                 }
52         case trbFunc: // func(T, R) bool
53                 if ni == 2 && no == 1 && t.Out(0) == boolType {
54                         return true
55                 }
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 }
67
68 var lastIdentRx = regexp.MustCompile(`[_\p{L}][_\p{L}\p{N}]*$`)
69
70 // NameOf returns the name of the function value.
71 func 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 }