136 lines
2.4 KiB
Go
136 lines
2.4 KiB
Go
|
package di
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"reflect"
|
||
|
|
||
|
"git.loafle.net/loafer/annotation-go"
|
||
|
luReflect "git.loafle.net/loafer/util-go/reflect"
|
||
|
)
|
||
|
|
||
|
type TypeDefinition struct {
|
||
|
FullName string
|
||
|
PkgName string
|
||
|
TypeName string
|
||
|
Type reflect.Type
|
||
|
RealType reflect.Type
|
||
|
|
||
|
TypeAnnotations map[reflect.Type]annotation.Annotation
|
||
|
MethodAnnotations map[string]map[reflect.Type]annotation.Annotation
|
||
|
Fields []*FieldDefinition
|
||
|
}
|
||
|
|
||
|
func (td *TypeDefinition) GetTypeAnnotationByType(at reflect.Type, includeEmbedding bool) annotation.Annotation {
|
||
|
if nil == td.TypeAnnotations {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
if !includeEmbedding {
|
||
|
return td.TypeAnnotations[at]
|
||
|
}
|
||
|
|
||
|
for _, v := range td.TypeAnnotations {
|
||
|
if at == reflect.TypeOf(v) {
|
||
|
return v
|
||
|
}
|
||
|
|
||
|
if includeEmbedding {
|
||
|
if checkAnnotation(reflect.TypeOf(v), at) {
|
||
|
return v
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (td *TypeDefinition) GetMethodAnnotationByType(at reflect.Type, methodName string) annotation.Annotation {
|
||
|
if nil == td.MethodAnnotations {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
ms, ok := td.MethodAnnotations[methodName]
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
return ms[at]
|
||
|
}
|
||
|
|
||
|
func (td *TypeDefinition) GetMethodAnnotationsByType(at reflect.Type) map[string]annotation.Annotation {
|
||
|
if nil == td.MethodAnnotations {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
mas := make(map[string]annotation.Annotation)
|
||
|
for k, v := range td.MethodAnnotations {
|
||
|
a, ok := v[at]
|
||
|
if !ok {
|
||
|
continue
|
||
|
}
|
||
|
mas[k] = a
|
||
|
}
|
||
|
|
||
|
return mas
|
||
|
}
|
||
|
|
||
|
func checkAnnotation(t reflect.Type, st reflect.Type) bool {
|
||
|
rt, _, _ := luReflect.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
|
||
|
|
||
|
Annotations map[reflect.Type]annotation.Annotation
|
||
|
}
|
||
|
|
||
|
func (fd *FieldDefinition) GetAnnotationByType(at reflect.Type, includeEmbedding bool) annotation.Annotation {
|
||
|
if nil == fd.Annotations {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
if !includeEmbedding {
|
||
|
return fd.Annotations[at]
|
||
|
}
|
||
|
|
||
|
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)
|
||
|
}
|