import { extendsMetadata } from "./extends" ; import { parseClass } from "./parser" ; import { Class , ClassReflection , ConstructorReflection , MethodReflection , ParameterPropertyReflection , ParameterReflection , PropertyReflection , Reflection , } from "./types" ; type TypedReflection = ClassReflection | MethodReflection | PropertyReflection | ParameterReflection | ConstructorReflection | ParameterPropertyReflection ; type WalkMemberVisitor = ( value : TypedReflection , ctx : WalkMemberContext ) => TypedReflection | undefined ; interface WalkMemberContext { target : Class ; classPath : Class [ ] ; parent : Reflection ; memberVisitor : WalkMemberVisitor ; } interface WalkParentContext { target : Class ; memberVisitor : WalkMemberVisitor ; classPath : Class [ ] ; } param ref param ctx function walkReflectionMembers ( ref , ctx ) { const result = ctx . memberVisitor ( ref , ctx ) ; for ( const key in result ) { if ( [ "parameters" , "properties" , "methods" , "ctor" ] . some ( x => x === key ) ) { const item = ( result as any ) [ key ] ; if ( Array . isArray ( item ) ) { const node = item . map ( ( x , i ) => walkReflectionMembers ( x , { ... ctx , parent : result } ) ) ; ( result as any ) [ key ] = node . filter ( x => ! ! x ) ; } else { const node = walkReflectionMembers ( item , { ... ctx , parent : item } ) ; ( result as any ) [ key ] = node ; } } } return result as ClassReflection ; } function walkTypeMembers ( type , memberVisitor , classPath ) { const rawMeta = parseClass ( type ) ; return walkReflectionMembers ( rawMeta , { memberVisitor , parent : rawMeta , target : type , classPath } ) ; } param type function walkTypeMembersRecursive ( type , ctx ) { const defaultRef = { super : Object , kind : "Class" , type : Object , name : "Object" , ctor : { } as ConstructorReflection , methods : [ ] , properties : [ ] , decorators : [ ] } ; const parent = Object . getPrototypeOf ( type ) ; const parentMeta = ! ! parent . prototype ? walkTypeMembersRecursive ( parent , { ... ctx , classPath : ctx . classPath . concat ( type ) } ) : defaultRef ; const childMeta = walkTypeMembers ( type , ctx . memberVisitor , ctx . classPath ) ; return extendsMetadata ( childMeta , parentMeta ) ; } export { walkTypeMembersRecursive , walkReflectionMembers , WalkMemberVisitor , TypedReflection , WalkMemberContext } ;