@tsrx/core 0.1.42 → 0.1.43
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/comment-utils.js +16 -1
- package/src/transform/jsx/helpers.js +33 -1
- package/src/transform/jsx/index.js +14 -4
package/package.json
CHANGED
package/src/comment-utils.js
CHANGED
|
@@ -58,6 +58,18 @@ export function is_jsdoc_ts_annotation(comment) {
|
|
|
58
58
|
return tsAnnotations.some((annotation) => comment.value.includes(annotation));
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Check if a comment is a TypeScript JSX pragma (`@jsxImportSource`,
|
|
63
|
+
* `@jsxRuntime`, `@jsxFrag`, `@jsx`). TS reads these from a file's LEADING
|
|
64
|
+
* comments to pick that file's JSX type source/factory, overriding tsconfig —
|
|
65
|
+
* dropping one silently retypes every JSX expression in the file.
|
|
66
|
+
* @param {AST.CommentWithLocation} comment
|
|
67
|
+
* @returns {boolean}
|
|
68
|
+
*/
|
|
69
|
+
export function is_jsx_pragma(comment) {
|
|
70
|
+
return /@jsx(ImportSource|Runtime|Frag)?\b/.test(comment.value);
|
|
71
|
+
}
|
|
72
|
+
|
|
61
73
|
/**
|
|
62
74
|
* Check if a comment should be preserved in to_ts mode
|
|
63
75
|
* @param {AST.CommentWithLocation} comment
|
|
@@ -65,7 +77,10 @@ export function is_jsdoc_ts_annotation(comment) {
|
|
|
65
77
|
*/
|
|
66
78
|
export function should_preserve_comment(comment) {
|
|
67
79
|
return (
|
|
68
|
-
is_ts_pragma(comment) ||
|
|
80
|
+
is_ts_pragma(comment) ||
|
|
81
|
+
is_triple_slash_directive(comment) ||
|
|
82
|
+
is_jsdoc_ts_annotation(comment) ||
|
|
83
|
+
is_jsx_pragma(comment)
|
|
69
84
|
);
|
|
70
85
|
}
|
|
71
86
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
/** @import { Visitors } from 'zimmerframe' */
|
|
3
3
|
|
|
4
4
|
import tsx from 'esrap/languages/tsx';
|
|
5
|
+
import { should_preserve_comment, format_comment } from '../../comment-utils.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Zimmerframe provides `path` as the ancestor chain. A native template node in
|
|
@@ -68,10 +69,32 @@ export function set_node_path_metadata(node, path) {
|
|
|
68
69
|
* (structural tokens carry one-character source locations). typeOnly/volar
|
|
69
70
|
* prints opt in — their maps are consumed positionally by the language
|
|
70
71
|
* tooling and never shipped; build prints stay sparse.
|
|
72
|
+
* @param {AST.CommentWithLocation[]} [comments] Source comments; the ones
|
|
73
|
+
* `should_preserve_comment` classifies as semantic-to-TS (`@ts-nocheck`,
|
|
74
|
+
* `@jsxImportSource`, triple-slash references, …) and that LEAD the program
|
|
75
|
+
* are re-emitted at the top of the printed output. The generated TSX is real
|
|
76
|
+
* TS input — dropping a leading pragma changes how the whole file checks.
|
|
71
77
|
*/
|
|
72
|
-
export function tsx_with_ts_locations(boundary_tokens = false) {
|
|
78
|
+
export function tsx_with_ts_locations(boundary_tokens = false, comments = undefined) {
|
|
73
79
|
const base = /** @type {any} */ (tsx({ boundaryTokens: boundary_tokens }));
|
|
74
80
|
|
|
81
|
+
const leading_preserved = (/** @type {any} */ program) => {
|
|
82
|
+
if (!comments?.length) return [];
|
|
83
|
+
// Injected statements (dynamic-import/try-import prepends) carry no
|
|
84
|
+
// loc; anchor "leading" on the first statement that maps to source,
|
|
85
|
+
// else every preserved comment in the file would hoist to the top.
|
|
86
|
+
const first = program.body?.find((/** @type {any} */ node) => node.loc);
|
|
87
|
+
return comments.filter(
|
|
88
|
+
(/** @type {any} */ comment) =>
|
|
89
|
+
should_preserve_comment(comment) &&
|
|
90
|
+
(first?.loc == null ||
|
|
91
|
+
(comment.loc &&
|
|
92
|
+
(comment.loc.end.line < first.loc.start.line ||
|
|
93
|
+
(comment.loc.end.line === first.loc.start.line &&
|
|
94
|
+
comment.loc.end.column <= first.loc.start.column)))),
|
|
95
|
+
);
|
|
96
|
+
};
|
|
97
|
+
|
|
75
98
|
/**
|
|
76
99
|
* @param {any} node
|
|
77
100
|
* @param {any} context
|
|
@@ -89,6 +112,15 @@ export function tsx_with_ts_locations(boundary_tokens = false) {
|
|
|
89
112
|
|
|
90
113
|
/** @type {Record<string, (node: any, context: any) => void>} */
|
|
91
114
|
const wrappers = {
|
|
115
|
+
Program: (node, context) => {
|
|
116
|
+
for (const comment of leading_preserved(node)) {
|
|
117
|
+
if (comment.loc) context.location(comment.loc.start.line, comment.loc.start.column);
|
|
118
|
+
context.write(format_comment(comment));
|
|
119
|
+
if (comment.loc) context.location(comment.loc.end.line, comment.loc.end.column);
|
|
120
|
+
context.newline();
|
|
121
|
+
}
|
|
122
|
+
base.Program(node, context);
|
|
123
|
+
},
|
|
92
124
|
ArrayPattern: (node, context) => {
|
|
93
125
|
base.ArrayPattern(node, context);
|
|
94
126
|
if (node.typeAnnotation) {
|
|
@@ -841,10 +841,20 @@ export function createJsxTransform(platform) {
|
|
|
841
841
|
: apply_lazy_transforms(/** @type {any} */ (lowered_program), new Map())
|
|
842
842
|
);
|
|
843
843
|
|
|
844
|
-
const result = print(
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
844
|
+
const result = print(
|
|
845
|
+
final_program,
|
|
846
|
+
// typeOnly output is real TS input: re-emit preserved leading comments
|
|
847
|
+
// (@jsxImportSource / @ts-nocheck / triple-slash references) so TS
|
|
848
|
+
// semantics survive the comment-stripping print.
|
|
849
|
+
tsx_with_ts_locations(
|
|
850
|
+
transform_context.typeOnly,
|
|
851
|
+
transform_context.typeOnly ? transform_context.comments : undefined,
|
|
852
|
+
),
|
|
853
|
+
{
|
|
854
|
+
sourceMapSource: filename,
|
|
855
|
+
sourceMapContent: source,
|
|
856
|
+
},
|
|
857
|
+
);
|
|
848
858
|
|
|
849
859
|
const { css, cssHash } = render_css_result(/** @type {any} */ (stylesheets));
|
|
850
860
|
|