@tsrx/core 0.0.28 → 0.1.0
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 +115 -24
- package/src/scope.js +7 -0
- package/src/transform/jsx/ast-builders.js +1 -0
- package/src/transform/jsx/index.js +66 -0
- package/types/index.d.ts +12 -1
- package/types/parse.d.ts +1 -1
package/package.json
CHANGED
package/src/plugin.js
CHANGED
|
@@ -18,7 +18,7 @@ import { error } from './errors.js';
|
|
|
18
18
|
import { DIAGNOSTIC_CODES } from './diagnostics.js';
|
|
19
19
|
|
|
20
20
|
const JSX_EXPRESSION_VALUE_ERROR =
|
|
21
|
-
'JSX elements cannot be used as expressions. Wrap with `<>...</>` or `<tsx>...</tsx
|
|
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
|
|
|
23
23
|
/** @type {WeakMap<Record<string, boolean>, Map<string, number>>} */
|
|
24
24
|
const argument_clash_first_positions = new WeakMap();
|
|
@@ -325,7 +325,10 @@ export function TSRXPlugin(config) {
|
|
|
325
325
|
}
|
|
326
326
|
|
|
327
327
|
const parent = this.#path.at(-1);
|
|
328
|
-
if (
|
|
328
|
+
if (
|
|
329
|
+
!parent ||
|
|
330
|
+
(parent.type !== 'Component' && parent.type !== 'Element' && parent.type !== 'Tsrx')
|
|
331
|
+
) {
|
|
329
332
|
return false;
|
|
330
333
|
}
|
|
331
334
|
|
|
@@ -1809,7 +1812,8 @@ export function TSRXPlugin(config) {
|
|
|
1809
1812
|
ch === 125 &&
|
|
1810
1813
|
(this.#path.length === 0 ||
|
|
1811
1814
|
this.#path.at(-1)?.type === 'Component' ||
|
|
1812
|
-
this.#path.at(-1)?.type === 'Element'
|
|
1815
|
+
this.#path.at(-1)?.type === 'Element' ||
|
|
1816
|
+
this.#path.at(-1)?.type === 'Tsrx')
|
|
1813
1817
|
) {
|
|
1814
1818
|
this.#resetTokenStartToCurrentPosition();
|
|
1815
1819
|
return original.readToken.call(this, ch);
|
|
@@ -1849,7 +1853,9 @@ export function TSRXPlugin(config) {
|
|
|
1849
1853
|
* Override jsx_parseElement to intercept expression-level JSX.
|
|
1850
1854
|
* This is called by acorn-jsx's parseExprAtom when it encounters <
|
|
1851
1855
|
* in expression position. Bare fragments are treated as shorthand
|
|
1852
|
-
* for <tsx>...</tsx
|
|
1856
|
+
* for <tsx>...</tsx>. <tsrx>...</tsrx> admits native TSRX
|
|
1857
|
+
* template syntax as an expression value. Other tags must still use
|
|
1858
|
+
* <tsx>, <tsrx>, or <tsx:*>.
|
|
1853
1859
|
* @type {Parse.Parser['jsx_parseElement']}
|
|
1854
1860
|
*/
|
|
1855
1861
|
jsx_parseElement() {
|
|
@@ -1859,11 +1865,12 @@ export function TSRXPlugin(config) {
|
|
|
1859
1865
|
return super.jsx_parseElement();
|
|
1860
1866
|
}
|
|
1861
1867
|
|
|
1862
|
-
// Check if the element being parsed IS a <tsx
|
|
1868
|
+
// Check if the element being parsed IS a <tsx>, <tsrx>, or <tsx:*> tag
|
|
1863
1869
|
// Current token is jsxTagStart, this.end is position after '<'
|
|
1864
1870
|
const tag_name_start = this.end;
|
|
1865
1871
|
const is_fragment_tag = this.input.charCodeAt(tag_name_start) === 62;
|
|
1866
1872
|
const char_after_tsx = this.input.charCodeAt(tag_name_start + 3);
|
|
1873
|
+
const char_after_tsrx = this.input.charCodeAt(tag_name_start + 4);
|
|
1867
1874
|
const is_tsx_tag =
|
|
1868
1875
|
this.input.startsWith('tsx', tag_name_start) &&
|
|
1869
1876
|
(tag_name_start + 3 >= this.input.length ||
|
|
@@ -1874,9 +1881,18 @@ export function TSRXPlugin(config) {
|
|
|
1874
1881
|
char_after_tsx === 10 || // newline
|
|
1875
1882
|
char_after_tsx === 13 || // carriage return
|
|
1876
1883
|
char_after_tsx === 58); // : (tsx:react)
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1884
|
+
const is_tsrx_tag =
|
|
1885
|
+
this.input.startsWith('tsrx', tag_name_start) &&
|
|
1886
|
+
(tag_name_start + 4 >= this.input.length ||
|
|
1887
|
+
char_after_tsrx === 62 || // >
|
|
1888
|
+
char_after_tsrx === 47 || // / (self-closing)
|
|
1889
|
+
char_after_tsrx === 32 || // space
|
|
1890
|
+
char_after_tsrx === 9 || // tab
|
|
1891
|
+
char_after_tsrx === 10 || // newline
|
|
1892
|
+
char_after_tsrx === 13); // carriage return
|
|
1893
|
+
|
|
1894
|
+
if (is_fragment_tag || is_tsx_tag || is_tsrx_tag) {
|
|
1895
|
+
// Use Ripple's parseElement to create a Tsx/Tsrx/TsxCompat node.
|
|
1880
1896
|
// Bare fragments (<></>) are shorthand for <tsx>...</tsx>.
|
|
1881
1897
|
this.next();
|
|
1882
1898
|
return /** @type {import('estree-jsx').JSXElement} */ (
|
|
@@ -1907,7 +1923,9 @@ export function TSRXPlugin(config) {
|
|
|
1907
1923
|
const start = this.start - 1;
|
|
1908
1924
|
const position = new acorn.Position(this.curLine, start - this.lineStart);
|
|
1909
1925
|
|
|
1910
|
-
const element = /** @type {AST.Element | AST.Tsx | AST.TsxCompat} */ (
|
|
1926
|
+
const element = /** @type {AST.Element | AST.Tsx | AST.Tsrx | AST.TsxCompat} */ (
|
|
1927
|
+
this.startNode()
|
|
1928
|
+
);
|
|
1911
1929
|
element.start = start;
|
|
1912
1930
|
/** @type {AST.NodeWithLocation} */ (element).loc.start = position;
|
|
1913
1931
|
element.metadata = { path: [] };
|
|
@@ -1928,6 +1946,11 @@ export function TSRXPlugin(config) {
|
|
|
1928
1946
|
!is_tsx_compat &&
|
|
1929
1947
|
open.name.type === 'JSXIdentifier' &&
|
|
1930
1948
|
open.name.name === 'tsx';
|
|
1949
|
+
const is_tsrx =
|
|
1950
|
+
!is_fragment &&
|
|
1951
|
+
!is_tsx_compat &&
|
|
1952
|
+
open.name.type === 'JSXIdentifier' &&
|
|
1953
|
+
open.name.name === 'tsrx';
|
|
1931
1954
|
|
|
1932
1955
|
if (is_tsx_compat) {
|
|
1933
1956
|
const namespace_node = /** @type {ESTreeJSX.JSXNamespacedName} */ (open.name);
|
|
@@ -1950,6 +1973,15 @@ export function TSRXPlugin(config) {
|
|
|
1950
1973
|
`TSX elements cannot be self-closing. '<tsx />' must have a closing tag '</tsx>'.`,
|
|
1951
1974
|
);
|
|
1952
1975
|
}
|
|
1976
|
+
} else if (is_tsrx) {
|
|
1977
|
+
/** @type {AST.Tsrx} */ (element).type = 'Tsrx';
|
|
1978
|
+
|
|
1979
|
+
if (open.selfClosing) {
|
|
1980
|
+
this.raise(
|
|
1981
|
+
open.start,
|
|
1982
|
+
`TSRX elements cannot be self-closing. '<tsrx />' must have a closing tag '</tsrx>'.`,
|
|
1983
|
+
);
|
|
1984
|
+
}
|
|
1953
1985
|
} else if (is_fragment) {
|
|
1954
1986
|
/** @type {AST.Tsx} */ (element).type = 'Tsx';
|
|
1955
1987
|
} else {
|
|
@@ -1987,7 +2019,7 @@ export function TSRXPlugin(config) {
|
|
|
1987
2019
|
}
|
|
1988
2020
|
}
|
|
1989
2021
|
|
|
1990
|
-
if (!is_tsx_compat && !is_tsx && !is_fragment) {
|
|
2022
|
+
if (!is_tsx_compat && !is_tsx && !is_tsrx && !is_fragment) {
|
|
1991
2023
|
/** @type {AST.Element} */ (element).id = /** @type {AST.Identifier} */ (
|
|
1992
2024
|
convert_from_jsx(/** @type {ESTreeJSX.JSXIdentifier} */ (open.name))
|
|
1993
2025
|
);
|
|
@@ -2181,6 +2213,7 @@ export function TSRXPlugin(config) {
|
|
|
2181
2213
|
parent?.type === 'Component' ||
|
|
2182
2214
|
parent?.type === 'Element' ||
|
|
2183
2215
|
parent?.type === 'Tsx' ||
|
|
2216
|
+
parent?.type === 'Tsrx' ||
|
|
2184
2217
|
parent?.type === 'TsxCompat';
|
|
2185
2218
|
|
|
2186
2219
|
if (curContext === tstc.tc_expr && !insideTemplate) {
|
|
@@ -2249,7 +2282,21 @@ export function TSRXPlugin(config) {
|
|
|
2249
2282
|
this.#popTsxTokenContextBeforeTemplateExpressionChild();
|
|
2250
2283
|
this.next();
|
|
2251
2284
|
}
|
|
2252
|
-
} else if (this.#path[this.#path.length - 1] === element) {
|
|
2285
|
+
} else if (element.type === 'Tsrx' && this.#path[this.#path.length - 1] === element) {
|
|
2286
|
+
this.#report_broken_markup_error(
|
|
2287
|
+
this.start,
|
|
2288
|
+
"Unclosed tag '<tsrx>'. Expected '</tsrx>' before end of component.",
|
|
2289
|
+
);
|
|
2290
|
+
element.unclosed = true;
|
|
2291
|
+
/** @type {AST.SourceLocation} */ (element.loc).end = {
|
|
2292
|
+
.../** @type {AST.SourceLocation} */ (element.openingElement.loc).end,
|
|
2293
|
+
};
|
|
2294
|
+
element.end = element.openingElement.end;
|
|
2295
|
+
this.#path.pop();
|
|
2296
|
+
} else if (
|
|
2297
|
+
element.type === 'Element' &&
|
|
2298
|
+
this.#path[this.#path.length - 1] === element
|
|
2299
|
+
) {
|
|
2253
2300
|
// Check if this element was properly closed
|
|
2254
2301
|
const tagName = this.getElementName(element.id);
|
|
2255
2302
|
this.#report_broken_markup_error(
|
|
@@ -2257,7 +2304,7 @@ export function TSRXPlugin(config) {
|
|
|
2257
2304
|
`Unclosed tag '<${tagName}>'. Expected '</${tagName}>' before end of component.`,
|
|
2258
2305
|
);
|
|
2259
2306
|
element.unclosed = true;
|
|
2260
|
-
element.loc.end = {
|
|
2307
|
+
/** @type {AST.SourceLocation} */ (element.loc).end = {
|
|
2261
2308
|
.../** @type {AST.SourceLocation} */ (element.openingElement.loc).end,
|
|
2262
2309
|
};
|
|
2263
2310
|
element.end = element.openingElement.end;
|
|
@@ -2272,6 +2319,7 @@ export function TSRXPlugin(config) {
|
|
|
2272
2319
|
parent?.type === 'Component' ||
|
|
2273
2320
|
parent?.type === 'Element' ||
|
|
2274
2321
|
parent?.type === 'Tsx' ||
|
|
2322
|
+
parent?.type === 'Tsrx' ||
|
|
2275
2323
|
parent?.type === 'TsxCompat';
|
|
2276
2324
|
|
|
2277
2325
|
if (curContext === tstc.tc_expr && !insideTemplate) {
|
|
@@ -2279,7 +2327,13 @@ export function TSRXPlugin(config) {
|
|
|
2279
2327
|
}
|
|
2280
2328
|
}
|
|
2281
2329
|
|
|
2282
|
-
if (
|
|
2330
|
+
if (
|
|
2331
|
+
element.closingElement &&
|
|
2332
|
+
!is_tsx_compat &&
|
|
2333
|
+
!is_tsx &&
|
|
2334
|
+
!is_tsrx &&
|
|
2335
|
+
element.closingElement.name
|
|
2336
|
+
) {
|
|
2283
2337
|
/** @type {unknown} */ (element.closingElement.name) = convert_from_jsx(
|
|
2284
2338
|
element.closingElement.name,
|
|
2285
2339
|
);
|
|
@@ -2480,10 +2534,26 @@ export function TSRXPlugin(config) {
|
|
|
2480
2534
|
this.context.pop();
|
|
2481
2535
|
}
|
|
2482
2536
|
return;
|
|
2483
|
-
} else if (
|
|
2537
|
+
} else if (
|
|
2538
|
+
this.type === tstt.jsxTagStart ||
|
|
2539
|
+
(this.input.charCodeAt(this.start) === 60 /* < */ &&
|
|
2540
|
+
this.input.charCodeAt(this.start + 1) === 47) /* / */
|
|
2541
|
+
) {
|
|
2484
2542
|
const startPos = this.start;
|
|
2485
2543
|
const startLoc = this.startLoc;
|
|
2486
|
-
this.
|
|
2544
|
+
if (this.type === tstt.jsxTagStart) {
|
|
2545
|
+
this.next();
|
|
2546
|
+
} else {
|
|
2547
|
+
// A control-flow block inside <tsrx> can leave the tokenizer
|
|
2548
|
+
// in normal JS mode, so `</tsrx>` may arrive as a relational
|
|
2549
|
+
// `<` token. Re-enter JSX closing-tag parsing manually.
|
|
2550
|
+
this.pos = startPos + 1;
|
|
2551
|
+
this.type = tstt.jsxTagStart;
|
|
2552
|
+
this.start = startPos;
|
|
2553
|
+
this.startLoc = startLoc;
|
|
2554
|
+
this.exprAllowed = false;
|
|
2555
|
+
this.next();
|
|
2556
|
+
}
|
|
2487
2557
|
if (this.value === '/' || this.type === tt.slash) {
|
|
2488
2558
|
// Consume '/'
|
|
2489
2559
|
this.next();
|
|
@@ -2500,6 +2570,7 @@ export function TSRXPlugin(config) {
|
|
|
2500
2570
|
!currentElement ||
|
|
2501
2571
|
(currentElement.type !== 'Element' &&
|
|
2502
2572
|
currentElement.type !== 'Tsx' &&
|
|
2573
|
+
currentElement.type !== 'Tsrx' &&
|
|
2503
2574
|
currentElement.type !== 'TsxCompat')
|
|
2504
2575
|
) {
|
|
2505
2576
|
this.raise(this.start, 'Unexpected closing tag');
|
|
@@ -2522,6 +2593,12 @@ export function TSRXPlugin(config) {
|
|
|
2522
2593
|
closingElement.name?.type === 'JSXNamespacedName'
|
|
2523
2594
|
? closingElement.name.namespace.name + ':' + closingElement.name.name.name
|
|
2524
2595
|
: this.getElementName(closingElement.name);
|
|
2596
|
+
} else if (currentElement.type === 'Tsrx') {
|
|
2597
|
+
openingTagName = 'tsrx';
|
|
2598
|
+
closingTagName =
|
|
2599
|
+
closingElement.name?.type === 'JSXNamespacedName'
|
|
2600
|
+
? closingElement.name.namespace.name + ':' + closingElement.name.name.name
|
|
2601
|
+
: this.getElementName(closingElement.name);
|
|
2525
2602
|
} else {
|
|
2526
2603
|
// Regular Element node (or fragment)
|
|
2527
2604
|
openingTagName = currentElement.id ? this.getElementName(currentElement.id) : null;
|
|
@@ -2544,7 +2621,12 @@ export function TSRXPlugin(config) {
|
|
|
2544
2621
|
const elem = this.#path[this.#path.length - 1];
|
|
2545
2622
|
|
|
2546
2623
|
// Stop at non-Element boundaries (Component, etc.)
|
|
2547
|
-
if (
|
|
2624
|
+
if (
|
|
2625
|
+
elem.type !== 'Element' &&
|
|
2626
|
+
elem.type !== 'Tsx' &&
|
|
2627
|
+
elem.type !== 'Tsrx' &&
|
|
2628
|
+
elem.type !== 'TsxCompat'
|
|
2629
|
+
) {
|
|
2548
2630
|
break;
|
|
2549
2631
|
}
|
|
2550
2632
|
|
|
@@ -2555,9 +2637,11 @@ export function TSRXPlugin(config) {
|
|
|
2555
2637
|
? elem.openingElement.name
|
|
2556
2638
|
? 'tsx'
|
|
2557
2639
|
: null
|
|
2558
|
-
: elem.
|
|
2559
|
-
?
|
|
2560
|
-
:
|
|
2640
|
+
: elem.type === 'Tsrx'
|
|
2641
|
+
? 'tsrx'
|
|
2642
|
+
: elem.id
|
|
2643
|
+
? this.getElementName(elem.id)
|
|
2644
|
+
: null;
|
|
2561
2645
|
|
|
2562
2646
|
// Found matching opening tag
|
|
2563
2647
|
if (elemName === closingTagName) {
|
|
@@ -2576,12 +2660,19 @@ export function TSRXPlugin(config) {
|
|
|
2576
2660
|
}
|
|
2577
2661
|
|
|
2578
2662
|
const elementToClose = this.#path[this.#path.length - 1];
|
|
2579
|
-
if (
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2663
|
+
if (
|
|
2664
|
+
elementToClose &&
|
|
2665
|
+
(elementToClose.type === 'Element' || elementToClose.type === 'Tsrx')
|
|
2666
|
+
) {
|
|
2667
|
+
const elementToCloseName =
|
|
2668
|
+
elementToClose.type === 'Tsrx'
|
|
2669
|
+
? 'tsrx'
|
|
2670
|
+
: /** @type {AST.Element} */ (elementToClose).id
|
|
2671
|
+
? this.getElementName(/** @type {AST.Element} */ (elementToClose).id)
|
|
2672
|
+
: null;
|
|
2583
2673
|
if (elementToCloseName === closingTagName) {
|
|
2584
|
-
/** @type {AST.Element} */ (elementToClose).closingElement =
|
|
2674
|
+
/** @type {AST.Element | AST.Tsrx} */ (elementToClose).closingElement =
|
|
2675
|
+
closingElement;
|
|
2585
2676
|
}
|
|
2586
2677
|
}
|
|
2587
2678
|
|
package/src/scope.js
CHANGED
|
@@ -127,6 +127,13 @@ export function create_scopes(ast, root, parent, error_options) {
|
|
|
127
127
|
next({ scope });
|
|
128
128
|
},
|
|
129
129
|
|
|
130
|
+
Tsrx(node, { state, next }) {
|
|
131
|
+
const scope = state.scope.child();
|
|
132
|
+
scopes.set(node, scope);
|
|
133
|
+
|
|
134
|
+
next({ scope });
|
|
135
|
+
},
|
|
136
|
+
|
|
130
137
|
TSModuleDeclaration(node, { state, next }) {
|
|
131
138
|
const is_submodule = node.metadata?.module_keyword === 'module';
|
|
132
139
|
if (is_submodule && node.id?.type === 'Identifier') {
|
|
@@ -390,6 +390,17 @@ export function createJsxTransform(platform) {
|
|
|
390
390
|
);
|
|
391
391
|
},
|
|
392
392
|
|
|
393
|
+
Tsrx(node, { next, path, state }) {
|
|
394
|
+
const inner = /** @type {any} */ (next() ?? node);
|
|
395
|
+
const in_jsx_child = in_jsx_child_context(path);
|
|
396
|
+
return /** @type {any} */ (
|
|
397
|
+
wrap_jsx_setup_declarations(
|
|
398
|
+
tsrx_node_to_jsx_expression(inner, state, in_jsx_child),
|
|
399
|
+
in_jsx_child,
|
|
400
|
+
)
|
|
401
|
+
);
|
|
402
|
+
},
|
|
403
|
+
|
|
393
404
|
TsxCompat(node, { next, path, state }) {
|
|
394
405
|
const inner = /** @type {any} */ (next() ?? node);
|
|
395
406
|
const in_jsx_child = in_jsx_child_context(path);
|
|
@@ -3379,6 +3390,8 @@ function to_jsx_child(node, transform_context) {
|
|
|
3379
3390
|
// We're inside a JSX child position by construction, so keep a
|
|
3380
3391
|
// JSXExpressionContainer wrapper for bare `{expr}` children.
|
|
3381
3392
|
return tsx_node_to_jsx_expression(node, true);
|
|
3393
|
+
case 'Tsrx':
|
|
3394
|
+
return tsrx_node_to_jsx_expression(node, transform_context, true);
|
|
3382
3395
|
case 'TsxCompat':
|
|
3383
3396
|
return tsx_compat_node_to_jsx_expression(node, transform_context, true);
|
|
3384
3397
|
case 'Element':
|
|
@@ -3413,6 +3426,59 @@ function to_jsx_child(node, transform_context) {
|
|
|
3413
3426
|
}
|
|
3414
3427
|
}
|
|
3415
3428
|
|
|
3429
|
+
/**
|
|
3430
|
+
* Lower a `<tsrx>` node's native TSRX template body to a JSX expression.
|
|
3431
|
+
* Unlike `<tsx>`, children have already been parsed and transformed through
|
|
3432
|
+
* the normal TSRX Element/Text/control-flow visitors.
|
|
3433
|
+
*
|
|
3434
|
+
* @param {any} node
|
|
3435
|
+
* @param {TransformContext} transform_context
|
|
3436
|
+
* @param {boolean} [in_jsx_child]
|
|
3437
|
+
* @returns {any}
|
|
3438
|
+
*/
|
|
3439
|
+
function tsrx_node_to_jsx_expression(node, transform_context, in_jsx_child = false) {
|
|
3440
|
+
const children = (node.children || []).filter(
|
|
3441
|
+
(/** @type {any} */ child) =>
|
|
3442
|
+
child &&
|
|
3443
|
+
child.type !== 'EmptyStatement' &&
|
|
3444
|
+
(child.type !== 'JSXText' || child.value.trim() !== ''),
|
|
3445
|
+
);
|
|
3446
|
+
|
|
3447
|
+
/** @type {any} */
|
|
3448
|
+
let expression;
|
|
3449
|
+
if (children.length === 0) {
|
|
3450
|
+
expression = create_null_literal();
|
|
3451
|
+
} else if (
|
|
3452
|
+
children.every(is_inline_element_child) &&
|
|
3453
|
+
!children_contain_return_semantics(children)
|
|
3454
|
+
) {
|
|
3455
|
+
const saved_inside_element_child = transform_context.inside_element_child;
|
|
3456
|
+
transform_context.inside_element_child = true;
|
|
3457
|
+
try {
|
|
3458
|
+
const render_nodes = children.map((/** @type {any} */ child) =>
|
|
3459
|
+
to_jsx_child(child, transform_context),
|
|
3460
|
+
);
|
|
3461
|
+
expression = build_return_expression(render_nodes) || create_null_literal();
|
|
3462
|
+
} finally {
|
|
3463
|
+
transform_context.inside_element_child = saved_inside_element_child;
|
|
3464
|
+
}
|
|
3465
|
+
} else {
|
|
3466
|
+
expression = statement_body_to_jsx_child(children, transform_context).expression;
|
|
3467
|
+
}
|
|
3468
|
+
|
|
3469
|
+
if (
|
|
3470
|
+
in_jsx_child &&
|
|
3471
|
+
expression.type !== 'JSXElement' &&
|
|
3472
|
+
expression.type !== 'JSXFragment' &&
|
|
3473
|
+
expression.type !== 'JSXText' &&
|
|
3474
|
+
expression.type !== 'JSXExpressionContainer'
|
|
3475
|
+
) {
|
|
3476
|
+
return to_jsx_expression_container(expression, node);
|
|
3477
|
+
}
|
|
3478
|
+
|
|
3479
|
+
return expression;
|
|
3480
|
+
}
|
|
3481
|
+
|
|
3416
3482
|
/**
|
|
3417
3483
|
* @param {any} node
|
|
3418
3484
|
* @param {TransformContext} transform_context
|
package/types/index.d.ts
CHANGED
|
@@ -205,6 +205,7 @@ declare module 'estree' {
|
|
|
205
205
|
interface NodeMap {
|
|
206
206
|
Component: Component;
|
|
207
207
|
Tsx: Tsx;
|
|
208
|
+
Tsrx: Tsrx;
|
|
208
209
|
TsxCompat: TsxCompat;
|
|
209
210
|
TSRXExpression: TSRXExpression;
|
|
210
211
|
Html: Html;
|
|
@@ -346,6 +347,16 @@ declare module 'estree' {
|
|
|
346
347
|
closingElement: ESTreeJSX.JSXClosingElement;
|
|
347
348
|
}
|
|
348
349
|
|
|
350
|
+
interface Tsrx extends AST.BaseNode {
|
|
351
|
+
type: 'Tsrx';
|
|
352
|
+
attributes: Array<any>;
|
|
353
|
+
children: AST.Node[];
|
|
354
|
+
selfClosing?: boolean;
|
|
355
|
+
unclosed?: boolean;
|
|
356
|
+
openingElement: ESTreeJSX.JSXOpeningElement;
|
|
357
|
+
closingElement: ESTreeJSX.JSXClosingElement;
|
|
358
|
+
}
|
|
359
|
+
|
|
349
360
|
interface TsxCompat extends AST.BaseNode {
|
|
350
361
|
type: 'TsxCompat';
|
|
351
362
|
kind: string;
|
|
@@ -479,7 +490,7 @@ declare module 'estree' {
|
|
|
479
490
|
|
|
480
491
|
export type TSRXStatement = AST.Statement | TSESTree.Statement;
|
|
481
492
|
|
|
482
|
-
export type NodeWithChildren = AST.Element | AST.Tsx | AST.TsxCompat;
|
|
493
|
+
export type NodeWithChildren = AST.Element | AST.Tsx | AST.Tsrx | AST.TsxCompat;
|
|
483
494
|
|
|
484
495
|
export namespace CSS {
|
|
485
496
|
export interface BaseNode extends AST.NodeWithMaybeComments {
|
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.Tsx | AST.TsxCompat;
|
|
1175
|
+
parseElement(): AST.Element | AST.Tsx | AST.Tsrx | AST.TsxCompat;
|
|
1176
1176
|
|
|
1177
1177
|
parseDoubleQuotedTextChild(): AST.TextNode;
|
|
1178
1178
|
|