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) }