forked from andeya/goutil
-
Notifications
You must be signed in to change notification settings - Fork 0
/
type.go
56 lines (51 loc) · 1.42 KB
/
type.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package goutil
import (
"reflect"
"runtime"
"unicode"
"unicode/utf8"
)
// IsExportedOrBuiltinType is this type exported or a builtin?
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 IsExportedName(t.Name()) || t.PkgPath() == ""
}
// IsExportedName is this an exported - upper case - name?
func IsExportedName(name string) bool {
rune, _ := utf8.DecodeRuneInString(name)
return unicode.IsUpper(rune)
}
// ObjectName gets the type name of the object
func ObjectName(obj interface{}) string {
v := reflect.ValueOf(obj)
t := v.Type()
if t.Kind() == reflect.Func {
return runtime.FuncForPC(v.Pointer()).Name()
}
return t.String()
}
// IsCompositionMethod determines whether the method inherits from the anonymous field of the struct.
func IsCompositionMethod(method reflect.Method) bool {
fn := runtime.FuncForPC(method.Func.Pointer())
file, _ := fn.FileLine(fn.Entry())
if file != "<autogenerated>" {
return false
}
recv := method.Type.In(0)
var found bool
if recv.Kind() == reflect.Ptr {
method, found = recv.Elem().MethodByName(method.Name)
} else {
method, found = reflect.PtrTo(recv).MethodByName(method.Name)
}
if !found {
return true
}
fn = runtime.FuncForPC(method.Func.Pointer())
file, _ = fn.FileLine(fn.Entry())
return file == "<autogenerated>"
}