// 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 file.

// Package function provides functionality for identifying function types.
package function import ( ) type funcType int const ( _ funcType = iota tbFunc // func(T) bool ttbFunc // func(T, T) bool trbFunc // func(T, R) bool tibFunc // func(T, I) bool trFunc // func(T) R Equal = ttbFunc // func(T, T) bool EqualAssignable = tibFunc // func(T, I) bool; encapsulates func(T, T) bool Transformer = trFunc // func(T) R ValueFilter = ttbFunc // func(T, T) bool Less = ttbFunc // func(T, T) bool ValuePredicate = tbFunc // func(T) bool KeyValuePredicate = trbFunc // func(T, R) bool ) var boolType = reflect.TypeOf(true) // IsType reports whether the reflect.Type is of the specified function type. func ( reflect.Type, funcType) bool { if == nil || .Kind() != reflect.Func || .IsVariadic() { return false } , := .NumIn(), .NumOut() switch { case tbFunc: // func(T) bool if == 1 && == 1 && .Out(0) == boolType { return true } case ttbFunc: // func(T, T) bool if == 2 && == 1 && .In(0) == .In(1) && .Out(0) == boolType { return true } case trbFunc: // func(T, R) bool if == 2 && == 1 && .Out(0) == boolType { return true } case tibFunc: // func(T, I) bool if == 2 && == 1 && .In(0).AssignableTo(.In(1)) && .Out(0) == boolType { return true } case trFunc: // func(T) R if == 1 && == 1 { return true } } return false } var lastIdentRx = regexp.MustCompile(`[_\p{L}][_\p{L}\p{N}]*$`) // NameOf returns the name of the function value. func ( reflect.Value) string { := runtime.FuncForPC(.Pointer()) if == nil { return "<unknown>" } := .Name() // e.g., "long/path/name/mypkg.(*MyType).(long/path/name/mypkg.myMethod)-fm" // Method closures have a "-fm" suffix. = strings.TrimSuffix(, "-fm") var string for len() > 0 { := strings.HasSuffix(, ")") = strings.TrimSuffix(, ")") := lastIdentRx.FindString() if == "" { break } = + "." + = strings.TrimSuffix(, ) if := strings.LastIndexByte(, '('); && >= 0 { = [:] } = strings.TrimSuffix(, ".") } return strings.TrimSuffix(, ".") }