@tsrx/vue 0.0.21 → 0.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -3
- package/src/index.js +2 -1
- package/src/transform.js +435 -193
- package/types/index.d.ts +3 -16
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Vue compiler built on @tsrx/core",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Dominic Gannaway",
|
|
6
|
-
"version": "0.0.
|
|
6
|
+
"version": "0.0.22",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"publishConfig": {
|
|
9
9
|
"access": "public"
|
|
@@ -29,12 +29,13 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"esrap": "^2.1.0",
|
|
32
|
+
"is-reference": "^3.0.3",
|
|
32
33
|
"zimmerframe": "^1.1.2",
|
|
33
|
-
"@tsrx/core": "0.0.
|
|
34
|
+
"@tsrx/core": "0.0.27"
|
|
34
35
|
},
|
|
35
36
|
"peerDependencies": {
|
|
36
37
|
"vue": ">=3.5",
|
|
37
|
-
"vue-jsx-vapor": ">=3.2.
|
|
38
|
+
"vue-jsx-vapor": ">=3.2.12"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
41
|
"@types/estree": "^1.0.8",
|
package/src/index.js
CHANGED
|
@@ -22,7 +22,7 @@ export function parse(source, filename, options) {
|
|
|
22
22
|
* @param {string} source
|
|
23
23
|
* @param {string} [filename]
|
|
24
24
|
* @param {{ collect?: boolean, loose?: boolean }} [options]
|
|
25
|
-
* @returns {{ code: string, map: any, css:
|
|
25
|
+
* @returns {{ code: string, map: any, css: string, cssHash: string | null, errors: CompileError[] }}
|
|
26
26
|
*/
|
|
27
27
|
export function compile(source, filename, options) {
|
|
28
28
|
const errors = /** @type {CompileError[]} */ ([]);
|
|
@@ -63,6 +63,7 @@ export function compile_to_volar_mappings(source, filename, options) {
|
|
|
63
63
|
const transformed = transform(ast, source, filename, {
|
|
64
64
|
collect: true,
|
|
65
65
|
loose: !!options?.loose,
|
|
66
|
+
typeOnly: true,
|
|
66
67
|
errors,
|
|
67
68
|
comments,
|
|
68
69
|
});
|
package/src/transform.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/** @import { JsxPlatform } from '@tsrx/core/types' */
|
|
2
2
|
|
|
3
|
+
import { walk } from 'zimmerframe';
|
|
4
|
+
import is_reference from 'is-reference';
|
|
3
5
|
import {
|
|
4
6
|
builders,
|
|
5
7
|
clone_expression_node,
|
|
6
8
|
clone_identifier,
|
|
9
|
+
create_generated_identifier,
|
|
7
10
|
componentToFunctionDeclaration,
|
|
8
11
|
createJsxTransform,
|
|
9
12
|
error,
|
|
10
|
-
identifier_to_jsx_name,
|
|
11
13
|
setLocation,
|
|
12
14
|
} from '@tsrx/core';
|
|
13
15
|
|
|
@@ -41,6 +43,7 @@ const vue_platform = {
|
|
|
41
43
|
hooks: {
|
|
42
44
|
initialState: () => ({
|
|
43
45
|
needs_define_vapor_component: false,
|
|
46
|
+
needs_vapor_for: false,
|
|
44
47
|
}),
|
|
45
48
|
isTopLevelSetupCall(call_expression) {
|
|
46
49
|
return is_vue_setup_call(call_expression);
|
|
@@ -55,18 +58,10 @@ const vue_platform = {
|
|
|
55
58
|
preprocessElementAttributes(attrs, ctx, element) {
|
|
56
59
|
return preprocess_ref_attributes(attrs, element, ctx);
|
|
57
60
|
},
|
|
58
|
-
renderForOf: (node, loop_params, body_statements) =>
|
|
59
|
-
|
|
61
|
+
renderForOf: (node, loop_params, body_statements, ctx) =>
|
|
62
|
+
render_for_of_as_vapor_for(node, loop_params, body_statements, ctx),
|
|
60
63
|
createErrorBoundaryContent(try_content) {
|
|
61
|
-
return
|
|
62
|
-
type: 'ArrowFunctionExpression',
|
|
63
|
-
params: [],
|
|
64
|
-
body: try_content.expression,
|
|
65
|
-
async: false,
|
|
66
|
-
generator: false,
|
|
67
|
-
expression: true,
|
|
68
|
-
metadata: { path: [] },
|
|
69
|
-
};
|
|
64
|
+
return builders.arrow([], try_content.expression);
|
|
70
65
|
},
|
|
71
66
|
transformElementChildren(node, walked_children, raw_children, attributes, ctx) {
|
|
72
67
|
return rewrite_host_text_or_html_children(
|
|
@@ -128,26 +123,12 @@ function component_to_vapor_component_declaration(component, transform_context,
|
|
|
128
123
|
};
|
|
129
124
|
/** @type {any} */ (component_id.metadata).hover = create_component_hover_replacement(fn.params);
|
|
130
125
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
type: 'VariableDeclarator',
|
|
138
|
-
id: component_id,
|
|
139
|
-
init: call,
|
|
140
|
-
metadata: { path: [] },
|
|
141
|
-
},
|
|
142
|
-
],
|
|
143
|
-
metadata: {
|
|
144
|
-
path: [],
|
|
145
|
-
generated_helpers,
|
|
146
|
-
generated_statics,
|
|
147
|
-
},
|
|
148
|
-
}),
|
|
149
|
-
component,
|
|
150
|
-
);
|
|
126
|
+
const declaration = builders.declaration('const', [builders.declarator(component_id, call)]);
|
|
127
|
+
Object.assign(/** @type {any} */ (declaration.metadata), {
|
|
128
|
+
generated_helpers,
|
|
129
|
+
generated_statics,
|
|
130
|
+
});
|
|
131
|
+
return setLocation(/** @type {any} */ (declaration), component);
|
|
151
132
|
}
|
|
152
133
|
|
|
153
134
|
/**
|
|
@@ -158,24 +139,17 @@ function component_to_vapor_component_declaration(component, transform_context,
|
|
|
158
139
|
*/
|
|
159
140
|
function wrap_helper_component(helper_fn, helper_id, source_node) {
|
|
160
141
|
return setLocation(
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
source_node,
|
|
173
|
-
),
|
|
174
|
-
metadata: { path: [] },
|
|
175
|
-
},
|
|
176
|
-
],
|
|
177
|
-
metadata: { path: [] },
|
|
178
|
-
}),
|
|
142
|
+
builders.declaration('const', [
|
|
143
|
+
builders.declarator(
|
|
144
|
+
clone_identifier(helper_id),
|
|
145
|
+
create_define_vapor_component_call(
|
|
146
|
+
function_declaration_to_expression(helper_fn),
|
|
147
|
+
[],
|
|
148
|
+
[],
|
|
149
|
+
source_node,
|
|
150
|
+
),
|
|
151
|
+
),
|
|
152
|
+
]),
|
|
179
153
|
source_node,
|
|
180
154
|
);
|
|
181
155
|
}
|
|
@@ -193,33 +167,22 @@ function create_define_vapor_component_call(
|
|
|
193
167
|
generated_statics,
|
|
194
168
|
source_node,
|
|
195
169
|
) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
metadata: { path: [] },
|
|
203
|
-
},
|
|
204
|
-
arguments: [fn_expression],
|
|
205
|
-
optional: false,
|
|
206
|
-
metadata: {
|
|
207
|
-
path: [],
|
|
208
|
-
generated_helpers,
|
|
209
|
-
generated_statics,
|
|
210
|
-
},
|
|
211
|
-
}),
|
|
212
|
-
source_node,
|
|
213
|
-
);
|
|
170
|
+
const call = builders.call('defineVaporComponent', fn_expression);
|
|
171
|
+
Object.assign(/** @type {any} */ (call.metadata), {
|
|
172
|
+
generated_helpers,
|
|
173
|
+
generated_statics,
|
|
174
|
+
});
|
|
175
|
+
return setLocation(call, source_node);
|
|
214
176
|
}
|
|
215
177
|
|
|
216
178
|
/**
|
|
217
179
|
* @param {any} node
|
|
218
180
|
* @param {any[]} loop_params
|
|
219
181
|
* @param {any[]} body_statements
|
|
182
|
+
* @param {any} transform_context
|
|
220
183
|
* @returns {any | null}
|
|
221
184
|
*/
|
|
222
|
-
function
|
|
185
|
+
function render_for_of_as_vapor_for(node, loop_params, body_statements, transform_context) {
|
|
223
186
|
if (body_statements.length !== 1) {
|
|
224
187
|
return null;
|
|
225
188
|
}
|
|
@@ -238,49 +201,43 @@ function render_for_of_as_vapor_template(node, loop_params, body_statements) {
|
|
|
238
201
|
? clone_expression_node(node.key)
|
|
239
202
|
: (find_jsx_key_expression(rendered) ??
|
|
240
203
|
(node.index ? clone_expression_node(node.index) : null));
|
|
241
|
-
|
|
242
|
-
const
|
|
204
|
+
|
|
205
|
+
const slot = key_expression
|
|
206
|
+
? create_keyed_vapor_for_slot(loop_params, rendered)
|
|
207
|
+
: { params: loop_params, body: rendered, expression: true };
|
|
208
|
+
if (!slot) {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
transform_context.needs_vapor_for = true;
|
|
213
|
+
|
|
214
|
+
if (key_expression) {
|
|
215
|
+
strip_top_level_jsx_keys(slot.body);
|
|
216
|
+
}
|
|
217
|
+
|
|
243
218
|
const attributes = [
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
type: 'BinaryExpression',
|
|
249
|
-
operator: 'in',
|
|
250
|
-
left: create_v_for_left(loop_params),
|
|
251
|
-
right: clone_expression_node(node.right),
|
|
252
|
-
metadata: { path: [] },
|
|
253
|
-
}),
|
|
254
|
-
metadata: { path: [] },
|
|
255
|
-
},
|
|
219
|
+
builders.jsx_attribute(
|
|
220
|
+
builders.jsx_id('in'),
|
|
221
|
+
to_jsx_expression_container(clone_expression_node(node.right)),
|
|
222
|
+
),
|
|
256
223
|
];
|
|
257
224
|
|
|
258
225
|
if (key_expression) {
|
|
259
|
-
attributes.push(
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
226
|
+
attributes.push(
|
|
227
|
+
builders.jsx_attribute(
|
|
228
|
+
builders.jsx_id('getKey'),
|
|
229
|
+
to_jsx_expression_container(create_loop_callback(loop_params, key_expression, true)),
|
|
230
|
+
),
|
|
231
|
+
);
|
|
265
232
|
}
|
|
266
233
|
|
|
267
|
-
return to_jsx_expression_container(
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
metadata: { path: [] },
|
|
275
|
-
},
|
|
276
|
-
closingElement: {
|
|
277
|
-
type: 'JSXClosingElement',
|
|
278
|
-
name: { type: 'JSXIdentifier', name: 'template', metadata: { path: [] } },
|
|
279
|
-
metadata: { path: [] },
|
|
280
|
-
},
|
|
281
|
-
children,
|
|
282
|
-
metadata: { path: [] },
|
|
283
|
-
});
|
|
234
|
+
return to_jsx_expression_container(
|
|
235
|
+
builders.jsx_element_fresh(
|
|
236
|
+
builders.jsx_opening_element(builders.jsx_id('VaporFor'), attributes),
|
|
237
|
+
builders.jsx_closing_element(builders.jsx_id('VaporFor')),
|
|
238
|
+
[to_jsx_expression_container(create_loop_callback(slot.params, slot.body, slot.expression))],
|
|
239
|
+
),
|
|
240
|
+
);
|
|
284
241
|
}
|
|
285
242
|
|
|
286
243
|
/**
|
|
@@ -290,47 +247,20 @@ function render_for_of_as_vapor_template(node, loop_params, body_statements) {
|
|
|
290
247
|
* @returns {any}
|
|
291
248
|
*/
|
|
292
249
|
function render_for_of_as_flat_map(node, loop_params, rendered) {
|
|
293
|
-
return to_jsx_expression_container(
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
},
|
|
303
|
-
arguments: [
|
|
304
|
-
{
|
|
305
|
-
type: 'ArrowFunctionExpression',
|
|
306
|
-
params: loop_params,
|
|
307
|
-
body: {
|
|
308
|
-
type: 'BlockStatement',
|
|
309
|
-
body: [
|
|
310
|
-
{
|
|
311
|
-
type: 'ReturnStatement',
|
|
312
|
-
argument: to_array_render_expression(rendered),
|
|
313
|
-
metadata: { path: [] },
|
|
314
|
-
},
|
|
315
|
-
],
|
|
316
|
-
metadata: { path: [] },
|
|
317
|
-
},
|
|
318
|
-
async: false,
|
|
319
|
-
generator: false,
|
|
320
|
-
expression: false,
|
|
321
|
-
metadata: { path: [] },
|
|
322
|
-
},
|
|
323
|
-
],
|
|
324
|
-
async: false,
|
|
325
|
-
optional: false,
|
|
326
|
-
metadata: { path: [] },
|
|
327
|
-
});
|
|
250
|
+
return to_jsx_expression_container(
|
|
251
|
+
builders.call(
|
|
252
|
+
builders.member(clone_expression_node(node.right), 'flatMap'),
|
|
253
|
+
builders.arrow(
|
|
254
|
+
loop_params,
|
|
255
|
+
builders.block([builders.return(to_array_render_expression(rendered))]),
|
|
256
|
+
),
|
|
257
|
+
),
|
|
258
|
+
);
|
|
328
259
|
}
|
|
329
260
|
|
|
330
261
|
/**
|
|
331
|
-
*
|
|
332
|
-
*
|
|
333
|
-
* lowering so `continue` truly skips the iteration.
|
|
262
|
+
* Loop bodies that can return `null` need the shared callback lowering so
|
|
263
|
+
* `continue` truly skips the iteration.
|
|
334
264
|
*
|
|
335
265
|
* @param {any} node
|
|
336
266
|
* @returns {boolean}
|
|
@@ -386,22 +316,6 @@ function to_array_render_expression(node) {
|
|
|
386
316
|
return builders.array([node]);
|
|
387
317
|
}
|
|
388
318
|
|
|
389
|
-
/**
|
|
390
|
-
* @param {any[]} loop_params
|
|
391
|
-
* @returns {any}
|
|
392
|
-
*/
|
|
393
|
-
function create_v_for_left(loop_params) {
|
|
394
|
-
if (loop_params.length === 1) {
|
|
395
|
-
return clone_expression_node(loop_params[0]);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
return {
|
|
399
|
-
type: 'SequenceExpression',
|
|
400
|
-
expressions: loop_params.map((param) => clone_expression_node(param)),
|
|
401
|
-
metadata: { path: [] },
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
|
|
405
319
|
/**
|
|
406
320
|
* @param {any} node
|
|
407
321
|
* @returns {any | null}
|
|
@@ -450,6 +364,360 @@ function strip_top_level_jsx_keys(node) {
|
|
|
450
364
|
}
|
|
451
365
|
}
|
|
452
366
|
|
|
367
|
+
/**
|
|
368
|
+
* @param {any[]} loop_params
|
|
369
|
+
* @param {any} body
|
|
370
|
+
* @param {boolean} expression
|
|
371
|
+
* @returns {any}
|
|
372
|
+
*/
|
|
373
|
+
function create_loop_callback(loop_params, body, expression) {
|
|
374
|
+
const callback = builders.arrow(
|
|
375
|
+
loop_params.map((param) => clone_expression_node(param)),
|
|
376
|
+
body,
|
|
377
|
+
);
|
|
378
|
+
callback.expression = expression;
|
|
379
|
+
return callback;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* @param {any[]} loop_params
|
|
384
|
+
* @param {any} rendered
|
|
385
|
+
* @returns {{ params: any[], body: any, expression: boolean } | null}
|
|
386
|
+
*/
|
|
387
|
+
function create_keyed_vapor_for_slot(loop_params, rendered) {
|
|
388
|
+
if (loop_params[0]?.type === 'Identifier') {
|
|
389
|
+
return {
|
|
390
|
+
params: loop_params,
|
|
391
|
+
body: rewrite_vapor_for_keyed_slot_refs(rendered, loop_params),
|
|
392
|
+
expression: true,
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const item_ref = create_generated_identifier('__vapor_item');
|
|
397
|
+
const item_ref_value = create_value_member_expression(item_ref);
|
|
398
|
+
const replacements = create_pattern_replacements(loop_params[0], item_ref_value);
|
|
399
|
+
if (!replacements) {
|
|
400
|
+
return null;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
const params = [item_ref, ...loop_params.slice(1)];
|
|
404
|
+
const rewritten_rendered = rewrite_vapor_for_keyed_slot_refs(
|
|
405
|
+
rendered,
|
|
406
|
+
loop_params.slice(1),
|
|
407
|
+
replacements,
|
|
408
|
+
);
|
|
409
|
+
|
|
410
|
+
return {
|
|
411
|
+
params,
|
|
412
|
+
body: rewritten_rendered,
|
|
413
|
+
expression: true,
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Vue's `VaporFor` passes plain item values to unkeyed slots, but keyed slots
|
|
419
|
+
* receive shallow refs so row instances can update in place. Match that runtime
|
|
420
|
+
* shape by reading loop params through `.value` inside the slot body.
|
|
421
|
+
*
|
|
422
|
+
* @param {any} node
|
|
423
|
+
* @param {any[]} loop_params
|
|
424
|
+
* @param {Map<string, any>} [replacements]
|
|
425
|
+
* @returns {any}
|
|
426
|
+
*/
|
|
427
|
+
function rewrite_vapor_for_keyed_slot_refs(node, loop_params, replacements = new Map()) {
|
|
428
|
+
const loop_param_names = new Set();
|
|
429
|
+
for (const param of loop_params) {
|
|
430
|
+
collect_pattern_names(param, loop_param_names);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (loop_param_names.size === 0 && replacements.size === 0) {
|
|
434
|
+
return node;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
return walk(
|
|
438
|
+
node,
|
|
439
|
+
{ loop_param_names, shadowed_names: new Set() },
|
|
440
|
+
{
|
|
441
|
+
Identifier(identifier, { path, state, next }) {
|
|
442
|
+
const parent = path.at(-1);
|
|
443
|
+
if (
|
|
444
|
+
(state.loop_param_names.has(identifier.name) || replacements.has(identifier.name)) &&
|
|
445
|
+
!state.shadowed_names.has(identifier.name) &&
|
|
446
|
+
parent &&
|
|
447
|
+
is_runtime_reference(identifier, parent)
|
|
448
|
+
) {
|
|
449
|
+
const replacement = replacements.get(identifier.name);
|
|
450
|
+
if (replacement) {
|
|
451
|
+
return clone_expression_node(replacement);
|
|
452
|
+
}
|
|
453
|
+
return create_value_member_expression(identifier);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
return next();
|
|
457
|
+
},
|
|
458
|
+
FunctionDeclaration: rewrite_function_shadowed_refs,
|
|
459
|
+
FunctionExpression: rewrite_function_shadowed_refs,
|
|
460
|
+
ArrowFunctionExpression: rewrite_function_shadowed_refs,
|
|
461
|
+
BlockStatement: rewrite_block_shadowed_refs,
|
|
462
|
+
},
|
|
463
|
+
);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* @param {any} identifier
|
|
468
|
+
* @param {any} parent
|
|
469
|
+
* @returns {boolean}
|
|
470
|
+
*/
|
|
471
|
+
function is_runtime_reference(identifier, parent) {
|
|
472
|
+
if (parent.type === 'JSXExpressionContainer') {
|
|
473
|
+
return parent.expression === identifier;
|
|
474
|
+
}
|
|
475
|
+
if (parent.type === 'JSXAttribute') {
|
|
476
|
+
return parent.value === identifier || parent.value?.expression === identifier;
|
|
477
|
+
}
|
|
478
|
+
return is_reference(identifier, parent);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* @param {any} pattern
|
|
483
|
+
* @param {any} source
|
|
484
|
+
* @returns {Map<string, any> | null}
|
|
485
|
+
*/
|
|
486
|
+
function create_pattern_replacements(pattern, source) {
|
|
487
|
+
const replacements = new Map();
|
|
488
|
+
return collect_pattern_replacements(pattern, source, replacements) ? replacements : null;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* @param {any} pattern
|
|
493
|
+
* @param {any} source
|
|
494
|
+
* @param {Map<string, any>} replacements
|
|
495
|
+
* @returns {boolean}
|
|
496
|
+
*/
|
|
497
|
+
function collect_pattern_replacements(pattern, source, replacements) {
|
|
498
|
+
if (!pattern) return true;
|
|
499
|
+
|
|
500
|
+
switch (pattern.type) {
|
|
501
|
+
case 'Identifier':
|
|
502
|
+
replacements.set(pattern.name, source);
|
|
503
|
+
return true;
|
|
504
|
+
case 'ObjectPattern':
|
|
505
|
+
for (const property of pattern.properties || []) {
|
|
506
|
+
if (property.type === 'RestElement' || property.computed) {
|
|
507
|
+
return false;
|
|
508
|
+
}
|
|
509
|
+
if (
|
|
510
|
+
property.type !== 'Property' ||
|
|
511
|
+
!collect_pattern_replacements(
|
|
512
|
+
property.value,
|
|
513
|
+
create_property_member_expression(source, property.key),
|
|
514
|
+
replacements,
|
|
515
|
+
)
|
|
516
|
+
) {
|
|
517
|
+
return false;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
return true;
|
|
521
|
+
case 'ArrayPattern':
|
|
522
|
+
for (let index = 0; index < (pattern.elements || []).length; index++) {
|
|
523
|
+
const element = pattern.elements[index];
|
|
524
|
+
if (
|
|
525
|
+
element &&
|
|
526
|
+
!collect_pattern_replacements(
|
|
527
|
+
element,
|
|
528
|
+
create_index_member_expression(source, index),
|
|
529
|
+
replacements,
|
|
530
|
+
)
|
|
531
|
+
) {
|
|
532
|
+
return false;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
return true;
|
|
536
|
+
default:
|
|
537
|
+
return false;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* @param {any} node
|
|
543
|
+
* @param {{ state: { loop_param_names: Set<string>, shadowed_names: Set<string> }, next: (state?: any) => any }} context
|
|
544
|
+
* @returns {any}
|
|
545
|
+
*/
|
|
546
|
+
function rewrite_function_shadowed_refs(node, { state, next }) {
|
|
547
|
+
const shadowed_names = new Set(state.shadowed_names);
|
|
548
|
+
if (node.id) {
|
|
549
|
+
collect_pattern_names(node.id, shadowed_names);
|
|
550
|
+
}
|
|
551
|
+
for (const param of node.params || []) {
|
|
552
|
+
collect_pattern_names(param, shadowed_names);
|
|
553
|
+
}
|
|
554
|
+
collect_function_var_names(node.body, shadowed_names);
|
|
555
|
+
return next({ ...state, shadowed_names });
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* @param {any} node
|
|
560
|
+
* @param {{ state: { loop_param_names: Set<string>, shadowed_names: Set<string> }, next: (state?: any) => any }} context
|
|
561
|
+
* @returns {any}
|
|
562
|
+
*/
|
|
563
|
+
function rewrite_block_shadowed_refs(node, { state, next }) {
|
|
564
|
+
const shadowed_names = new Set(state.shadowed_names);
|
|
565
|
+
collect_block_lexical_names(node.body, shadowed_names);
|
|
566
|
+
return next({ ...state, shadowed_names });
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* @param {any[]} statements
|
|
571
|
+
* @param {Set<string>} names
|
|
572
|
+
* @returns {void}
|
|
573
|
+
*/
|
|
574
|
+
function collect_block_lexical_names(statements, names) {
|
|
575
|
+
for (const statement of statements || []) {
|
|
576
|
+
if (statement.type === 'VariableDeclaration' && statement.kind !== 'var') {
|
|
577
|
+
for (const declaration of statement.declarations || []) {
|
|
578
|
+
collect_pattern_names(declaration.id, names);
|
|
579
|
+
}
|
|
580
|
+
continue;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
if (
|
|
584
|
+
(statement.type === 'FunctionDeclaration' || statement.type === 'ClassDeclaration') &&
|
|
585
|
+
statement.id
|
|
586
|
+
) {
|
|
587
|
+
collect_pattern_names(statement.id, names);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* @param {any} node
|
|
594
|
+
* @param {Set<string>} names
|
|
595
|
+
* @returns {void}
|
|
596
|
+
*/
|
|
597
|
+
function collect_function_var_names(node, names) {
|
|
598
|
+
if (!node || typeof node !== 'object') return;
|
|
599
|
+
|
|
600
|
+
if (Array.isArray(node)) {
|
|
601
|
+
for (const child of node) {
|
|
602
|
+
collect_function_var_names(child, names);
|
|
603
|
+
}
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
if (
|
|
608
|
+
node.type === 'FunctionDeclaration' ||
|
|
609
|
+
node.type === 'FunctionExpression' ||
|
|
610
|
+
node.type === 'ArrowFunctionExpression' ||
|
|
611
|
+
node.type === 'ClassDeclaration' ||
|
|
612
|
+
node.type === 'ClassExpression'
|
|
613
|
+
) {
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
if (node.type === 'VariableDeclaration' && node.kind === 'var') {
|
|
618
|
+
for (const declaration of node.declarations || []) {
|
|
619
|
+
collect_pattern_names(declaration.id, names);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
for (const key of Object.keys(node)) {
|
|
624
|
+
if (key === 'loc' || key === 'start' || key === 'end' || key === 'metadata') {
|
|
625
|
+
continue;
|
|
626
|
+
}
|
|
627
|
+
collect_function_var_names(node[key], names);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
/**
|
|
632
|
+
* @param {any} node
|
|
633
|
+
* @param {Set<string>} names
|
|
634
|
+
* @returns {void}
|
|
635
|
+
*/
|
|
636
|
+
function collect_pattern_names(node, names) {
|
|
637
|
+
if (!node) return;
|
|
638
|
+
|
|
639
|
+
switch (node.type) {
|
|
640
|
+
case 'Identifier':
|
|
641
|
+
names.add(node.name);
|
|
642
|
+
break;
|
|
643
|
+
case 'RestElement':
|
|
644
|
+
collect_pattern_names(node.argument, names);
|
|
645
|
+
break;
|
|
646
|
+
case 'AssignmentPattern':
|
|
647
|
+
collect_pattern_names(node.left, names);
|
|
648
|
+
break;
|
|
649
|
+
case 'ArrayPattern':
|
|
650
|
+
for (const element of node.elements || []) {
|
|
651
|
+
collect_pattern_names(element, names);
|
|
652
|
+
}
|
|
653
|
+
break;
|
|
654
|
+
case 'ObjectPattern':
|
|
655
|
+
for (const property of node.properties || []) {
|
|
656
|
+
collect_pattern_names(property, names);
|
|
657
|
+
}
|
|
658
|
+
break;
|
|
659
|
+
case 'Property':
|
|
660
|
+
collect_pattern_names(node.value, names);
|
|
661
|
+
break;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* @param {any} object
|
|
667
|
+
* @param {any} key
|
|
668
|
+
* @returns {any}
|
|
669
|
+
*/
|
|
670
|
+
function create_property_member_expression(object, key) {
|
|
671
|
+
if (key?.type === 'Identifier') {
|
|
672
|
+
return create_member_expression(
|
|
673
|
+
clone_expression_node(object),
|
|
674
|
+
clone_identifier(key),
|
|
675
|
+
false,
|
|
676
|
+
key,
|
|
677
|
+
);
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
return create_member_expression(
|
|
681
|
+
clone_expression_node(object),
|
|
682
|
+
clone_expression_node(key),
|
|
683
|
+
true,
|
|
684
|
+
key,
|
|
685
|
+
);
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* @param {any} object
|
|
690
|
+
* @param {number} index
|
|
691
|
+
* @returns {any}
|
|
692
|
+
*/
|
|
693
|
+
function create_index_member_expression(object, index) {
|
|
694
|
+
return create_member_expression(
|
|
695
|
+
clone_expression_node(object),
|
|
696
|
+
builders.literal(index),
|
|
697
|
+
true,
|
|
698
|
+
object,
|
|
699
|
+
);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
/**
|
|
703
|
+
* @param {any} identifier
|
|
704
|
+
* @returns {any}
|
|
705
|
+
*/
|
|
706
|
+
function create_value_member_expression(identifier) {
|
|
707
|
+
return create_member_expression(clone_identifier(identifier), 'value', false, identifier);
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* @param {any} object
|
|
712
|
+
* @param {any} property
|
|
713
|
+
* @param {boolean} computed
|
|
714
|
+
* @param {any} source_node
|
|
715
|
+
* @returns {any}
|
|
716
|
+
*/
|
|
717
|
+
function create_member_expression(object, property, computed, source_node) {
|
|
718
|
+
return builders.member(object, property, computed, false, source_node);
|
|
719
|
+
}
|
|
720
|
+
|
|
453
721
|
/**
|
|
454
722
|
* @param {any} fn
|
|
455
723
|
* @returns {any}
|
|
@@ -652,16 +920,7 @@ function has_dom_content_attribute(attributes, name) {
|
|
|
652
920
|
* @returns {any}
|
|
653
921
|
*/
|
|
654
922
|
function create_jsx_attribute(name, value, source_node) {
|
|
655
|
-
return
|
|
656
|
-
/** @type {any} */ ({
|
|
657
|
-
type: 'JSXAttribute',
|
|
658
|
-
name: identifier_to_jsx_name(builders.id(name)),
|
|
659
|
-
value,
|
|
660
|
-
shorthand: false,
|
|
661
|
-
metadata: { path: [] },
|
|
662
|
-
}),
|
|
663
|
-
source_node,
|
|
664
|
-
);
|
|
923
|
+
return builders.jsx_attribute(builders.jsx_id(name), value, false, source_node);
|
|
665
924
|
}
|
|
666
925
|
|
|
667
926
|
/**
|
|
@@ -670,12 +929,7 @@ function create_jsx_attribute(name, value, source_node) {
|
|
|
670
929
|
* @returns {any}
|
|
671
930
|
*/
|
|
672
931
|
function to_jsx_expression_container(expression, source_node = expression) {
|
|
673
|
-
|
|
674
|
-
return {
|
|
675
|
-
type: 'JSXExpressionContainer',
|
|
676
|
-
expression,
|
|
677
|
-
metadata: { path: [] },
|
|
678
|
-
};
|
|
932
|
+
return builders.jsx_expression_container(expression, source_node);
|
|
679
933
|
}
|
|
680
934
|
|
|
681
935
|
/**
|
|
@@ -741,6 +995,10 @@ function inject_vue_imports(program, transform_context) {
|
|
|
741
995
|
ensure_named_import(program, 'vue-jsx-vapor', 'defineVaporComponent');
|
|
742
996
|
}
|
|
743
997
|
|
|
998
|
+
if (transform_context.needs_vapor_for) {
|
|
999
|
+
ensure_named_import(program, 'vue-jsx-vapor', 'VaporFor');
|
|
1000
|
+
}
|
|
1001
|
+
|
|
744
1002
|
if (transform_context.needs_suspense) {
|
|
745
1003
|
ensure_named_import(program, 'vue', 'Suspense');
|
|
746
1004
|
}
|
|
@@ -782,7 +1040,7 @@ function ensure_named_import(program, source, name, local = name) {
|
|
|
782
1040
|
return;
|
|
783
1041
|
}
|
|
784
1042
|
|
|
785
|
-
program.body.unshift(
|
|
1043
|
+
program.body.unshift(builders.imports([[name, local, 'value']], source));
|
|
786
1044
|
}
|
|
787
1045
|
|
|
788
1046
|
/**
|
|
@@ -799,19 +1057,3 @@ function create_import_specifier(name, local = name) {
|
|
|
799
1057
|
metadata: { path: [] },
|
|
800
1058
|
};
|
|
801
1059
|
}
|
|
802
|
-
|
|
803
|
-
/**
|
|
804
|
-
* @param {string} source
|
|
805
|
-
* @param {any[]} specifiers
|
|
806
|
-
* @returns {any}
|
|
807
|
-
*/
|
|
808
|
-
function create_import_declaration(source, specifiers) {
|
|
809
|
-
return {
|
|
810
|
-
type: 'ImportDeclaration',
|
|
811
|
-
attributes: [],
|
|
812
|
-
specifiers,
|
|
813
|
-
importKind: 'value',
|
|
814
|
-
source: builders.literal(source),
|
|
815
|
-
metadata: { path: [] },
|
|
816
|
-
};
|
|
817
|
-
}
|
package/types/index.d.ts
CHANGED
|
@@ -1,21 +1,8 @@
|
|
|
1
1
|
import type { Program } from 'estree';
|
|
2
|
-
import type {
|
|
2
|
+
import type { CompileFn, ParseOptions, VolarCompileFn } from '@tsrx/core/types';
|
|
3
3
|
|
|
4
4
|
export function parse(source: string, filename?: string, options?: ParseOptions): Program;
|
|
5
5
|
|
|
6
|
-
export
|
|
7
|
-
source: string,
|
|
8
|
-
filename?: string,
|
|
9
|
-
options?: { collect?: boolean; loose?: boolean },
|
|
10
|
-
): {
|
|
11
|
-
code: string;
|
|
12
|
-
map: unknown;
|
|
13
|
-
css: { code: string; hash: string } | null;
|
|
14
|
-
errors: CompileError[];
|
|
15
|
-
};
|
|
6
|
+
export const compile: CompileFn;
|
|
16
7
|
|
|
17
|
-
export
|
|
18
|
-
source: string,
|
|
19
|
-
filename?: string,
|
|
20
|
-
options?: ParseOptions,
|
|
21
|
-
): VolarMappingsResult;
|
|
8
|
+
export const compile_to_volar_mappings: VolarCompileFn;
|