|
1 | 1 | import { tinyassert } from '@hiogawa/utils'
|
2 |
| -import type { Program } from 'estree' |
| 2 | +import type { Program, Literal } from 'estree' |
3 | 3 | import { walk } from 'estree-walker'
|
4 | 4 | import MagicString from 'magic-string'
|
5 | 5 | import { analyze } from 'periscopic'
|
@@ -56,7 +56,7 @@ export function transformHoistInlineDirective(
|
56 | 56 | node.type === 'ArrowFunctionExpression') &&
|
57 | 57 | node.body.type === 'BlockStatement'
|
58 | 58 | ) {
|
59 |
| - const match = matchDirective(node.body.body, directive) |
| 59 | + const match = matchDirective(node.body.body, directive)?.match |
60 | 60 | if (!match) return
|
61 | 61 | if (!node.async && rejectNonAsyncFunction) {
|
62 | 62 | throw Object.assign(
|
@@ -156,17 +156,33 @@ const exactRegex = (s: string): RegExp =>
|
156 | 156 | function matchDirective(
|
157 | 157 | body: Program['body'],
|
158 | 158 | directive: RegExp,
|
159 |
| -): RegExpMatchArray | undefined { |
160 |
| - for (const stable of body) { |
| 159 | +): { match: RegExpMatchArray; node: Literal } | undefined { |
| 160 | + for (const stmt of body) { |
161 | 161 | if (
|
162 |
| - stable.type === 'ExpressionStatement' && |
163 |
| - stable.expression.type === 'Literal' && |
164 |
| - typeof stable.expression.value === 'string' |
| 162 | + stmt.type === 'ExpressionStatement' && |
| 163 | + stmt.expression.type === 'Literal' && |
| 164 | + typeof stmt.expression.value === 'string' |
165 | 165 | ) {
|
166 |
| - const match = stable.expression.value.match(directive) |
| 166 | + const match = stmt.expression.value.match(directive) |
167 | 167 | if (match) {
|
168 |
| - return match |
| 168 | + return { match, node: stmt.expression } |
169 | 169 | }
|
170 | 170 | }
|
171 | 171 | }
|
172 | 172 | }
|
| 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