@tsrx/core 0.0.11 → 0.0.13
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/plugin.js +15 -1
- package/src/transform/jsx/helpers.js +9 -1
- package/src/transform/jsx/index.js +125 -75
- package/src/transform/segments.js +17 -12
- package/types/parse.d.ts +1 -1
package/package.json
CHANGED
package/src/plugin.js
CHANGED
|
@@ -1059,9 +1059,23 @@ export function TSRXPlugin(config) {
|
|
|
1059
1059
|
* @type {Parse.Parser['jsx_parseAttribute']}
|
|
1060
1060
|
*/
|
|
1061
1061
|
jsx_parseAttribute() {
|
|
1062
|
-
let node =
|
|
1062
|
+
let node =
|
|
1063
|
+
/** @type {AST.TSRXAttribute | ESTreeJSX.JSXAttribute | ESTreeJSX.JSXSpreadAttribute} */ (
|
|
1064
|
+
this.startNode()
|
|
1065
|
+
);
|
|
1063
1066
|
|
|
1064
1067
|
if (this.eat(tt.braceL)) {
|
|
1068
|
+
const inside_tsx = this.#path.findLast((n) => n.type === 'TsxCompat' || n.type === 'Tsx');
|
|
1069
|
+
if (inside_tsx) {
|
|
1070
|
+
if (this.type === tt.ellipsis) {
|
|
1071
|
+
this.expect(tt.ellipsis);
|
|
1072
|
+
/** @type {ESTreeJSX.JSXSpreadAttribute} */ (node).argument = this.parseMaybeAssign();
|
|
1073
|
+
this.expect(tt.braceR);
|
|
1074
|
+
return this.finishNode(node, 'JSXSpreadAttribute');
|
|
1075
|
+
}
|
|
1076
|
+
this.unexpected();
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1065
1079
|
if (this.value === 'ref') {
|
|
1066
1080
|
this.next();
|
|
1067
1081
|
if (this.type === tt.braceR) {
|
|
@@ -99,7 +99,14 @@ export function tsx_with_ts_locations() {
|
|
|
99
99
|
};
|
|
100
100
|
|
|
101
101
|
/** @type {Record<string, (node: any, context: any) => void>} */
|
|
102
|
-
const wrappers = {
|
|
102
|
+
const wrappers = {
|
|
103
|
+
ArrayPattern: (node, context) => {
|
|
104
|
+
base.ArrayPattern(node, context);
|
|
105
|
+
if (node.typeAnnotation) {
|
|
106
|
+
context.visit(node.typeAnnotation);
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
};
|
|
103
110
|
for (const type of [
|
|
104
111
|
// JS nodes whose esrap printer emits no location marker, causing
|
|
105
112
|
// segments.js get_mapping_from_node() to throw when it asks for the
|
|
@@ -111,6 +118,7 @@ export function tsx_with_ts_locations() {
|
|
|
111
118
|
'ReturnStatement',
|
|
112
119
|
'ForStatement',
|
|
113
120
|
'ForInStatement',
|
|
121
|
+
'ForOfStatement',
|
|
114
122
|
'TemplateLiteral',
|
|
115
123
|
'AwaitExpression',
|
|
116
124
|
'TaggedTemplateExpression',
|
|
@@ -805,8 +805,8 @@ function create_helper_props_pattern(bindings) {
|
|
|
805
805
|
* @returns {AST.Property}
|
|
806
806
|
*/
|
|
807
807
|
function create_helper_props_property(binding) {
|
|
808
|
-
const key =
|
|
809
|
-
const value =
|
|
808
|
+
const key = create_generated_identifier(binding.name);
|
|
809
|
+
const value = create_generated_identifier(binding.name);
|
|
810
810
|
|
|
811
811
|
return /** @type {any} */ ({
|
|
812
812
|
type: 'Property',
|
|
@@ -824,38 +824,46 @@ function create_helper_props_property(binding) {
|
|
|
824
824
|
* @param {AST.Identifier} helper_id
|
|
825
825
|
* @param {AST.Identifier[]} bindings
|
|
826
826
|
* @param {any} source_node
|
|
827
|
+
* @param {{
|
|
828
|
+
* mapWrapper?: boolean,
|
|
829
|
+
* mapBindingNames?: boolean,
|
|
830
|
+
* mapBindingValues?: boolean,
|
|
831
|
+
* }} [mapping]
|
|
827
832
|
* @returns {ESTreeJSX.JSXElement}
|
|
828
833
|
*/
|
|
829
|
-
function create_helper_component_element(helper_id, bindings, source_node) {
|
|
834
|
+
function create_helper_component_element(helper_id, bindings, source_node, mapping = {}) {
|
|
835
|
+
const { mapWrapper = true, mapBindingNames = true, mapBindingValues = true } = mapping;
|
|
830
836
|
const attributes = bindings.map(
|
|
831
837
|
(binding) =>
|
|
832
838
|
/** @type {any} */ ({
|
|
833
839
|
type: 'JSXAttribute',
|
|
834
|
-
name: identifier_to_jsx_name(
|
|
835
|
-
|
|
840
|
+
name: identifier_to_jsx_name(
|
|
841
|
+
mapBindingNames ? clone_identifier(binding) : create_generated_identifier(binding.name),
|
|
842
|
+
),
|
|
843
|
+
value: to_jsx_expression_container(
|
|
844
|
+
mapBindingValues ? clone_identifier(binding) : create_generated_identifier(binding.name),
|
|
845
|
+
binding,
|
|
846
|
+
),
|
|
836
847
|
metadata: { path: [] },
|
|
837
848
|
}),
|
|
838
849
|
);
|
|
839
850
|
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
}),
|
|
857
|
-
source_node,
|
|
858
|
-
);
|
|
851
|
+
const openingElement = {
|
|
852
|
+
type: 'JSXOpeningElement',
|
|
853
|
+
name: identifier_to_jsx_name(clone_identifier(helper_id)),
|
|
854
|
+
attributes,
|
|
855
|
+
selfClosing: true,
|
|
856
|
+
metadata: { path: [] },
|
|
857
|
+
};
|
|
858
|
+
const element = /** @type {any} */ ({
|
|
859
|
+
type: 'JSXElement',
|
|
860
|
+
openingElement: mapWrapper ? set_loc(openingElement, source_node) : openingElement,
|
|
861
|
+
closingElement: null,
|
|
862
|
+
children: [],
|
|
863
|
+
metadata: { path: [] },
|
|
864
|
+
});
|
|
865
|
+
|
|
866
|
+
return mapWrapper ? set_loc(element, source_node) : element;
|
|
859
867
|
}
|
|
860
868
|
|
|
861
869
|
/**
|
|
@@ -1117,12 +1125,23 @@ function is_lone_return_if_statement(node) {
|
|
|
1117
1125
|
/**
|
|
1118
1126
|
* @param {any[]} render_nodes
|
|
1119
1127
|
* @param {any} source_node
|
|
1128
|
+
* @param {boolean} [map_render_node_locations]
|
|
1120
1129
|
* @returns {any}
|
|
1121
1130
|
*/
|
|
1122
|
-
function create_component_return_statement(
|
|
1131
|
+
function create_component_return_statement(
|
|
1132
|
+
render_nodes,
|
|
1133
|
+
source_node,
|
|
1134
|
+
map_render_node_locations = true,
|
|
1135
|
+
) {
|
|
1123
1136
|
return /** @type {any} */ ({
|
|
1124
1137
|
type: 'ReturnStatement',
|
|
1125
|
-
argument: build_return_expression(
|
|
1138
|
+
argument: build_return_expression(
|
|
1139
|
+
render_nodes.map((node) =>
|
|
1140
|
+
map_render_node_locations
|
|
1141
|
+
? clone_expression_node(node)
|
|
1142
|
+
: clone_expression_node_without_locations(node),
|
|
1143
|
+
),
|
|
1144
|
+
) || {
|
|
1126
1145
|
type: 'Literal',
|
|
1127
1146
|
value: null,
|
|
1128
1147
|
raw: 'null',
|
|
@@ -1148,7 +1167,7 @@ function create_component_lone_return_if_statement(node, render_nodes) {
|
|
|
1148
1167
|
consequent: set_loc(
|
|
1149
1168
|
/** @type {any} */ ({
|
|
1150
1169
|
type: 'BlockStatement',
|
|
1151
|
-
body: [create_component_return_statement(render_nodes, consequent_body[0])],
|
|
1170
|
+
body: [create_component_return_statement(render_nodes, consequent_body[0], false)],
|
|
1152
1171
|
metadata: { path: [] },
|
|
1153
1172
|
}),
|
|
1154
1173
|
node.consequent,
|
|
@@ -1160,6 +1179,30 @@ function create_component_lone_return_if_statement(node, render_nodes) {
|
|
|
1160
1179
|
);
|
|
1161
1180
|
}
|
|
1162
1181
|
|
|
1182
|
+
/**
|
|
1183
|
+
* @param {any} node
|
|
1184
|
+
* @returns {any}
|
|
1185
|
+
*/
|
|
1186
|
+
function clone_expression_node_without_locations(node) {
|
|
1187
|
+
if (!node || typeof node !== 'object') return node;
|
|
1188
|
+
if (Array.isArray(node)) return node.map(clone_expression_node_without_locations);
|
|
1189
|
+
|
|
1190
|
+
const clone = { ...node };
|
|
1191
|
+
delete clone.loc;
|
|
1192
|
+
delete clone.start;
|
|
1193
|
+
delete clone.end;
|
|
1194
|
+
|
|
1195
|
+
for (const key of Object.keys(clone)) {
|
|
1196
|
+
if (key === 'metadata') {
|
|
1197
|
+
clone.metadata = clone.metadata ? { ...clone.metadata } : { path: [] };
|
|
1198
|
+
continue;
|
|
1199
|
+
}
|
|
1200
|
+
clone[key] = clone_expression_node_without_locations(clone[key]);
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
return clone;
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1163
1206
|
const TEMPLATE_FRAGMENT_ERROR =
|
|
1164
1207
|
'JSX fragment syntax is not needed in TSRX templates. TSRX renders in immediate mode, so everything is already a fragment. Use `<>...</>` only within <tsx>...</tsx>.';
|
|
1165
1208
|
|
|
@@ -1349,9 +1392,8 @@ function statement_body_to_jsx_child(body_nodes, transform_context) {
|
|
|
1349
1392
|
*/
|
|
1350
1393
|
function hook_safe_statement_body_to_jsx_child(body_nodes, transform_context) {
|
|
1351
1394
|
const source_node = get_body_source_node(body_nodes);
|
|
1352
|
-
const helper_id =
|
|
1353
|
-
|
|
1354
|
-
source_node,
|
|
1395
|
+
const helper_id = create_generated_identifier(
|
|
1396
|
+
create_local_statement_component_name(transform_context),
|
|
1355
1397
|
);
|
|
1356
1398
|
const helper_bindings = Array.from(transform_context.available_bindings.values());
|
|
1357
1399
|
|
|
@@ -1359,26 +1401,23 @@ function hook_safe_statement_body_to_jsx_child(body_nodes, transform_context) {
|
|
|
1359
1401
|
const saved_bindings = transform_context.available_bindings;
|
|
1360
1402
|
transform_context.available_bindings = new Map(saved_bindings);
|
|
1361
1403
|
|
|
1362
|
-
const helper_fn =
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
}),
|
|
1380
|
-
source_node,
|
|
1381
|
-
);
|
|
1404
|
+
const helper_fn = /** @type {any} */ ({
|
|
1405
|
+
type: 'FunctionDeclaration',
|
|
1406
|
+
id: helper_id,
|
|
1407
|
+
params: helper_bindings.length > 0 ? [create_helper_props_pattern(helper_bindings)] : [],
|
|
1408
|
+
body: {
|
|
1409
|
+
type: 'BlockStatement',
|
|
1410
|
+
body: build_render_statements(body_nodes, true, transform_context),
|
|
1411
|
+
metadata: { path: [] },
|
|
1412
|
+
},
|
|
1413
|
+
async: false,
|
|
1414
|
+
generator: false,
|
|
1415
|
+
metadata: {
|
|
1416
|
+
path: [],
|
|
1417
|
+
is_component: true,
|
|
1418
|
+
is_method: false,
|
|
1419
|
+
},
|
|
1420
|
+
});
|
|
1382
1421
|
|
|
1383
1422
|
// Restore bindings
|
|
1384
1423
|
transform_context.available_bindings = saved_bindings;
|
|
@@ -1388,7 +1427,13 @@ function hook_safe_statement_body_to_jsx_child(body_nodes, transform_context) {
|
|
|
1388
1427
|
transform_context.helper_state.helpers.push(helper_fn);
|
|
1389
1428
|
|
|
1390
1429
|
return to_jsx_expression_container(
|
|
1391
|
-
/** @type {any} */ (
|
|
1430
|
+
/** @type {any} */ (
|
|
1431
|
+
create_helper_component_element(helper_id, helper_bindings, source_node, {
|
|
1432
|
+
mapWrapper: false,
|
|
1433
|
+
mapBindingNames: false,
|
|
1434
|
+
mapBindingValues: false,
|
|
1435
|
+
})
|
|
1436
|
+
),
|
|
1392
1437
|
source_node,
|
|
1393
1438
|
);
|
|
1394
1439
|
}
|
|
@@ -1405,7 +1450,11 @@ function hook_safe_statement_body_to_jsx_child(body_nodes, transform_context) {
|
|
|
1405
1450
|
helper_fn,
|
|
1406
1451
|
{
|
|
1407
1452
|
type: 'ReturnStatement',
|
|
1408
|
-
argument: create_helper_component_element(helper_id, helper_bindings, source_node
|
|
1453
|
+
argument: create_helper_component_element(helper_id, helper_bindings, source_node, {
|
|
1454
|
+
mapWrapper: false,
|
|
1455
|
+
mapBindingNames: false,
|
|
1456
|
+
mapBindingValues: false,
|
|
1457
|
+
}),
|
|
1409
1458
|
metadata: { path: [] },
|
|
1410
1459
|
},
|
|
1411
1460
|
],
|
|
@@ -1448,9 +1497,8 @@ function create_local_statement_component_name(transform_context) {
|
|
|
1448
1497
|
*/
|
|
1449
1498
|
function hook_safe_render_statements(body_nodes, key_expression, transform_context) {
|
|
1450
1499
|
const source_node = get_body_source_node(body_nodes);
|
|
1451
|
-
const helper_id =
|
|
1452
|
-
|
|
1453
|
-
source_node,
|
|
1500
|
+
const helper_id = create_generated_identifier(
|
|
1501
|
+
create_local_statement_component_name(transform_context),
|
|
1454
1502
|
);
|
|
1455
1503
|
const helper_bindings = Array.from(transform_context.available_bindings.values());
|
|
1456
1504
|
|
|
@@ -1458,26 +1506,23 @@ function hook_safe_render_statements(body_nodes, key_expression, transform_conte
|
|
|
1458
1506
|
const saved_bindings = transform_context.available_bindings;
|
|
1459
1507
|
transform_context.available_bindings = new Map(saved_bindings);
|
|
1460
1508
|
|
|
1461
|
-
const helper_fn =
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
}),
|
|
1479
|
-
source_node,
|
|
1480
|
-
);
|
|
1509
|
+
const helper_fn = /** @type {any} */ ({
|
|
1510
|
+
type: 'FunctionDeclaration',
|
|
1511
|
+
id: helper_id,
|
|
1512
|
+
params: helper_bindings.length > 0 ? [create_helper_props_pattern(helper_bindings)] : [],
|
|
1513
|
+
body: {
|
|
1514
|
+
type: 'BlockStatement',
|
|
1515
|
+
body: build_render_statements(body_nodes, true, transform_context),
|
|
1516
|
+
metadata: { path: [] },
|
|
1517
|
+
},
|
|
1518
|
+
async: false,
|
|
1519
|
+
generator: false,
|
|
1520
|
+
metadata: {
|
|
1521
|
+
path: [],
|
|
1522
|
+
is_component: true,
|
|
1523
|
+
is_method: false,
|
|
1524
|
+
},
|
|
1525
|
+
});
|
|
1481
1526
|
|
|
1482
1527
|
// Restore bindings
|
|
1483
1528
|
transform_context.available_bindings = saved_bindings;
|
|
@@ -1491,6 +1536,11 @@ function hook_safe_render_statements(body_nodes, key_expression, transform_conte
|
|
|
1491
1536
|
helper_id,
|
|
1492
1537
|
helper_bindings,
|
|
1493
1538
|
source_node,
|
|
1539
|
+
{
|
|
1540
|
+
mapWrapper: false,
|
|
1541
|
+
mapBindingNames: false,
|
|
1542
|
+
mapBindingValues: false,
|
|
1543
|
+
},
|
|
1494
1544
|
);
|
|
1495
1545
|
|
|
1496
1546
|
if (key_expression) {
|
|
@@ -761,7 +761,8 @@ export function convert_source_map_to_mappings(
|
|
|
761
761
|
// Add function/component keyword token
|
|
762
762
|
if (
|
|
763
763
|
(node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression') &&
|
|
764
|
-
!is_method
|
|
764
|
+
!is_method &&
|
|
765
|
+
node.loc
|
|
765
766
|
) {
|
|
766
767
|
const node_fn = /** @type (typeof node) & AST.NodeWithLocation */ (node);
|
|
767
768
|
const is_component = node_fn.metadata?.is_component;
|
|
@@ -2250,21 +2251,25 @@ export function create_volar_mappings_result({
|
|
|
2250
2251
|
* @returns {CodeMapping[]}
|
|
2251
2252
|
*/
|
|
2252
2253
|
export function dedupe_mappings(mappings) {
|
|
2253
|
-
|
|
2254
|
-
|
|
2254
|
+
// keep for now more for testing and maybe logging later.
|
|
2255
|
+
// We should not use deduping and instead should be
|
|
2256
|
+
// fixing source map generation or mapping generation
|
|
2257
|
+
return mappings;
|
|
2258
|
+
// const deduped = [];
|
|
2259
|
+
// const seen = new Set();
|
|
2255
2260
|
|
|
2256
|
-
for (const mapping of mappings) {
|
|
2257
|
-
|
|
2261
|
+
// for (const mapping of mappings) {
|
|
2262
|
+
// const key = JSON.stringify(serialize_mapping_value(mapping));
|
|
2258
2263
|
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2264
|
+
// if (seen.has(key)) {
|
|
2265
|
+
// continue;
|
|
2266
|
+
// }
|
|
2262
2267
|
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
}
|
|
2268
|
+
// seen.add(key);
|
|
2269
|
+
// deduped.push(mapping);
|
|
2270
|
+
// }
|
|
2266
2271
|
|
|
2267
|
-
return deduped;
|
|
2272
|
+
// return deduped;
|
|
2268
2273
|
}
|
|
2269
2274
|
|
|
2270
2275
|
/**
|
package/types/parse.d.ts
CHANGED
|
@@ -1639,7 +1639,7 @@ export namespace Parse {
|
|
|
1639
1639
|
* Parse JSX attribute (name="value" or {spread})
|
|
1640
1640
|
* @returns JSXAttribute or JSXSpreadAttribute
|
|
1641
1641
|
*/
|
|
1642
|
-
jsx_parseAttribute(): AST.TSRXAttribute | ESTreeJSX.JSXAttribute;
|
|
1642
|
+
jsx_parseAttribute(): AST.TSRXAttribute | ESTreeJSX.JSXAttribute | ESTreeJSX.JSXSpreadAttribute;
|
|
1643
1643
|
|
|
1644
1644
|
/**
|
|
1645
1645
|
* Parse JSX opening element at position
|