github.com/wfusion/gofusion@v1.1.14/common/utils/inspect/inspect.go (about) 1 // Inspired by github.com/chenzhuoyu/go-inspect 2 3 package inspect 4 5 import ( 6 "reflect" 7 "runtime" 8 "sync" 9 "unsafe" 10 ) 11 12 var ( 13 lock sync.RWMutex 14 structs = make(map[string]reflect.Type) 15 funcs = make(map[string]unsafe.Pointer) 16 17 supportTypes = map[reflect.Kind]bool{ 18 reflect.Bool: true, 19 reflect.Int: true, 20 reflect.Int8: true, 21 reflect.Int16: true, 22 reflect.Int32: true, 23 reflect.Int64: true, 24 reflect.Uint: true, 25 reflect.Uint8: true, 26 reflect.Uint16: true, 27 reflect.Uint32: true, 28 reflect.Uint64: true, 29 reflect.Uintptr: true, 30 reflect.Float32: true, 31 reflect.Float64: true, 32 reflect.Complex64: true, 33 reflect.Complex128: true, 34 reflect.Array: true, 35 reflect.Chan: true, 36 reflect.Map: true, 37 reflect.Slice: true, 38 reflect.String: true, 39 reflect.Struct: true, 40 reflect.Interface: true, 41 } 42 ) 43 44 // TypeOf find the type by package path and name 45 func TypeOf(typeName string) reflect.Type { 46 lock.RLock() 47 defer lock.RUnlock() 48 if typ, ok := structs[typeName]; ok { 49 return typ 50 } 51 return nil 52 } 53 54 // RuntimeTypeOf find the type by package path and name in runtime 55 func RuntimeTypeOf(typeName string) (r reflect.Type) { 56 enumerateTypes(func(typ reflect.Type) bool { 57 if typ.PkgPath()+"."+typ.Name() == typeName { 58 r = typ 59 return false 60 } 61 return true 62 }) 63 return 64 } 65 66 // FuncOf find the function entry by package path and name, 67 // the function should be linked and should not be inlined 68 func FuncOf(funcName string) unsafe.Pointer { 69 lock.RLock() 70 defer lock.RUnlock() 71 if entry, ok := funcs[funcName]; ok { 72 return unsafe.Pointer(&entry) 73 } 74 return nil 75 } 76 77 // RuntimeFuncOf find the function entry by package path and name in runtime, 78 // the function should be linked and should not be inlined 79 func RuntimeFuncOf(funcName string) (r unsafe.Pointer) { 80 enumerateFuncs(func(fn *runtime.Func, addr uintptr) bool { 81 if fn.Name() == funcName { 82 r = unsafe.Pointer(&addr) 83 return false 84 } 85 return true 86 }) 87 return 88 } 89 90 func init() { 91 lock.Lock() 92 defer lock.Unlock() 93 94 // inspect structs 95 enumerateTypes(func(typ reflect.Type) bool { 96 pkgName := typ.PkgPath() 97 typeName := typ.Name() 98 if pkgName != "" && typeName != "" { 99 structs[pkgName+"."+typeName] = typ 100 } 101 102 return true 103 }) 104 105 // inspect function 106 enumerateFuncs(func(fn *runtime.Func, addr uintptr) bool { 107 if funcName := fn.Name(); funcName != "" { 108 funcs[funcName] = unsafe.Pointer(&addr) 109 } 110 return true 111 }) 112 }