@tsrx/core 0.1.18 → 0.1.20
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/plugin.js +59 -171
- package/src/scope.js +3 -3
- package/src/transform/jsx/ast-builders.js +3 -4
- package/src/transform/jsx/helpers.js +21 -23
- package/src/transform/jsx/index.js +403 -292
- package/types/index.d.ts +24 -19
- package/types/jsx-platform.d.ts +1 -7
- package/types/parse.d.ts +1 -1
|
@@ -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';
|
|
@@ -62,7 +62,7 @@ const HOOK_OUTER_ASSIGNMENT_ERROR =
|
|
|
62
62
|
const HOOK_CALLBACK_OUTER_MUTATION_ERROR =
|
|
63
63
|
'Hook callbacks inside conditional or repeated TSRX scopes must not mutate bindings declared outside the generated hook component.';
|
|
64
64
|
const TEMPLATE_FRAGMENT_ERROR =
|
|
65
|
-
'JSX fragment syntax is not needed in TSRX templates. TSRX renders in immediate mode, so everything is already a fragment. Use `<>...</>` only
|
|
65
|
+
'JSX fragment syntax is not needed in TSRX templates. TSRX renders in immediate mode, so everything is already a fragment. Use `<>...</>` only in expression position.';
|
|
66
66
|
|
|
67
67
|
/**
|
|
68
68
|
* @param {AST.Node} node
|
|
@@ -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,42 +207,30 @@ 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, {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
return /** @type {any} */ (
|
|
218
|
-
wrap_jsx_setup_declarations(tsx_node_to_jsx_expression(inner, in_jsx_child), in_jsx_child)
|
|
219
|
-
);
|
|
211
|
+
_(node, { next, path }) {
|
|
212
|
+
set_node_path_metadata(node, path);
|
|
213
|
+
return next();
|
|
220
214
|
},
|
|
221
215
|
|
|
222
|
-
|
|
223
|
-
/** @type {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
216
|
+
TsrxFragment(node, { next, path, state, visit }) {
|
|
217
|
+
const parent = /** @type {AST.ArrowFunctionExpression} */ (path.at(-1));
|
|
218
|
+
if (parent?.metadata?.native_tsrx && parent.body === node) {
|
|
219
|
+
return /** @type {any} */ (visit(create_native_tsrx_render_block(node, state), state));
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const style_context = prepare_tsrx_fragment_styles(node, state);
|
|
223
|
+
const target = style_context?.fragment ?? next() ?? node;
|
|
224
|
+
const in_jsx_child = in_jsx_child_context(path);
|
|
225
|
+
const expression = tsrx_node_to_jsx_expression(target, state, in_jsx_child);
|
|
229
226
|
for (const statement of create_tsrx_style_ref_setup_statements(
|
|
230
|
-
|
|
227
|
+
target,
|
|
231
228
|
style_context,
|
|
232
229
|
state,
|
|
233
230
|
)) {
|
|
234
|
-
add_jsx_setup_declaration(
|
|
231
|
+
add_jsx_setup_declaration(expression, statement);
|
|
235
232
|
}
|
|
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
|
-
);
|
|
233
|
+
return /** @type {any} */ (wrap_jsx_setup_declarations(expression, in_jsx_child));
|
|
243
234
|
},
|
|
244
235
|
|
|
245
236
|
TsxCompat(node, { next, path, state }) {
|
|
@@ -259,7 +250,7 @@ export function createJsxTransform(platform) {
|
|
|
259
250
|
if (stylesheet) {
|
|
260
251
|
analyze_css(stylesheet);
|
|
261
252
|
state.stylesheets.push(stylesheet);
|
|
262
|
-
return /** @type {any} */ (
|
|
253
|
+
return /** @type {any} */ (create_style_expression_value(node, stylesheet, state));
|
|
263
254
|
}
|
|
264
255
|
}
|
|
265
256
|
|
|
@@ -288,9 +279,9 @@ export function createJsxTransform(platform) {
|
|
|
288
279
|
return /** @type {any} */ (to_jsx_expression_container(inner.expression, inner));
|
|
289
280
|
},
|
|
290
281
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
282
|
+
BlockStatement: transform_block_statement,
|
|
283
|
+
ReturnStatement: transform_return_statement,
|
|
284
|
+
|
|
294
285
|
// If an uppercase JS function contains hook-bearing TSRX, give it a
|
|
295
286
|
// temporary helper scope so extracted hook helpers get stable identities.
|
|
296
287
|
FunctionDeclaration: transform_function,
|
|
@@ -303,17 +294,24 @@ export function createJsxTransform(platform) {
|
|
|
303
294
|
return visited;
|
|
304
295
|
}
|
|
305
296
|
const is_component = is_component_like_jsx_name(visited.name);
|
|
306
|
-
return
|
|
307
|
-
|
|
308
|
-
|
|
297
|
+
return b.jsx_opening_element(
|
|
298
|
+
visited.name,
|
|
299
|
+
merge_duplicate_refs(
|
|
309
300
|
normalize_host_ref_spreads(visited.attributes || [], !is_component, transform_context),
|
|
310
301
|
transform_context,
|
|
311
302
|
),
|
|
312
|
-
|
|
303
|
+
visited.selfClosing,
|
|
304
|
+
visited.typeArguments,
|
|
305
|
+
visited,
|
|
306
|
+
);
|
|
313
307
|
},
|
|
314
308
|
});
|
|
315
309
|
|
|
316
|
-
const
|
|
310
|
+
const transformed_program = /** @type {AST.Program} */ (transformed);
|
|
311
|
+
if (type_only_style_anchors.length > 0) {
|
|
312
|
+
transformed_program.body.unshift(...type_only_style_anchors);
|
|
313
|
+
}
|
|
314
|
+
const expanded = expand_component_helpers(transformed_program);
|
|
317
315
|
if (platform.hooks?.injectImports) {
|
|
318
316
|
platform.hooks.injectImports(expanded, transform_context, suspense_source);
|
|
319
317
|
} else {
|
|
@@ -593,48 +591,56 @@ function is_interleaved_body(body_nodes) {
|
|
|
593
591
|
* @param {TransformContext} transform_context
|
|
594
592
|
* @returns {boolean}
|
|
595
593
|
*/
|
|
596
|
-
function
|
|
594
|
+
function needs_hook_split(node, transform_context) {
|
|
597
595
|
return (
|
|
598
596
|
transform_context.platform.hooks?.componentBodyHookHelpers === true &&
|
|
599
597
|
node.body?.type === 'BlockStatement' &&
|
|
600
|
-
|
|
598
|
+
find_hook_split_index(node.body.body || [], transform_context) !== -1
|
|
601
599
|
);
|
|
602
600
|
}
|
|
603
601
|
|
|
604
602
|
/**
|
|
605
603
|
* @param {any} node
|
|
606
604
|
* @param {TransformContext} transform_context
|
|
607
|
-
* @returns {
|
|
605
|
+
* @returns {any}
|
|
608
606
|
*/
|
|
609
|
-
function
|
|
607
|
+
function create_hook_split_block(node, transform_context) {
|
|
610
608
|
if (
|
|
611
609
|
transform_context.platform.hooks?.componentBodyHookHelpers !== true ||
|
|
612
610
|
!should_extract_hook_helpers(transform_context) ||
|
|
613
611
|
node.body?.type !== 'BlockStatement'
|
|
614
612
|
) {
|
|
615
|
-
return;
|
|
613
|
+
return null;
|
|
616
614
|
}
|
|
617
615
|
|
|
618
616
|
const body = node.body.body || [];
|
|
619
|
-
const split_index =
|
|
617
|
+
const split_index = find_hook_split_index(body, transform_context);
|
|
620
618
|
if (split_index === -1) {
|
|
621
|
-
return;
|
|
619
|
+
return null;
|
|
622
620
|
}
|
|
623
621
|
|
|
624
622
|
const split_statement = body[split_index];
|
|
625
623
|
const continuation_body = body.slice(split_index + 1);
|
|
626
624
|
const helper = create_hook_safe_helper(
|
|
627
|
-
continuation_body,
|
|
625
|
+
expand_native_tsrx_return_statement_list(continuation_body, transform_context),
|
|
628
626
|
undefined,
|
|
629
627
|
get_body_source_node(continuation_body) || split_statement,
|
|
630
628
|
transform_context,
|
|
631
629
|
);
|
|
632
630
|
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
631
|
+
const block = b.block(
|
|
632
|
+
[
|
|
633
|
+
...body.slice(0, split_index + 1),
|
|
634
|
+
...helper.setup_statements,
|
|
635
|
+
set_loc(b.return(helper.component_element), split_statement),
|
|
636
|
+
],
|
|
637
|
+
node.body,
|
|
638
|
+
);
|
|
639
|
+
block.metadata = {
|
|
640
|
+
...(block.metadata || {}),
|
|
641
|
+
hook_split_block: true,
|
|
642
|
+
};
|
|
643
|
+
return block;
|
|
638
644
|
}
|
|
639
645
|
|
|
640
646
|
/**
|
|
@@ -642,7 +648,7 @@ function rewrite_component_body_conditional_hook_splits(node, transform_context)
|
|
|
642
648
|
* @param {TransformContext} transform_context
|
|
643
649
|
* @returns {number}
|
|
644
650
|
*/
|
|
645
|
-
function
|
|
651
|
+
function find_hook_split_index(body_nodes, transform_context) {
|
|
646
652
|
for (let i = 0; i < body_nodes.length; i += 1) {
|
|
647
653
|
if (!is_component_body_conditional_return_statement(body_nodes[i])) {
|
|
648
654
|
continue;
|
|
@@ -945,22 +951,82 @@ function create_helper_state(base_name) {
|
|
|
945
951
|
};
|
|
946
952
|
}
|
|
947
953
|
|
|
954
|
+
/**
|
|
955
|
+
* @param {{ helpers: any[], statics: any[] }} helper_state
|
|
956
|
+
* @returns {{ generated_helpers: any[], generated_statics: any[] } | null}
|
|
957
|
+
*/
|
|
958
|
+
function create_generated_helper_metadata(helper_state) {
|
|
959
|
+
if (helper_state.helpers.length === 0 && helper_state.statics.length === 0) {
|
|
960
|
+
return null;
|
|
961
|
+
}
|
|
962
|
+
return {
|
|
963
|
+
generated_helpers: helper_state.helpers,
|
|
964
|
+
generated_statics: helper_state.statics,
|
|
965
|
+
};
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
/**
|
|
969
|
+
* @param {any} metadata
|
|
970
|
+
* @returns {any}
|
|
971
|
+
*/
|
|
972
|
+
function strip_function_transform_metadata(metadata) {
|
|
973
|
+
const { native_tsrx, hook_split, ...next_metadata } = metadata || {};
|
|
974
|
+
return next_metadata;
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
/**
|
|
978
|
+
* @param {AST.BlockStatement} node
|
|
979
|
+
* @param {{ next: () => any, visit: (node: any, state?: TransformContext) => any, state: TransformContext, path: AST.Node[] }} context
|
|
980
|
+
* @returns {any}
|
|
981
|
+
*/
|
|
982
|
+
function transform_block_statement(node, { next, visit, state, path }) {
|
|
983
|
+
if (node.metadata?.hook_split_block || node.metadata?.native_return_block) {
|
|
984
|
+
return next() ?? node;
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
const parent = /** @type {any} */ (path.at(-1));
|
|
988
|
+
if (parent?.metadata?.hook_split && parent.body === node) {
|
|
989
|
+
const block = create_hook_split_block(parent, state);
|
|
990
|
+
if (block) {
|
|
991
|
+
return visit(block, state);
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
if (get_active_native_tsrx_function(path)) {
|
|
996
|
+
const block = create_native_tsrx_statement_list_block(node, state);
|
|
997
|
+
if (block) {
|
|
998
|
+
return visit(block, state);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
return next() ?? node;
|
|
1003
|
+
}
|
|
1004
|
+
|
|
948
1005
|
/**
|
|
949
1006
|
* @param {any} node
|
|
950
|
-
* @param {{ next: (state?: TransformContext) => any, state: TransformContext }} context
|
|
1007
|
+
* @param {{ next: () => any, visit: (node: any, state?: TransformContext) => any, state: TransformContext, path: AST.Node[] }} context
|
|
951
1008
|
* @returns {any}
|
|
952
1009
|
*/
|
|
953
|
-
function
|
|
954
|
-
if (
|
|
955
|
-
return
|
|
1010
|
+
function transform_return_statement(node, { next, visit, state, path }) {
|
|
1011
|
+
if (get_active_native_tsrx_function(path) && node.argument?.type === 'TsrxFragment') {
|
|
1012
|
+
return visit(create_native_tsrx_render_block(node.argument, state), state);
|
|
956
1013
|
}
|
|
957
1014
|
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
native_tsrx_function: true,
|
|
961
|
-
};
|
|
1015
|
+
return next() ?? node;
|
|
1016
|
+
}
|
|
962
1017
|
|
|
963
|
-
|
|
1018
|
+
/**
|
|
1019
|
+
* @param {AST.Node[]} path
|
|
1020
|
+
* @returns {any | null}
|
|
1021
|
+
*/
|
|
1022
|
+
function get_active_native_tsrx_function(path) {
|
|
1023
|
+
for (let i = path.length - 1; i >= 0; i -= 1) {
|
|
1024
|
+
const node = /** @type {any} */ (path[i]);
|
|
1025
|
+
if (is_function_or_class_boundary(node)) {
|
|
1026
|
+
return node.metadata?.native_tsrx ? node : null;
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
return null;
|
|
964
1030
|
}
|
|
965
1031
|
|
|
966
1032
|
/**
|
|
@@ -978,47 +1044,49 @@ function transform_function(node, context) {
|
|
|
978
1044
|
|
|
979
1045
|
/**
|
|
980
1046
|
* @param {any} node
|
|
981
|
-
* @param {{ next: () => any, state: TransformContext
|
|
1047
|
+
* @param {{ next: () => any, state: TransformContext }} context
|
|
982
1048
|
* @returns {any}
|
|
983
1049
|
*/
|
|
984
|
-
function transform_native_tsrx_function(node, { next, state
|
|
1050
|
+
function transform_native_tsrx_function(node, { next, state }) {
|
|
985
1051
|
const helper_state =
|
|
986
|
-
state.helper_state || create_helper_state(get_function_helper_base_name(node
|
|
1052
|
+
state.helper_state || create_helper_state(get_function_helper_base_name(node));
|
|
987
1053
|
const saved_helper_state = state.helper_state;
|
|
988
1054
|
const saved_bindings = state.available_bindings;
|
|
989
1055
|
const saved_hook_helpers_enabled = state.hook_helpers_enabled;
|
|
990
1056
|
|
|
991
1057
|
state.helper_state = helper_state;
|
|
992
|
-
state.hook_helpers_enabled = is_uppercase_function_like(node
|
|
1058
|
+
state.hook_helpers_enabled = is_uppercase_function_like(node);
|
|
1059
|
+
node.metadata = {
|
|
1060
|
+
...(node.metadata || {}),
|
|
1061
|
+
native_tsrx: true,
|
|
1062
|
+
...(needs_hook_split(node, state) ? { hook_split: true } : {}),
|
|
1063
|
+
};
|
|
993
1064
|
state.available_bindings = merge_binding_maps(
|
|
994
1065
|
saved_bindings,
|
|
995
1066
|
collect_function_scope_bindings(node),
|
|
996
1067
|
);
|
|
997
1068
|
|
|
998
|
-
|
|
999
|
-
expand_native_tsrx_function_returns(node, state);
|
|
1000
|
-
rewrite_component_body_conditional_hook_splits(node, state);
|
|
1069
|
+
validate_native_await(node, state);
|
|
1001
1070
|
|
|
1002
1071
|
const inner = /** @type {any} */ (next() ?? node);
|
|
1072
|
+
if (
|
|
1073
|
+
inner !== node &&
|
|
1074
|
+
node.type === 'ArrowFunctionExpression' &&
|
|
1075
|
+
node.body?.type === 'TsrxFragment' &&
|
|
1076
|
+
inner.body?.type === 'BlockStatement'
|
|
1077
|
+
) {
|
|
1078
|
+
inner.expression = false;
|
|
1079
|
+
}
|
|
1003
1080
|
|
|
1004
1081
|
state.helper_state = saved_helper_state;
|
|
1005
1082
|
state.available_bindings = saved_bindings;
|
|
1006
1083
|
state.hook_helpers_enabled = saved_hook_helpers_enabled;
|
|
1007
1084
|
|
|
1008
|
-
ensure_function_metadata(inner, { next: () => inner });
|
|
1009
1085
|
inner.metadata = {
|
|
1010
|
-
...(inner.metadata
|
|
1086
|
+
...strip_function_transform_metadata(inner.metadata),
|
|
1011
1087
|
native_tsrx_function: true,
|
|
1088
|
+
...(!saved_helper_state ? create_generated_helper_metadata(helper_state) || {} : {}),
|
|
1012
1089
|
};
|
|
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
1090
|
|
|
1023
1091
|
return inner;
|
|
1024
1092
|
}
|
|
@@ -1028,8 +1096,8 @@ function transform_native_tsrx_function(node, { next, state, path }) {
|
|
|
1028
1096
|
* @param {TransformContext} transform_context
|
|
1029
1097
|
* @returns {void}
|
|
1030
1098
|
*/
|
|
1031
|
-
function
|
|
1032
|
-
const await_node =
|
|
1099
|
+
function validate_native_await(node, transform_context) {
|
|
1100
|
+
const await_node = find_native_await(node);
|
|
1033
1101
|
if (!await_node) {
|
|
1034
1102
|
return;
|
|
1035
1103
|
}
|
|
@@ -1055,7 +1123,7 @@ function validate_native_tsrx_function_await(node, transform_context) {
|
|
|
1055
1123
|
* @param {any} node
|
|
1056
1124
|
* @returns {any | null}
|
|
1057
1125
|
*/
|
|
1058
|
-
function
|
|
1126
|
+
function find_native_await(node) {
|
|
1059
1127
|
if (
|
|
1060
1128
|
node.type === 'ArrowFunctionExpression' &&
|
|
1061
1129
|
node.body?.type !== 'BlockStatement' &&
|
|
@@ -1065,16 +1133,16 @@ function find_first_top_level_await_in_native_tsrx_function(node) {
|
|
|
1065
1133
|
}
|
|
1066
1134
|
|
|
1067
1135
|
const body = node.body?.type === 'BlockStatement' ? node.body.body || [] : [];
|
|
1068
|
-
return
|
|
1136
|
+
return find_native_await_in_list(body);
|
|
1069
1137
|
}
|
|
1070
1138
|
|
|
1071
1139
|
/**
|
|
1072
1140
|
* @param {any[]} statements
|
|
1073
1141
|
* @returns {any | null}
|
|
1074
1142
|
*/
|
|
1075
|
-
function
|
|
1143
|
+
function find_native_await_in_list(statements) {
|
|
1076
1144
|
for (const statement of statements) {
|
|
1077
|
-
const found =
|
|
1145
|
+
const found = find_native_await_in_statement(statement);
|
|
1078
1146
|
if (found) return found;
|
|
1079
1147
|
}
|
|
1080
1148
|
return null;
|
|
@@ -1084,10 +1152,10 @@ function find_first_top_level_await_in_native_tsrx_statements(statements) {
|
|
|
1084
1152
|
* @param {any} statement
|
|
1085
1153
|
* @returns {any | null}
|
|
1086
1154
|
*/
|
|
1087
|
-
function
|
|
1155
|
+
function find_native_await_in_statement(statement) {
|
|
1088
1156
|
if (!statement || typeof statement !== 'object') return null;
|
|
1089
1157
|
|
|
1090
|
-
if (statement.type === 'ReturnStatement' && statement.argument?.type === '
|
|
1158
|
+
if (statement.type === 'ReturnStatement' && statement.argument?.type === 'TsrxFragment') {
|
|
1091
1159
|
return find_first_top_level_await_in_tsrx_function_body(statement.argument.children || []);
|
|
1092
1160
|
}
|
|
1093
1161
|
|
|
@@ -1103,21 +1171,19 @@ function find_first_top_level_await_in_native_tsrx_statement(statement) {
|
|
|
1103
1171
|
}
|
|
1104
1172
|
|
|
1105
1173
|
if (statement.type === 'BlockStatement') {
|
|
1106
|
-
return
|
|
1174
|
+
return find_native_await_in_list(statement.body || []);
|
|
1107
1175
|
}
|
|
1108
1176
|
|
|
1109
1177
|
if (statement.type === 'IfStatement') {
|
|
1110
1178
|
return (
|
|
1111
|
-
|
|
1112
|
-
|
|
1179
|
+
find_native_await_in_statement(statement.consequent) ||
|
|
1180
|
+
find_native_await_in_statement(statement.alternate)
|
|
1113
1181
|
);
|
|
1114
1182
|
}
|
|
1115
1183
|
|
|
1116
1184
|
if (statement.type === 'SwitchStatement') {
|
|
1117
1185
|
for (const switch_case of statement.cases || []) {
|
|
1118
|
-
const found =
|
|
1119
|
-
switch_case.consequent || [],
|
|
1120
|
-
);
|
|
1186
|
+
const found = find_native_await_in_list(switch_case.consequent || []);
|
|
1121
1187
|
if (found) return found;
|
|
1122
1188
|
}
|
|
1123
1189
|
return null;
|
|
@@ -1125,9 +1191,9 @@ function find_first_top_level_await_in_native_tsrx_statement(statement) {
|
|
|
1125
1191
|
|
|
1126
1192
|
if (statement.type === 'TryStatement') {
|
|
1127
1193
|
return (
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1194
|
+
find_native_await_in_statement(statement.block) ||
|
|
1195
|
+
find_native_await_in_statement(statement.handler?.body) ||
|
|
1196
|
+
find_native_await_in_statement(statement.finalizer)
|
|
1131
1197
|
);
|
|
1132
1198
|
}
|
|
1133
1199
|
|
|
@@ -1136,32 +1202,34 @@ function find_first_top_level_await_in_native_tsrx_statement(statement) {
|
|
|
1136
1202
|
|
|
1137
1203
|
/**
|
|
1138
1204
|
* @param {any} node
|
|
1139
|
-
* @param {{ next: () => any, state: TransformContext
|
|
1205
|
+
* @param {{ next: () => any, state: TransformContext }} context
|
|
1140
1206
|
* @returns {any}
|
|
1141
1207
|
*/
|
|
1142
|
-
function transform_function_with_hook_helpers(node, { next, state
|
|
1208
|
+
function transform_function_with_hook_helpers(node, { next, state }) {
|
|
1143
1209
|
const has_hook_bearing_tsrx = function_contains_hook_bearing_tsrx(node, state);
|
|
1144
|
-
const
|
|
1210
|
+
const has_hook_split = needs_hook_split(node, state);
|
|
1145
1211
|
if (
|
|
1146
1212
|
state.helper_state ||
|
|
1147
|
-
!is_uppercase_function_like(node
|
|
1148
|
-
(!has_hook_bearing_tsrx && !
|
|
1213
|
+
!is_uppercase_function_like(node) ||
|
|
1214
|
+
(!has_hook_bearing_tsrx && !has_hook_split)
|
|
1149
1215
|
) {
|
|
1150
|
-
return
|
|
1216
|
+
return next() ?? node;
|
|
1151
1217
|
}
|
|
1152
1218
|
|
|
1153
|
-
const helper_state = create_helper_state(get_function_helper_base_name(node
|
|
1219
|
+
const helper_state = create_helper_state(get_function_helper_base_name(node));
|
|
1154
1220
|
const saved_helper_state = state.helper_state;
|
|
1155
1221
|
const saved_bindings = state.available_bindings;
|
|
1156
1222
|
const saved_hook_helpers_enabled = state.hook_helpers_enabled;
|
|
1157
1223
|
|
|
1158
1224
|
state.helper_state = helper_state;
|
|
1159
1225
|
state.hook_helpers_enabled = true;
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1226
|
+
if (has_hook_split) {
|
|
1227
|
+
node.metadata = {
|
|
1228
|
+
...(node.metadata || {}),
|
|
1229
|
+
hook_split: true,
|
|
1230
|
+
};
|
|
1164
1231
|
}
|
|
1232
|
+
state.available_bindings = collect_function_scope_bindings(node);
|
|
1165
1233
|
|
|
1166
1234
|
const inner = /** @type {any} */ (next() ?? node);
|
|
1167
1235
|
|
|
@@ -1169,48 +1237,41 @@ function transform_function_with_hook_helpers(node, { next, state, path }) {
|
|
|
1169
1237
|
state.available_bindings = saved_bindings;
|
|
1170
1238
|
state.hook_helpers_enabled = saved_hook_helpers_enabled;
|
|
1171
1239
|
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
generated_helpers: helper_state.helpers,
|
|
1177
|
-
generated_statics: helper_state.statics,
|
|
1178
|
-
};
|
|
1179
|
-
}
|
|
1240
|
+
inner.metadata = {
|
|
1241
|
+
...strip_function_transform_metadata(inner.metadata),
|
|
1242
|
+
...(create_generated_helper_metadata(helper_state) || {}),
|
|
1243
|
+
};
|
|
1180
1244
|
|
|
1181
1245
|
return inner;
|
|
1182
1246
|
}
|
|
1183
1247
|
|
|
1184
1248
|
/**
|
|
1185
1249
|
* @param {any} node
|
|
1186
|
-
* @param {AST.Node[]} [path]
|
|
1187
1250
|
* @returns {string}
|
|
1188
1251
|
*/
|
|
1189
|
-
function get_function_helper_base_name(node
|
|
1190
|
-
return get_function_like_name(node
|
|
1252
|
+
function get_function_helper_base_name(node) {
|
|
1253
|
+
return get_function_like_name(node) || 'TsrxFragment';
|
|
1191
1254
|
}
|
|
1192
1255
|
|
|
1193
1256
|
/**
|
|
1194
1257
|
* @param {any} node
|
|
1195
|
-
* @param {AST.Node[]} path
|
|
1196
1258
|
* @returns {boolean}
|
|
1197
1259
|
*/
|
|
1198
|
-
function is_uppercase_function_like(node
|
|
1199
|
-
const name = get_function_like_name(node
|
|
1260
|
+
function is_uppercase_function_like(node) {
|
|
1261
|
+
const name = get_function_like_name(node);
|
|
1200
1262
|
return !!(name && /^[A-Z]/.test(name));
|
|
1201
1263
|
}
|
|
1202
1264
|
|
|
1203
1265
|
/**
|
|
1204
1266
|
* @param {any} node
|
|
1205
|
-
* @param {AST.Node[]} path
|
|
1206
1267
|
* @returns {string | null}
|
|
1207
1268
|
*/
|
|
1208
|
-
function get_function_like_name(node
|
|
1269
|
+
function get_function_like_name(node) {
|
|
1209
1270
|
if (node.id?.type === 'Identifier') {
|
|
1210
1271
|
return node.id.name;
|
|
1211
1272
|
}
|
|
1212
1273
|
|
|
1213
|
-
const parent = /** @type {any} */ (path
|
|
1274
|
+
const parent = /** @type {any} */ (node.metadata?.path?.at(-1));
|
|
1214
1275
|
if (!parent) return null;
|
|
1215
1276
|
|
|
1216
1277
|
if (parent.type === 'VariableDeclarator' && parent.init === node) {
|
|
@@ -1268,7 +1329,7 @@ function collect_function_scope_bindings(node) {
|
|
|
1268
1329
|
const bindings = collect_param_bindings(node.params || []);
|
|
1269
1330
|
if (node.body?.type === 'BlockStatement') {
|
|
1270
1331
|
for (const statement of node.body.body || []) {
|
|
1271
|
-
if (statement.type === 'ReturnStatement' && statement.argument?.type === '
|
|
1332
|
+
if (statement.type === 'ReturnStatement' && statement.argument?.type === 'TsrxFragment') {
|
|
1272
1333
|
for (const child of get_tsrx_render_children(statement.argument)) {
|
|
1273
1334
|
collect_statement_bindings(child, bindings);
|
|
1274
1335
|
}
|
|
@@ -1377,7 +1438,7 @@ function statement_contains_native_tsrx_return(statement) {
|
|
|
1377
1438
|
*/
|
|
1378
1439
|
function node_contains_native_tsrx_template(node) {
|
|
1379
1440
|
if (!node || typeof node !== 'object') return false;
|
|
1380
|
-
if (node.type === 'Element' || node.type === '
|
|
1441
|
+
if (node.type === 'Element' || node.type === 'TsrxFragment') return true;
|
|
1381
1442
|
|
|
1382
1443
|
if (is_function_or_class_boundary(node)) {
|
|
1383
1444
|
return false;
|
|
@@ -1419,7 +1480,7 @@ function collect_tsrx_stylesheet(node) {
|
|
|
1419
1480
|
/**
|
|
1420
1481
|
* @param {any} node
|
|
1421
1482
|
* @param {TransformContext} transform_context
|
|
1422
|
-
* @returns {{ css: any, style_refs: any[] } | null}
|
|
1483
|
+
* @returns {{ css: any, style_refs: any[], fragment: any } | null}
|
|
1423
1484
|
*/
|
|
1424
1485
|
function prepare_tsrx_fragment_styles(node, transform_context) {
|
|
1425
1486
|
const css = collect_tsrx_stylesheet(node);
|
|
@@ -1428,21 +1489,21 @@ function prepare_tsrx_fragment_styles(node, transform_context) {
|
|
|
1428
1489
|
const style_refs = collect_style_ref_attributes(node);
|
|
1429
1490
|
apply_css_definition_metadata(node, css, style_refs.length > 0);
|
|
1430
1491
|
transform_context.stylesheets.push(css);
|
|
1431
|
-
annotate_tsrx_with_hash(
|
|
1492
|
+
const fragment = annotate_tsrx_with_hash(
|
|
1432
1493
|
node,
|
|
1433
1494
|
css.hash,
|
|
1434
1495
|
transform_context.platform.jsx.classAttrName ??
|
|
1435
1496
|
(transform_context.platform.jsx.rewriteClassAttr ? 'className' : 'class'),
|
|
1436
1497
|
transform_context.typeOnly,
|
|
1437
1498
|
);
|
|
1438
|
-
return { css, style_refs };
|
|
1499
|
+
return { css, style_refs, fragment };
|
|
1439
1500
|
}
|
|
1440
1501
|
|
|
1441
1502
|
/**
|
|
1442
1503
|
* @template T
|
|
1443
1504
|
* @param {any} node
|
|
1444
1505
|
* @param {TransformContext} transform_context
|
|
1445
|
-
* @param {(style_context: { css: any, style_refs: any[] } | null) => T} callback
|
|
1506
|
+
* @param {(style_context: { css: any, style_refs: any[], fragment: any } | null) => T} callback
|
|
1446
1507
|
* @returns {T}
|
|
1447
1508
|
*/
|
|
1448
1509
|
function with_tsrx_fragment_styles(node, transform_context, callback) {
|
|
@@ -1452,7 +1513,7 @@ function with_tsrx_fragment_styles(node, transform_context, callback) {
|
|
|
1452
1513
|
|
|
1453
1514
|
/**
|
|
1454
1515
|
* @param {any} fragment
|
|
1455
|
-
* @param {{ css: any, style_refs: any[] } | null} style_context
|
|
1516
|
+
* @param {{ css: any, style_refs: any[], fragment: any } | null} style_context
|
|
1456
1517
|
* @param {TransformContext} transform_context
|
|
1457
1518
|
* @returns {AST.Statement[]}
|
|
1458
1519
|
*/
|
|
@@ -1472,6 +1533,64 @@ function create_tsrx_style_ref_setup_statements(fragment, style_context, transfo
|
|
|
1472
1533
|
);
|
|
1473
1534
|
}
|
|
1474
1535
|
|
|
1536
|
+
/**
|
|
1537
|
+
* @param {any} node
|
|
1538
|
+
* @param {any} stylesheet
|
|
1539
|
+
* @param {TransformContext} transform_context
|
|
1540
|
+
* @returns {AST.Expression}
|
|
1541
|
+
*/
|
|
1542
|
+
function create_style_expression_value(node, stylesheet, transform_context) {
|
|
1543
|
+
const class_map = create_style_class_map_from_stylesheet(stylesheet);
|
|
1544
|
+
if (!transform_context.typeOnly) {
|
|
1545
|
+
return class_map;
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1548
|
+
add_type_only_style_anchor(node, transform_context);
|
|
1549
|
+
return class_map;
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1552
|
+
/**
|
|
1553
|
+
* @param {any} node
|
|
1554
|
+
* @param {TransformContext} transform_context
|
|
1555
|
+
*/
|
|
1556
|
+
function add_type_only_style_anchor(node, transform_context) {
|
|
1557
|
+
const style_anchor = b.jsx_element(clone_expression_node(node, true), [], []);
|
|
1558
|
+
disable_style_anchor_verification(style_anchor);
|
|
1559
|
+
|
|
1560
|
+
const anchor_id = create_generated_identifier(create_style_anchor_name(transform_context));
|
|
1561
|
+
transform_context.type_only_style_anchors.push(
|
|
1562
|
+
b.const(anchor_id, style_anchor),
|
|
1563
|
+
b.stmt(clone_identifier(anchor_id)),
|
|
1564
|
+
);
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
/**
|
|
1568
|
+
* @param {TransformContext} transform_context
|
|
1569
|
+
* @returns {string}
|
|
1570
|
+
*/
|
|
1571
|
+
function create_style_anchor_name(transform_context) {
|
|
1572
|
+
transform_context.local_statement_component_index += 1;
|
|
1573
|
+
return `_tsrx_style_anchor_${transform_context.local_statement_component_index}`;
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
/**
|
|
1577
|
+
* @param {ESTreeJSX.JSXElement} element
|
|
1578
|
+
*/
|
|
1579
|
+
function disable_style_anchor_verification(element) {
|
|
1580
|
+
if (element.openingElement?.name) {
|
|
1581
|
+
element.openingElement.name.metadata = {
|
|
1582
|
+
...(element.openingElement.name.metadata || {}),
|
|
1583
|
+
disable_verification: true,
|
|
1584
|
+
};
|
|
1585
|
+
}
|
|
1586
|
+
if (element.closingElement?.name) {
|
|
1587
|
+
element.closingElement.name.metadata = {
|
|
1588
|
+
...(element.closingElement.name.metadata || {}),
|
|
1589
|
+
disable_verification: true,
|
|
1590
|
+
};
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1475
1594
|
/**
|
|
1476
1595
|
* @param {TransformContext} transform_context
|
|
1477
1596
|
* @returns {string}
|
|
@@ -1510,7 +1629,7 @@ function collect_style_elements(node, styles) {
|
|
|
1510
1629
|
return;
|
|
1511
1630
|
}
|
|
1512
1631
|
|
|
1513
|
-
if (is_function_or_class_boundary(node) || node.type === '
|
|
1632
|
+
if (is_function_or_class_boundary(node) || node.type === 'TsrxFragment') {
|
|
1514
1633
|
return;
|
|
1515
1634
|
}
|
|
1516
1635
|
|
|
@@ -1549,15 +1668,22 @@ function collect_style_elements(node, styles) {
|
|
|
1549
1668
|
* @param {string} hash
|
|
1550
1669
|
* @param {'class' | 'className'} jsx_class_attr_name
|
|
1551
1670
|
* @param {boolean} preserve_style_elements
|
|
1552
|
-
* @returns {
|
|
1671
|
+
* @returns {any}
|
|
1553
1672
|
*/
|
|
1554
1673
|
function annotate_tsrx_with_hash(node, hash, jsx_class_attr_name, preserve_style_elements) {
|
|
1555
|
-
|
|
1556
|
-
|
|
1674
|
+
const annotated = { ...node };
|
|
1675
|
+
annotated.children = (node.children || []).map((/** @type {any} */ statement) =>
|
|
1676
|
+
annotate_with_hash(
|
|
1677
|
+
clone_expression_node(statement),
|
|
1678
|
+
hash,
|
|
1679
|
+
jsx_class_attr_name,
|
|
1680
|
+
preserve_style_elements,
|
|
1681
|
+
),
|
|
1557
1682
|
);
|
|
1558
1683
|
if (!preserve_style_elements) {
|
|
1559
|
-
|
|
1684
|
+
annotated.children = strip_style_elements(annotated.children);
|
|
1560
1685
|
}
|
|
1686
|
+
return annotated;
|
|
1561
1687
|
}
|
|
1562
1688
|
|
|
1563
1689
|
/**
|
|
@@ -1622,8 +1748,7 @@ function is_style_expression_position(path) {
|
|
|
1622
1748
|
const parent = path.at(-1);
|
|
1623
1749
|
return !(
|
|
1624
1750
|
parent?.type === 'Element' ||
|
|
1625
|
-
parent?.type === '
|
|
1626
|
-
parent?.type === 'Tsx' ||
|
|
1751
|
+
parent?.type === 'TsrxFragment' ||
|
|
1627
1752
|
parent?.type === 'TsxCompat' ||
|
|
1628
1753
|
parent?.type === 'BlockStatement' ||
|
|
1629
1754
|
parent?.type === 'Program' ||
|
|
@@ -1632,32 +1757,58 @@ function is_style_expression_position(path) {
|
|
|
1632
1757
|
}
|
|
1633
1758
|
|
|
1634
1759
|
/**
|
|
1635
|
-
* @param {any}
|
|
1760
|
+
* @param {any} fragment
|
|
1636
1761
|
* @param {TransformContext} transform_context
|
|
1637
|
-
* @returns {
|
|
1762
|
+
* @returns {any}
|
|
1638
1763
|
*/
|
|
1639
|
-
function
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
})
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1764
|
+
function create_native_tsrx_render_block(fragment, transform_context) {
|
|
1765
|
+
const block = b.block(
|
|
1766
|
+
mark_native_pretransformed_jsx(
|
|
1767
|
+
create_native_tsrx_render_statements(fragment, transform_context),
|
|
1768
|
+
),
|
|
1769
|
+
fragment,
|
|
1770
|
+
);
|
|
1771
|
+
block.metadata = {
|
|
1772
|
+
...(block.metadata || {}),
|
|
1773
|
+
native_return_block: true,
|
|
1774
|
+
};
|
|
1775
|
+
return block;
|
|
1776
|
+
}
|
|
1652
1777
|
|
|
1653
|
-
|
|
1654
|
-
|
|
1778
|
+
/**
|
|
1779
|
+
* @param {any} block
|
|
1780
|
+
* @param {TransformContext} transform_context
|
|
1781
|
+
* @returns {any | null}
|
|
1782
|
+
*/
|
|
1783
|
+
function create_native_tsrx_statement_list_block(block, transform_context) {
|
|
1784
|
+
const source_body = block.body || [];
|
|
1785
|
+
const body = expand_native_tsrx_return_statement_list(source_body, transform_context);
|
|
1786
|
+
|
|
1787
|
+
if (body === source_body) {
|
|
1788
|
+
return null;
|
|
1655
1789
|
}
|
|
1656
1790
|
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1791
|
+
const next_block = b.block(mark_native_pretransformed_jsx(body), block);
|
|
1792
|
+
next_block.metadata = {
|
|
1793
|
+
...(next_block.metadata || {}),
|
|
1794
|
+
native_return_block: true,
|
|
1795
|
+
};
|
|
1796
|
+
return next_block;
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
/**
|
|
1800
|
+
* @param {any} fragment
|
|
1801
|
+
* @param {TransformContext} transform_context
|
|
1802
|
+
* @returns {AST.Statement[]}
|
|
1803
|
+
*/
|
|
1804
|
+
function create_native_tsrx_render_statements(fragment, transform_context) {
|
|
1805
|
+
return with_tsrx_fragment_styles(fragment, transform_context, (style_context) => {
|
|
1806
|
+
const target = style_context?.fragment ?? fragment;
|
|
1807
|
+
return [
|
|
1808
|
+
...create_tsrx_style_ref_setup_statements(target, style_context, transform_context),
|
|
1809
|
+
...build_render_statements(get_tsrx_render_children(target), true, transform_context),
|
|
1810
|
+
];
|
|
1811
|
+
});
|
|
1661
1812
|
}
|
|
1662
1813
|
|
|
1663
1814
|
/**
|
|
@@ -1666,9 +1817,15 @@ function expand_native_tsrx_function_returns(node, transform_context) {
|
|
|
1666
1817
|
* @returns {any[]}
|
|
1667
1818
|
*/
|
|
1668
1819
|
function expand_native_tsrx_return_statement_list(statements, transform_context) {
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1820
|
+
let changed = false;
|
|
1821
|
+
const next_statements = statements.flatMap((statement) => {
|
|
1822
|
+
const result = expand_native_tsrx_return_statement(statement, transform_context);
|
|
1823
|
+
if (result.length !== 1 || result[0] !== statement) {
|
|
1824
|
+
changed = true;
|
|
1825
|
+
}
|
|
1826
|
+
return result;
|
|
1827
|
+
});
|
|
1828
|
+
return changed ? next_statements : statements;
|
|
1672
1829
|
}
|
|
1673
1830
|
|
|
1674
1831
|
/**
|
|
@@ -1679,14 +1836,8 @@ function expand_native_tsrx_return_statement_list(statements, transform_context)
|
|
|
1679
1836
|
function expand_native_tsrx_return_statement(statement, transform_context) {
|
|
1680
1837
|
if (!statement || typeof statement !== 'object') return [statement];
|
|
1681
1838
|
|
|
1682
|
-
if (statement.type === 'ReturnStatement' && statement.argument?.type === '
|
|
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
|
-
});
|
|
1839
|
+
if (statement.type === 'ReturnStatement' && statement.argument?.type === 'TsrxFragment') {
|
|
1840
|
+
return create_native_tsrx_render_statements(statement.argument, transform_context);
|
|
1690
1841
|
}
|
|
1691
1842
|
|
|
1692
1843
|
if (is_function_or_class_boundary(statement)) {
|
|
@@ -1694,52 +1845,65 @@ function expand_native_tsrx_return_statement(statement, transform_context) {
|
|
|
1694
1845
|
}
|
|
1695
1846
|
|
|
1696
1847
|
if (statement.type === 'BlockStatement') {
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
transform_context,
|
|
1700
|
-
);
|
|
1701
|
-
return [statement];
|
|
1848
|
+
const body = expand_native_tsrx_return_statement_list(statement.body || [], transform_context);
|
|
1849
|
+
return body === statement.body ? [statement] : [b.block(body, statement)];
|
|
1702
1850
|
}
|
|
1703
1851
|
|
|
1704
1852
|
if (statement.type === 'IfStatement') {
|
|
1705
|
-
|
|
1853
|
+
const consequent = expand_embedded_native_return_statement(
|
|
1706
1854
|
statement.consequent,
|
|
1707
1855
|
transform_context,
|
|
1708
1856
|
);
|
|
1709
|
-
|
|
1710
|
-
statement.alternate
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1857
|
+
const alternate = statement.alternate
|
|
1858
|
+
? expand_embedded_native_return_statement(statement.alternate, transform_context)
|
|
1859
|
+
: statement.alternate;
|
|
1860
|
+
if (consequent === statement.consequent && alternate === statement.alternate) {
|
|
1861
|
+
return [statement];
|
|
1714
1862
|
}
|
|
1715
|
-
return [statement];
|
|
1863
|
+
return [set_loc(b.if(statement.test, consequent, alternate), statement)];
|
|
1716
1864
|
}
|
|
1717
1865
|
|
|
1718
1866
|
if (statement.type === 'SwitchStatement') {
|
|
1719
|
-
|
|
1720
|
-
|
|
1867
|
+
let changed = false;
|
|
1868
|
+
const cases = (statement.cases || []).map((/** @type {any} */ switch_case) => {
|
|
1869
|
+
const consequent = expand_native_tsrx_return_statement_list(
|
|
1721
1870
|
switch_case.consequent || [],
|
|
1722
1871
|
transform_context,
|
|
1723
1872
|
);
|
|
1724
|
-
|
|
1725
|
-
|
|
1873
|
+
if (consequent === switch_case.consequent) {
|
|
1874
|
+
return switch_case;
|
|
1875
|
+
}
|
|
1876
|
+
changed = true;
|
|
1877
|
+
return set_loc(b.switch_case(switch_case.test, consequent), switch_case);
|
|
1878
|
+
});
|
|
1879
|
+
return changed ? [set_loc(b.switch(statement.discriminant, cases), statement)] : [statement];
|
|
1726
1880
|
}
|
|
1727
1881
|
|
|
1728
1882
|
if (statement.type === 'TryStatement') {
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
statement.handler.body
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
)
|
|
1735
|
-
|
|
1736
|
-
if (
|
|
1737
|
-
statement.
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1883
|
+
const block = expand_embedded_native_return_statement(statement.block, transform_context);
|
|
1884
|
+
const handler_body = statement.handler?.body
|
|
1885
|
+
? expand_embedded_native_return_statement(statement.handler.body, transform_context)
|
|
1886
|
+
: statement.handler?.body;
|
|
1887
|
+
const finalizer = statement.finalizer
|
|
1888
|
+
? expand_embedded_native_return_statement(statement.finalizer, transform_context)
|
|
1889
|
+
: statement.finalizer;
|
|
1890
|
+
if (
|
|
1891
|
+
block === statement.block &&
|
|
1892
|
+
handler_body === statement.handler?.body &&
|
|
1893
|
+
finalizer === statement.finalizer
|
|
1894
|
+
) {
|
|
1895
|
+
return [statement];
|
|
1741
1896
|
}
|
|
1742
|
-
|
|
1897
|
+
const handler =
|
|
1898
|
+
statement.handler && handler_body !== statement.handler.body
|
|
1899
|
+
? b.catch_clause(
|
|
1900
|
+
statement.handler.param,
|
|
1901
|
+
statement.handler.resetParam,
|
|
1902
|
+
handler_body,
|
|
1903
|
+
statement.handler,
|
|
1904
|
+
)
|
|
1905
|
+
: statement.handler;
|
|
1906
|
+
return [set_loc(b.try(block, handler, finalizer, statement.pending ?? null), statement)];
|
|
1743
1907
|
}
|
|
1744
1908
|
|
|
1745
1909
|
return [statement];
|
|
@@ -1872,7 +2036,7 @@ function node_contains_hook_bearing_tsrx(node, transform_context) {
|
|
|
1872
2036
|
return node.some((child) => node_contains_hook_bearing_tsrx(child, transform_context));
|
|
1873
2037
|
}
|
|
1874
2038
|
|
|
1875
|
-
if (node.type === '
|
|
2039
|
+
if (node.type === 'TsrxFragment') {
|
|
1876
2040
|
return body_contains_top_level_hook_call(node.children || [], transform_context, true);
|
|
1877
2041
|
}
|
|
1878
2042
|
|
|
@@ -1919,7 +2083,7 @@ function should_extract_hook_helpers(transform_context) {
|
|
|
1919
2083
|
*/
|
|
1920
2084
|
function create_module_scoped_hook_component_id(helper_id, transform_context) {
|
|
1921
2085
|
return create_generated_identifier(
|
|
1922
|
-
`${transform_context.helper_state?.base_name || '
|
|
2086
|
+
`${transform_context.helper_state?.base_name || 'TsrxFragment'}__${helper_id.name}`,
|
|
1923
2087
|
);
|
|
1924
2088
|
}
|
|
1925
2089
|
|
|
@@ -2645,15 +2809,7 @@ function to_jsx_element(node, transform_context, raw_children = node.children ||
|
|
|
2645
2809
|
if (node.type === 'JSXElement') return node;
|
|
2646
2810
|
if (!node.id) {
|
|
2647
2811
|
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
|
-
);
|
|
2812
|
+
return set_loc(b.jsx_fragment(), node);
|
|
2657
2813
|
}
|
|
2658
2814
|
if (is_dynamic_element_id(node.id)) {
|
|
2659
2815
|
return dynamic_element_to_jsx_child(node, transform_context);
|
|
@@ -2707,7 +2863,11 @@ function to_jsx_element(node, transform_context, raw_children = node.children ||
|
|
|
2707
2863
|
node.closingElement || node,
|
|
2708
2864
|
);
|
|
2709
2865
|
|
|
2710
|
-
|
|
2866
|
+
const element = set_loc(b.jsx_element_fresh(openingElement, closingElement, children), node);
|
|
2867
|
+
if (transform_context.typeOnly && is_style_element(node)) {
|
|
2868
|
+
disable_style_anchor_verification(element);
|
|
2869
|
+
}
|
|
2870
|
+
return element;
|
|
2711
2871
|
}
|
|
2712
2872
|
|
|
2713
2873
|
/**
|
|
@@ -3632,12 +3792,7 @@ export function create_hook_safe_helper(
|
|
|
3632
3792
|
|
|
3633
3793
|
if (key_expression) {
|
|
3634
3794
|
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
|
-
}),
|
|
3795
|
+
b.jsx_attribute(b.jsx_id('key'), to_jsx_expression_container(key_expression, key_expression)),
|
|
3641
3796
|
);
|
|
3642
3797
|
}
|
|
3643
3798
|
|
|
@@ -3805,11 +3960,19 @@ function create_cached_helper_declaration(helper_id, cache_id, helper_init) {
|
|
|
3805
3960
|
* @returns {AST.FunctionDeclaration}
|
|
3806
3961
|
*/
|
|
3807
3962
|
function create_helper_function_declaration_from_expression(helper_id, helper_fn) {
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3963
|
+
const declaration = set_loc(
|
|
3964
|
+
b.function_declaration(
|
|
3965
|
+
clone_identifier(helper_id),
|
|
3966
|
+
helper_fn.params,
|
|
3967
|
+
helper_fn.body,
|
|
3968
|
+
helper_fn.async,
|
|
3969
|
+
helper_fn.typeParameters,
|
|
3970
|
+
),
|
|
3971
|
+
helper_fn,
|
|
3972
|
+
);
|
|
3973
|
+
declaration.generator = helper_fn.generator;
|
|
3974
|
+
declaration.metadata = { ...(helper_fn.metadata || {}), path: helper_fn.metadata?.path || [] };
|
|
3975
|
+
return declaration;
|
|
3813
3976
|
}
|
|
3814
3977
|
|
|
3815
3978
|
/**
|
|
@@ -3842,11 +4005,7 @@ function get_body_source_node(body_nodes) {
|
|
|
3842
4005
|
function to_jsx_child(node, transform_context) {
|
|
3843
4006
|
if (!node) return node;
|
|
3844
4007
|
switch (node.type) {
|
|
3845
|
-
case '
|
|
3846
|
-
// We're inside a JSX child position by construction, so keep a
|
|
3847
|
-
// JSXExpressionContainer wrapper for bare `{expr}` children.
|
|
3848
|
-
return tsx_node_to_jsx_expression(node, true);
|
|
3849
|
-
case 'Tsrx':
|
|
4008
|
+
case 'TsrxFragment':
|
|
3850
4009
|
return tsrx_node_to_jsx_expression(node, transform_context, true);
|
|
3851
4010
|
case 'TsxCompat':
|
|
3852
4011
|
return tsx_compat_node_to_jsx_expression(node, transform_context, true);
|
|
@@ -3880,8 +4039,8 @@ function to_jsx_child(node, transform_context) {
|
|
|
3880
4039
|
|
|
3881
4040
|
/**
|
|
3882
4041
|
* Lower a native TSRX fragment body to a JSX expression.
|
|
3883
|
-
*
|
|
3884
|
-
*
|
|
4042
|
+
* Children have already been parsed and transformed through the normal TSRX
|
|
4043
|
+
* Element/Text/control-flow visitors.
|
|
3885
4044
|
*
|
|
3886
4045
|
* @param {any} node
|
|
3887
4046
|
* @param {TransformContext} transform_context
|
|
@@ -4574,14 +4733,7 @@ function try_statement_to_jsx_child(node, transform_context) {
|
|
|
4574
4733
|
) ??
|
|
4575
4734
|
create_jsx_element(
|
|
4576
4735
|
'Suspense',
|
|
4577
|
-
[
|
|
4578
|
-
{
|
|
4579
|
-
type: 'JSXAttribute',
|
|
4580
|
-
name: { type: 'JSXIdentifier', name: 'fallback', metadata: { path: [] } },
|
|
4581
|
-
value: fallback_content,
|
|
4582
|
-
metadata: { path: [] },
|
|
4583
|
-
},
|
|
4584
|
-
],
|
|
4736
|
+
[b.jsx_attribute(b.jsx_id('fallback'), fallback_content)],
|
|
4585
4737
|
[result],
|
|
4586
4738
|
);
|
|
4587
4739
|
}
|
|
@@ -5066,14 +5218,12 @@ function build_switch_with_lift(switch_node, transform_context) {
|
|
|
5066
5218
|
(/** @type {any} */ original_case, /** @type {number} */ i) => {
|
|
5067
5219
|
const helper = case_helpers[i];
|
|
5068
5220
|
if (helper) {
|
|
5069
|
-
return
|
|
5070
|
-
|
|
5071
|
-
test: original_case.test,
|
|
5072
|
-
consequent: [
|
|
5221
|
+
return set_loc(
|
|
5222
|
+
b.switch_case(original_case.test, [
|
|
5073
5223
|
create_component_return_statement([helper.component_element], original_case),
|
|
5074
|
-
],
|
|
5075
|
-
|
|
5076
|
-
|
|
5224
|
+
]),
|
|
5225
|
+
original_case,
|
|
5226
|
+
);
|
|
5077
5227
|
}
|
|
5078
5228
|
|
|
5079
5229
|
const { own_body, has_terminator } = case_info[i];
|
|
@@ -5082,12 +5232,7 @@ function build_switch_with_lift(switch_node, transform_context) {
|
|
|
5082
5232
|
// Alias-pattern empty case (`case 'a': case 'b': ...`) — keep
|
|
5083
5233
|
// the arm body empty so JS falls through to the next case at
|
|
5084
5234
|
// runtime, where the helper invocation actually lives.
|
|
5085
|
-
return
|
|
5086
|
-
type: 'SwitchCase',
|
|
5087
|
-
test: original_case.test,
|
|
5088
|
-
consequent: [],
|
|
5089
|
-
metadata: { path: [] },
|
|
5090
|
-
});
|
|
5235
|
+
return set_loc(b.switch_case(original_case.test, []), original_case);
|
|
5091
5236
|
}
|
|
5092
5237
|
|
|
5093
5238
|
const case_body = [];
|
|
@@ -5128,45 +5273,23 @@ function build_switch_with_lift(switch_node, transform_context) {
|
|
|
5128
5273
|
// Empty body with explicit `break;` / bare `return;` — keep
|
|
5129
5274
|
// a `break` so JS doesn't fall through into the next case
|
|
5130
5275
|
// (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
|
-
);
|
|
5276
|
+
case_body.push(b.break);
|
|
5138
5277
|
} else if (case_body.length > 0) {
|
|
5139
5278
|
// Statements-only inline case without terminator. We've
|
|
5140
5279
|
// already inlined the downstream chain via the helper
|
|
5141
5280
|
// reference above, so emit a `break` to stop the runtime
|
|
5142
5281
|
// 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
|
-
);
|
|
5282
|
+
case_body.push(b.break);
|
|
5150
5283
|
}
|
|
5151
5284
|
}
|
|
5152
5285
|
|
|
5153
|
-
return
|
|
5154
|
-
type: 'SwitchCase',
|
|
5155
|
-
test: original_case.test,
|
|
5156
|
-
consequent: case_body,
|
|
5157
|
-
metadata: { path: [] },
|
|
5158
|
-
});
|
|
5286
|
+
return set_loc(b.switch_case(original_case.test, case_body), original_case);
|
|
5159
5287
|
},
|
|
5160
5288
|
);
|
|
5161
5289
|
|
|
5162
5290
|
return {
|
|
5163
5291
|
setup_statements,
|
|
5164
|
-
switch_statement:
|
|
5165
|
-
type: 'SwitchStatement',
|
|
5166
|
-
discriminant: switch_node.discriminant,
|
|
5167
|
-
cases: new_cases,
|
|
5168
|
-
metadata: { path: [] },
|
|
5169
|
-
}),
|
|
5292
|
+
switch_statement: b.switch(switch_node.discriminant, new_cases, switch_node),
|
|
5170
5293
|
};
|
|
5171
5294
|
}
|
|
5172
5295
|
|
|
@@ -5393,7 +5516,7 @@ function wrap_jsx_setup_declarations(expression, in_jsx_child) {
|
|
|
5393
5516
|
* This validator runs over the raw, pre-lowering attribute list so each
|
|
5394
5517
|
* shape is still distinguishable by `type`. Ripple `Element` attributes have type `Attribute` with an
|
|
5395
5518
|
* `Identifier` name (the parser normalizes `JSXAttribute`/`JSXIdentifier`
|
|
5396
|
-
* for
|
|
5519
|
+
* for native elements); inside `<tsx:react>` compat blocks they retain
|
|
5397
5520
|
* the original `JSXAttribute`/`JSXIdentifier` shape, so we accept both.
|
|
5398
5521
|
*
|
|
5399
5522
|
* @param {any[]} raw_attrs
|
|
@@ -5781,19 +5904,7 @@ function build_return_expression(render_nodes) {
|
|
|
5781
5904
|
const first = render_nodes[0];
|
|
5782
5905
|
const last = render_nodes[render_nodes.length - 1];
|
|
5783
5906
|
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
|
-
},
|
|
5907
|
+
b.jsx_fragment(render_nodes),
|
|
5797
5908
|
first?.loc && last?.loc
|
|
5798
5909
|
? {
|
|
5799
5910
|
start: first.start,
|
|
@@ -5818,7 +5929,7 @@ function tsx_compat_node_to_jsx_expression(node, transform_context, in_jsx_child
|
|
|
5818
5929
|
if (!platform.jsx.acceptedTsxKinds.includes(node.kind)) {
|
|
5819
5930
|
const accepted = platform.jsx.acceptedTsxKinds.map((k) => `<tsx:${k}>`).join(', ');
|
|
5820
5931
|
error(
|
|
5821
|
-
`${platform.name} TSRX does not support <tsx:${node.kind}> blocks. Use
|
|
5932
|
+
`${platform.name} TSRX does not support <tsx:${node.kind}> blocks. Use one of: ${accepted}.`,
|
|
5822
5933
|
transform_context.filename,
|
|
5823
5934
|
node,
|
|
5824
5935
|
transform_context.errors,
|