import { Definition , EnumMemberDeclaration , NodeIndex , ObjectLikeMember , TypeParameterDeclaration } from '#ast' ; import { Declaration , RootDeclaration } from '#ast/node-aliases' ; import { isClassDeclaration , isDefinition , isEnumDeclaration , isFunctionDeclaration , isInterfaceDeclaration , isObjectLikeNode , isPropertyDeclaration , isTypeDeclaration , isTypeParameterDeclaration , isVariableDeclaration } from '#ast/utilities/node-typeguards' ; import { NodeMap } from '#ast/components' ; import { accForEach } from '@crosstype/common' ; findTargetDeclarationsByPath . priority = [ isInterfaceDeclaration , isClassDeclaration , isTypeDeclaration , isVariableDeclaration , isEnumDeclaration , isFunctionDeclaration ] ; internal export function findTargetDeclarationsByPath ( targetBase , paths , priority = findTargetDeclarationsByPath . priority ) { if ( targetBase . name !== paths [ 0 ] ) return void 0 ; const matches = new Map < RootDeclaration | TypeParameterDeclaration , Declaration > ( ) ; const declarations = isDefinition ( targetBase ) ? targetBase . declarations . toArray ( ) : [ targetBase ] ; if ( paths . length === 1 ) declarations . forEach ( ( d ) => matches . set ( d , d ) ) ; else { declarationLoop : for ( const declaration of declarations ) { let members = ( ( isTypeDeclaration ( declaration ) || isVariableDeclaration ( declaration ) ) && isObjectLikeNode ( declaration . value ) ) ? declaration . value . members : ( isTypeParameterDeclaration ( declaration ) && declaration . constraint && isObjectLikeNode ( declaration . constraint ) ) ? declaration . constraint . members : ( isEnumDeclaration ( declaration ) || isClassDeclaration ( declaration ) || isInterfaceDeclaration ( declaration ) ) ? declaration . members : void 0 ; if ( ! members ) continue ; let node ; for ( let i = 1 ; i < paths . length ; i ++ ) { node = members . get ( paths [ i ] ) ; if ( ! node ) continue declarationLoop ; if ( i === ( paths . length - 1 ) ) { matches . set ( declaration , node ) ; continue declarationLoop ; } else if ( isPropertyDeclaration ( node ) && isObjectLikeNode ( node . value ) ) members = node . value . members ; } } } if ( ! matches . size ) return void 0 ; if ( matches . size === 1 ) return [ ... matches . values ( ) ] ; const matchArray = [ ... matches . entries ( ) ] ; return accForEach ( priority , < Declaration [ ] > [ ] , ( predicate , res ) => { const item = matchArray . find ( ( [ root ] ) => predicate ( root ) ) ?. [ 1 ] ; if ( item ) res . push ( item ) ; } ) ; }