You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
64 lines
1.4 KiB
Go
64 lines
1.4 KiB
Go
package component
|
|
|
|
import (
|
|
"reflect"
|
|
"unicode"
|
|
"unicode/utf8"
|
|
)
|
|
|
|
var (
|
|
typeOfError = reflect.TypeOf((*error)(nil)).Elem()
|
|
typeOfBytes = reflect.TypeOf(([]byte)(nil))
|
|
// TODO cycle not allow IConnection
|
|
typeOfConnection = reflect.TypeOf(([]byte)(nil))
|
|
)
|
|
|
|
func isExported(name string) bool {
|
|
w, _ := utf8.DecodeRuneInString(name)
|
|
return unicode.IsUpper(w)
|
|
}
|
|
|
|
func isExportedOrBuiltinType(t reflect.Type) bool {
|
|
for t.Kind() == reflect.Ptr {
|
|
t = t.Elem()
|
|
}
|
|
// PkgPath will be non-empty even for an exported type,
|
|
// so we need to check the type name as well.
|
|
return isExported(t.Name()) || t.PkgPath() == ""
|
|
}
|
|
|
|
func isHandlerMethod(method reflect.Method) bool {
|
|
mt := method.Type
|
|
// 必须是可导出的
|
|
if isExportedOrBuiltinType(mt) {
|
|
return false
|
|
}
|
|
|
|
// 必须具有3个入参: receiver, *Request, []byte/pointer
|
|
// receiver指代 func (*receiver) xxx() 的receiver部分
|
|
if mt.NumIn() != 3 {
|
|
return false
|
|
}
|
|
|
|
// 至少要有一个出参 且是error
|
|
if mt.NumOut() < 1 {
|
|
return false
|
|
}
|
|
|
|
// 第一个显式入参必须是实现了IConnection的具体类的指针类型
|
|
if t1 := mt.In(1); t1.Kind() != reflect.Ptr || t1 != typeOfConnection {
|
|
return false
|
|
}
|
|
|
|
// 第二个显式入参必须是 []byte 或者 任意pointer
|
|
if t2 := mt.In(2); t2.Kind() != reflect.Ptr || t2 != typeOfBytes {
|
|
return false
|
|
}
|
|
|
|
// 最后一个出参必须是error
|
|
if o1 := mt.Out(mt.NumOut() - 1); o1 != typeOfError {
|
|
return false
|
|
}
|
|
return true
|
|
}
|