11import { tinyassert } from '@hiogawa/utils'
2- import type { Program } from 'estree'
2+ import type { Program , Literal } from 'estree'
33import { walk } from 'estree-walker'
44import MagicString from 'magic-string'
55import { analyze } from 'periscopic'
@@ -56,7 +56,7 @@ export function transformHoistInlineDirective(
5656 node . type === 'ArrowFunctionExpression' ) &&
5757 node . body . type === 'BlockStatement'
5858 ) {
59- const match = matchDirective ( node . body . body , directive )
59+ const match = matchDirective ( node . body . body , directive ) ?. match
6060 if ( ! match ) return
6161 if ( ! node . async && rejectNonAsyncFunction ) {
6262 throw Object . assign (
@@ -156,7 +156,7 @@ const exactRegex = (s: string): RegExp =>
156156function matchDirective (
157157 body : Program [ 'body' ] ,
158158 directive : RegExp ,
159- ) : RegExpMatchArray | undefined {
159+ ) : { match : RegExpMatchArray ; node : Literal } | undefined {
160160 for ( const stable of body ) {
161161 if (
162162 stable . type === 'ExpressionStatement' &&
@@ -165,8 +165,24 @@ function matchDirective(
165165 ) {
166166 const match = stable . expression . value . match ( directive )
167167 if ( match ) {
168- return match
168+ return { match, node : stable . expression }
169169 }
170170 }
171171 }
172172}
173+
174+ export function findDirectives ( ast : Program , directive : string ) : Literal [ ] {
175+ const directiveRE = exactRegex ( directive )
176+ const nodes : Literal [ ] = [ ]
177+ walk ( ast , {
178+ enter ( node ) {
179+ if ( node . type === 'Program' || node . type === 'BlockStatement' ) {
180+ const match = matchDirective ( node . body , directiveRE )
181+ if ( match ) {
182+ nodes . push ( match . node )
183+ }
184+ }
185+ } ,
186+ } )
187+ return nodes
188+ }
0 commit comments