@tsrx/core 0.1.19 → 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/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 +4 -4
- package/src/transform/jsx/index.js +18 -31
- package/types/index.d.ts +7 -20
- package/types/parse.d.ts +1 -1
package/package.json
CHANGED
package/src/plugin.js
CHANGED
|
@@ -341,10 +341,7 @@ export function TSRXPlugin(config) {
|
|
|
341
341
|
*/
|
|
342
342
|
#isNativeTemplateNode(node) {
|
|
343
343
|
return (
|
|
344
|
-
node?.type === 'Element' ||
|
|
345
|
-
node?.type === 'Tsx' ||
|
|
346
|
-
node?.type === 'Tsrx' ||
|
|
347
|
-
node?.type === 'TsxCompat'
|
|
344
|
+
node?.type === 'Element' || node?.type === 'TsrxFragment' || node?.type === 'TsxCompat'
|
|
348
345
|
);
|
|
349
346
|
}
|
|
350
347
|
|
|
@@ -368,7 +365,7 @@ export function TSRXPlugin(config) {
|
|
|
368
365
|
);
|
|
369
366
|
}
|
|
370
367
|
this.#reportDynamicJsxElementsInTsx(/** @type {AST.Node[]} */ (child.children));
|
|
371
|
-
} else if (child?.type === '
|
|
368
|
+
} else if (child?.type === 'TsxCompat') {
|
|
372
369
|
this.#reportDynamicJsxElementsInTsx(/** @type {AST.Node[]} */ (child.children));
|
|
373
370
|
}
|
|
374
371
|
}
|
|
@@ -396,16 +393,11 @@ export function TSRXPlugin(config) {
|
|
|
396
393
|
}
|
|
397
394
|
|
|
398
395
|
/**
|
|
399
|
-
* @param {AST.
|
|
396
|
+
* @param {AST.TsxCompat} island
|
|
400
397
|
* @param {AST.Node[]} body
|
|
401
398
|
*/
|
|
402
399
|
#parseTsxIslandBody(island, body) {
|
|
403
|
-
const tagName =
|
|
404
|
-
island.type === 'TsxCompat'
|
|
405
|
-
? `tsx:${island.kind}`
|
|
406
|
-
: island.openingElement.name
|
|
407
|
-
? 'tsx'
|
|
408
|
-
: '';
|
|
400
|
+
const tagName = `tsx:${island.kind}`;
|
|
409
401
|
|
|
410
402
|
this.exprAllowed = true;
|
|
411
403
|
|
|
@@ -424,7 +416,7 @@ export function TSRXPlugin(config) {
|
|
|
424
416
|
return;
|
|
425
417
|
}
|
|
426
418
|
|
|
427
|
-
if (this.#isAtTsxIslandClosing(
|
|
419
|
+
if (this.#isAtTsxIslandClosing()) {
|
|
428
420
|
this.exprAllowed = false;
|
|
429
421
|
return;
|
|
430
422
|
}
|
|
@@ -459,7 +451,7 @@ export function TSRXPlugin(config) {
|
|
|
459
451
|
);
|
|
460
452
|
node.expression = expression;
|
|
461
453
|
this.#popTokenContextsAfterTemplateExpressionElement(
|
|
462
|
-
/** @type {AST.
|
|
454
|
+
/** @type {AST.TsrxFragment | AST.TsxCompat} */ (/** @type {unknown} */ (expression)),
|
|
463
455
|
);
|
|
464
456
|
this.expect(tt.braceR);
|
|
465
457
|
return this.finishNode(node, 'JSXExpressionContainer');
|
|
@@ -499,38 +491,13 @@ export function TSRXPlugin(config) {
|
|
|
499
491
|
* @param {number} index
|
|
500
492
|
*/
|
|
501
493
|
#isReservedTemplateTagNameStart(index) {
|
|
502
|
-
|
|
503
|
-
return (
|
|
504
|
-
this.input.startsWith('tsx', index) &&
|
|
505
|
-
(index + 3 >= this.input.length ||
|
|
506
|
-
char_after_tsx === CharCode.greaterThan ||
|
|
507
|
-
char_after_tsx === CharCode.slash ||
|
|
508
|
-
char_after_tsx === CharCode.space ||
|
|
509
|
-
char_after_tsx === CharCode.tab ||
|
|
510
|
-
char_after_tsx === CharCode.lineFeed ||
|
|
511
|
-
char_after_tsx === CharCode.carriageReturn ||
|
|
512
|
-
char_after_tsx === CharCode.colon)
|
|
513
|
-
);
|
|
494
|
+
return this.input.startsWith('tsx:', index);
|
|
514
495
|
}
|
|
515
496
|
|
|
516
497
|
/**
|
|
517
|
-
* @param {AST.Tsx | AST.TsxCompat} island
|
|
518
498
|
*/
|
|
519
|
-
#isAtTsxIslandClosing(
|
|
520
|
-
|
|
521
|
-
return this.input.slice(this.pos, this.pos + 5) === '/tsx:';
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
if (!island.openingElement.name) {
|
|
525
|
-
return this.input.slice(this.pos, this.pos + 2) === '/>';
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
if (this.input.slice(this.pos, this.pos + 4) !== '/tsx') {
|
|
529
|
-
return false;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
const after = this.input.charCodeAt(this.pos + 4);
|
|
533
|
-
return after === CharCode.greaterThan;
|
|
499
|
+
#isAtTsxIslandClosing() {
|
|
500
|
+
return this.input.slice(this.pos, this.pos + 5) === '/tsx:';
|
|
534
501
|
}
|
|
535
502
|
|
|
536
503
|
#parseTsxIslandText() {
|
|
@@ -567,7 +534,7 @@ export function TSRXPlugin(config) {
|
|
|
567
534
|
let index = this.pos;
|
|
568
535
|
let has_newline = false;
|
|
569
536
|
|
|
570
|
-
// Text-only
|
|
537
|
+
// Text-only compat islands can leave the tokenizer in JSX text mode.
|
|
571
538
|
// Only unwind it for ASI before a following TSRX `{expr}` child;
|
|
572
539
|
// fragment props like `content={<></>}` still need the JSX context.
|
|
573
540
|
while (index < this.input.length) {
|
|
@@ -664,7 +631,7 @@ export function TSRXPlugin(config) {
|
|
|
664
631
|
}
|
|
665
632
|
|
|
666
633
|
/**
|
|
667
|
-
* @param {AST.
|
|
634
|
+
* @param {AST.TsrxFragment | AST.TsxCompat} node
|
|
668
635
|
* @returns {boolean}
|
|
669
636
|
*/
|
|
670
637
|
#hasDirectStatementChild(node) {
|
|
@@ -674,7 +641,7 @@ export function TSRXPlugin(config) {
|
|
|
674
641
|
}
|
|
675
642
|
|
|
676
643
|
/**
|
|
677
|
-
* @param {AST.
|
|
644
|
+
* @param {AST.TsrxFragment | AST.TsxCompat} node
|
|
678
645
|
*/
|
|
679
646
|
#popTokenContextsAfterTemplateExpressionElement(node) {
|
|
680
647
|
const ctx = this.context;
|
|
@@ -769,15 +736,14 @@ export function TSRXPlugin(config) {
|
|
|
769
736
|
|
|
770
737
|
#isDoubleQuotedTextChildStart() {
|
|
771
738
|
const current_template_node = this.#path.findLast(
|
|
772
|
-
(n) =>
|
|
773
|
-
n.type === 'Element' || n.type === 'Tsx' || n.type === 'Tsrx' || n.type === 'TsxCompat',
|
|
739
|
+
(n) => n.type === 'Element' || n.type === 'TsrxFragment' || n.type === 'TsxCompat',
|
|
774
740
|
);
|
|
775
|
-
if (current_template_node?.type === 'TsxCompat'
|
|
741
|
+
if (current_template_node?.type === 'TsxCompat') {
|
|
776
742
|
return false;
|
|
777
743
|
}
|
|
778
744
|
|
|
779
745
|
const parent = this.#path.at(-1);
|
|
780
|
-
if (!parent || (parent.type !== 'Element' && parent.type !== '
|
|
746
|
+
if (!parent || (parent.type !== 'Element' && parent.type !== 'TsrxFragment')) {
|
|
781
747
|
return false;
|
|
782
748
|
}
|
|
783
749
|
|
|
@@ -1193,7 +1159,7 @@ export function TSRXPlugin(config) {
|
|
|
1193
1159
|
const parent = this.#path.at(-1);
|
|
1194
1160
|
const inNativeTemplate =
|
|
1195
1161
|
this.#functionBodyDepth === 0 &&
|
|
1196
|
-
(parent?.type === 'Element' || parent?.type === '
|
|
1162
|
+
(parent?.type === 'Element' || parent?.type === 'TsrxFragment');
|
|
1197
1163
|
/** @type {number | null} */
|
|
1198
1164
|
let prevNonWhitespaceChar = null;
|
|
1199
1165
|
|
|
@@ -1740,16 +1706,9 @@ export function TSRXPlugin(config) {
|
|
|
1740
1706
|
|
|
1741
1707
|
if (this.eat(tt.braceL)) {
|
|
1742
1708
|
const current_template_node = this.#path.findLast(
|
|
1743
|
-
(n) =>
|
|
1744
|
-
n.type === 'Element' ||
|
|
1745
|
-
n.type === 'Tsx' ||
|
|
1746
|
-
n.type === 'Tsrx' ||
|
|
1747
|
-
n.type === 'TsxCompat',
|
|
1709
|
+
(n) => n.type === 'Element' || n.type === 'TsrxFragment' || n.type === 'TsxCompat',
|
|
1748
1710
|
);
|
|
1749
|
-
if (
|
|
1750
|
-
current_template_node?.type === 'Tsx' ||
|
|
1751
|
-
current_template_node?.type === 'TsxCompat'
|
|
1752
|
-
) {
|
|
1711
|
+
if (current_template_node?.type === 'TsxCompat') {
|
|
1753
1712
|
if (this.type === tt.ellipsis) {
|
|
1754
1713
|
this.expect(tt.ellipsis);
|
|
1755
1714
|
/** @type {ESTreeJSX.JSXSpreadAttribute} */ (node).argument = this.parseMaybeAssign();
|
|
@@ -1981,10 +1940,9 @@ export function TSRXPlugin(config) {
|
|
|
1981
1940
|
/** @type {Parse.Parser['jsx_readToken']} */
|
|
1982
1941
|
jsx_readToken() {
|
|
1983
1942
|
const current_template_node = this.#path.findLast(
|
|
1984
|
-
(n) =>
|
|
1985
|
-
n.type === 'Element' || n.type === 'Tsx' || n.type === 'Tsrx' || n.type === 'TsxCompat',
|
|
1943
|
+
(n) => n.type === 'Element' || n.type === 'TsrxFragment' || n.type === 'TsxCompat',
|
|
1986
1944
|
);
|
|
1987
|
-
if (current_template_node?.type === 'TsxCompat'
|
|
1945
|
+
if (current_template_node?.type === 'TsxCompat') {
|
|
1988
1946
|
return super.jsx_readToken();
|
|
1989
1947
|
}
|
|
1990
1948
|
let out = '',
|
|
@@ -1993,11 +1951,7 @@ export function TSRXPlugin(config) {
|
|
|
1993
1951
|
while (true) {
|
|
1994
1952
|
if (this.pos >= this.input.length) {
|
|
1995
1953
|
const inside_open_template = this.#path.findLast(
|
|
1996
|
-
(n) =>
|
|
1997
|
-
n.type === 'Element' ||
|
|
1998
|
-
n.type === 'Tsrx' ||
|
|
1999
|
-
n.type === 'TsxCompat' ||
|
|
2000
|
-
n.type === 'Tsx',
|
|
1954
|
+
(n) => n.type === 'Element' || n.type === 'TsrxFragment' || n.type === 'TsxCompat',
|
|
2001
1955
|
);
|
|
2002
1956
|
if (!inside_open_template) {
|
|
2003
1957
|
while (this.curContext() === tstc.tc_expr) {
|
|
@@ -2117,7 +2071,7 @@ export function TSRXPlugin(config) {
|
|
|
2117
2071
|
ch === CharCode.closeBrace &&
|
|
2118
2072
|
(this.#path.length === 0 ||
|
|
2119
2073
|
this.#path.at(-1)?.type === 'Element' ||
|
|
2120
|
-
this.#path.at(-1)?.type === '
|
|
2074
|
+
this.#path.at(-1)?.type === 'TsrxFragment')
|
|
2121
2075
|
) {
|
|
2122
2076
|
this.#resetTokenStartToCurrentPosition();
|
|
2123
2077
|
return original.readToken.call(this, ch);
|
|
@@ -2155,19 +2109,17 @@ export function TSRXPlugin(config) {
|
|
|
2155
2109
|
|
|
2156
2110
|
/**
|
|
2157
2111
|
* Override jsx_parseElement to parse tags and bare fragments as native TSRX
|
|
2158
|
-
* by default. Explicit <tsx
|
|
2159
|
-
*
|
|
2112
|
+
* by default. Explicit <tsx:*> islands keep ordinary TSX parsing for
|
|
2113
|
+
* their children.
|
|
2160
2114
|
* @type {Parse.Parser['jsx_parseElement']}
|
|
2161
2115
|
*/
|
|
2162
2116
|
jsx_parseElement() {
|
|
2163
2117
|
// Current token is jsxTagStart, this.end is position after '<'
|
|
2164
2118
|
const tag_name_start = this.end;
|
|
2165
2119
|
const current_template_node = this.#path.findLast(
|
|
2166
|
-
(n) =>
|
|
2167
|
-
n.type === 'Element' || n.type === 'Tsx' || n.type === 'Tsrx' || n.type === 'TsxCompat',
|
|
2120
|
+
(n) => n.type === 'Element' || n.type === 'TsrxFragment' || n.type === 'TsxCompat',
|
|
2168
2121
|
);
|
|
2169
|
-
const inside_tsx_island =
|
|
2170
|
-
current_template_node?.type === 'Tsx' || current_template_node?.type === 'TsxCompat';
|
|
2122
|
+
const inside_tsx_island = current_template_node?.type === 'TsxCompat';
|
|
2171
2123
|
if (inside_tsx_island) {
|
|
2172
2124
|
if (this.input.charCodeAt(tag_name_start) === CharCode.at) {
|
|
2173
2125
|
this.#report_recoverable_error_range(
|
|
@@ -2186,7 +2138,7 @@ export function TSRXPlugin(config) {
|
|
|
2186
2138
|
);
|
|
2187
2139
|
if (!inside_tsx_island) {
|
|
2188
2140
|
this.#popTokenContextsAfterTemplateExpressionElement(
|
|
2189
|
-
/** @type {AST.
|
|
2141
|
+
/** @type {AST.TsrxFragment | AST.TsxCompat} */ (/** @type {unknown} */ (parsed)),
|
|
2190
2142
|
);
|
|
2191
2143
|
} else if (this.type === tt.braceR && this.curContext() === tstc.tc_expr) {
|
|
2192
2144
|
if (this.#tsxIslandExpressionDepth === 0) {
|
|
@@ -2210,7 +2162,7 @@ export function TSRXPlugin(config) {
|
|
|
2210
2162
|
const start = this.start - 1;
|
|
2211
2163
|
const position = new acorn.Position(this.curLine, start - this.lineStart);
|
|
2212
2164
|
|
|
2213
|
-
const element = /** @type {AST.Element | AST.
|
|
2165
|
+
const element = /** @type {AST.Element | AST.TsrxFragment | AST.TsxCompat} */ (
|
|
2214
2166
|
this.startNode()
|
|
2215
2167
|
);
|
|
2216
2168
|
element.start = start;
|
|
@@ -2229,19 +2181,10 @@ export function TSRXPlugin(config) {
|
|
|
2229
2181
|
|
|
2230
2182
|
// Fragments (<>) produce JSXOpeningFragment with no `name` property
|
|
2231
2183
|
const is_fragment = !open.name;
|
|
2232
|
-
const is_tsx_compat =
|
|
2233
|
-
const is_tsx =
|
|
2234
|
-
!is_fragment &&
|
|
2235
|
-
!is_tsx_compat &&
|
|
2236
|
-
open.name.type === 'JSXIdentifier' &&
|
|
2237
|
-
open.name.name === 'tsx';
|
|
2238
|
-
const is_dynamic_name =
|
|
2184
|
+
const is_tsx_compat =
|
|
2239
2185
|
!is_fragment &&
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
open.name.object.type === 'JSXIdentifier' &&
|
|
2243
|
-
open.name.object.tracked));
|
|
2244
|
-
|
|
2186
|
+
open.name.type === 'JSXNamespacedName' &&
|
|
2187
|
+
open.name.namespace.name === 'tsx';
|
|
2245
2188
|
if (is_tsx_compat) {
|
|
2246
2189
|
const namespace_node = /** @type {ESTreeJSX.JSXNamespacedName} */ (open.name);
|
|
2247
2190
|
/** @type {AST.TsxCompat} */ (element).type = 'TsxCompat';
|
|
@@ -2254,29 +2197,12 @@ export function TSRXPlugin(config) {
|
|
|
2254
2197
|
`TSX compatibility elements cannot be self-closing. '<${tagName} />' must have a closing tag '</${tagName}>'.`,
|
|
2255
2198
|
);
|
|
2256
2199
|
}
|
|
2257
|
-
} else if (is_tsx) {
|
|
2258
|
-
/** @type {AST.Tsx} */ (element).type = 'Tsx';
|
|
2259
|
-
|
|
2260
|
-
if (open.selfClosing) {
|
|
2261
|
-
this.raise(
|
|
2262
|
-
open.start,
|
|
2263
|
-
`TSX elements cannot be self-closing. '<tsx />' must have a closing tag '</tsx>'.`,
|
|
2264
|
-
);
|
|
2265
|
-
}
|
|
2266
2200
|
} else if (is_fragment) {
|
|
2267
|
-
/** @type {AST.
|
|
2201
|
+
/** @type {AST.TsrxFragment} */ (element).type = 'TsrxFragment';
|
|
2268
2202
|
} else {
|
|
2269
2203
|
element.type = 'Element';
|
|
2270
2204
|
}
|
|
2271
2205
|
|
|
2272
|
-
if (is_tsx && is_dynamic_name) {
|
|
2273
|
-
this.#report_recoverable_error_range(
|
|
2274
|
-
open.name.start ?? open.start,
|
|
2275
|
-
open.name.end ?? open.end,
|
|
2276
|
-
DYNAMIC_ELEMENT_IN_TSX_ERROR,
|
|
2277
|
-
);
|
|
2278
|
-
}
|
|
2279
|
-
|
|
2280
2206
|
for (const attr of open.attributes) {
|
|
2281
2207
|
if (attr.type === 'JSXAttribute') {
|
|
2282
2208
|
/** @type {AST.Attribute} */ (/** @type {unknown} */ (attr)).type = 'Attribute';
|
|
@@ -2298,7 +2224,7 @@ export function TSRXPlugin(config) {
|
|
|
2298
2224
|
}
|
|
2299
2225
|
}
|
|
2300
2226
|
|
|
2301
|
-
if (!is_tsx_compat && !
|
|
2227
|
+
if (!is_tsx_compat && !is_fragment) {
|
|
2302
2228
|
/** @type {AST.Element} */ (element).id = /** @type {AST.Identifier} */ (
|
|
2303
2229
|
convert_from_jsx(/** @type {ESTreeJSX.JSXIdentifier} */ (open.name))
|
|
2304
2230
|
);
|
|
@@ -2496,35 +2422,8 @@ export function TSRXPlugin(config) {
|
|
|
2496
2422
|
enterScope: true,
|
|
2497
2423
|
resetFunctionBodyDepth: true,
|
|
2498
2424
|
});
|
|
2499
|
-
if (/** @type {AST.
|
|
2425
|
+
if (/** @type {AST.TsxCompat} */ (element).type === 'TsxCompat') {
|
|
2500
2426
|
this.#reportDynamicJsxElementsInTsx(/** @type {AST.Element} */ (element).children);
|
|
2501
|
-
}
|
|
2502
|
-
|
|
2503
|
-
if (/** @type {AST.Tsx} */ (element).type === 'Tsx') {
|
|
2504
|
-
this.#path.pop();
|
|
2505
|
-
|
|
2506
|
-
if (!element.unclosed) {
|
|
2507
|
-
const raise_error = () => {
|
|
2508
|
-
this.raise(this.start, `Expected closing tag '</tsx>'`);
|
|
2509
|
-
};
|
|
2510
|
-
|
|
2511
|
-
this.next();
|
|
2512
|
-
// we should expect to see </tsx>
|
|
2513
|
-
if (this.value !== '/') {
|
|
2514
|
-
raise_error();
|
|
2515
|
-
}
|
|
2516
|
-
this.next();
|
|
2517
|
-
if (this.value !== 'tsx') {
|
|
2518
|
-
raise_error();
|
|
2519
|
-
}
|
|
2520
|
-
this.next();
|
|
2521
|
-
if (this.type !== tstt.jsxTagEnd) {
|
|
2522
|
-
raise_error();
|
|
2523
|
-
}
|
|
2524
|
-
this.#popTsxTokenContextBeforeTemplateExpressionChild();
|
|
2525
|
-
this.next();
|
|
2526
|
-
}
|
|
2527
|
-
} else if (/** @type {AST.TsxCompat} */ (element).type === 'TsxCompat') {
|
|
2528
2427
|
this.#path.pop();
|
|
2529
2428
|
|
|
2530
2429
|
if (!element.unclosed) {
|
|
@@ -2560,7 +2459,7 @@ export function TSRXPlugin(config) {
|
|
|
2560
2459
|
this.next();
|
|
2561
2460
|
}
|
|
2562
2461
|
} else if (
|
|
2563
|
-
/** @type {AST.
|
|
2462
|
+
/** @type {AST.TsrxFragment} */ (element).type === 'TsrxFragment' &&
|
|
2564
2463
|
this.#path[this.#path.length - 1] === element
|
|
2565
2464
|
) {
|
|
2566
2465
|
const displayTag = element.openingElement.name ? 'tsrx' : '';
|
|
@@ -2603,7 +2502,7 @@ export function TSRXPlugin(config) {
|
|
|
2603
2502
|
}
|
|
2604
2503
|
}
|
|
2605
2504
|
|
|
2606
|
-
if (element.closingElement && !is_tsx_compat &&
|
|
2505
|
+
if (element.closingElement && !is_tsx_compat && element.closingElement.name) {
|
|
2607
2506
|
/** @type {unknown} */ (element.closingElement.name) = convert_from_jsx(
|
|
2608
2507
|
element.closingElement.name,
|
|
2609
2508
|
);
|
|
@@ -2620,15 +2519,12 @@ export function TSRXPlugin(config) {
|
|
|
2620
2519
|
const inside_func =
|
|
2621
2520
|
this.context.some((n) => n.token === 'function') || this.scopeStack.length > 1;
|
|
2622
2521
|
const current_template_node = this.#path.findLast(
|
|
2623
|
-
(n) =>
|
|
2624
|
-
n.type === 'Element' || n.type === 'Tsx' || n.type === 'Tsrx' || n.type === 'TsxCompat',
|
|
2522
|
+
(n) => n.type === 'Element' || n.type === 'TsrxFragment' || n.type === 'TsxCompat',
|
|
2625
2523
|
);
|
|
2626
2524
|
const inside_tsx_island =
|
|
2627
|
-
current_template_node?.type === '
|
|
2628
|
-
? current_template_node
|
|
2629
|
-
: null;
|
|
2525
|
+
current_template_node?.type === 'TsxCompat' ? current_template_node : null;
|
|
2630
2526
|
|
|
2631
|
-
if (current_template_node?.type === '
|
|
2527
|
+
if (current_template_node?.type === 'TsrxFragment' && this.type === tstt.jsxText) {
|
|
2632
2528
|
while (this.curContext() === tstc.tc_expr) {
|
|
2633
2529
|
this.context.pop();
|
|
2634
2530
|
}
|
|
@@ -2649,13 +2545,13 @@ export function TSRXPlugin(config) {
|
|
|
2649
2545
|
|
|
2650
2546
|
if (inside_tsx_island) {
|
|
2651
2547
|
this.#parseTsxIslandBody(
|
|
2652
|
-
/** @type {AST.
|
|
2548
|
+
/** @type {AST.TsxCompat} */ (inside_tsx_island),
|
|
2653
2549
|
/** @type {AST.Node[]} */ (/** @type {unknown} */ (body)),
|
|
2654
2550
|
);
|
|
2655
2551
|
return;
|
|
2656
2552
|
}
|
|
2657
2553
|
if (
|
|
2658
|
-
current_template_node?.type === '
|
|
2554
|
+
current_template_node?.type === 'TsrxFragment' &&
|
|
2659
2555
|
!current_template_node.openingElement.name &&
|
|
2660
2556
|
((this.type === tstt.jsxTagStart && this.input.slice(this.pos, this.pos + 2) === '/>') ||
|
|
2661
2557
|
(this.input.charCodeAt(this.start) === CharCode.lessThan &&
|
|
@@ -2715,8 +2611,7 @@ export function TSRXPlugin(config) {
|
|
|
2715
2611
|
if (
|
|
2716
2612
|
!currentElement ||
|
|
2717
2613
|
(currentElement.type !== 'Element' &&
|
|
2718
|
-
currentElement.type !== '
|
|
2719
|
-
currentElement.type !== 'Tsrx' &&
|
|
2614
|
+
currentElement.type !== 'TsrxFragment' &&
|
|
2720
2615
|
currentElement.type !== 'TsxCompat')
|
|
2721
2616
|
) {
|
|
2722
2617
|
this.raise(this.start, 'Unexpected closing tag');
|
|
@@ -2733,13 +2628,7 @@ export function TSRXPlugin(config) {
|
|
|
2733
2628
|
closingElement.name?.type === 'JSXNamespacedName'
|
|
2734
2629
|
? closingElement.name.namespace.name + ':' + closingElement.name.name.name
|
|
2735
2630
|
: this.getElementName(closingElement.name);
|
|
2736
|
-
} else if (currentElement.type === '
|
|
2737
|
-
openingTagName = currentElement.openingElement.name ? 'tsx' : null;
|
|
2738
|
-
closingTagName =
|
|
2739
|
-
closingElement.name?.type === 'JSXNamespacedName'
|
|
2740
|
-
? closingElement.name.namespace.name + ':' + closingElement.name.name.name
|
|
2741
|
-
: this.getElementName(closingElement.name);
|
|
2742
|
-
} else if (currentElement.type === 'Tsrx') {
|
|
2631
|
+
} else if (currentElement.type === 'TsrxFragment') {
|
|
2743
2632
|
openingTagName = '';
|
|
2744
2633
|
closingTagName =
|
|
2745
2634
|
closingElement.name?.type === 'JSXNamespacedName'
|
|
@@ -2769,8 +2658,7 @@ export function TSRXPlugin(config) {
|
|
|
2769
2658
|
// Stop at non-template boundaries.
|
|
2770
2659
|
if (
|
|
2771
2660
|
elem.type !== 'Element' &&
|
|
2772
|
-
elem.type !== '
|
|
2773
|
-
elem.type !== 'Tsrx' &&
|
|
2661
|
+
elem.type !== 'TsrxFragment' &&
|
|
2774
2662
|
elem.type !== 'TsxCompat'
|
|
2775
2663
|
) {
|
|
2776
2664
|
break;
|
|
@@ -2779,15 +2667,11 @@ export function TSRXPlugin(config) {
|
|
|
2779
2667
|
const elemName =
|
|
2780
2668
|
elem.type === 'TsxCompat'
|
|
2781
2669
|
? 'tsx:' + elem.kind
|
|
2782
|
-
: elem.type === '
|
|
2783
|
-
?
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
? ''
|
|
2788
|
-
: elem.id
|
|
2789
|
-
? this.getElementName(elem.id)
|
|
2790
|
-
: null;
|
|
2670
|
+
: elem.type === 'TsrxFragment'
|
|
2671
|
+
? ''
|
|
2672
|
+
: elem.id
|
|
2673
|
+
? this.getElementName(elem.id)
|
|
2674
|
+
: null;
|
|
2791
2675
|
|
|
2792
2676
|
// Found matching opening tag
|
|
2793
2677
|
if (elemName === closingTagName) {
|
|
@@ -2808,16 +2692,16 @@ export function TSRXPlugin(config) {
|
|
|
2808
2692
|
const elementToClose = this.#path[this.#path.length - 1];
|
|
2809
2693
|
if (
|
|
2810
2694
|
elementToClose &&
|
|
2811
|
-
(elementToClose.type === 'Element' || elementToClose.type === '
|
|
2695
|
+
(elementToClose.type === 'Element' || elementToClose.type === 'TsrxFragment')
|
|
2812
2696
|
) {
|
|
2813
2697
|
const elementToCloseName =
|
|
2814
|
-
elementToClose.type === '
|
|
2698
|
+
elementToClose.type === 'TsrxFragment'
|
|
2815
2699
|
? ''
|
|
2816
2700
|
: /** @type {AST.Element} */ (elementToClose).id
|
|
2817
2701
|
? this.getElementName(/** @type {AST.Element} */ (elementToClose).id)
|
|
2818
2702
|
: null;
|
|
2819
2703
|
if (elementToCloseName === closingTagName) {
|
|
2820
|
-
/** @type {AST.Element | AST.
|
|
2704
|
+
/** @type {AST.Element | AST.TsrxFragment} */ (elementToClose).closingElement =
|
|
2821
2705
|
closingElement;
|
|
2822
2706
|
}
|
|
2823
2707
|
}
|
|
@@ -2933,7 +2817,11 @@ export function TSRXPlugin(config) {
|
|
|
2933
2817
|
if (!node) {
|
|
2934
2818
|
this.unexpected();
|
|
2935
2819
|
}
|
|
2936
|
-
if (
|
|
2820
|
+
if (
|
|
2821
|
+
this.#functionBodyDepth > 0 &&
|
|
2822
|
+
node.type === 'TsrxFragment' &&
|
|
2823
|
+
this.curContext() === b_stat
|
|
2824
|
+
) {
|
|
2937
2825
|
this.context.pop();
|
|
2938
2826
|
if (this.curContext() === tstc.tc_expr) {
|
|
2939
2827
|
this.context.pop();
|
|
@@ -2949,7 +2837,7 @@ export function TSRXPlugin(config) {
|
|
|
2949
2837
|
this.#functionBodyDepth === 0 &&
|
|
2950
2838
|
this.type === tt.string &&
|
|
2951
2839
|
this.input.charCodeAt(this.start) === CharCode.doubleQuote &&
|
|
2952
|
-
(this.#path.at(-1)?.type === 'Element' || this.#path.at(-1)?.type === '
|
|
2840
|
+
(this.#path.at(-1)?.type === 'Element' || this.#path.at(-1)?.type === 'TsrxFragment')
|
|
2953
2841
|
) {
|
|
2954
2842
|
this.pos = this.start;
|
|
2955
2843
|
this.#readDoubleQuotedTextChildToken();
|
|
@@ -3003,7 +2891,7 @@ export function TSRXPlugin(config) {
|
|
|
3003
2891
|
// nested function callable, not in a template.
|
|
3004
2892
|
if (
|
|
3005
2893
|
this.#functionBodyDepth === 0 &&
|
|
3006
|
-
(parent?.type === 'Element' || parent?.type === '
|
|
2894
|
+
(parent?.type === 'Element' || parent?.type === 'TsrxFragment')
|
|
3007
2895
|
) {
|
|
3008
2896
|
if (createNewLexicalScope === void 0) createNewLexicalScope = true;
|
|
3009
2897
|
if (node === void 0) node = /** @type {AST.BlockStatement} */ (this.startNode());
|
package/src/scope.js
CHANGED
|
@@ -114,7 +114,7 @@ export function create_scopes(ast, root, parent, error_options) {
|
|
|
114
114
|
next({ scope });
|
|
115
115
|
},
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
TsrxFragment(node, { state, next }) {
|
|
118
118
|
const scope = state.scope.child();
|
|
119
119
|
scopes.set(node, scope);
|
|
120
120
|
|
|
@@ -192,13 +192,13 @@ export function create_scopes(ast, root, parent, error_options) {
|
|
|
192
192
|
for (const declarator of node.declarations) {
|
|
193
193
|
/** @type {Binding[]} */
|
|
194
194
|
const bindings = [];
|
|
195
|
-
const initial = /** @type {AST.Expression | AST.
|
|
195
|
+
const initial = /** @type {AST.Expression | AST.TsrxFragment | null} */ (declarator.init);
|
|
196
196
|
|
|
197
197
|
state.scope.declarators.set(declarator, bindings);
|
|
198
198
|
|
|
199
199
|
for (const id of extract_identifiers(declarator.id)) {
|
|
200
200
|
const binding = state.scope.declare(id, 'normal', node.kind, initial);
|
|
201
|
-
if (initial?.type === '
|
|
201
|
+
if (initial?.type === 'TsrxFragment') {
|
|
202
202
|
binding.metadata = {
|
|
203
203
|
...(binding.metadata ?? {}),
|
|
204
204
|
is_template_value: true,
|
|
@@ -242,8 +242,7 @@ export function is_jsx_child(node) {
|
|
|
242
242
|
t === 'JSXFragment' ||
|
|
243
243
|
t === 'JSXExpressionContainer' ||
|
|
244
244
|
t === 'JSXText' ||
|
|
245
|
-
t === '
|
|
246
|
-
t === 'Tsrx' ||
|
|
245
|
+
t === 'TsrxFragment' ||
|
|
247
246
|
t === 'TsxCompat' ||
|
|
248
247
|
t === 'Element' ||
|
|
249
248
|
t === 'Text' ||
|
|
@@ -256,8 +255,8 @@ export function is_jsx_child(node) {
|
|
|
256
255
|
}
|
|
257
256
|
|
|
258
257
|
/**
|
|
259
|
-
*
|
|
260
|
-
*
|
|
258
|
+
* Expression-position lowering unwraps single-expression native fragments to
|
|
259
|
+
* the inner expression.
|
|
261
260
|
* When such a node appears directly in a component or statement render body,
|
|
262
261
|
* the unwrapped expression is still render output rather than an executable
|
|
263
262
|
* statement.
|
|
@@ -5,9 +5,9 @@ import tsx from 'esrap/languages/tsx';
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Zimmerframe provides `path` as the ancestor chain (in original pre-transform
|
|
8
|
-
* types, since visitors run bottom-up). A
|
|
9
|
-
* `Element` will render as a JSX child of that element; anywhere else
|
|
10
|
-
* renders as a standalone expression (e.g. a return value).
|
|
8
|
+
* types, since visitors run bottom-up). A native template node whose parent is
|
|
9
|
+
* a ripple `Element` will render as a JSX child of that element; anywhere else
|
|
10
|
+
* it renders as a standalone expression (e.g. a return value).
|
|
11
11
|
*
|
|
12
12
|
* @param {any[]} path
|
|
13
13
|
* @returns {boolean}
|
|
@@ -35,7 +35,7 @@ export function set_node_path_metadata(node, path) {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
|
-
* Flatten a
|
|
38
|
+
* Flatten a JSX-compatible island's children into a single expression. In a
|
|
39
39
|
* JSX-child position, a JSXExpressionContainer `{expr}` is valid and must stay
|
|
40
40
|
* wrapped. In an expression position (e.g. `return ...`), `{expr}` parses as
|
|
41
41
|
* a block/object literal, so unwrap to `expr`.
|
|
@@ -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
|
|
@@ -213,15 +213,7 @@ export function createJsxTransform(platform) {
|
|
|
213
213
|
return next();
|
|
214
214
|
},
|
|
215
215
|
|
|
216
|
-
|
|
217
|
-
const inner = /** @type {any} */ (next() ?? node);
|
|
218
|
-
const in_jsx_child = in_jsx_child_context(path);
|
|
219
|
-
return /** @type {any} */ (
|
|
220
|
-
wrap_jsx_setup_declarations(tsx_node_to_jsx_expression(inner, in_jsx_child), in_jsx_child)
|
|
221
|
-
);
|
|
222
|
-
},
|
|
223
|
-
|
|
224
|
-
Tsrx(node, { next, path, state, visit }) {
|
|
216
|
+
TsrxFragment(node, { next, path, state, visit }) {
|
|
225
217
|
const parent = /** @type {AST.ArrowFunctionExpression} */ (path.at(-1));
|
|
226
218
|
if (parent?.metadata?.native_tsrx && parent.body === node) {
|
|
227
219
|
return /** @type {any} */ (visit(create_native_tsrx_render_block(node, state), state));
|
|
@@ -1016,7 +1008,7 @@ function transform_block_statement(node, { next, visit, state, path }) {
|
|
|
1016
1008
|
* @returns {any}
|
|
1017
1009
|
*/
|
|
1018
1010
|
function transform_return_statement(node, { next, visit, state, path }) {
|
|
1019
|
-
if (get_active_native_tsrx_function(path) && node.argument?.type === '
|
|
1011
|
+
if (get_active_native_tsrx_function(path) && node.argument?.type === 'TsrxFragment') {
|
|
1020
1012
|
return visit(create_native_tsrx_render_block(node.argument, state), state);
|
|
1021
1013
|
}
|
|
1022
1014
|
|
|
@@ -1080,7 +1072,7 @@ function transform_native_tsrx_function(node, { next, state }) {
|
|
|
1080
1072
|
if (
|
|
1081
1073
|
inner !== node &&
|
|
1082
1074
|
node.type === 'ArrowFunctionExpression' &&
|
|
1083
|
-
node.body?.type === '
|
|
1075
|
+
node.body?.type === 'TsrxFragment' &&
|
|
1084
1076
|
inner.body?.type === 'BlockStatement'
|
|
1085
1077
|
) {
|
|
1086
1078
|
inner.expression = false;
|
|
@@ -1163,7 +1155,7 @@ function find_native_await_in_list(statements) {
|
|
|
1163
1155
|
function find_native_await_in_statement(statement) {
|
|
1164
1156
|
if (!statement || typeof statement !== 'object') return null;
|
|
1165
1157
|
|
|
1166
|
-
if (statement.type === 'ReturnStatement' && statement.argument?.type === '
|
|
1158
|
+
if (statement.type === 'ReturnStatement' && statement.argument?.type === 'TsrxFragment') {
|
|
1167
1159
|
return find_first_top_level_await_in_tsrx_function_body(statement.argument.children || []);
|
|
1168
1160
|
}
|
|
1169
1161
|
|
|
@@ -1258,7 +1250,7 @@ function transform_function_with_hook_helpers(node, { next, state }) {
|
|
|
1258
1250
|
* @returns {string}
|
|
1259
1251
|
*/
|
|
1260
1252
|
function get_function_helper_base_name(node) {
|
|
1261
|
-
return get_function_like_name(node) || '
|
|
1253
|
+
return get_function_like_name(node) || 'TsrxFragment';
|
|
1262
1254
|
}
|
|
1263
1255
|
|
|
1264
1256
|
/**
|
|
@@ -1337,7 +1329,7 @@ function collect_function_scope_bindings(node) {
|
|
|
1337
1329
|
const bindings = collect_param_bindings(node.params || []);
|
|
1338
1330
|
if (node.body?.type === 'BlockStatement') {
|
|
1339
1331
|
for (const statement of node.body.body || []) {
|
|
1340
|
-
if (statement.type === 'ReturnStatement' && statement.argument?.type === '
|
|
1332
|
+
if (statement.type === 'ReturnStatement' && statement.argument?.type === 'TsrxFragment') {
|
|
1341
1333
|
for (const child of get_tsrx_render_children(statement.argument)) {
|
|
1342
1334
|
collect_statement_bindings(child, bindings);
|
|
1343
1335
|
}
|
|
@@ -1446,7 +1438,7 @@ function statement_contains_native_tsrx_return(statement) {
|
|
|
1446
1438
|
*/
|
|
1447
1439
|
function node_contains_native_tsrx_template(node) {
|
|
1448
1440
|
if (!node || typeof node !== 'object') return false;
|
|
1449
|
-
if (node.type === 'Element' || node.type === '
|
|
1441
|
+
if (node.type === 'Element' || node.type === 'TsrxFragment') return true;
|
|
1450
1442
|
|
|
1451
1443
|
if (is_function_or_class_boundary(node)) {
|
|
1452
1444
|
return false;
|
|
@@ -1637,7 +1629,7 @@ function collect_style_elements(node, styles) {
|
|
|
1637
1629
|
return;
|
|
1638
1630
|
}
|
|
1639
1631
|
|
|
1640
|
-
if (is_function_or_class_boundary(node) || node.type === '
|
|
1632
|
+
if (is_function_or_class_boundary(node) || node.type === 'TsrxFragment') {
|
|
1641
1633
|
return;
|
|
1642
1634
|
}
|
|
1643
1635
|
|
|
@@ -1756,8 +1748,7 @@ function is_style_expression_position(path) {
|
|
|
1756
1748
|
const parent = path.at(-1);
|
|
1757
1749
|
return !(
|
|
1758
1750
|
parent?.type === 'Element' ||
|
|
1759
|
-
parent?.type === '
|
|
1760
|
-
parent?.type === 'Tsx' ||
|
|
1751
|
+
parent?.type === 'TsrxFragment' ||
|
|
1761
1752
|
parent?.type === 'TsxCompat' ||
|
|
1762
1753
|
parent?.type === 'BlockStatement' ||
|
|
1763
1754
|
parent?.type === 'Program' ||
|
|
@@ -1845,7 +1836,7 @@ function expand_native_tsrx_return_statement_list(statements, transform_context)
|
|
|
1845
1836
|
function expand_native_tsrx_return_statement(statement, transform_context) {
|
|
1846
1837
|
if (!statement || typeof statement !== 'object') return [statement];
|
|
1847
1838
|
|
|
1848
|
-
if (statement.type === 'ReturnStatement' && statement.argument?.type === '
|
|
1839
|
+
if (statement.type === 'ReturnStatement' && statement.argument?.type === 'TsrxFragment') {
|
|
1849
1840
|
return create_native_tsrx_render_statements(statement.argument, transform_context);
|
|
1850
1841
|
}
|
|
1851
1842
|
|
|
@@ -2045,7 +2036,7 @@ function node_contains_hook_bearing_tsrx(node, transform_context) {
|
|
|
2045
2036
|
return node.some((child) => node_contains_hook_bearing_tsrx(child, transform_context));
|
|
2046
2037
|
}
|
|
2047
2038
|
|
|
2048
|
-
if (node.type === '
|
|
2039
|
+
if (node.type === 'TsrxFragment') {
|
|
2049
2040
|
return body_contains_top_level_hook_call(node.children || [], transform_context, true);
|
|
2050
2041
|
}
|
|
2051
2042
|
|
|
@@ -2092,7 +2083,7 @@ function should_extract_hook_helpers(transform_context) {
|
|
|
2092
2083
|
*/
|
|
2093
2084
|
function create_module_scoped_hook_component_id(helper_id, transform_context) {
|
|
2094
2085
|
return create_generated_identifier(
|
|
2095
|
-
`${transform_context.helper_state?.base_name || '
|
|
2086
|
+
`${transform_context.helper_state?.base_name || 'TsrxFragment'}__${helper_id.name}`,
|
|
2096
2087
|
);
|
|
2097
2088
|
}
|
|
2098
2089
|
|
|
@@ -4014,11 +4005,7 @@ function get_body_source_node(body_nodes) {
|
|
|
4014
4005
|
function to_jsx_child(node, transform_context) {
|
|
4015
4006
|
if (!node) return node;
|
|
4016
4007
|
switch (node.type) {
|
|
4017
|
-
case '
|
|
4018
|
-
// We're inside a JSX child position by construction, so keep a
|
|
4019
|
-
// JSXExpressionContainer wrapper for bare `{expr}` children.
|
|
4020
|
-
return tsx_node_to_jsx_expression(node, true);
|
|
4021
|
-
case 'Tsrx':
|
|
4008
|
+
case 'TsrxFragment':
|
|
4022
4009
|
return tsrx_node_to_jsx_expression(node, transform_context, true);
|
|
4023
4010
|
case 'TsxCompat':
|
|
4024
4011
|
return tsx_compat_node_to_jsx_expression(node, transform_context, true);
|
|
@@ -4052,8 +4039,8 @@ function to_jsx_child(node, transform_context) {
|
|
|
4052
4039
|
|
|
4053
4040
|
/**
|
|
4054
4041
|
* Lower a native TSRX fragment body to a JSX expression.
|
|
4055
|
-
*
|
|
4056
|
-
*
|
|
4042
|
+
* Children have already been parsed and transformed through the normal TSRX
|
|
4043
|
+
* Element/Text/control-flow visitors.
|
|
4057
4044
|
*
|
|
4058
4045
|
* @param {any} node
|
|
4059
4046
|
* @param {TransformContext} transform_context
|
|
@@ -5529,7 +5516,7 @@ function wrap_jsx_setup_declarations(expression, in_jsx_child) {
|
|
|
5529
5516
|
* This validator runs over the raw, pre-lowering attribute list so each
|
|
5530
5517
|
* shape is still distinguishable by `type`. Ripple `Element` attributes have type `Attribute` with an
|
|
5531
5518
|
* `Identifier` name (the parser normalizes `JSXAttribute`/`JSXIdentifier`
|
|
5532
|
-
* for
|
|
5519
|
+
* for native elements); inside `<tsx:react>` compat blocks they retain
|
|
5533
5520
|
* the original `JSXAttribute`/`JSXIdentifier` shape, so we accept both.
|
|
5534
5521
|
*
|
|
5535
5522
|
* @param {any[]} raw_attrs
|
|
@@ -5942,7 +5929,7 @@ function tsx_compat_node_to_jsx_expression(node, transform_context, in_jsx_child
|
|
|
5942
5929
|
if (!platform.jsx.acceptedTsxKinds.includes(node.kind)) {
|
|
5943
5930
|
const accepted = platform.jsx.acceptedTsxKinds.map((k) => `<tsx:${k}>`).join(', ');
|
|
5944
5931
|
error(
|
|
5945
|
-
`${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}.`,
|
|
5946
5933
|
transform_context.filename,
|
|
5947
5934
|
node,
|
|
5948
5935
|
transform_context.errors,
|
package/types/index.d.ts
CHANGED
|
@@ -236,8 +236,7 @@ declare module 'estree' {
|
|
|
236
236
|
|
|
237
237
|
// Include TypeScript node types and TSRX-specific nodes in NodeMap
|
|
238
238
|
interface NodeMap {
|
|
239
|
-
|
|
240
|
-
Tsrx: Tsrx;
|
|
239
|
+
TsrxFragment: TsrxFragment;
|
|
241
240
|
TsxCompat: TsxCompat;
|
|
242
241
|
TSRXExpression: TSRXExpression;
|
|
243
242
|
Element: Element;
|
|
@@ -249,7 +248,7 @@ declare module 'estree' {
|
|
|
249
248
|
}
|
|
250
249
|
|
|
251
250
|
interface ExpressionMap {
|
|
252
|
-
|
|
251
|
+
TsrxFragment: TsrxFragment;
|
|
253
252
|
Text: TextNode;
|
|
254
253
|
JSXEmptyExpression: ESTreeJSX.JSXEmptyExpression;
|
|
255
254
|
ParenthesizedExpression: ParenthesizedExpression;
|
|
@@ -345,18 +344,8 @@ declare module 'estree' {
|
|
|
345
344
|
trailingComments?: AST.Comment[] | undefined;
|
|
346
345
|
}
|
|
347
346
|
|
|
348
|
-
interface
|
|
349
|
-
type: '
|
|
350
|
-
attributes: Array<any>;
|
|
351
|
-
children: ESTreeJSX.JSXElement['children'];
|
|
352
|
-
selfClosing?: boolean;
|
|
353
|
-
unclosed?: boolean;
|
|
354
|
-
openingElement: ESTreeJSX.JSXOpeningElement;
|
|
355
|
-
closingElement: ESTreeJSX.JSXClosingElement;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
interface Tsrx extends AST.BaseExpression {
|
|
359
|
-
type: 'Tsrx';
|
|
347
|
+
interface TsrxFragment extends AST.BaseExpression {
|
|
348
|
+
type: 'TsrxFragment';
|
|
360
349
|
attributes: Array<any>;
|
|
361
350
|
children: AST.Node[];
|
|
362
351
|
selfClosing?: boolean;
|
|
@@ -461,7 +450,7 @@ declare module 'estree' {
|
|
|
461
450
|
|
|
462
451
|
export type TSRXStatement = AST.Statement | TSESTree.Statement;
|
|
463
452
|
|
|
464
|
-
export type NodeWithChildren = AST.Element | AST.
|
|
453
|
+
export type NodeWithChildren = AST.Element | AST.TsrxFragment | AST.TsxCompat;
|
|
465
454
|
|
|
466
455
|
export namespace CSS {
|
|
467
456
|
export interface BaseNode extends AST.NodeWithMaybeComments {
|
|
@@ -1222,8 +1211,7 @@ export interface Binding {
|
|
|
1222
1211
|
| AST.ClassDeclaration
|
|
1223
1212
|
| AST.ImportDeclaration
|
|
1224
1213
|
| AST.TSModuleDeclaration
|
|
1225
|
-
| AST.
|
|
1226
|
-
| AST.Tsrx;
|
|
1214
|
+
| AST.TsrxFragment;
|
|
1227
1215
|
/** Whether this binding has been reassigned */
|
|
1228
1216
|
reassigned: boolean;
|
|
1229
1217
|
/** Whether this binding has been mutated (property access) */
|
|
@@ -1323,8 +1311,7 @@ export interface ScopeInterface {
|
|
|
1323
1311
|
| AST.ClassDeclaration
|
|
1324
1312
|
| AST.ImportDeclaration
|
|
1325
1313
|
| AST.TSModuleDeclaration
|
|
1326
|
-
| AST.
|
|
1327
|
-
| AST.Tsrx,
|
|
1314
|
+
| AST.TsrxFragment,
|
|
1328
1315
|
): Binding;
|
|
1329
1316
|
/** Get binding by name */
|
|
1330
1317
|
get(name: string): Binding | null;
|
package/types/parse.d.ts
CHANGED
|
@@ -1172,7 +1172,7 @@ export namespace Parse {
|
|
|
1172
1172
|
*/
|
|
1173
1173
|
parseTopLevel(node: AST.Program): AST.Program;
|
|
1174
1174
|
|
|
1175
|
-
parseElement(): AST.Element | AST.
|
|
1175
|
+
parseElement(): AST.Element | AST.TsrxFragment | AST.TsxCompat;
|
|
1176
1176
|
|
|
1177
1177
|
parseDoubleQuotedTextChild(): AST.TextNode;
|
|
1178
1178
|
|