@tsrx/core 0.1.14 → 0.1.16
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/parse/index.js +22 -2
- package/src/plugin.js +75 -0
- package/src/transform/jsx/helpers.js +1 -0
- package/src/transform/segments.js +17 -0
package/package.json
CHANGED
package/src/parse/index.js
CHANGED
|
@@ -605,6 +605,10 @@ export function get_comment_handlers(source, comments, index = 0) {
|
|
|
605
605
|
node_array = parent.elements;
|
|
606
606
|
} else if (parent.type === 'ObjectExpression') {
|
|
607
607
|
node_array = parent.properties;
|
|
608
|
+
} else if (parent.type === 'ObjectPattern') {
|
|
609
|
+
node_array = parent.properties;
|
|
610
|
+
} else if (parent.type === 'TSTypeLiteral') {
|
|
611
|
+
node_array = parent.members;
|
|
608
612
|
} else if (
|
|
609
613
|
parent.type === 'FunctionDeclaration' ||
|
|
610
614
|
parent.type === 'FunctionExpression' ||
|
|
@@ -622,11 +626,22 @@ export function get_comment_handlers(source, comments, index = 0) {
|
|
|
622
626
|
is_last_in_array = node_array.indexOf(node) === node_array.length - 1;
|
|
623
627
|
}
|
|
624
628
|
|
|
629
|
+
const trailingCommentBoundary =
|
|
630
|
+
parent &&
|
|
631
|
+
parent.type === 'ObjectPattern' &&
|
|
632
|
+
parent.typeAnnotation &&
|
|
633
|
+
parent.typeAnnotation.start !== undefined
|
|
634
|
+
? parent.typeAnnotation.start
|
|
635
|
+
: parent?.end;
|
|
636
|
+
|
|
625
637
|
if (is_last_in_array) {
|
|
626
638
|
if (isParam || isArgument) {
|
|
627
639
|
while (comments.length) {
|
|
628
640
|
const potentialComment = comments[0];
|
|
629
|
-
if (
|
|
641
|
+
if (
|
|
642
|
+
trailingCommentBoundary !== undefined &&
|
|
643
|
+
potentialComment.start >= trailingCommentBoundary
|
|
644
|
+
) {
|
|
630
645
|
break;
|
|
631
646
|
}
|
|
632
647
|
|
|
@@ -653,7 +668,12 @@ export function get_comment_handlers(source, comments, index = 0) {
|
|
|
653
668
|
// and they can be separated by newlines
|
|
654
669
|
while (comments.length) {
|
|
655
670
|
const comment = comments[0];
|
|
656
|
-
if (
|
|
671
|
+
if (
|
|
672
|
+
trailingCommentBoundary !== undefined &&
|
|
673
|
+
comment.start >= trailingCommentBoundary
|
|
674
|
+
) {
|
|
675
|
+
break;
|
|
676
|
+
}
|
|
657
677
|
|
|
658
678
|
const maybeInner = getEmptyElementInnerCommentTarget(comment);
|
|
659
679
|
if (maybeInner) {
|
package/src/plugin.js
CHANGED
|
@@ -21,6 +21,10 @@ const JSX_EXPRESSION_VALUE_ERROR =
|
|
|
21
21
|
'JSX elements cannot be used as expressions. Wrap JSX with `<>...</>` or `<tsx>...</tsx>`, wrap TSRX templates with `<tsrx>...</tsrx>`, or use elements as statements within a component.';
|
|
22
22
|
const HTML_ATTRIBUTE_VALUE_ERROR =
|
|
23
23
|
'`{html ...}` is not supported as an attribute value. Use a string literal or expression without `html`.';
|
|
24
|
+
const DYNAMIC_ELEMENT_IN_TSX_ERROR =
|
|
25
|
+
'Dynamic element syntax (`<@...>`) is only supported in native TSRX templates.';
|
|
26
|
+
const DYNAMIC_ATTRIBUTE_NAME_ERROR =
|
|
27
|
+
'Dynamic component / element syntax (`@`) is only supported on native TSRX element names, not attribute names.';
|
|
24
28
|
|
|
25
29
|
const CharCode = Object.freeze({
|
|
26
30
|
tab: 9,
|
|
@@ -408,6 +412,38 @@ export function TSRXPlugin(config) {
|
|
|
408
412
|
);
|
|
409
413
|
}
|
|
410
414
|
|
|
415
|
+
/**
|
|
416
|
+
* @param {AST.Node[]} children
|
|
417
|
+
*/
|
|
418
|
+
#reportDynamicJsxElementsInTsx(children) {
|
|
419
|
+
for (const child of children) {
|
|
420
|
+
if (child?.type === 'Tsrx') {
|
|
421
|
+
continue;
|
|
422
|
+
}
|
|
423
|
+
if (child?.type === 'JSXElement') {
|
|
424
|
+
const name = child.openingElement?.name;
|
|
425
|
+
if (name?.type === 'JSXIdentifier' && name.name === 'tsrx') {
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
428
|
+
const is_dynamic_name =
|
|
429
|
+
(name?.type === 'JSXIdentifier' && name.tracked) ||
|
|
430
|
+
(name?.type === 'JSXMemberExpression' &&
|
|
431
|
+
name.object.type === 'JSXIdentifier' &&
|
|
432
|
+
name.object.tracked);
|
|
433
|
+
if (is_dynamic_name) {
|
|
434
|
+
this.#report_recoverable_error_range(
|
|
435
|
+
/** @type {AST.NodeWithLocation} */ (name).start ?? child.start,
|
|
436
|
+
/** @type {AST.NodeWithLocation} */ (name).end ?? child.end,
|
|
437
|
+
DYNAMIC_ELEMENT_IN_TSX_ERROR,
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
this.#reportDynamicJsxElementsInTsx(/** @type {AST.Node[]} */ (child.children));
|
|
441
|
+
} else if (child?.type === 'Tsx' || child?.type === 'TsxCompat') {
|
|
442
|
+
this.#reportDynamicJsxElementsInTsx(/** @type {AST.Node[]} */ (child.children));
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
411
447
|
#parseNativeTemplateExpressionContainer() {
|
|
412
448
|
const allow_trailing_semicolon = this.#allowExpressionContainerTrailingSemicolon;
|
|
413
449
|
this.#allowExpressionContainerTrailingSemicolon = true;
|
|
@@ -2107,6 +2143,20 @@ export function TSRXPlugin(config) {
|
|
|
2107
2143
|
}
|
|
2108
2144
|
}
|
|
2109
2145
|
/** @type {ESTreeJSX.JSXAttribute} */ (node).name = this.jsx_parseNamespacedName();
|
|
2146
|
+
if (
|
|
2147
|
+
/** @type {ESTreeJSX.JSXAttribute} */ (node).name.type === 'JSXIdentifier' &&
|
|
2148
|
+
/** @type {ESTreeJSX.JSXIdentifier} */ (/** @type {ESTreeJSX.JSXAttribute} */ (node).name)
|
|
2149
|
+
.tracked
|
|
2150
|
+
) {
|
|
2151
|
+
this.#report_recoverable_error_range(
|
|
2152
|
+
/** @type {AST.NodeWithLocation} */ (node).start,
|
|
2153
|
+
/** @type {AST.NodeWithLocation} */ (/** @type {ESTreeJSX.JSXAttribute} */ (node).name)
|
|
2154
|
+
.end ??
|
|
2155
|
+
node.end ??
|
|
2156
|
+
node.start,
|
|
2157
|
+
DYNAMIC_ATTRIBUTE_NAME_ERROR,
|
|
2158
|
+
);
|
|
2159
|
+
}
|
|
2110
2160
|
const value = /** @type {ESTreeJSX.JSXAttribute['value'] | null} */ (
|
|
2111
2161
|
this.eat(tt.eq) ? this.jsx_parseAttributeValue() : null
|
|
2112
2162
|
);
|
|
@@ -2512,6 +2562,13 @@ export function TSRXPlugin(config) {
|
|
|
2512
2562
|
(current_template_node?.type === 'TsxCompat' || current_template_node?.type === 'Tsx') &&
|
|
2513
2563
|
!is_tsrx_tag
|
|
2514
2564
|
) {
|
|
2565
|
+
if (this.input.charCodeAt(tag_name_start) === CharCode.at) {
|
|
2566
|
+
this.#report_recoverable_error_range(
|
|
2567
|
+
this.start,
|
|
2568
|
+
tag_name_start + 1,
|
|
2569
|
+
DYNAMIC_ELEMENT_IN_TSX_ERROR,
|
|
2570
|
+
);
|
|
2571
|
+
}
|
|
2515
2572
|
// Inside tsx/tsx:*, let acorn-jsx handle regular TSX tags normally.
|
|
2516
2573
|
// Nested <tsrx> still needs Ripple's native template parser so it
|
|
2517
2574
|
// can lower through the same path as <tsrx> in component bodies.
|
|
@@ -2603,6 +2660,12 @@ export function TSRXPlugin(config) {
|
|
|
2603
2660
|
!is_tsx_compat &&
|
|
2604
2661
|
open.name.type === 'JSXIdentifier' &&
|
|
2605
2662
|
open.name.name === 'tsrx';
|
|
2663
|
+
const is_dynamic_name =
|
|
2664
|
+
!is_fragment &&
|
|
2665
|
+
((open.name.type === 'JSXIdentifier' && open.name.tracked) ||
|
|
2666
|
+
(open.name.type === 'JSXMemberExpression' &&
|
|
2667
|
+
open.name.object.type === 'JSXIdentifier' &&
|
|
2668
|
+
open.name.object.tracked));
|
|
2606
2669
|
|
|
2607
2670
|
if (is_tsx_compat) {
|
|
2608
2671
|
const namespace_node = /** @type {ESTreeJSX.JSXNamespacedName} */ (open.name);
|
|
@@ -2640,6 +2703,14 @@ export function TSRXPlugin(config) {
|
|
|
2640
2703
|
element.type = 'Element';
|
|
2641
2704
|
}
|
|
2642
2705
|
|
|
2706
|
+
if ((is_tsx || is_fragment) && is_dynamic_name) {
|
|
2707
|
+
this.#report_recoverable_error_range(
|
|
2708
|
+
open.name.start ?? open.start,
|
|
2709
|
+
open.name.end ?? open.end,
|
|
2710
|
+
DYNAMIC_ELEMENT_IN_TSX_ERROR,
|
|
2711
|
+
);
|
|
2712
|
+
}
|
|
2713
|
+
|
|
2643
2714
|
for (const attr of open.attributes) {
|
|
2644
2715
|
if (attr.type === 'JSXAttribute') {
|
|
2645
2716
|
/** @type {AST.Attribute} */ (/** @type {unknown} */ (attr)).type = 'Attribute';
|
|
@@ -2698,6 +2769,7 @@ export function TSRXPlugin(config) {
|
|
|
2698
2769
|
this.#parseNativeTemplateBody(element, /** @type {AST.Element} */ (element).children, {
|
|
2699
2770
|
enterScope: true,
|
|
2700
2771
|
});
|
|
2772
|
+
this.#reportDynamicJsxElementsInTsx(/** @type {AST.Element} */ (element).children);
|
|
2701
2773
|
|
|
2702
2774
|
if (/** @type {AST.Tsx} */ (element).type === 'Tsx') {
|
|
2703
2775
|
this.#path.pop();
|
|
@@ -2875,6 +2947,9 @@ export function TSRXPlugin(config) {
|
|
|
2875
2947
|
this.#parseNativeTemplateBody(element, /** @type {AST.Element} */ (element).children, {
|
|
2876
2948
|
enterScope: true,
|
|
2877
2949
|
});
|
|
2950
|
+
if (/** @type {AST.Tsx} */ (element).type === 'Tsx') {
|
|
2951
|
+
this.#reportDynamicJsxElementsInTsx(/** @type {AST.Element} */ (element).children);
|
|
2952
|
+
}
|
|
2878
2953
|
|
|
2879
2954
|
if (/** @type {AST.Tsx} */ (element).type === 'Tsx') {
|
|
2880
2955
|
this.#path.pop();
|
|
@@ -235,6 +235,7 @@ export function tsx_with_ts_locations() {
|
|
|
235
235
|
'AwaitExpression',
|
|
236
236
|
'SwitchStatement',
|
|
237
237
|
'TaggedTemplateExpression',
|
|
238
|
+
'ArrowFunctionExpression',
|
|
238
239
|
// JSX wrapper nodes: esrap writes `<`, `>`, `</`, `{`, `}` without
|
|
239
240
|
// locations, so the opening/closing element's and expression
|
|
240
241
|
// container's start and end don't resolve.
|
|
@@ -903,6 +903,23 @@ export function convert_source_map_to_mappings(
|
|
|
903
903
|
node.type === 'ArrowFunctionExpression'
|
|
904
904
|
) {
|
|
905
905
|
const is_method = node.metadata?.is_method;
|
|
906
|
+
|
|
907
|
+
if (node.type === 'ArrowFunctionExpression' && node.loc) {
|
|
908
|
+
const start_key = `${node.loc.start.line}:${node.loc.start.column}`;
|
|
909
|
+
const end_key = `${node.loc.end.line}:${node.loc.end.column}`;
|
|
910
|
+
|
|
911
|
+
if (src_to_gen_map.has(start_key) && src_to_gen_map.has(end_key)) {
|
|
912
|
+
mappings.push(
|
|
913
|
+
get_mapping_from_node(
|
|
914
|
+
node,
|
|
915
|
+
src_to_gen_map,
|
|
916
|
+
gen_line_offsets,
|
|
917
|
+
mapping_data_verify_only,
|
|
918
|
+
),
|
|
919
|
+
);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
|
|
906
923
|
// Add function/component keyword token
|
|
907
924
|
if (
|
|
908
925
|
(node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression') &&
|