@tsrx/core 0.1.18 → 0.1.19
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 +1 -1
- package/src/index.js +0 -1
- package/src/transform/jsx/helpers.js +17 -19
- package/src/transform/jsx/index.js +391 -267
- package/types/index.d.ts +19 -1
- package/types/jsx-platform.d.ts +1 -7
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -162,7 +162,6 @@ export {
|
|
|
162
162
|
validate_at_most_one_ref_attribute as validateAtMostOneRefAttribute,
|
|
163
163
|
} from './transform/jsx/index.js';
|
|
164
164
|
export {
|
|
165
|
-
ensure_function_metadata as ensureFunctionMetadata,
|
|
166
165
|
in_jsx_child_context as inJsxChildContext,
|
|
167
166
|
tsx_node_to_jsx_expression as tsxNodeToJsxExpression,
|
|
168
167
|
tsx_with_ts_locations as tsxWithTsLocations,
|
|
@@ -17,6 +17,23 @@ export function in_jsx_child_context(path) {
|
|
|
17
17
|
return !!parent && parent.type === 'Element';
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Match Ripple's transform path metadata shape: every node seen by the walker
|
|
22
|
+
* carries its current ancestor path for downstream CSS pruning and mapping
|
|
23
|
+
* helpers.
|
|
24
|
+
*
|
|
25
|
+
* @param {any} node
|
|
26
|
+
* @param {any[]} path
|
|
27
|
+
* @returns {void}
|
|
28
|
+
*/
|
|
29
|
+
export function set_node_path_metadata(node, path) {
|
|
30
|
+
if (!node.metadata) {
|
|
31
|
+
node.metadata = { path: [...path] };
|
|
32
|
+
} else {
|
|
33
|
+
node.metadata.path = [...path];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
20
37
|
/**
|
|
21
38
|
* Flatten a `<tsx>` / fragment node's children into a single expression. In a
|
|
22
39
|
* JSX-child position, a JSXExpressionContainer `{expr}` is valid and must stay
|
|
@@ -49,25 +66,6 @@ export function tsx_node_to_jsx_expression(node, in_jsx_child = false) {
|
|
|
49
66
|
});
|
|
50
67
|
}
|
|
51
68
|
|
|
52
|
-
/**
|
|
53
|
-
* Default `node.metadata` to `{ path: [] }` if missing, then continue the
|
|
54
|
-
* walk. Use as the `FunctionDeclaration` / `FunctionExpression` /
|
|
55
|
-
* `ArrowFunctionExpression` visitor in a zimmerframe walk so that downstream
|
|
56
|
-
* consumers don't trip on an undefined metadata object.
|
|
57
|
-
*
|
|
58
|
-
* Ripple's analyze phase does this via `visit_function`; the tsrx-* targets
|
|
59
|
-
* have no analyze phase, so we default metadata during the main walk.
|
|
60
|
-
*
|
|
61
|
-
* @param {any} node
|
|
62
|
-
* @param {{ next: () => any }} ctx
|
|
63
|
-
*/
|
|
64
|
-
export function ensure_function_metadata(node, { next }) {
|
|
65
|
-
if (!node.metadata) {
|
|
66
|
-
node.metadata = { path: [] };
|
|
67
|
-
}
|
|
68
|
-
return next();
|
|
69
|
-
}
|
|
70
|
-
|
|
71
69
|
/**
|
|
72
70
|
* Wrap esrap's `tsx()` printer with location markers for nodes whose spans
|
|
73
71
|
* (e.g. the leading `new ` of a NewExpression or the angle-bracket delimiters
|
|
@@ -8,8 +8,8 @@ import { error } from '../../errors.js';
|
|
|
8
8
|
import { analyze_css } from '../../analyze/css-analyze.js';
|
|
9
9
|
import { prune_css } from '../../analyze/prune.js';
|
|
10
10
|
import {
|
|
11
|
-
ensure_function_metadata,
|
|
12
11
|
in_jsx_child_context,
|
|
12
|
+
set_node_path_metadata,
|
|
13
13
|
tsx_node_to_jsx_expression,
|
|
14
14
|
tsx_with_ts_locations,
|
|
15
15
|
} from './helpers.js';
|
|
@@ -169,6 +169,8 @@ export function createJsxTransform(platform) {
|
|
|
169
169
|
const collect = !!(options?.collect || options?.loose);
|
|
170
170
|
/** @type {any[]} */
|
|
171
171
|
const stylesheets = [];
|
|
172
|
+
/** @type {AST.Statement[]} */
|
|
173
|
+
const type_only_style_anchors = [];
|
|
172
174
|
|
|
173
175
|
/** @type {TransformContext} */
|
|
174
176
|
const transform_context = {
|
|
@@ -183,6 +185,7 @@ export function createJsxTransform(platform) {
|
|
|
183
185
|
needs_for_of_iterable: false,
|
|
184
186
|
needs_iteration_value_type: false,
|
|
185
187
|
stylesheets,
|
|
188
|
+
type_only_style_anchors,
|
|
186
189
|
module_scoped_hook_components:
|
|
187
190
|
options?.moduleScopedHookComponents ?? !!platform.hooks?.moduleScopedHookComponents,
|
|
188
191
|
helper_state: null,
|
|
@@ -204,13 +207,12 @@ export function createJsxTransform(platform) {
|
|
|
204
207
|
preallocate_lazy_ids(/** @type {any} */ (ast), transform_context);
|
|
205
208
|
}
|
|
206
209
|
|
|
207
|
-
walk(/** @type {any} */ (ast), transform_context, {
|
|
208
|
-
FunctionDeclaration: collect_native_function_tsrx_metadata,
|
|
209
|
-
FunctionExpression: collect_native_function_tsrx_metadata,
|
|
210
|
-
ArrowFunctionExpression: collect_native_function_tsrx_metadata,
|
|
211
|
-
});
|
|
212
|
-
|
|
213
210
|
const transformed = walk(/** @type {any} */ (ast), transform_context, {
|
|
211
|
+
_(node, { next, path }) {
|
|
212
|
+
set_node_path_metadata(node, path);
|
|
213
|
+
return next();
|
|
214
|
+
},
|
|
215
|
+
|
|
214
216
|
Tsx(node, { next, path }) {
|
|
215
217
|
const inner = /** @type {any} */ (next() ?? node);
|
|
216
218
|
const in_jsx_child = in_jsx_child_context(path);
|
|
@@ -219,27 +221,24 @@ export function createJsxTransform(platform) {
|
|
|
219
221
|
);
|
|
220
222
|
},
|
|
221
223
|
|
|
222
|
-
Tsrx(node, { next, path, state }) {
|
|
223
|
-
/** @type {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
224
|
+
Tsrx(node, { next, path, state, visit }) {
|
|
225
|
+
const parent = /** @type {AST.ArrowFunctionExpression} */ (path.at(-1));
|
|
226
|
+
if (parent?.metadata?.native_tsrx && parent.body === node) {
|
|
227
|
+
return /** @type {any} */ (visit(create_native_tsrx_render_block(node, state), state));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const style_context = prepare_tsrx_fragment_styles(node, state);
|
|
231
|
+
const target = style_context?.fragment ?? next() ?? node;
|
|
232
|
+
const in_jsx_child = in_jsx_child_context(path);
|
|
233
|
+
const expression = tsrx_node_to_jsx_expression(target, state, in_jsx_child);
|
|
229
234
|
for (const statement of create_tsrx_style_ref_setup_statements(
|
|
230
|
-
|
|
235
|
+
target,
|
|
231
236
|
style_context,
|
|
232
237
|
state,
|
|
233
238
|
)) {
|
|
234
|
-
add_jsx_setup_declaration(
|
|
239
|
+
add_jsx_setup_declaration(expression, statement);
|
|
235
240
|
}
|
|
236
|
-
|
|
237
|
-
return /** @type {any} */ (
|
|
238
|
-
wrap_jsx_setup_declarations(
|
|
239
|
-
tsrx_node_to_jsx_expression(inner, state, in_jsx_child),
|
|
240
|
-
in_jsx_child,
|
|
241
|
-
)
|
|
242
|
-
);
|
|
241
|
+
return /** @type {any} */ (wrap_jsx_setup_declarations(expression, in_jsx_child));
|
|
243
242
|
},
|
|
244
243
|
|
|
245
244
|
TsxCompat(node, { next, path, state }) {
|
|
@@ -259,7 +258,7 @@ export function createJsxTransform(platform) {
|
|
|
259
258
|
if (stylesheet) {
|
|
260
259
|
analyze_css(stylesheet);
|
|
261
260
|
state.stylesheets.push(stylesheet);
|
|
262
|
-
return /** @type {any} */ (
|
|
261
|
+
return /** @type {any} */ (create_style_expression_value(node, stylesheet, state));
|
|
263
262
|
}
|
|
264
263
|
}
|
|
265
264
|
|
|
@@ -288,9 +287,9 @@ export function createJsxTransform(platform) {
|
|
|
288
287
|
return /** @type {any} */ (to_jsx_expression_container(inner.expression, inner));
|
|
289
288
|
},
|
|
290
289
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
290
|
+
BlockStatement: transform_block_statement,
|
|
291
|
+
ReturnStatement: transform_return_statement,
|
|
292
|
+
|
|
294
293
|
// If an uppercase JS function contains hook-bearing TSRX, give it a
|
|
295
294
|
// temporary helper scope so extracted hook helpers get stable identities.
|
|
296
295
|
FunctionDeclaration: transform_function,
|
|
@@ -303,17 +302,24 @@ export function createJsxTransform(platform) {
|
|
|
303
302
|
return visited;
|
|
304
303
|
}
|
|
305
304
|
const is_component = is_component_like_jsx_name(visited.name);
|
|
306
|
-
return
|
|
307
|
-
|
|
308
|
-
|
|
305
|
+
return b.jsx_opening_element(
|
|
306
|
+
visited.name,
|
|
307
|
+
merge_duplicate_refs(
|
|
309
308
|
normalize_host_ref_spreads(visited.attributes || [], !is_component, transform_context),
|
|
310
309
|
transform_context,
|
|
311
310
|
),
|
|
312
|
-
|
|
311
|
+
visited.selfClosing,
|
|
312
|
+
visited.typeArguments,
|
|
313
|
+
visited,
|
|
314
|
+
);
|
|
313
315
|
},
|
|
314
316
|
});
|
|
315
317
|
|
|
316
|
-
const
|
|
318
|
+
const transformed_program = /** @type {AST.Program} */ (transformed);
|
|
319
|
+
if (type_only_style_anchors.length > 0) {
|
|
320
|
+
transformed_program.body.unshift(...type_only_style_anchors);
|
|
321
|
+
}
|
|
322
|
+
const expanded = expand_component_helpers(transformed_program);
|
|
317
323
|
if (platform.hooks?.injectImports) {
|
|
318
324
|
platform.hooks.injectImports(expanded, transform_context, suspense_source);
|
|
319
325
|
} else {
|
|
@@ -593,48 +599,56 @@ function is_interleaved_body(body_nodes) {
|
|
|
593
599
|
* @param {TransformContext} transform_context
|
|
594
600
|
* @returns {boolean}
|
|
595
601
|
*/
|
|
596
|
-
function
|
|
602
|
+
function needs_hook_split(node, transform_context) {
|
|
597
603
|
return (
|
|
598
604
|
transform_context.platform.hooks?.componentBodyHookHelpers === true &&
|
|
599
605
|
node.body?.type === 'BlockStatement' &&
|
|
600
|
-
|
|
606
|
+
find_hook_split_index(node.body.body || [], transform_context) !== -1
|
|
601
607
|
);
|
|
602
608
|
}
|
|
603
609
|
|
|
604
610
|
/**
|
|
605
611
|
* @param {any} node
|
|
606
612
|
* @param {TransformContext} transform_context
|
|
607
|
-
* @returns {
|
|
613
|
+
* @returns {any}
|
|
608
614
|
*/
|
|
609
|
-
function
|
|
615
|
+
function create_hook_split_block(node, transform_context) {
|
|
610
616
|
if (
|
|
611
617
|
transform_context.platform.hooks?.componentBodyHookHelpers !== true ||
|
|
612
618
|
!should_extract_hook_helpers(transform_context) ||
|
|
613
619
|
node.body?.type !== 'BlockStatement'
|
|
614
620
|
) {
|
|
615
|
-
return;
|
|
621
|
+
return null;
|
|
616
622
|
}
|
|
617
623
|
|
|
618
624
|
const body = node.body.body || [];
|
|
619
|
-
const split_index =
|
|
625
|
+
const split_index = find_hook_split_index(body, transform_context);
|
|
620
626
|
if (split_index === -1) {
|
|
621
|
-
return;
|
|
627
|
+
return null;
|
|
622
628
|
}
|
|
623
629
|
|
|
624
630
|
const split_statement = body[split_index];
|
|
625
631
|
const continuation_body = body.slice(split_index + 1);
|
|
626
632
|
const helper = create_hook_safe_helper(
|
|
627
|
-
continuation_body,
|
|
633
|
+
expand_native_tsrx_return_statement_list(continuation_body, transform_context),
|
|
628
634
|
undefined,
|
|
629
635
|
get_body_source_node(continuation_body) || split_statement,
|
|
630
636
|
transform_context,
|
|
631
637
|
);
|
|
632
638
|
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
639
|
+
const block = b.block(
|
|
640
|
+
[
|
|
641
|
+
...body.slice(0, split_index + 1),
|
|
642
|
+
...helper.setup_statements,
|
|
643
|
+
set_loc(b.return(helper.component_element), split_statement),
|
|
644
|
+
],
|
|
645
|
+
node.body,
|
|
646
|
+
);
|
|
647
|
+
block.metadata = {
|
|
648
|
+
...(block.metadata || {}),
|
|
649
|
+
hook_split_block: true,
|
|
650
|
+
};
|
|
651
|
+
return block;
|
|
638
652
|
}
|
|
639
653
|
|
|
640
654
|
/**
|
|
@@ -642,7 +656,7 @@ function rewrite_component_body_conditional_hook_splits(node, transform_context)
|
|
|
642
656
|
* @param {TransformContext} transform_context
|
|
643
657
|
* @returns {number}
|
|
644
658
|
*/
|
|
645
|
-
function
|
|
659
|
+
function find_hook_split_index(body_nodes, transform_context) {
|
|
646
660
|
for (let i = 0; i < body_nodes.length; i += 1) {
|
|
647
661
|
if (!is_component_body_conditional_return_statement(body_nodes[i])) {
|
|
648
662
|
continue;
|
|
@@ -945,22 +959,82 @@ function create_helper_state(base_name) {
|
|
|
945
959
|
};
|
|
946
960
|
}
|
|
947
961
|
|
|
962
|
+
/**
|
|
963
|
+
* @param {{ helpers: any[], statics: any[] }} helper_state
|
|
964
|
+
* @returns {{ generated_helpers: any[], generated_statics: any[] } | null}
|
|
965
|
+
*/
|
|
966
|
+
function create_generated_helper_metadata(helper_state) {
|
|
967
|
+
if (helper_state.helpers.length === 0 && helper_state.statics.length === 0) {
|
|
968
|
+
return null;
|
|
969
|
+
}
|
|
970
|
+
return {
|
|
971
|
+
generated_helpers: helper_state.helpers,
|
|
972
|
+
generated_statics: helper_state.statics,
|
|
973
|
+
};
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
/**
|
|
977
|
+
* @param {any} metadata
|
|
978
|
+
* @returns {any}
|
|
979
|
+
*/
|
|
980
|
+
function strip_function_transform_metadata(metadata) {
|
|
981
|
+
const { native_tsrx, hook_split, ...next_metadata } = metadata || {};
|
|
982
|
+
return next_metadata;
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
/**
|
|
986
|
+
* @param {AST.BlockStatement} node
|
|
987
|
+
* @param {{ next: () => any, visit: (node: any, state?: TransformContext) => any, state: TransformContext, path: AST.Node[] }} context
|
|
988
|
+
* @returns {any}
|
|
989
|
+
*/
|
|
990
|
+
function transform_block_statement(node, { next, visit, state, path }) {
|
|
991
|
+
if (node.metadata?.hook_split_block || node.metadata?.native_return_block) {
|
|
992
|
+
return next() ?? node;
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
const parent = /** @type {any} */ (path.at(-1));
|
|
996
|
+
if (parent?.metadata?.hook_split && parent.body === node) {
|
|
997
|
+
const block = create_hook_split_block(parent, state);
|
|
998
|
+
if (block) {
|
|
999
|
+
return visit(block, state);
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
if (get_active_native_tsrx_function(path)) {
|
|
1004
|
+
const block = create_native_tsrx_statement_list_block(node, state);
|
|
1005
|
+
if (block) {
|
|
1006
|
+
return visit(block, state);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
return next() ?? node;
|
|
1011
|
+
}
|
|
1012
|
+
|
|
948
1013
|
/**
|
|
949
1014
|
* @param {any} node
|
|
950
|
-
* @param {{ next: (state?: TransformContext) => any, state: TransformContext }} context
|
|
1015
|
+
* @param {{ next: () => any, visit: (node: any, state?: TransformContext) => any, state: TransformContext, path: AST.Node[] }} context
|
|
951
1016
|
* @returns {any}
|
|
952
1017
|
*/
|
|
953
|
-
function
|
|
954
|
-
if (
|
|
955
|
-
return
|
|
1018
|
+
function transform_return_statement(node, { next, visit, state, path }) {
|
|
1019
|
+
if (get_active_native_tsrx_function(path) && node.argument?.type === 'Tsrx') {
|
|
1020
|
+
return visit(create_native_tsrx_render_block(node.argument, state), state);
|
|
956
1021
|
}
|
|
957
1022
|
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
native_tsrx_function: true,
|
|
961
|
-
};
|
|
1023
|
+
return next() ?? node;
|
|
1024
|
+
}
|
|
962
1025
|
|
|
963
|
-
|
|
1026
|
+
/**
|
|
1027
|
+
* @param {AST.Node[]} path
|
|
1028
|
+
* @returns {any | null}
|
|
1029
|
+
*/
|
|
1030
|
+
function get_active_native_tsrx_function(path) {
|
|
1031
|
+
for (let i = path.length - 1; i >= 0; i -= 1) {
|
|
1032
|
+
const node = /** @type {any} */ (path[i]);
|
|
1033
|
+
if (is_function_or_class_boundary(node)) {
|
|
1034
|
+
return node.metadata?.native_tsrx ? node : null;
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
return null;
|
|
964
1038
|
}
|
|
965
1039
|
|
|
966
1040
|
/**
|
|
@@ -978,47 +1052,49 @@ function transform_function(node, context) {
|
|
|
978
1052
|
|
|
979
1053
|
/**
|
|
980
1054
|
* @param {any} node
|
|
981
|
-
* @param {{ next: () => any, state: TransformContext
|
|
1055
|
+
* @param {{ next: () => any, state: TransformContext }} context
|
|
982
1056
|
* @returns {any}
|
|
983
1057
|
*/
|
|
984
|
-
function transform_native_tsrx_function(node, { next, state
|
|
1058
|
+
function transform_native_tsrx_function(node, { next, state }) {
|
|
985
1059
|
const helper_state =
|
|
986
|
-
state.helper_state || create_helper_state(get_function_helper_base_name(node
|
|
1060
|
+
state.helper_state || create_helper_state(get_function_helper_base_name(node));
|
|
987
1061
|
const saved_helper_state = state.helper_state;
|
|
988
1062
|
const saved_bindings = state.available_bindings;
|
|
989
1063
|
const saved_hook_helpers_enabled = state.hook_helpers_enabled;
|
|
990
1064
|
|
|
991
1065
|
state.helper_state = helper_state;
|
|
992
|
-
state.hook_helpers_enabled = is_uppercase_function_like(node
|
|
1066
|
+
state.hook_helpers_enabled = is_uppercase_function_like(node);
|
|
1067
|
+
node.metadata = {
|
|
1068
|
+
...(node.metadata || {}),
|
|
1069
|
+
native_tsrx: true,
|
|
1070
|
+
...(needs_hook_split(node, state) ? { hook_split: true } : {}),
|
|
1071
|
+
};
|
|
993
1072
|
state.available_bindings = merge_binding_maps(
|
|
994
1073
|
saved_bindings,
|
|
995
1074
|
collect_function_scope_bindings(node),
|
|
996
1075
|
);
|
|
997
1076
|
|
|
998
|
-
|
|
999
|
-
expand_native_tsrx_function_returns(node, state);
|
|
1000
|
-
rewrite_component_body_conditional_hook_splits(node, state);
|
|
1077
|
+
validate_native_await(node, state);
|
|
1001
1078
|
|
|
1002
1079
|
const inner = /** @type {any} */ (next() ?? node);
|
|
1080
|
+
if (
|
|
1081
|
+
inner !== node &&
|
|
1082
|
+
node.type === 'ArrowFunctionExpression' &&
|
|
1083
|
+
node.body?.type === 'Tsrx' &&
|
|
1084
|
+
inner.body?.type === 'BlockStatement'
|
|
1085
|
+
) {
|
|
1086
|
+
inner.expression = false;
|
|
1087
|
+
}
|
|
1003
1088
|
|
|
1004
1089
|
state.helper_state = saved_helper_state;
|
|
1005
1090
|
state.available_bindings = saved_bindings;
|
|
1006
1091
|
state.hook_helpers_enabled = saved_hook_helpers_enabled;
|
|
1007
1092
|
|
|
1008
|
-
ensure_function_metadata(inner, { next: () => inner });
|
|
1009
1093
|
inner.metadata = {
|
|
1010
|
-
...(inner.metadata
|
|
1094
|
+
...strip_function_transform_metadata(inner.metadata),
|
|
1011
1095
|
native_tsrx_function: true,
|
|
1096
|
+
...(!saved_helper_state ? create_generated_helper_metadata(helper_state) || {} : {}),
|
|
1012
1097
|
};
|
|
1013
|
-
if (!saved_helper_state && (helper_state.helpers.length || helper_state.statics.length)) {
|
|
1014
|
-
inner.metadata.generated_helpers = helper_state.helpers;
|
|
1015
|
-
inner.metadata.generated_statics = helper_state.statics;
|
|
1016
|
-
}
|
|
1017
|
-
|
|
1018
|
-
const wrapped = state.platform.hooks?.wrapNativeFunctionComponent?.(inner, state, path);
|
|
1019
|
-
if (wrapped) {
|
|
1020
|
-
return wrapped;
|
|
1021
|
-
}
|
|
1022
1098
|
|
|
1023
1099
|
return inner;
|
|
1024
1100
|
}
|
|
@@ -1028,8 +1104,8 @@ function transform_native_tsrx_function(node, { next, state, path }) {
|
|
|
1028
1104
|
* @param {TransformContext} transform_context
|
|
1029
1105
|
* @returns {void}
|
|
1030
1106
|
*/
|
|
1031
|
-
function
|
|
1032
|
-
const await_node =
|
|
1107
|
+
function validate_native_await(node, transform_context) {
|
|
1108
|
+
const await_node = find_native_await(node);
|
|
1033
1109
|
if (!await_node) {
|
|
1034
1110
|
return;
|
|
1035
1111
|
}
|
|
@@ -1055,7 +1131,7 @@ function validate_native_tsrx_function_await(node, transform_context) {
|
|
|
1055
1131
|
* @param {any} node
|
|
1056
1132
|
* @returns {any | null}
|
|
1057
1133
|
*/
|
|
1058
|
-
function
|
|
1134
|
+
function find_native_await(node) {
|
|
1059
1135
|
if (
|
|
1060
1136
|
node.type === 'ArrowFunctionExpression' &&
|
|
1061
1137
|
node.body?.type !== 'BlockStatement' &&
|
|
@@ -1065,16 +1141,16 @@ function find_first_top_level_await_in_native_tsrx_function(node) {
|
|
|
1065
1141
|
}
|
|
1066
1142
|
|
|
1067
1143
|
const body = node.body?.type === 'BlockStatement' ? node.body.body || [] : [];
|
|
1068
|
-
return
|
|
1144
|
+
return find_native_await_in_list(body);
|
|
1069
1145
|
}
|
|
1070
1146
|
|
|
1071
1147
|
/**
|
|
1072
1148
|
* @param {any[]} statements
|
|
1073
1149
|
* @returns {any | null}
|
|
1074
1150
|
*/
|
|
1075
|
-
function
|
|
1151
|
+
function find_native_await_in_list(statements) {
|
|
1076
1152
|
for (const statement of statements) {
|
|
1077
|
-
const found =
|
|
1153
|
+
const found = find_native_await_in_statement(statement);
|
|
1078
1154
|
if (found) return found;
|
|
1079
1155
|
}
|
|
1080
1156
|
return null;
|
|
@@ -1084,7 +1160,7 @@ function find_first_top_level_await_in_native_tsrx_statements(statements) {
|
|
|
1084
1160
|
* @param {any} statement
|
|
1085
1161
|
* @returns {any | null}
|
|
1086
1162
|
*/
|
|
1087
|
-
function
|
|
1163
|
+
function find_native_await_in_statement(statement) {
|
|
1088
1164
|
if (!statement || typeof statement !== 'object') return null;
|
|
1089
1165
|
|
|
1090
1166
|
if (statement.type === 'ReturnStatement' && statement.argument?.type === 'Tsrx') {
|
|
@@ -1103,21 +1179,19 @@ function find_first_top_level_await_in_native_tsrx_statement(statement) {
|
|
|
1103
1179
|
}
|
|
1104
1180
|
|
|
1105
1181
|
if (statement.type === 'BlockStatement') {
|
|
1106
|
-
return
|
|
1182
|
+
return find_native_await_in_list(statement.body || []);
|
|
1107
1183
|
}
|
|
1108
1184
|
|
|
1109
1185
|
if (statement.type === 'IfStatement') {
|
|
1110
1186
|
return (
|
|
1111
|
-
|
|
1112
|
-
|
|
1187
|
+
find_native_await_in_statement(statement.consequent) ||
|
|
1188
|
+
find_native_await_in_statement(statement.alternate)
|
|
1113
1189
|
);
|
|
1114
1190
|
}
|
|
1115
1191
|
|
|
1116
1192
|
if (statement.type === 'SwitchStatement') {
|
|
1117
1193
|
for (const switch_case of statement.cases || []) {
|
|
1118
|
-
const found =
|
|
1119
|
-
switch_case.consequent || [],
|
|
1120
|
-
);
|
|
1194
|
+
const found = find_native_await_in_list(switch_case.consequent || []);
|
|
1121
1195
|
if (found) return found;
|
|
1122
1196
|
}
|
|
1123
1197
|
return null;
|
|
@@ -1125,9 +1199,9 @@ function find_first_top_level_await_in_native_tsrx_statement(statement) {
|
|
|
1125
1199
|
|
|
1126
1200
|
if (statement.type === 'TryStatement') {
|
|
1127
1201
|
return (
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1202
|
+
find_native_await_in_statement(statement.block) ||
|
|
1203
|
+
find_native_await_in_statement(statement.handler?.body) ||
|
|
1204
|
+
find_native_await_in_statement(statement.finalizer)
|
|
1131
1205
|
);
|
|
1132
1206
|
}
|
|
1133
1207
|
|
|
@@ -1136,32 +1210,34 @@ function find_first_top_level_await_in_native_tsrx_statement(statement) {
|
|
|
1136
1210
|
|
|
1137
1211
|
/**
|
|
1138
1212
|
* @param {any} node
|
|
1139
|
-
* @param {{ next: () => any, state: TransformContext
|
|
1213
|
+
* @param {{ next: () => any, state: TransformContext }} context
|
|
1140
1214
|
* @returns {any}
|
|
1141
1215
|
*/
|
|
1142
|
-
function transform_function_with_hook_helpers(node, { next, state
|
|
1216
|
+
function transform_function_with_hook_helpers(node, { next, state }) {
|
|
1143
1217
|
const has_hook_bearing_tsrx = function_contains_hook_bearing_tsrx(node, state);
|
|
1144
|
-
const
|
|
1218
|
+
const has_hook_split = needs_hook_split(node, state);
|
|
1145
1219
|
if (
|
|
1146
1220
|
state.helper_state ||
|
|
1147
|
-
!is_uppercase_function_like(node
|
|
1148
|
-
(!has_hook_bearing_tsrx && !
|
|
1221
|
+
!is_uppercase_function_like(node) ||
|
|
1222
|
+
(!has_hook_bearing_tsrx && !has_hook_split)
|
|
1149
1223
|
) {
|
|
1150
|
-
return
|
|
1224
|
+
return next() ?? node;
|
|
1151
1225
|
}
|
|
1152
1226
|
|
|
1153
|
-
const helper_state = create_helper_state(get_function_helper_base_name(node
|
|
1227
|
+
const helper_state = create_helper_state(get_function_helper_base_name(node));
|
|
1154
1228
|
const saved_helper_state = state.helper_state;
|
|
1155
1229
|
const saved_bindings = state.available_bindings;
|
|
1156
1230
|
const saved_hook_helpers_enabled = state.hook_helpers_enabled;
|
|
1157
1231
|
|
|
1158
1232
|
state.helper_state = helper_state;
|
|
1159
1233
|
state.hook_helpers_enabled = true;
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1234
|
+
if (has_hook_split) {
|
|
1235
|
+
node.metadata = {
|
|
1236
|
+
...(node.metadata || {}),
|
|
1237
|
+
hook_split: true,
|
|
1238
|
+
};
|
|
1164
1239
|
}
|
|
1240
|
+
state.available_bindings = collect_function_scope_bindings(node);
|
|
1165
1241
|
|
|
1166
1242
|
const inner = /** @type {any} */ (next() ?? node);
|
|
1167
1243
|
|
|
@@ -1169,48 +1245,41 @@ function transform_function_with_hook_helpers(node, { next, state, path }) {
|
|
|
1169
1245
|
state.available_bindings = saved_bindings;
|
|
1170
1246
|
state.hook_helpers_enabled = saved_hook_helpers_enabled;
|
|
1171
1247
|
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
generated_helpers: helper_state.helpers,
|
|
1177
|
-
generated_statics: helper_state.statics,
|
|
1178
|
-
};
|
|
1179
|
-
}
|
|
1248
|
+
inner.metadata = {
|
|
1249
|
+
...strip_function_transform_metadata(inner.metadata),
|
|
1250
|
+
...(create_generated_helper_metadata(helper_state) || {}),
|
|
1251
|
+
};
|
|
1180
1252
|
|
|
1181
1253
|
return inner;
|
|
1182
1254
|
}
|
|
1183
1255
|
|
|
1184
1256
|
/**
|
|
1185
1257
|
* @param {any} node
|
|
1186
|
-
* @param {AST.Node[]} [path]
|
|
1187
1258
|
* @returns {string}
|
|
1188
1259
|
*/
|
|
1189
|
-
function get_function_helper_base_name(node
|
|
1190
|
-
return get_function_like_name(node
|
|
1260
|
+
function get_function_helper_base_name(node) {
|
|
1261
|
+
return get_function_like_name(node) || 'Tsrx';
|
|
1191
1262
|
}
|
|
1192
1263
|
|
|
1193
1264
|
/**
|
|
1194
1265
|
* @param {any} node
|
|
1195
|
-
* @param {AST.Node[]} path
|
|
1196
1266
|
* @returns {boolean}
|
|
1197
1267
|
*/
|
|
1198
|
-
function is_uppercase_function_like(node
|
|
1199
|
-
const name = get_function_like_name(node
|
|
1268
|
+
function is_uppercase_function_like(node) {
|
|
1269
|
+
const name = get_function_like_name(node);
|
|
1200
1270
|
return !!(name && /^[A-Z]/.test(name));
|
|
1201
1271
|
}
|
|
1202
1272
|
|
|
1203
1273
|
/**
|
|
1204
1274
|
* @param {any} node
|
|
1205
|
-
* @param {AST.Node[]} path
|
|
1206
1275
|
* @returns {string | null}
|
|
1207
1276
|
*/
|
|
1208
|
-
function get_function_like_name(node
|
|
1277
|
+
function get_function_like_name(node) {
|
|
1209
1278
|
if (node.id?.type === 'Identifier') {
|
|
1210
1279
|
return node.id.name;
|
|
1211
1280
|
}
|
|
1212
1281
|
|
|
1213
|
-
const parent = /** @type {any} */ (path
|
|
1282
|
+
const parent = /** @type {any} */ (node.metadata?.path?.at(-1));
|
|
1214
1283
|
if (!parent) return null;
|
|
1215
1284
|
|
|
1216
1285
|
if (parent.type === 'VariableDeclarator' && parent.init === node) {
|
|
@@ -1419,7 +1488,7 @@ function collect_tsrx_stylesheet(node) {
|
|
|
1419
1488
|
/**
|
|
1420
1489
|
* @param {any} node
|
|
1421
1490
|
* @param {TransformContext} transform_context
|
|
1422
|
-
* @returns {{ css: any, style_refs: any[] } | null}
|
|
1491
|
+
* @returns {{ css: any, style_refs: any[], fragment: any } | null}
|
|
1423
1492
|
*/
|
|
1424
1493
|
function prepare_tsrx_fragment_styles(node, transform_context) {
|
|
1425
1494
|
const css = collect_tsrx_stylesheet(node);
|
|
@@ -1428,21 +1497,21 @@ function prepare_tsrx_fragment_styles(node, transform_context) {
|
|
|
1428
1497
|
const style_refs = collect_style_ref_attributes(node);
|
|
1429
1498
|
apply_css_definition_metadata(node, css, style_refs.length > 0);
|
|
1430
1499
|
transform_context.stylesheets.push(css);
|
|
1431
|
-
annotate_tsrx_with_hash(
|
|
1500
|
+
const fragment = annotate_tsrx_with_hash(
|
|
1432
1501
|
node,
|
|
1433
1502
|
css.hash,
|
|
1434
1503
|
transform_context.platform.jsx.classAttrName ??
|
|
1435
1504
|
(transform_context.platform.jsx.rewriteClassAttr ? 'className' : 'class'),
|
|
1436
1505
|
transform_context.typeOnly,
|
|
1437
1506
|
);
|
|
1438
|
-
return { css, style_refs };
|
|
1507
|
+
return { css, style_refs, fragment };
|
|
1439
1508
|
}
|
|
1440
1509
|
|
|
1441
1510
|
/**
|
|
1442
1511
|
* @template T
|
|
1443
1512
|
* @param {any} node
|
|
1444
1513
|
* @param {TransformContext} transform_context
|
|
1445
|
-
* @param {(style_context: { css: any, style_refs: any[] } | null) => T} callback
|
|
1514
|
+
* @param {(style_context: { css: any, style_refs: any[], fragment: any } | null) => T} callback
|
|
1446
1515
|
* @returns {T}
|
|
1447
1516
|
*/
|
|
1448
1517
|
function with_tsrx_fragment_styles(node, transform_context, callback) {
|
|
@@ -1452,7 +1521,7 @@ function with_tsrx_fragment_styles(node, transform_context, callback) {
|
|
|
1452
1521
|
|
|
1453
1522
|
/**
|
|
1454
1523
|
* @param {any} fragment
|
|
1455
|
-
* @param {{ css: any, style_refs: any[] } | null} style_context
|
|
1524
|
+
* @param {{ css: any, style_refs: any[], fragment: any } | null} style_context
|
|
1456
1525
|
* @param {TransformContext} transform_context
|
|
1457
1526
|
* @returns {AST.Statement[]}
|
|
1458
1527
|
*/
|
|
@@ -1472,6 +1541,64 @@ function create_tsrx_style_ref_setup_statements(fragment, style_context, transfo
|
|
|
1472
1541
|
);
|
|
1473
1542
|
}
|
|
1474
1543
|
|
|
1544
|
+
/**
|
|
1545
|
+
* @param {any} node
|
|
1546
|
+
* @param {any} stylesheet
|
|
1547
|
+
* @param {TransformContext} transform_context
|
|
1548
|
+
* @returns {AST.Expression}
|
|
1549
|
+
*/
|
|
1550
|
+
function create_style_expression_value(node, stylesheet, transform_context) {
|
|
1551
|
+
const class_map = create_style_class_map_from_stylesheet(stylesheet);
|
|
1552
|
+
if (!transform_context.typeOnly) {
|
|
1553
|
+
return class_map;
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
add_type_only_style_anchor(node, transform_context);
|
|
1557
|
+
return class_map;
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1560
|
+
/**
|
|
1561
|
+
* @param {any} node
|
|
1562
|
+
* @param {TransformContext} transform_context
|
|
1563
|
+
*/
|
|
1564
|
+
function add_type_only_style_anchor(node, transform_context) {
|
|
1565
|
+
const style_anchor = b.jsx_element(clone_expression_node(node, true), [], []);
|
|
1566
|
+
disable_style_anchor_verification(style_anchor);
|
|
1567
|
+
|
|
1568
|
+
const anchor_id = create_generated_identifier(create_style_anchor_name(transform_context));
|
|
1569
|
+
transform_context.type_only_style_anchors.push(
|
|
1570
|
+
b.const(anchor_id, style_anchor),
|
|
1571
|
+
b.stmt(clone_identifier(anchor_id)),
|
|
1572
|
+
);
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
/**
|
|
1576
|
+
* @param {TransformContext} transform_context
|
|
1577
|
+
* @returns {string}
|
|
1578
|
+
*/
|
|
1579
|
+
function create_style_anchor_name(transform_context) {
|
|
1580
|
+
transform_context.local_statement_component_index += 1;
|
|
1581
|
+
return `_tsrx_style_anchor_${transform_context.local_statement_component_index}`;
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
/**
|
|
1585
|
+
* @param {ESTreeJSX.JSXElement} element
|
|
1586
|
+
*/
|
|
1587
|
+
function disable_style_anchor_verification(element) {
|
|
1588
|
+
if (element.openingElement?.name) {
|
|
1589
|
+
element.openingElement.name.metadata = {
|
|
1590
|
+
...(element.openingElement.name.metadata || {}),
|
|
1591
|
+
disable_verification: true,
|
|
1592
|
+
};
|
|
1593
|
+
}
|
|
1594
|
+
if (element.closingElement?.name) {
|
|
1595
|
+
element.closingElement.name.metadata = {
|
|
1596
|
+
...(element.closingElement.name.metadata || {}),
|
|
1597
|
+
disable_verification: true,
|
|
1598
|
+
};
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1475
1602
|
/**
|
|
1476
1603
|
* @param {TransformContext} transform_context
|
|
1477
1604
|
* @returns {string}
|
|
@@ -1549,15 +1676,22 @@ function collect_style_elements(node, styles) {
|
|
|
1549
1676
|
* @param {string} hash
|
|
1550
1677
|
* @param {'class' | 'className'} jsx_class_attr_name
|
|
1551
1678
|
* @param {boolean} preserve_style_elements
|
|
1552
|
-
* @returns {
|
|
1679
|
+
* @returns {any}
|
|
1553
1680
|
*/
|
|
1554
1681
|
function annotate_tsrx_with_hash(node, hash, jsx_class_attr_name, preserve_style_elements) {
|
|
1555
|
-
|
|
1556
|
-
|
|
1682
|
+
const annotated = { ...node };
|
|
1683
|
+
annotated.children = (node.children || []).map((/** @type {any} */ statement) =>
|
|
1684
|
+
annotate_with_hash(
|
|
1685
|
+
clone_expression_node(statement),
|
|
1686
|
+
hash,
|
|
1687
|
+
jsx_class_attr_name,
|
|
1688
|
+
preserve_style_elements,
|
|
1689
|
+
),
|
|
1557
1690
|
);
|
|
1558
1691
|
if (!preserve_style_elements) {
|
|
1559
|
-
|
|
1692
|
+
annotated.children = strip_style_elements(annotated.children);
|
|
1560
1693
|
}
|
|
1694
|
+
return annotated;
|
|
1561
1695
|
}
|
|
1562
1696
|
|
|
1563
1697
|
/**
|
|
@@ -1632,32 +1766,58 @@ function is_style_expression_position(path) {
|
|
|
1632
1766
|
}
|
|
1633
1767
|
|
|
1634
1768
|
/**
|
|
1635
|
-
* @param {any}
|
|
1769
|
+
* @param {any} fragment
|
|
1636
1770
|
* @param {TransformContext} transform_context
|
|
1637
|
-
* @returns {
|
|
1771
|
+
* @returns {any}
|
|
1638
1772
|
*/
|
|
1639
|
-
function
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
})
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1773
|
+
function create_native_tsrx_render_block(fragment, transform_context) {
|
|
1774
|
+
const block = b.block(
|
|
1775
|
+
mark_native_pretransformed_jsx(
|
|
1776
|
+
create_native_tsrx_render_statements(fragment, transform_context),
|
|
1777
|
+
),
|
|
1778
|
+
fragment,
|
|
1779
|
+
);
|
|
1780
|
+
block.metadata = {
|
|
1781
|
+
...(block.metadata || {}),
|
|
1782
|
+
native_return_block: true,
|
|
1783
|
+
};
|
|
1784
|
+
return block;
|
|
1785
|
+
}
|
|
1652
1786
|
|
|
1653
|
-
|
|
1654
|
-
|
|
1787
|
+
/**
|
|
1788
|
+
* @param {any} block
|
|
1789
|
+
* @param {TransformContext} transform_context
|
|
1790
|
+
* @returns {any | null}
|
|
1791
|
+
*/
|
|
1792
|
+
function create_native_tsrx_statement_list_block(block, transform_context) {
|
|
1793
|
+
const source_body = block.body || [];
|
|
1794
|
+
const body = expand_native_tsrx_return_statement_list(source_body, transform_context);
|
|
1795
|
+
|
|
1796
|
+
if (body === source_body) {
|
|
1797
|
+
return null;
|
|
1655
1798
|
}
|
|
1656
1799
|
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1800
|
+
const next_block = b.block(mark_native_pretransformed_jsx(body), block);
|
|
1801
|
+
next_block.metadata = {
|
|
1802
|
+
...(next_block.metadata || {}),
|
|
1803
|
+
native_return_block: true,
|
|
1804
|
+
};
|
|
1805
|
+
return next_block;
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1808
|
+
/**
|
|
1809
|
+
* @param {any} fragment
|
|
1810
|
+
* @param {TransformContext} transform_context
|
|
1811
|
+
* @returns {AST.Statement[]}
|
|
1812
|
+
*/
|
|
1813
|
+
function create_native_tsrx_render_statements(fragment, transform_context) {
|
|
1814
|
+
return with_tsrx_fragment_styles(fragment, transform_context, (style_context) => {
|
|
1815
|
+
const target = style_context?.fragment ?? fragment;
|
|
1816
|
+
return [
|
|
1817
|
+
...create_tsrx_style_ref_setup_statements(target, style_context, transform_context),
|
|
1818
|
+
...build_render_statements(get_tsrx_render_children(target), true, transform_context),
|
|
1819
|
+
];
|
|
1820
|
+
});
|
|
1661
1821
|
}
|
|
1662
1822
|
|
|
1663
1823
|
/**
|
|
@@ -1666,9 +1826,15 @@ function expand_native_tsrx_function_returns(node, transform_context) {
|
|
|
1666
1826
|
* @returns {any[]}
|
|
1667
1827
|
*/
|
|
1668
1828
|
function expand_native_tsrx_return_statement_list(statements, transform_context) {
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1829
|
+
let changed = false;
|
|
1830
|
+
const next_statements = statements.flatMap((statement) => {
|
|
1831
|
+
const result = expand_native_tsrx_return_statement(statement, transform_context);
|
|
1832
|
+
if (result.length !== 1 || result[0] !== statement) {
|
|
1833
|
+
changed = true;
|
|
1834
|
+
}
|
|
1835
|
+
return result;
|
|
1836
|
+
});
|
|
1837
|
+
return changed ? next_statements : statements;
|
|
1672
1838
|
}
|
|
1673
1839
|
|
|
1674
1840
|
/**
|
|
@@ -1680,13 +1846,7 @@ function expand_native_tsrx_return_statement(statement, transform_context) {
|
|
|
1680
1846
|
if (!statement || typeof statement !== 'object') return [statement];
|
|
1681
1847
|
|
|
1682
1848
|
if (statement.type === 'ReturnStatement' && statement.argument?.type === 'Tsrx') {
|
|
1683
|
-
|
|
1684
|
-
return with_tsrx_fragment_styles(fragment, transform_context, (style_context) => {
|
|
1685
|
-
return mark_native_pretransformed_jsx([
|
|
1686
|
-
...create_tsrx_style_ref_setup_statements(fragment, style_context, transform_context),
|
|
1687
|
-
...build_render_statements(get_tsrx_render_children(fragment), true, transform_context),
|
|
1688
|
-
]);
|
|
1689
|
-
});
|
|
1849
|
+
return create_native_tsrx_render_statements(statement.argument, transform_context);
|
|
1690
1850
|
}
|
|
1691
1851
|
|
|
1692
1852
|
if (is_function_or_class_boundary(statement)) {
|
|
@@ -1694,52 +1854,65 @@ function expand_native_tsrx_return_statement(statement, transform_context) {
|
|
|
1694
1854
|
}
|
|
1695
1855
|
|
|
1696
1856
|
if (statement.type === 'BlockStatement') {
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
transform_context,
|
|
1700
|
-
);
|
|
1701
|
-
return [statement];
|
|
1857
|
+
const body = expand_native_tsrx_return_statement_list(statement.body || [], transform_context);
|
|
1858
|
+
return body === statement.body ? [statement] : [b.block(body, statement)];
|
|
1702
1859
|
}
|
|
1703
1860
|
|
|
1704
1861
|
if (statement.type === 'IfStatement') {
|
|
1705
|
-
|
|
1862
|
+
const consequent = expand_embedded_native_return_statement(
|
|
1706
1863
|
statement.consequent,
|
|
1707
1864
|
transform_context,
|
|
1708
1865
|
);
|
|
1709
|
-
|
|
1710
|
-
statement.alternate
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1866
|
+
const alternate = statement.alternate
|
|
1867
|
+
? expand_embedded_native_return_statement(statement.alternate, transform_context)
|
|
1868
|
+
: statement.alternate;
|
|
1869
|
+
if (consequent === statement.consequent && alternate === statement.alternate) {
|
|
1870
|
+
return [statement];
|
|
1714
1871
|
}
|
|
1715
|
-
return [statement];
|
|
1872
|
+
return [set_loc(b.if(statement.test, consequent, alternate), statement)];
|
|
1716
1873
|
}
|
|
1717
1874
|
|
|
1718
1875
|
if (statement.type === 'SwitchStatement') {
|
|
1719
|
-
|
|
1720
|
-
|
|
1876
|
+
let changed = false;
|
|
1877
|
+
const cases = (statement.cases || []).map((/** @type {any} */ switch_case) => {
|
|
1878
|
+
const consequent = expand_native_tsrx_return_statement_list(
|
|
1721
1879
|
switch_case.consequent || [],
|
|
1722
1880
|
transform_context,
|
|
1723
1881
|
);
|
|
1724
|
-
|
|
1725
|
-
|
|
1882
|
+
if (consequent === switch_case.consequent) {
|
|
1883
|
+
return switch_case;
|
|
1884
|
+
}
|
|
1885
|
+
changed = true;
|
|
1886
|
+
return set_loc(b.switch_case(switch_case.test, consequent), switch_case);
|
|
1887
|
+
});
|
|
1888
|
+
return changed ? [set_loc(b.switch(statement.discriminant, cases), statement)] : [statement];
|
|
1726
1889
|
}
|
|
1727
1890
|
|
|
1728
1891
|
if (statement.type === 'TryStatement') {
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
statement.handler.body
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
)
|
|
1735
|
-
|
|
1736
|
-
if (
|
|
1737
|
-
statement.
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1892
|
+
const block = expand_embedded_native_return_statement(statement.block, transform_context);
|
|
1893
|
+
const handler_body = statement.handler?.body
|
|
1894
|
+
? expand_embedded_native_return_statement(statement.handler.body, transform_context)
|
|
1895
|
+
: statement.handler?.body;
|
|
1896
|
+
const finalizer = statement.finalizer
|
|
1897
|
+
? expand_embedded_native_return_statement(statement.finalizer, transform_context)
|
|
1898
|
+
: statement.finalizer;
|
|
1899
|
+
if (
|
|
1900
|
+
block === statement.block &&
|
|
1901
|
+
handler_body === statement.handler?.body &&
|
|
1902
|
+
finalizer === statement.finalizer
|
|
1903
|
+
) {
|
|
1904
|
+
return [statement];
|
|
1741
1905
|
}
|
|
1742
|
-
|
|
1906
|
+
const handler =
|
|
1907
|
+
statement.handler && handler_body !== statement.handler.body
|
|
1908
|
+
? b.catch_clause(
|
|
1909
|
+
statement.handler.param,
|
|
1910
|
+
statement.handler.resetParam,
|
|
1911
|
+
handler_body,
|
|
1912
|
+
statement.handler,
|
|
1913
|
+
)
|
|
1914
|
+
: statement.handler;
|
|
1915
|
+
return [set_loc(b.try(block, handler, finalizer, statement.pending ?? null), statement)];
|
|
1743
1916
|
}
|
|
1744
1917
|
|
|
1745
1918
|
return [statement];
|
|
@@ -2645,15 +2818,7 @@ function to_jsx_element(node, transform_context, raw_children = node.children ||
|
|
|
2645
2818
|
if (node.type === 'JSXElement') return node;
|
|
2646
2819
|
if (!node.id) {
|
|
2647
2820
|
report_jsx_fragment_in_tsrx_error(node, transform_context);
|
|
2648
|
-
return set_loc(
|
|
2649
|
-
/** @type {any} */ ({
|
|
2650
|
-
type: 'JSXFragment',
|
|
2651
|
-
openingFragment: { type: 'JSXOpeningFragment' },
|
|
2652
|
-
closingFragment: { type: 'JSXClosingFragment' },
|
|
2653
|
-
children: [],
|
|
2654
|
-
}),
|
|
2655
|
-
node,
|
|
2656
|
-
);
|
|
2821
|
+
return set_loc(b.jsx_fragment(), node);
|
|
2657
2822
|
}
|
|
2658
2823
|
if (is_dynamic_element_id(node.id)) {
|
|
2659
2824
|
return dynamic_element_to_jsx_child(node, transform_context);
|
|
@@ -2707,7 +2872,11 @@ function to_jsx_element(node, transform_context, raw_children = node.children ||
|
|
|
2707
2872
|
node.closingElement || node,
|
|
2708
2873
|
);
|
|
2709
2874
|
|
|
2710
|
-
|
|
2875
|
+
const element = set_loc(b.jsx_element_fresh(openingElement, closingElement, children), node);
|
|
2876
|
+
if (transform_context.typeOnly && is_style_element(node)) {
|
|
2877
|
+
disable_style_anchor_verification(element);
|
|
2878
|
+
}
|
|
2879
|
+
return element;
|
|
2711
2880
|
}
|
|
2712
2881
|
|
|
2713
2882
|
/**
|
|
@@ -3632,12 +3801,7 @@ export function create_hook_safe_helper(
|
|
|
3632
3801
|
|
|
3633
3802
|
if (key_expression) {
|
|
3634
3803
|
component_element.openingElement.attributes.push(
|
|
3635
|
-
|
|
3636
|
-
type: 'JSXAttribute',
|
|
3637
|
-
name: { type: 'JSXIdentifier', name: 'key', metadata: { path: [] } },
|
|
3638
|
-
value: to_jsx_expression_container(key_expression, key_expression),
|
|
3639
|
-
metadata: { path: [] },
|
|
3640
|
-
}),
|
|
3804
|
+
b.jsx_attribute(b.jsx_id('key'), to_jsx_expression_container(key_expression, key_expression)),
|
|
3641
3805
|
);
|
|
3642
3806
|
}
|
|
3643
3807
|
|
|
@@ -3805,11 +3969,19 @@ function create_cached_helper_declaration(helper_id, cache_id, helper_init) {
|
|
|
3805
3969
|
* @returns {AST.FunctionDeclaration}
|
|
3806
3970
|
*/
|
|
3807
3971
|
function create_helper_function_declaration_from_expression(helper_id, helper_fn) {
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3972
|
+
const declaration = set_loc(
|
|
3973
|
+
b.function_declaration(
|
|
3974
|
+
clone_identifier(helper_id),
|
|
3975
|
+
helper_fn.params,
|
|
3976
|
+
helper_fn.body,
|
|
3977
|
+
helper_fn.async,
|
|
3978
|
+
helper_fn.typeParameters,
|
|
3979
|
+
),
|
|
3980
|
+
helper_fn,
|
|
3981
|
+
);
|
|
3982
|
+
declaration.generator = helper_fn.generator;
|
|
3983
|
+
declaration.metadata = { ...(helper_fn.metadata || {}), path: helper_fn.metadata?.path || [] };
|
|
3984
|
+
return declaration;
|
|
3813
3985
|
}
|
|
3814
3986
|
|
|
3815
3987
|
/**
|
|
@@ -4574,14 +4746,7 @@ function try_statement_to_jsx_child(node, transform_context) {
|
|
|
4574
4746
|
) ??
|
|
4575
4747
|
create_jsx_element(
|
|
4576
4748
|
'Suspense',
|
|
4577
|
-
[
|
|
4578
|
-
{
|
|
4579
|
-
type: 'JSXAttribute',
|
|
4580
|
-
name: { type: 'JSXIdentifier', name: 'fallback', metadata: { path: [] } },
|
|
4581
|
-
value: fallback_content,
|
|
4582
|
-
metadata: { path: [] },
|
|
4583
|
-
},
|
|
4584
|
-
],
|
|
4749
|
+
[b.jsx_attribute(b.jsx_id('fallback'), fallback_content)],
|
|
4585
4750
|
[result],
|
|
4586
4751
|
);
|
|
4587
4752
|
}
|
|
@@ -5066,14 +5231,12 @@ function build_switch_with_lift(switch_node, transform_context) {
|
|
|
5066
5231
|
(/** @type {any} */ original_case, /** @type {number} */ i) => {
|
|
5067
5232
|
const helper = case_helpers[i];
|
|
5068
5233
|
if (helper) {
|
|
5069
|
-
return
|
|
5070
|
-
|
|
5071
|
-
test: original_case.test,
|
|
5072
|
-
consequent: [
|
|
5234
|
+
return set_loc(
|
|
5235
|
+
b.switch_case(original_case.test, [
|
|
5073
5236
|
create_component_return_statement([helper.component_element], original_case),
|
|
5074
|
-
],
|
|
5075
|
-
|
|
5076
|
-
|
|
5237
|
+
]),
|
|
5238
|
+
original_case,
|
|
5239
|
+
);
|
|
5077
5240
|
}
|
|
5078
5241
|
|
|
5079
5242
|
const { own_body, has_terminator } = case_info[i];
|
|
@@ -5082,12 +5245,7 @@ function build_switch_with_lift(switch_node, transform_context) {
|
|
|
5082
5245
|
// Alias-pattern empty case (`case 'a': case 'b': ...`) — keep
|
|
5083
5246
|
// the arm body empty so JS falls through to the next case at
|
|
5084
5247
|
// runtime, where the helper invocation actually lives.
|
|
5085
|
-
return
|
|
5086
|
-
type: 'SwitchCase',
|
|
5087
|
-
test: original_case.test,
|
|
5088
|
-
consequent: [],
|
|
5089
|
-
metadata: { path: [] },
|
|
5090
|
-
});
|
|
5248
|
+
return set_loc(b.switch_case(original_case.test, []), original_case);
|
|
5091
5249
|
}
|
|
5092
5250
|
|
|
5093
5251
|
const case_body = [];
|
|
@@ -5128,45 +5286,23 @@ function build_switch_with_lift(switch_node, transform_context) {
|
|
|
5128
5286
|
// Empty body with explicit `break;` / bare `return;` — keep
|
|
5129
5287
|
// a `break` so JS doesn't fall through into the next case
|
|
5130
5288
|
// (which may now hold the lifted helper invocation).
|
|
5131
|
-
case_body.push(
|
|
5132
|
-
/** @type {any} */ ({
|
|
5133
|
-
type: 'BreakStatement',
|
|
5134
|
-
label: null,
|
|
5135
|
-
metadata: { path: [] },
|
|
5136
|
-
}),
|
|
5137
|
-
);
|
|
5289
|
+
case_body.push(b.break);
|
|
5138
5290
|
} else if (case_body.length > 0) {
|
|
5139
5291
|
// Statements-only inline case without terminator. We've
|
|
5140
5292
|
// already inlined the downstream chain via the helper
|
|
5141
5293
|
// reference above, so emit a `break` to stop the runtime
|
|
5142
5294
|
// from re-running downstream statements via JS fall-through.
|
|
5143
|
-
case_body.push(
|
|
5144
|
-
/** @type {any} */ ({
|
|
5145
|
-
type: 'BreakStatement',
|
|
5146
|
-
label: null,
|
|
5147
|
-
metadata: { path: [] },
|
|
5148
|
-
}),
|
|
5149
|
-
);
|
|
5295
|
+
case_body.push(b.break);
|
|
5150
5296
|
}
|
|
5151
5297
|
}
|
|
5152
5298
|
|
|
5153
|
-
return
|
|
5154
|
-
type: 'SwitchCase',
|
|
5155
|
-
test: original_case.test,
|
|
5156
|
-
consequent: case_body,
|
|
5157
|
-
metadata: { path: [] },
|
|
5158
|
-
});
|
|
5299
|
+
return set_loc(b.switch_case(original_case.test, case_body), original_case);
|
|
5159
5300
|
},
|
|
5160
5301
|
);
|
|
5161
5302
|
|
|
5162
5303
|
return {
|
|
5163
5304
|
setup_statements,
|
|
5164
|
-
switch_statement:
|
|
5165
|
-
type: 'SwitchStatement',
|
|
5166
|
-
discriminant: switch_node.discriminant,
|
|
5167
|
-
cases: new_cases,
|
|
5168
|
-
metadata: { path: [] },
|
|
5169
|
-
}),
|
|
5305
|
+
switch_statement: b.switch(switch_node.discriminant, new_cases, switch_node),
|
|
5170
5306
|
};
|
|
5171
5307
|
}
|
|
5172
5308
|
|
|
@@ -5781,19 +5917,7 @@ function build_return_expression(render_nodes) {
|
|
|
5781
5917
|
const first = render_nodes[0];
|
|
5782
5918
|
const last = render_nodes[render_nodes.length - 1];
|
|
5783
5919
|
return set_loc(
|
|
5784
|
-
|
|
5785
|
-
type: 'JSXFragment',
|
|
5786
|
-
openingFragment: /** @type {any} */ ({
|
|
5787
|
-
type: 'JSXOpeningFragment',
|
|
5788
|
-
metadata: { path: [] },
|
|
5789
|
-
}),
|
|
5790
|
-
closingFragment: /** @type {any} */ ({
|
|
5791
|
-
type: 'JSXClosingFragment',
|
|
5792
|
-
metadata: { path: [] },
|
|
5793
|
-
}),
|
|
5794
|
-
children: render_nodes,
|
|
5795
|
-
metadata: { path: [] },
|
|
5796
|
-
},
|
|
5920
|
+
b.jsx_fragment(render_nodes),
|
|
5797
5921
|
first?.loc && last?.loc
|
|
5798
5922
|
? {
|
|
5799
5923
|
start: first.start,
|
package/types/index.d.ts
CHANGED
|
@@ -102,11 +102,15 @@ interface BaseNodeMetaData {
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
interface FunctionMetaData extends BaseNodeMetaData {
|
|
105
|
+
native_tsrx?: boolean;
|
|
105
106
|
native_tsrx_function?: boolean;
|
|
107
|
+
hook_split?: boolean;
|
|
106
108
|
is_method?: boolean;
|
|
107
109
|
tracked?: boolean;
|
|
108
110
|
has_lazy_descendants?: boolean;
|
|
109
111
|
synthetic_children?: boolean;
|
|
112
|
+
generated_helpers?: any[];
|
|
113
|
+
generated_statics?: any[];
|
|
110
114
|
}
|
|
111
115
|
|
|
112
116
|
// Strip parent, loc, and range from TSESTree nodes to match @sveltejs/acorn-typescript output
|
|
@@ -163,6 +167,13 @@ declare module 'estree' {
|
|
|
163
167
|
};
|
|
164
168
|
}
|
|
165
169
|
|
|
170
|
+
interface BlockStatement {
|
|
171
|
+
metadata: BaseNodeMetaData & {
|
|
172
|
+
hook_split_block?: boolean;
|
|
173
|
+
native_return_block?: boolean;
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
166
177
|
type Accessibility = 'public' | 'protected' | 'private'; // missing in acorn-typescript types
|
|
167
178
|
interface MethodDefinition {
|
|
168
179
|
typeParameters?: TSTypeParameterDeclaration;
|
|
@@ -238,6 +249,7 @@ declare module 'estree' {
|
|
|
238
249
|
}
|
|
239
250
|
|
|
240
251
|
interface ExpressionMap {
|
|
252
|
+
Tsrx: Tsrx;
|
|
241
253
|
Text: TextNode;
|
|
242
254
|
JSXEmptyExpression: ESTreeJSX.JSXEmptyExpression;
|
|
243
255
|
ParenthesizedExpression: ParenthesizedExpression;
|
|
@@ -343,7 +355,7 @@ declare module 'estree' {
|
|
|
343
355
|
closingElement: ESTreeJSX.JSXClosingElement;
|
|
344
356
|
}
|
|
345
357
|
|
|
346
|
-
interface Tsrx extends AST.
|
|
358
|
+
interface Tsrx extends AST.BaseExpression {
|
|
347
359
|
type: 'Tsrx';
|
|
348
360
|
attributes: Array<any>;
|
|
349
361
|
children: AST.Node[];
|
|
@@ -649,6 +661,12 @@ declare module 'estree-jsx' {
|
|
|
649
661
|
};
|
|
650
662
|
}
|
|
651
663
|
|
|
664
|
+
interface JSXOpeningElement {
|
|
665
|
+
metadata: BaseNodeMetaData & {
|
|
666
|
+
native_tsrx_pretransformed?: boolean;
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
|
|
652
670
|
interface JSXExpressionContainer {
|
|
653
671
|
text?: boolean;
|
|
654
672
|
style?: boolean;
|
package/types/jsx-platform.d.ts
CHANGED
|
@@ -42,6 +42,7 @@ export interface JsxTransformContext {
|
|
|
42
42
|
needs_for_of_iterable: boolean;
|
|
43
43
|
needs_iteration_value_type: boolean;
|
|
44
44
|
stylesheets: AST.CSS.StyleSheet[];
|
|
45
|
+
type_only_style_anchors: AST.Statement[];
|
|
45
46
|
module_scoped_hook_components: boolean;
|
|
46
47
|
helper_state: {
|
|
47
48
|
base_name: string;
|
|
@@ -154,13 +155,6 @@ export interface JsxPlatformHooks {
|
|
|
154
155
|
* state behaves like normal component state.
|
|
155
156
|
*/
|
|
156
157
|
wrapHelperComponent?: (helperFn: any, helperId: any, ctx: any, sourceNode: any) => any;
|
|
157
|
-
/**
|
|
158
|
-
* Wrap an uppercase JavaScript function that returns native TSRX as a target
|
|
159
|
-
* component. Vue uses this to turn `function App() { return <></>; }` into a
|
|
160
|
-
* `defineVaporComponent(function App() { ... })` binding while lowercase
|
|
161
|
-
* TSRX-returning callbacks stay plain functions.
|
|
162
|
-
*/
|
|
163
|
-
wrapNativeFunctionComponent?: (fn: any, ctx: any, path: any[]) => any;
|
|
164
158
|
/**
|
|
165
159
|
* Emit hook-isolation helper components as unique module-scope declarations
|
|
166
160
|
* instead of lazily creating and caching them from the parent component body.
|