@@ -3,19 +3,21 @@ import type { Program } from 'estree'
33import { walk } from 'estree-walker'
44import MagicString from 'magic-string'
55import { analyze } from 'periscopic'
6- import { hasDirective } from './utils'
76
87export function transformHoistInlineDirective (
98 input : string ,
109 ast : Program ,
1110 {
1211 runtime,
13- directive,
1412 rejectNonAsyncFunction,
1513 ...options
1614 } : {
17- runtime : ( value : string , name : string ) => string
18- directive : string
15+ runtime : (
16+ value : string ,
17+ name : string ,
18+ meta : { directiveMatch : RegExpMatchArray } ,
19+ ) => string
20+ directive : string | RegExp
1921 rejectNonAsyncFunction ?: boolean
2022 encode ?: ( value : string ) => string
2123 decode ?: ( value : string ) => string
@@ -26,6 +28,10 @@ export function transformHoistInlineDirective(
2628 names : string [ ]
2729} {
2830 const output = new MagicString ( input )
31+ const directive =
32+ typeof options . directive === 'string'
33+ ? exactRegex ( options . directive )
34+ : options . directive
2935
3036 // re-export somehow confuses periscopic scopes so remove them before analysis
3137 walk ( ast , {
@@ -48,9 +54,10 @@ export function transformHoistInlineDirective(
4854 ( node . type === 'FunctionExpression' ||
4955 node . type === 'FunctionDeclaration' ||
5056 node . type === 'ArrowFunctionExpression' ) &&
51- node . body . type === 'BlockStatement' &&
52- hasDirective ( node . body . body , directive )
57+ node . body . type === 'BlockStatement'
5358 ) {
59+ const match = matchDirective ( node . body . body , directive )
60+ if ( ! match ) return
5461 if ( ! node . async && rejectNonAsyncFunction ) {
5562 throw Object . assign (
5663 new Error ( `"${ directive } " doesn't allow non async function` ) ,
@@ -116,7 +123,9 @@ export function transformHoistInlineDirective(
116123 output . move ( node . start , node . end , input . length )
117124
118125 // replace original declartion with action register + bind
119- let newCode = `/* #__PURE__ */ ${ runtime ( newName , newName ) } `
126+ let newCode = `/* #__PURE__ */ ${ runtime ( newName , newName , {
127+ directiveMatch : match ,
128+ } ) } `
120129 if ( bindVars . length > 0 ) {
121130 const bindArgs = options . encode
122131 ? options . encode ( '[' + bindVars . join ( ', ' ) + ']' )
@@ -140,3 +149,24 @@ export function transformHoistInlineDirective(
140149 names,
141150 }
142151}
152+
153+ const exactRegex = ( s : string ) : RegExp =>
154+ new RegExp ( '^' + s . replace ( / [ - [ \] { } ( ) * + ? . , \\ ^ $ | # \s ] / g, '\\$&' ) + '$' )
155+
156+ function matchDirective (
157+ body : Program [ 'body' ] ,
158+ directive : RegExp ,
159+ ) : RegExpMatchArray | undefined {
160+ for ( const stable of body ) {
161+ if (
162+ stable . type === 'ExpressionStatement' &&
163+ stable . expression . type === 'Literal' &&
164+ typeof stable . expression . value === 'string'
165+ ) {
166+ const match = stable . expression . value . match ( directive )
167+ if ( match ) {
168+ return match
169+ }
170+ }
171+ }
172+ }
0 commit comments