ripple 0.2.134 → 0.2.136
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 +2 -2
- package/src/compiler/phases/1-parse/index.js +311 -69
- package/src/compiler/phases/3-transform/client/index.js +222 -61
- package/src/compiler/phases/3-transform/segments.js +16 -6
- package/src/runtime/internal/client/blocks.js +17 -2
- package/src/utils/builders.js +17 -0
- package/tests/client/basic/basic.components.test.ripple +30 -20
- package/tests/client/compiler/compiler.basic.test.ripple +91 -62
- package/tests/client/dynamic-elements.test.ripple +120 -1
- package/tests/setup-client.js +4 -4
- package/types/index.d.ts +11 -1
|
@@ -317,21 +317,21 @@ const visitors = {
|
|
|
317
317
|
if (!context.state.to_ts) {
|
|
318
318
|
return b.empty;
|
|
319
319
|
}
|
|
320
|
-
context.next();
|
|
320
|
+
return context.next();
|
|
321
321
|
},
|
|
322
322
|
|
|
323
323
|
TSInterfaceDeclaration(_, context) {
|
|
324
324
|
if (!context.state.to_ts) {
|
|
325
325
|
return b.empty;
|
|
326
326
|
}
|
|
327
|
-
context.next();
|
|
327
|
+
return context.next();
|
|
328
328
|
},
|
|
329
329
|
|
|
330
330
|
TSMappedType(_, context) {
|
|
331
331
|
if (!context.state.to_ts) {
|
|
332
332
|
return b.empty;
|
|
333
333
|
}
|
|
334
|
-
context.next();
|
|
334
|
+
return context.next();
|
|
335
335
|
},
|
|
336
336
|
|
|
337
337
|
NewExpression(node, context) {
|
|
@@ -384,7 +384,7 @@ const visitors = {
|
|
|
384
384
|
|
|
385
385
|
TrackedArrayExpression(node, context) {
|
|
386
386
|
if (context.state.to_ts) {
|
|
387
|
-
const arrayAlias = import_from_ripple_if_needed(
|
|
387
|
+
const arrayAlias = import_from_ripple_if_needed('TrackedArray', context);
|
|
388
388
|
|
|
389
389
|
return b.call(
|
|
390
390
|
b.member(b.id(arrayAlias), b.id('from')),
|
|
@@ -401,12 +401,9 @@ const visitors = {
|
|
|
401
401
|
|
|
402
402
|
TrackedObjectExpression(node, context) {
|
|
403
403
|
if (context.state.to_ts) {
|
|
404
|
-
const objectAlias = import_from_ripple_if_needed(
|
|
404
|
+
const objectAlias = import_from_ripple_if_needed('TrackedObject', context);
|
|
405
405
|
|
|
406
|
-
return b.new(
|
|
407
|
-
b.id(objectAlias),
|
|
408
|
-
b.object(node.properties.map((prop) => context.visit(prop))),
|
|
409
|
-
);
|
|
406
|
+
return b.new(b.id(objectAlias), b.object(node.properties.map((prop) => context.visit(prop))));
|
|
410
407
|
}
|
|
411
408
|
|
|
412
409
|
return b.call(
|
|
@@ -466,14 +463,17 @@ const visitors = {
|
|
|
466
463
|
}
|
|
467
464
|
|
|
468
465
|
if (node.tracked || (node.property.type === 'Identifier' && node.property.tracked)) {
|
|
466
|
+
// In TypeScript mode, skip the transformation and let transform_ts_child handle it
|
|
469
467
|
add_ripple_internal_import(context);
|
|
470
468
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
469
|
+
if (!context.state.to_ts) {
|
|
470
|
+
return b.call(
|
|
471
|
+
'_$_.get_property',
|
|
472
|
+
context.visit(node.object),
|
|
473
|
+
node.computed ? context.visit(node.property) : b.literal(node.property.name),
|
|
474
|
+
node.optional ? b.true : undefined,
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
477
|
}
|
|
478
478
|
|
|
479
479
|
if (node.object.type === 'MemberExpression' && node.object.optional) {
|
|
@@ -499,7 +499,7 @@ const visitors = {
|
|
|
499
499
|
}
|
|
500
500
|
}
|
|
501
501
|
} else {
|
|
502
|
-
context.next();
|
|
502
|
+
return context.next();
|
|
503
503
|
}
|
|
504
504
|
},
|
|
505
505
|
|
|
@@ -549,18 +549,68 @@ const visitors = {
|
|
|
549
549
|
},
|
|
550
550
|
|
|
551
551
|
JSXText(node, context) {
|
|
552
|
+
if (context.state.to_ts) {
|
|
553
|
+
return context.next();
|
|
554
|
+
}
|
|
552
555
|
return b.literal(node.value + '');
|
|
553
556
|
},
|
|
554
557
|
|
|
555
558
|
JSXIdentifier(node, context) {
|
|
559
|
+
if (context.state.to_ts) {
|
|
560
|
+
return context.next();
|
|
561
|
+
}
|
|
556
562
|
return b.id(node.name);
|
|
557
563
|
},
|
|
558
564
|
|
|
559
565
|
JSXExpressionContainer(node, context) {
|
|
566
|
+
if (context.state.to_ts) {
|
|
567
|
+
return context.next();
|
|
568
|
+
}
|
|
560
569
|
return context.visit(node.expression);
|
|
561
570
|
},
|
|
562
571
|
|
|
572
|
+
JSXFragment(node, context) {
|
|
573
|
+
if (context.state.to_ts) {
|
|
574
|
+
return context.next();
|
|
575
|
+
}
|
|
576
|
+
const attributes = node.openingFragment.attributes;
|
|
577
|
+
const normalized_children = node.children.filter((child) => {
|
|
578
|
+
return child.type !== 'JSXText' || child.value.trim() !== '';
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
const props = b.object(
|
|
582
|
+
attributes.map((attr) => {
|
|
583
|
+
if (attr.type === 'JSXAttribute') {
|
|
584
|
+
return b.prop('init', context.visit(attr.name), context.visit(attr.value));
|
|
585
|
+
} else if (attr.type === 'JSXSpreadAttribute') {
|
|
586
|
+
return b.spread(context.visit(attr.argument));
|
|
587
|
+
}
|
|
588
|
+
}),
|
|
589
|
+
);
|
|
590
|
+
|
|
591
|
+
if (normalized_children.length > 0) {
|
|
592
|
+
props.properties.push(
|
|
593
|
+
b.prop(
|
|
594
|
+
'init',
|
|
595
|
+
b.id('children'),
|
|
596
|
+
normalized_children.length === 1
|
|
597
|
+
? context.visit(normalized_children[0])
|
|
598
|
+
: b.array(normalized_children.map((child) => context.visit(child))),
|
|
599
|
+
),
|
|
600
|
+
);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
return b.call(
|
|
604
|
+
normalized_children.length > 1 ? '__compat.jsxs' : '__compat.jsx',
|
|
605
|
+
b.id('__compat.Fragment'),
|
|
606
|
+
props,
|
|
607
|
+
);
|
|
608
|
+
},
|
|
609
|
+
|
|
563
610
|
JSXElement(node, context) {
|
|
611
|
+
if (context.state.to_ts) {
|
|
612
|
+
return context.next();
|
|
613
|
+
}
|
|
564
614
|
const name = node.openingElement.name;
|
|
565
615
|
const attributes = node.openingElement.attributes;
|
|
566
616
|
const normalized_children = node.children.filter((child) => {
|
|
@@ -577,7 +627,7 @@ const visitors = {
|
|
|
577
627
|
}),
|
|
578
628
|
);
|
|
579
629
|
|
|
580
|
-
if (
|
|
630
|
+
if (normalized_children.length > 0) {
|
|
581
631
|
props.properties.push(
|
|
582
632
|
b.prop(
|
|
583
633
|
'init',
|
|
@@ -590,7 +640,7 @@ const visitors = {
|
|
|
590
640
|
}
|
|
591
641
|
|
|
592
642
|
return b.call(
|
|
593
|
-
'__compat.jsx',
|
|
643
|
+
normalized_children.length > 1 ? '__compat.jsxs' : '__compat.jsx',
|
|
594
644
|
name.type === 'JSXIdentifier' && name.name[0].toLowerCase() === name.name[0]
|
|
595
645
|
? b.literal(name.name)
|
|
596
646
|
: context.visit(name),
|
|
@@ -682,6 +732,29 @@ const visitors = {
|
|
|
682
732
|
const local_updates = [];
|
|
683
733
|
const is_void = is_void_element(node.id.name);
|
|
684
734
|
|
|
735
|
+
let scoping_hash = null;
|
|
736
|
+
if (node.metadata.scoped && state.component.css) {
|
|
737
|
+
scoping_hash = state.component.css.hash;
|
|
738
|
+
} else {
|
|
739
|
+
let inside_dynamic_children = false;
|
|
740
|
+
for (let i = context.path.length - 1; i >= 0; i--) {
|
|
741
|
+
const anc = context.path[i];
|
|
742
|
+
if (anc && anc.type === 'Component' && anc.metadata && anc.metadata.inherited_css) {
|
|
743
|
+
inside_dynamic_children = true;
|
|
744
|
+
break;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
if (inside_dynamic_children) {
|
|
748
|
+
for (let i = context.path.length - 1; i >= 0; i--) {
|
|
749
|
+
const anc = context.path[i];
|
|
750
|
+
if (anc && anc.type === 'Component' && anc.css) {
|
|
751
|
+
scoping_hash = anc.css.hash;
|
|
752
|
+
break;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
|
|
685
758
|
state.template.push(`<${node.id.name}`);
|
|
686
759
|
|
|
687
760
|
for (const attr of node.attributes) {
|
|
@@ -851,8 +924,8 @@ const visitors = {
|
|
|
851
924
|
if (class_attribute.value.type === 'Literal') {
|
|
852
925
|
let value = class_attribute.value.value;
|
|
853
926
|
|
|
854
|
-
if (
|
|
855
|
-
value = `${
|
|
927
|
+
if (scoping_hash) {
|
|
928
|
+
value = `${scoping_hash} ${value}`;
|
|
856
929
|
}
|
|
857
930
|
|
|
858
931
|
handle_static_attr(class_attribute.name.name, value);
|
|
@@ -861,10 +934,7 @@ const visitors = {
|
|
|
861
934
|
const metadata = { tracking: false, await: false };
|
|
862
935
|
let expression = visit(class_attribute.value, { ...state, metadata });
|
|
863
936
|
|
|
864
|
-
const hash_arg =
|
|
865
|
-
node.metadata.scoped && state.component.css
|
|
866
|
-
? b.literal(state.component.css.hash)
|
|
867
|
-
: undefined;
|
|
937
|
+
const hash_arg = scoping_hash ? b.literal(scoping_hash) : undefined;
|
|
868
938
|
const is_html = context.state.metadata.namespace === 'html' && node.id.name !== 'svg';
|
|
869
939
|
|
|
870
940
|
if (metadata.tracking) {
|
|
@@ -877,10 +947,8 @@ const visitors = {
|
|
|
877
947
|
);
|
|
878
948
|
}
|
|
879
949
|
}
|
|
880
|
-
} else if (
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
handle_static_attr(is_spreading ? '#class' : 'class', value);
|
|
950
|
+
} else if (scoping_hash) {
|
|
951
|
+
handle_static_attr(is_spreading ? '#class' : 'class', scoping_hash);
|
|
884
952
|
}
|
|
885
953
|
|
|
886
954
|
if (style_attribute !== null) {
|
|
@@ -1019,7 +1087,14 @@ const visitors = {
|
|
|
1019
1087
|
|
|
1020
1088
|
if (children_filtered.length > 0) {
|
|
1021
1089
|
const component_scope = context.state.scopes.get(node);
|
|
1022
|
-
const
|
|
1090
|
+
const children_component = b.component(b.id('children'), [], children_filtered);
|
|
1091
|
+
|
|
1092
|
+
children_component.metadata = {
|
|
1093
|
+
...(children_component.metadata || {}),
|
|
1094
|
+
inherited_css: true,
|
|
1095
|
+
};
|
|
1096
|
+
|
|
1097
|
+
const children = visit(children_component, {
|
|
1023
1098
|
...context.state,
|
|
1024
1099
|
scope: component_scope,
|
|
1025
1100
|
namespace: child_namespace,
|
|
@@ -1081,11 +1156,15 @@ const visitors = {
|
|
|
1081
1156
|
}),
|
|
1082
1157
|
];
|
|
1083
1158
|
|
|
1084
|
-
|
|
1159
|
+
const func = b.function(
|
|
1085
1160
|
node.id,
|
|
1086
1161
|
node.params.map((param) => context.visit(param, { ...context.state, metadata })),
|
|
1087
1162
|
b.block(body_statements),
|
|
1088
1163
|
);
|
|
1164
|
+
// Mark that this function was originally a component
|
|
1165
|
+
func.metadata = { ...func.metadata, was_component: true };
|
|
1166
|
+
func.loc = node.loc; // Copy source location for Volar mappings
|
|
1167
|
+
return func;
|
|
1089
1168
|
}
|
|
1090
1169
|
|
|
1091
1170
|
let props = b.id('__props');
|
|
@@ -1114,7 +1193,7 @@ const visitors = {
|
|
|
1114
1193
|
context.state.stylesheets.push(node.css);
|
|
1115
1194
|
}
|
|
1116
1195
|
|
|
1117
|
-
|
|
1196
|
+
const func = b.function(
|
|
1118
1197
|
node.id,
|
|
1119
1198
|
node.params.length > 0
|
|
1120
1199
|
? [b.id('__anchor'), props, b.id('__block')]
|
|
@@ -1126,6 +1205,10 @@ const visitors = {
|
|
|
1126
1205
|
: body_statements),
|
|
1127
1206
|
]),
|
|
1128
1207
|
);
|
|
1208
|
+
// Mark that this function was originally a component
|
|
1209
|
+
func.metadata = { ...func.metadata, was_component: true };
|
|
1210
|
+
func.loc = node.loc; // Copy source location for Volar mappings
|
|
1211
|
+
return func;
|
|
1129
1212
|
},
|
|
1130
1213
|
|
|
1131
1214
|
AssignmentExpression(node, context) {
|
|
@@ -1143,7 +1226,7 @@ const visitors = {
|
|
|
1143
1226
|
const operator = node.operator;
|
|
1144
1227
|
const right = node.right;
|
|
1145
1228
|
|
|
1146
|
-
if (operator !== '=') {
|
|
1229
|
+
if (operator !== '=' && context.state.metadata?.tracking === false) {
|
|
1147
1230
|
context.state.metadata.tracking = true;
|
|
1148
1231
|
}
|
|
1149
1232
|
|
|
@@ -1197,7 +1280,9 @@ const visitors = {
|
|
|
1197
1280
|
(argument.tracked || (argument.property.type === 'Identifier' && argument.property.tracked))
|
|
1198
1281
|
) {
|
|
1199
1282
|
add_ripple_internal_import(context);
|
|
1200
|
-
context.state.metadata
|
|
1283
|
+
if (context.state.metadata?.tracking === false) {
|
|
1284
|
+
context.state.metadata.tracking = true;
|
|
1285
|
+
}
|
|
1201
1286
|
|
|
1202
1287
|
return b.call(
|
|
1203
1288
|
node.prefix ? '_$_.update_pre_property' : '_$_.update_property',
|
|
@@ -1613,7 +1698,17 @@ function transform_ts_child(node, context) {
|
|
|
1613
1698
|
state.init.push(b.stmt(visit(node.expression, { ...state })));
|
|
1614
1699
|
} else if (node.type === 'Element') {
|
|
1615
1700
|
// Use capitalized name for dynamic components/elements in TypeScript output
|
|
1616
|
-
|
|
1701
|
+
// If node.id is not an Identifier (e.g., MemberExpression like props.children),
|
|
1702
|
+
// we need to visit it to get the proper expression
|
|
1703
|
+
let type_expression;
|
|
1704
|
+
let type_is_expression = false;
|
|
1705
|
+
if (node.id.type === 'MemberExpression') {
|
|
1706
|
+
// For MemberExpressions, we need to create a JSXExpression, not a JSXIdentifier
|
|
1707
|
+
type_expression = visit(node.id, state);
|
|
1708
|
+
type_is_expression = true;
|
|
1709
|
+
} else {
|
|
1710
|
+
type_expression = node.metadata?.ts_name || node.id.name;
|
|
1711
|
+
}
|
|
1617
1712
|
const children = [];
|
|
1618
1713
|
let has_children_props = false;
|
|
1619
1714
|
|
|
@@ -1651,9 +1746,7 @@ function transform_ts_child(node, context) {
|
|
|
1651
1746
|
const createRefKeyAlias = import_from_ripple_if_needed('createRefKey', context);
|
|
1652
1747
|
const metadata = { await: false };
|
|
1653
1748
|
const argument = visit(attr.argument, { ...state, metadata });
|
|
1654
|
-
const wrapper = b.object(
|
|
1655
|
-
[b.prop('init', b.call(createRefKeyAlias), argument, true)]
|
|
1656
|
-
);
|
|
1749
|
+
const wrapper = b.object([b.prop('init', b.call(createRefKeyAlias), argument, true)]);
|
|
1657
1750
|
return b.jsx_spread_attribute(wrapper);
|
|
1658
1751
|
}
|
|
1659
1752
|
});
|
|
@@ -1678,33 +1771,40 @@ function transform_ts_child(node, context) {
|
|
|
1678
1771
|
}
|
|
1679
1772
|
}
|
|
1680
1773
|
|
|
1681
|
-
|
|
1682
|
-
// Use node.id.loc if available, otherwise create a loc based on the element's position
|
|
1683
|
-
opening_type.loc = node.id.loc || {
|
|
1684
|
-
start: {
|
|
1685
|
-
line: node.loc.start.line,
|
|
1686
|
-
column: node.loc.start.column + 2, // After "<@"
|
|
1687
|
-
},
|
|
1688
|
-
end: {
|
|
1689
|
-
line: node.loc.start.line,
|
|
1690
|
-
column: node.loc.start.column + 2 + type.length,
|
|
1691
|
-
},
|
|
1692
|
-
};
|
|
1693
|
-
|
|
1694
|
-
let closing_type = undefined;
|
|
1774
|
+
let opening_type, closing_type;
|
|
1695
1775
|
|
|
1696
|
-
if (
|
|
1697
|
-
|
|
1698
|
-
|
|
1776
|
+
if (type_is_expression) {
|
|
1777
|
+
// For dynamic/expression-based components (e.g., props.children),
|
|
1778
|
+
// use JSX expression instead of identifier
|
|
1779
|
+
opening_type = type_expression;
|
|
1780
|
+
closing_type = node.selfClosing ? undefined : type_expression;
|
|
1781
|
+
} else {
|
|
1782
|
+
opening_type = b.jsx_id(type_expression);
|
|
1783
|
+
// Use node.id.loc if available, otherwise create a loc based on the element's position
|
|
1784
|
+
opening_type.loc = node.id.loc || {
|
|
1699
1785
|
start: {
|
|
1700
|
-
line: node.loc.
|
|
1701
|
-
column: node.loc.
|
|
1786
|
+
line: node.loc.start.line,
|
|
1787
|
+
column: node.loc.start.column + 2, // After "<@"
|
|
1702
1788
|
},
|
|
1703
1789
|
end: {
|
|
1704
|
-
line: node.loc.
|
|
1705
|
-
column: node.loc.
|
|
1790
|
+
line: node.loc.start.line,
|
|
1791
|
+
column: node.loc.start.column + 2 + type_expression.length,
|
|
1706
1792
|
},
|
|
1707
1793
|
};
|
|
1794
|
+
|
|
1795
|
+
if (!node.selfClosing) {
|
|
1796
|
+
closing_type = b.jsx_id(type_expression);
|
|
1797
|
+
closing_type.loc = {
|
|
1798
|
+
start: {
|
|
1799
|
+
line: node.loc.end.line,
|
|
1800
|
+
column: node.loc.end.column - type_expression.length - 1,
|
|
1801
|
+
},
|
|
1802
|
+
end: {
|
|
1803
|
+
line: node.loc.end.line,
|
|
1804
|
+
column: node.loc.end.column - 1,
|
|
1805
|
+
},
|
|
1806
|
+
};
|
|
1807
|
+
}
|
|
1708
1808
|
}
|
|
1709
1809
|
|
|
1710
1810
|
const jsxElement = b.jsx_element(
|
|
@@ -1819,8 +1919,14 @@ function transform_ts_child(node, context) {
|
|
|
1819
1919
|
state.init.push(component);
|
|
1820
1920
|
} else if (node.type === 'BreakStatement') {
|
|
1821
1921
|
state.init.push(b.break);
|
|
1822
|
-
} else {
|
|
1922
|
+
} else if (node.type === 'TsxCompat') {
|
|
1923
|
+
const children = node.children
|
|
1924
|
+
.map((child) => visit(child, state))
|
|
1925
|
+
.filter((child) => child.type !== 'JSXText' || child.value.trim() !== '');
|
|
1926
|
+
|
|
1823
1927
|
debugger;
|
|
1928
|
+
state.init.push(b.stmt(b.jsx_fragment(children)));
|
|
1929
|
+
} else {
|
|
1824
1930
|
throw new Error('TODO');
|
|
1825
1931
|
}
|
|
1826
1932
|
}
|
|
@@ -2077,6 +2183,56 @@ function create_tsx_with_typescript_support() {
|
|
|
2077
2183
|
context.visit(node.typeAnnotation);
|
|
2078
2184
|
context.write(')');
|
|
2079
2185
|
},
|
|
2186
|
+
// Custom handler for TSMappedType: { [K in keyof T]: T[K] }
|
|
2187
|
+
TSMappedType(node, context) {
|
|
2188
|
+
context.write('{ ');
|
|
2189
|
+
if (node.readonly) {
|
|
2190
|
+
if (node.readonly === '+' || node.readonly === true) {
|
|
2191
|
+
context.write('readonly ');
|
|
2192
|
+
} else if (node.readonly === '-') {
|
|
2193
|
+
context.write('-readonly ');
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
context.write('[');
|
|
2197
|
+
// Visit the entire type parameter (TSTypeParameter node)
|
|
2198
|
+
if (node.typeParameter) {
|
|
2199
|
+
context.visit(node.typeParameter);
|
|
2200
|
+
}
|
|
2201
|
+
context.write(']');
|
|
2202
|
+
if (node.optional) {
|
|
2203
|
+
if (node.optional === '+' || node.optional === true) {
|
|
2204
|
+
context.write('?');
|
|
2205
|
+
} else if (node.optional === '-') {
|
|
2206
|
+
context.write('-?');
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
context.write(': ');
|
|
2210
|
+
// Visit the value type - could be either typeAnnotation or nameType
|
|
2211
|
+
if (node.typeAnnotation) {
|
|
2212
|
+
context.visit(node.typeAnnotation);
|
|
2213
|
+
} else if (node.nameType) {
|
|
2214
|
+
context.visit(node.nameType);
|
|
2215
|
+
}
|
|
2216
|
+
context.write(' }');
|
|
2217
|
+
},
|
|
2218
|
+
// Custom handler for TSTypeParameter: K in T (for mapped types)
|
|
2219
|
+
// acord ts has a bug where `in` is printed as `extends`, so we override it here
|
|
2220
|
+
TSTypeParameter(node, context) {
|
|
2221
|
+
// For mapped types, the name is just a string, not an Identifier node
|
|
2222
|
+
if (typeof node.name === 'string') {
|
|
2223
|
+
context.write(node.name);
|
|
2224
|
+
} else if (node.name && node.name.name) {
|
|
2225
|
+
context.write(node.name.name);
|
|
2226
|
+
}
|
|
2227
|
+
if (node.constraint) {
|
|
2228
|
+
context.write(' in ');
|
|
2229
|
+
context.visit(node.constraint);
|
|
2230
|
+
}
|
|
2231
|
+
if (node.default) {
|
|
2232
|
+
context.write(' = ');
|
|
2233
|
+
context.visit(node.default);
|
|
2234
|
+
}
|
|
2235
|
+
},
|
|
2080
2236
|
// Override the ArrowFunctionExpression handler to support TypeScript return types
|
|
2081
2237
|
ArrowFunctionExpression(node, context) {
|
|
2082
2238
|
if (node.async) context.write('async ');
|
|
@@ -2108,7 +2264,7 @@ function create_tsx_with_typescript_support() {
|
|
|
2108
2264
|
} else {
|
|
2109
2265
|
context.visit(node.body);
|
|
2110
2266
|
}
|
|
2111
|
-
}
|
|
2267
|
+
},
|
|
2112
2268
|
};
|
|
2113
2269
|
}
|
|
2114
2270
|
|
|
@@ -2124,7 +2280,12 @@ export function transform_client(filename, source, analysis, to_ts) {
|
|
|
2124
2280
|
const ripple_user_imports = new Map(); // exported -> local
|
|
2125
2281
|
if (analysis && analysis.ast && Array.isArray(analysis.ast.body)) {
|
|
2126
2282
|
for (const stmt of analysis.ast.body) {
|
|
2127
|
-
if (
|
|
2283
|
+
if (
|
|
2284
|
+
stmt &&
|
|
2285
|
+
stmt.type === 'ImportDeclaration' &&
|
|
2286
|
+
stmt.source &&
|
|
2287
|
+
stmt.source.value === 'ripple'
|
|
2288
|
+
) {
|
|
2128
2289
|
for (const spec of stmt.specifiers || []) {
|
|
2129
2290
|
if (spec.type === 'ImportSpecifier' && spec.imported && spec.local) {
|
|
2130
2291
|
ripple_user_imports.set(spec.imported.name, spec.local.name);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { walk } from 'zimmerframe';
|
|
2
2
|
|
|
3
3
|
export const mapping_data = {
|
|
4
4
|
verification: true,
|
|
@@ -354,6 +354,13 @@ export function convert_source_map_to_mappings(ast, source, generated_code, sour
|
|
|
354
354
|
|
|
355
355
|
return;
|
|
356
356
|
} else if (node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') {
|
|
357
|
+
// Map function/component keywords
|
|
358
|
+
if (node.metadata?.was_component && node.loc) {
|
|
359
|
+
tokens.push({ source: 'component', generated: 'function' });
|
|
360
|
+
} else if (node.loc && node.type === 'FunctionDeclaration') {
|
|
361
|
+
tokens.push('function');
|
|
362
|
+
}
|
|
363
|
+
|
|
357
364
|
// Visit in source order: id, params, body
|
|
358
365
|
if (node.id) {
|
|
359
366
|
visit(node.id);
|
|
@@ -361,6 +368,9 @@ export function convert_source_map_to_mappings(ast, source, generated_code, sour
|
|
|
361
368
|
if (node.params) {
|
|
362
369
|
for (const param of node.params) {
|
|
363
370
|
visit(param);
|
|
371
|
+
if (param.typeAnnotation) {
|
|
372
|
+
visit(param.typeAnnotation);
|
|
373
|
+
}
|
|
364
374
|
}
|
|
365
375
|
}
|
|
366
376
|
if (node.body) {
|
|
@@ -1260,11 +1270,11 @@ export function convert_source_map_to_mappings(ast, source, generated_code, sour
|
|
|
1260
1270
|
sourceOffsets: [0],
|
|
1261
1271
|
generatedOffsets: [0],
|
|
1262
1272
|
lengths: [1],
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1273
|
+
data: {
|
|
1274
|
+
...mapping_data,
|
|
1275
|
+
codeActions: true, // auto-import
|
|
1276
|
+
rename: false, // avoid rename for a “dummy” mapping
|
|
1277
|
+
}
|
|
1268
1278
|
});
|
|
1269
1279
|
}
|
|
1270
1280
|
|
|
@@ -124,17 +124,32 @@ export function ref(element, get_fn) {
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
/**
|
|
127
|
-
* @param {() => void} fn
|
|
127
|
+
* @param {() => (void | (() => void))} fn
|
|
128
128
|
* @param {CompatOptions} [compat]
|
|
129
129
|
* @returns {Block}
|
|
130
130
|
*/
|
|
131
131
|
export function root(fn, compat) {
|
|
132
|
+
var target_fn = fn;
|
|
133
|
+
|
|
132
134
|
if (compat != null) {
|
|
135
|
+
/** @type {Array<void | (() => void)>} */
|
|
136
|
+
var unmounts = [];
|
|
133
137
|
for (var key in compat) {
|
|
134
138
|
var api = compat[key];
|
|
135
|
-
api.createRoot();
|
|
139
|
+
unmounts.push(api.createRoot());
|
|
136
140
|
}
|
|
141
|
+
target_fn = () => {
|
|
142
|
+
var component_unmount = fn();
|
|
143
|
+
|
|
144
|
+
return () => {
|
|
145
|
+
component_unmount?.();
|
|
146
|
+
for (var unmount of unmounts) {
|
|
147
|
+
unmount?.();
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
};
|
|
137
151
|
}
|
|
152
|
+
|
|
138
153
|
return block(ROOT_BLOCK, fn, { compat });
|
|
139
154
|
}
|
|
140
155
|
|
package/src/utils/builders.js
CHANGED
|
@@ -753,6 +753,23 @@ export function jsx_element(
|
|
|
753
753
|
return element;
|
|
754
754
|
}
|
|
755
755
|
|
|
756
|
+
/**
|
|
757
|
+
* @param {Array<ESTree.JSXText | ESTree.JSXExpressionContainer | ESTree.JSXSpreadChild | ESTree.JSXElement | ESTree.JSXFragment>} children
|
|
758
|
+
* @returns {ESTree.JSXFragment}
|
|
759
|
+
*/
|
|
760
|
+
export function jsx_fragment(children = []) {
|
|
761
|
+
return {
|
|
762
|
+
type: 'JSXFragment',
|
|
763
|
+
openingFragment: {
|
|
764
|
+
type: 'JSXOpeningFragment',
|
|
765
|
+
},
|
|
766
|
+
closingFragment: {
|
|
767
|
+
type: 'JSXClosingFragment',
|
|
768
|
+
},
|
|
769
|
+
children,
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
|
|
756
773
|
/**
|
|
757
774
|
* @param {ESTree.Expression | ESTree.JSXEmptyExpression} expression
|
|
758
775
|
* @returns {ESTree.JSXExpressionContainer}
|