@@ -3,19 +3,21 @@ import type { Program } from 'estree'
3
3
import { walk } from 'estree-walker'
4
4
import MagicString from 'magic-string'
5
5
import { analyze } from 'periscopic'
6
- import { hasDirective } from './utils'
7
6
8
7
export function transformHoistInlineDirective (
9
8
input : string ,
10
9
ast : Program ,
11
10
{
12
11
runtime,
13
- directive,
14
12
rejectNonAsyncFunction,
15
13
...options
16
14
} : {
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
19
21
rejectNonAsyncFunction ?: boolean
20
22
encode ?: ( value : string ) => string
21
23
decode ?: ( value : string ) => string
@@ -26,6 +28,10 @@ export function transformHoistInlineDirective(
26
28
names : string [ ]
27
29
} {
28
30
const output = new MagicString ( input )
31
+ const directive =
32
+ typeof options . directive === 'string'
33
+ ? exactRegex ( options . directive )
34
+ : options . directive
29
35
30
36
// re-export somehow confuses periscopic scopes so remove them before analysis
31
37
walk ( ast , {
@@ -48,9 +54,10 @@ export function transformHoistInlineDirective(
48
54
( node . type === 'FunctionExpression' ||
49
55
node . type === 'FunctionDeclaration' ||
50
56
node . type === 'ArrowFunctionExpression' ) &&
51
- node . body . type === 'BlockStatement' &&
52
- hasDirective ( node . body . body , directive )
57
+ node . body . type === 'BlockStatement'
53
58
) {
59
+ const match = matchDirective ( node . body . body , directive )
60
+ if ( ! match ) return
54
61
if ( ! node . async && rejectNonAsyncFunction ) {
55
62
throw Object . assign (
56
63
new Error ( `"${ directive } " doesn't allow non async function` ) ,
@@ -116,7 +123,9 @@ export function transformHoistInlineDirective(
116
123
output . move ( node . start , node . end , input . length )
117
124
118
125
// 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
+ } ) } `
120
129
if ( bindVars . length > 0 ) {
121
130
const bindArgs = options . encode
122
131
? options . encode ( '[' + bindVars . join ( ', ' ) + ']' )
@@ -140,3 +149,24 @@ export function transformHoistInlineDirective(
140
149
names,
141
150
}
142
151
}
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