di-go/registry/definition.go

136 lines
2.4 KiB
Go
Raw Permalink Normal View History

2018-04-03 09:02:31 +00:00
package registry
import (
"fmt"
"reflect"
cda "git.loafle.net/commons/di-go/annotation"
cur "git.loafle.net/commons/util-go/reflect"
)
type TypeDefinition struct {
FullName string
PkgName string
TypeName string
Type reflect.Type
RealType reflect.Type
2018-04-10 12:30:57 +00:00
TypeAnnotations map[reflect.Type]cda.Annotation
MethodAnnotations map[string]map[reflect.Type]cda.Annotation
2018-04-06 17:27:13 +00:00
Fields []*FieldDefinition
2018-04-03 09:02:31 +00:00
}
2018-04-10 12:30:57 +00:00
func (td *TypeDefinition) GetTypeAnnotationByType(at reflect.Type, includeEmbedding bool) cda.Annotation {
2018-04-03 09:02:31 +00:00
if nil == td.TypeAnnotations {
return nil
}
2018-04-10 12:30:57 +00:00
if !includeEmbedding {
return td.TypeAnnotations[at]
2018-04-03 09:02:31 +00:00
}
for _, v := range td.TypeAnnotations {
if at == reflect.TypeOf(v) {
return v
}
if includeEmbedding {
if checkAnnotation(reflect.TypeOf(v), at) {
return v
}
}
}
return nil
}
2018-04-06 18:00:06 +00:00
func (td *TypeDefinition) GetMethodAnnotationByType(at reflect.Type, methodName string) cda.Annotation {
if nil == td.MethodAnnotations {
return nil
}
ms, ok := td.MethodAnnotations[methodName]
if !ok {
return nil
}
2018-04-10 12:30:57 +00:00
return ms[at]
}
func (td *TypeDefinition) GetMethodAnnotationsByType(at reflect.Type) map[string]cda.Annotation {
if nil == td.MethodAnnotations {
return nil
}
mas := make(map[string]cda.Annotation)
for k, v := range td.MethodAnnotations {
a, ok := v[at]
if !ok {
continue
2018-04-06 18:00:06 +00:00
}
2018-04-10 12:30:57 +00:00
mas[k] = a
2018-04-06 18:00:06 +00:00
}
2018-04-10 12:30:57 +00:00
return mas
2018-04-06 18:00:06 +00:00
}
2018-04-03 09:02:31 +00:00
func checkAnnotation(t reflect.Type, st reflect.Type) bool {
rt, _, _ := cur.GetTypeInfo(t)
if reflect.Struct != rt.Kind() {
return false
}
for i := 0; i < rt.NumField(); i++ {
f := rt.Field(i)
if f.Anonymous {
if f.Type == st {
return true
}
if checkAnnotation(f.Type, st) {
return true
}
}
}
return false
}
type FieldDefinition struct {
FieldName string
PkgName string
TypeName string
Type reflect.Type
RealType reflect.Type
2018-04-10 12:30:57 +00:00
Annotations map[reflect.Type]cda.Annotation
2018-04-03 09:02:31 +00:00
}
2018-04-10 12:30:57 +00:00
func (fd *FieldDefinition) GetAnnotationByType(at reflect.Type, includeEmbedding bool) cda.Annotation {
2018-04-03 09:02:31 +00:00
if nil == fd.Annotations {
return nil
}
2018-04-10 12:30:57 +00:00
if !includeEmbedding {
return fd.Annotations[at]
2018-04-03 09:02:31 +00:00
}
for _, v := range fd.Annotations {
if at == reflect.TypeOf(v) {
return v
}
if includeEmbedding {
if checkAnnotation(reflect.TypeOf(v), at) {
return v
}
}
}
return nil
}
func FullName(pkgName, typeName string) string {
return fmt.Sprintf("%s/%s", pkgName, typeName)
}