11import { camelCase , CamelCaseString , Node } from '@codama/nodes' ;
22
3- import type { NodeStack } from './NodeStack ' ;
3+ import { NodePath } from './NodePath ' ;
44
55export type NodeSelector = NodeSelectorFunction | NodeSelectorPath ;
66
@@ -11,11 +11,11 @@ export type NodeSelector = NodeSelectorFunction | NodeSelectorPath;
1111 * - `[someNode]` matches a node of the given kind.
1212 * - `[someNode|someOtherNode]` matches a node with any of the given kind.
1313 * - `[someNode]someText` matches both the kind and the name of a node.
14- * - `a.b.c` matches a node `c` such that its parent stack contains `a` and `b` in order (but not necessarily subsequent).
14+ * - `a.b.c` matches a node `c` such that its ancestors contains `a` and `b` in order (but not necessarily subsequent).
1515 */
1616export type NodeSelectorPath = string ;
1717
18- export type NodeSelectorFunction = ( node : Node , stack : NodeStack ) => boolean ;
18+ export type NodeSelectorFunction = ( path : NodePath ) => boolean ;
1919
2020export const getNodeSelectorFunction = ( selector : NodeSelector ) : NodeSelectorFunction => {
2121 if ( typeof selector === 'function' ) return selector ;
@@ -40,25 +40,29 @@ export const getNodeSelectorFunction = (selector: NodeSelector): NodeSelectorFun
4040 return true ;
4141 } ;
4242
43- const checkStack = ( nodeStack : Node [ ] , nodeSelectors : string [ ] ) : boolean => {
43+ const checkPath = ( path : Node [ ] , nodeSelectors : string [ ] ) : boolean => {
4444 if ( nodeSelectors . length === 0 ) return true ;
45- if ( nodeStack . length === 0 ) return false ;
46- const lastNode = nodeStack . pop ( ) as Node ;
45+ if ( path . length === 0 ) return false ;
46+ const lastNode = path . pop ( ) as Node ;
4747 const lastNodeSelector = nodeSelectors . pop ( ) as string ;
4848 return checkNode ( lastNode , lastNodeSelector )
49- ? checkStack ( nodeStack , nodeSelectors )
50- : checkStack ( nodeStack , [ ...nodeSelectors , lastNodeSelector ] ) ;
49+ ? checkPath ( path , nodeSelectors )
50+ : checkPath ( path , [ ...nodeSelectors , lastNodeSelector ] ) ;
5151 } ;
5252
53- const nodeSelectors = selector . split ( '.' ) ;
54- const lastNodeSelector = nodeSelectors . pop ( ) as string ;
53+ const checkInitialPath = ( path : Node [ ] , nodeSelectors : string [ ] ) : boolean => {
54+ if ( nodeSelectors . length === 0 || path . length === 0 ) return false ;
55+ const lastNode = path . pop ( ) as Node ;
56+ const lastNodeSelector = nodeSelectors . pop ( ) as string ;
57+ return checkNode ( lastNode , lastNodeSelector ) && checkPath ( path , nodeSelectors ) ;
58+ } ;
5559
56- return ( node , stack ) =>
57- checkNode ( node , lastNodeSelector ) && checkStack ( stack . getPath ( ) as Node [ ] , [ ...nodeSelectors ] ) ;
60+ const nodeSelectors = selector . split ( '.' ) ;
61+ return path => checkInitialPath ( [ ... path ] , [ ...nodeSelectors ] ) ;
5862} ;
5963
6064export const getConjunctiveNodeSelectorFunction = ( selector : NodeSelector | NodeSelector [ ] ) : NodeSelectorFunction => {
6165 const selectors = Array . isArray ( selector ) ? selector : [ selector ] ;
6266 const selectorFunctions = selectors . map ( getNodeSelectorFunction ) ;
63- return ( node , stack ) => selectorFunctions . every ( fn => fn ( node , stack ) ) ;
67+ return path => selectorFunctions . every ( fn => fn ( path ) ) ;
6468} ;
0 commit comments