@@ -39,23 +39,14 @@ import type {
3939// Type for ast-grep language (built-in or custom string)
4040type NapiLang = Lang | string ;
4141
42- // Interface for a dynamic language package (has libraryPath property required by ast-grep)
43- interface DynamicLanguagePackage {
44- libraryPath : string ;
45- extensions : readonly string [ ] ;
46- languageSymbol : string ;
47- expandoChar : string ;
48- }
49-
50- // Type for dynamic language configuration expected by registerDynamicLanguage
51- type DynamicLanguageConfig = Record < string , DynamicLanguagePackage > ;
52-
5342// Register dynamic languages once
5443let languagesRegistered = false ;
5544
5645function ensureLanguagesRegistered ( ) {
5746 if ( ! languagesRegistered ) {
58- const config = {
47+ // The @ast -grep/lang-* packages export types with readonly arrays, but registerDynamicLanguage
48+ // expects mutable arrays. We need to cast here due to this external library type mismatch.
49+ const langConfig = {
5950 bash : langBash ,
6051 c : langC ,
6152 cpp : langCpp ,
@@ -71,8 +62,8 @@ function ensureLanguagesRegistered() {
7162 tsx : langTsx ,
7263 typescript : langTypeScript ,
7364 yaml : langYaml ,
74- } ;
75- registerDynamicLanguage ( config as DynamicLanguageConfig ) ;
65+ } as unknown as Parameters < typeof registerDynamicLanguage > [ 0 ] ;
66+ registerDynamicLanguage ( langConfig ) ;
7667 languagesRegistered = true ;
7768 }
7869}
@@ -397,7 +388,7 @@ export class ASTSearchService {
397388 // Handle atomic rules
398389 if ( rule . pattern ) {
399390 const pattern = typeof rule . pattern === 'string' ? rule . pattern : rule . pattern . selector ?? rule . pattern . context ?? '' ;
400- let nodes = root . findAll ( pattern ) ;
391+ let nodes = root . findAll ( pattern || '' ) ;
401392
402393 // Apply relational filters
403394 if ( rule . inside ) {
@@ -490,7 +481,7 @@ export class ASTSearchService {
490481 private nodeMatchesRule ( node : SgNode , rule : ASTRule ) : boolean {
491482 if ( rule . pattern ) {
492483 const pattern = typeof rule . pattern === 'string' ? rule . pattern : rule . pattern . selector ?? '' ;
493- if ( ! node . matches ( pattern ) ) return false ;
484+ if ( ! node . matches ( pattern || '' ) ) return false ;
494485 }
495486
496487 if ( rule . kind && node . kind ( ) !== rule . kind ) {
@@ -539,7 +530,7 @@ export class ASTSearchService {
539530 * Check inside relational rule
540531 */
541532 private checkInside ( node : SgNode , rule : ASTRule | string ) : boolean {
542- const pattern = typeof rule === 'string' ? rule : rule . pattern ?? '' ;
533+ const pattern = typeof rule === 'string' ? rule : typeof rule . pattern === 'string' ? rule . pattern : rule . pattern ?. selector ?? '' ;
543534 if ( ! pattern ) return true ;
544535
545536 return node . inside ( pattern ) ;
@@ -549,7 +540,7 @@ export class ASTSearchService {
549540 * Check has relational rule
550541 */
551542 private checkHas ( node : SgNode , rule : ASTRule | string ) : boolean {
552- const pattern = typeof rule === 'string' ? rule : rule . pattern ?? '' ;
543+ const pattern = typeof rule === 'string' ? rule : typeof rule . pattern === 'string' ? rule . pattern : rule . pattern ?. selector ?? '' ;
553544 if ( ! pattern ) return true ;
554545
555546 return node . has ( pattern ) ;
@@ -559,7 +550,7 @@ export class ASTSearchService {
559550 * Check precedes relational rule
560551 */
561552 private checkPrecedes ( node : SgNode , rule : ASTRule | string ) : boolean {
562- const pattern = typeof rule === 'string' ? rule : rule . pattern ?? '' ;
553+ const pattern = typeof rule === 'string' ? rule : typeof rule . pattern === 'string' ? rule . pattern : rule . pattern ?. selector ?? '' ;
563554 if ( ! pattern ) return true ;
564555
565556 return node . precedes ( pattern ) ;
@@ -569,7 +560,7 @@ export class ASTSearchService {
569560 * Check follows relational rule
570561 */
571562 private checkFollows ( node : SgNode , rule : ASTRule | string ) : boolean {
572- const pattern = typeof rule === 'string' ? rule : rule . pattern ?? '' ;
563+ const pattern = typeof rule === 'string' ? rule : typeof rule . pattern === 'string' ? rule . pattern : rule . pattern ?. selector ?? '' ;
573564 if ( ! pattern ) return true ;
574565
575566 return node . follows ( pattern ) ;
0 commit comments