@backtickjs/compiler 0.0.0-stage → 0.1.1

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.
Files changed (107) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +25 -2
  3. package/dist/CodeInformation.d.ts +8 -0
  4. package/dist/CodeInformation.js +2 -0
  5. package/dist/CodeInformation.js.map +1 -0
  6. package/dist/SourceRange.d.ts +4 -0
  7. package/dist/SourceRange.js +2 -0
  8. package/dist/SourceRange.js.map +1 -0
  9. package/dist/buildMappings.d.ts +10 -0
  10. package/dist/buildMappings.js +21 -0
  11. package/dist/buildMappings.js.map +1 -0
  12. package/dist/compileModule.d.ts +25 -0
  13. package/dist/compileModule.js +78 -0
  14. package/dist/compileModule.js.map +1 -0
  15. package/dist/compileScript.d.ts +24 -0
  16. package/dist/compileScript.js +66 -0
  17. package/dist/compileScript.js.map +1 -0
  18. package/dist/diagnostics.d.ts +8 -0
  19. package/dist/diagnostics.js +2 -0
  20. package/dist/diagnostics.js.map +1 -0
  21. package/dist/emitScript.d.ts +52 -0
  22. package/dist/emitScript.js +201 -0
  23. package/dist/emitScript.js.map +1 -0
  24. package/dist/emitScripts.d.ts +10 -0
  25. package/dist/emitScripts.js +23 -0
  26. package/dist/emitScripts.js.map +1 -0
  27. package/dist/flattenScripts.d.ts +2 -0
  28. package/dist/flattenScripts.js +10 -0
  29. package/dist/flattenScripts.js.map +1 -0
  30. package/dist/hashText.d.ts +1 -0
  31. package/dist/hashText.js +18 -0
  32. package/dist/hashText.js.map +1 -0
  33. package/dist/hostElements.d.ts +3 -0
  34. package/dist/hostElements.js +28 -0
  35. package/dist/hostElements.js.map +1 -0
  36. package/dist/index.d.ts +16 -0
  37. package/dist/index.js +10 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/isComponentTag.d.ts +1 -0
  40. package/dist/isComponentTag.js +15 -0
  41. package/dist/isComponentTag.js.map +1 -0
  42. package/dist/nodeFactory.d.ts +3 -0
  43. package/dist/nodeFactory.js +5 -0
  44. package/dist/nodeFactory.js.map +1 -0
  45. package/dist/parseFile.d.ts +34 -0
  46. package/dist/parseFile.js +200 -0
  47. package/dist/parseFile.js.map +1 -0
  48. package/dist/printVirtualCode.d.ts +9 -0
  49. package/dist/printVirtualCode.js +52 -0
  50. package/dist/printVirtualCode.js.map +1 -0
  51. package/dist/resolveBindings.d.ts +76 -0
  52. package/dist/resolveBindings.js +240 -0
  53. package/dist/resolveBindings.js.map +1 -0
  54. package/dist/rewriteFile.d.ts +12 -0
  55. package/dist/rewriteFile.js +22 -0
  56. package/dist/rewriteFile.js.map +1 -0
  57. package/dist/rewriteScript.d.ts +27 -0
  58. package/dist/rewriteScript.js +268 -0
  59. package/dist/rewriteScript.js.map +1 -0
  60. package/dist/segmentsToString.d.ts +9 -0
  61. package/dist/segmentsToString.js +4 -0
  62. package/dist/segmentsToString.js.map +1 -0
  63. package/dist/tagRoot.d.ts +2 -0
  64. package/dist/tagRoot.js +10 -0
  65. package/dist/tagRoot.js.map +1 -0
  66. package/dist/transform.d.ts +17 -0
  67. package/dist/transform.js +61 -0
  68. package/dist/transform.js.map +1 -0
  69. package/dist/transpile.d.ts +27 -0
  70. package/dist/transpile.js +41 -0
  71. package/dist/transpile.js.map +1 -0
  72. package/dist/unmangle.d.ts +2 -0
  73. package/dist/unmangle.js +9 -0
  74. package/dist/unmangle.js.map +1 -0
  75. package/dist/virtualScript.d.ts +22 -0
  76. package/dist/virtualScript.js +305 -0
  77. package/dist/virtualScript.js.map +1 -0
  78. package/dist/virtualize.d.ts +8 -0
  79. package/dist/virtualize.js +10 -0
  80. package/dist/virtualize.js.map +1 -0
  81. package/package.json +58 -3
  82. package/src/CodeInformation.ts +14 -0
  83. package/src/SourceRange.ts +4 -0
  84. package/src/buildMappings.ts +31 -0
  85. package/src/compileModule.ts +132 -0
  86. package/src/compileScript.ts +97 -0
  87. package/src/diagnostics.ts +9 -0
  88. package/src/emitScript.ts +297 -0
  89. package/src/emitScripts.ts +39 -0
  90. package/src/flattenScripts.ts +13 -0
  91. package/src/hashText.ts +17 -0
  92. package/src/hostElements.ts +34 -0
  93. package/src/index.ts +20 -0
  94. package/src/isComponentTag.ts +15 -0
  95. package/src/nodeFactory.ts +18 -0
  96. package/src/parseFile.ts +331 -0
  97. package/src/printVirtualCode.ts +93 -0
  98. package/src/resolveBindings.ts +417 -0
  99. package/src/rewriteFile.ts +52 -0
  100. package/src/rewriteScript.ts +413 -0
  101. package/src/segmentsToString.ts +16 -0
  102. package/src/tagRoot.ts +14 -0
  103. package/src/transform.ts +96 -0
  104. package/src/transpile.ts +49 -0
  105. package/src/unmangle.ts +10 -0
  106. package/src/virtualScript.ts +355 -0
  107. package/src/virtualize.ts +29 -0
@@ -0,0 +1,17 @@
1
+ import type ts from "typescript";
2
+ import { type Plugin } from "./compileScript.js";
3
+ export interface TransformOptions {
4
+ /**
5
+ * What a script's source map names its host file, given TypeScript's name for
6
+ * it: for a build whose file names are paths on its own machine. By default,
7
+ * TypeScript's name.
8
+ */
9
+ readonly sourceName?: (fileName: string) => string;
10
+ /**
11
+ * The framework's compile steps, run in series over each script: Solid's
12
+ * adapter's `solid()`. None by default, which leaves a script's JSX for a
13
+ * bundle's own plugins.
14
+ */
15
+ readonly plugins?: readonly Plugin[];
16
+ }
17
+ export declare function transform(ts: typeof import("typescript"), addDiagnostic?: (diagnostic: ts.Diagnostic) => void, { sourceName, plugins }?: TransformOptions): ts.TransformerFactory<ts.SourceFile>;
@@ -0,0 +1,61 @@
1
+ import { compileScript } from "./compileScript.js";
2
+ import { parseSourceFile } from "./parseFile.js";
3
+ import { rewriteFile } from "./rewriteFile.js";
4
+ import { createCall, moduleDeclaration } from "./rewriteScript.js";
5
+ export function transform(ts, addDiagnostic, { sourceName = (fileName) => fileName, plugins = [] } = {}) {
6
+ return (context) => (sourceFile) => {
7
+ const parsedFile = parseSourceFile(ts, sourceFile);
8
+ if (parsedFile.scripts.length === 0) {
9
+ return sourceFile;
10
+ }
11
+ const rewrittenFile = rewriteFile(ts, parsedFile);
12
+ if (addDiagnostic) {
13
+ for (const diagnostic of rewrittenFile.diagnostics) {
14
+ addDiagnostic({
15
+ file: sourceFile,
16
+ start: diagnostic.range.start,
17
+ length: diagnostic.range.end - diagnostic.range.start,
18
+ messageText: diagnostic.message,
19
+ category: diagnostic.category,
20
+ code: diagnostic.code,
21
+ source: "backtick",
22
+ });
23
+ }
24
+ }
25
+ // Each script as the client gets it, its module declared once for every
26
+ // run of it; one that didn't parse is left as written.
27
+ const name = sourceName(sourceFile.fileName);
28
+ const modules = [];
29
+ const byStart = new Map();
30
+ for (const [template, { runtime }] of rewrittenFile.scripts) {
31
+ if (runtime !== null) {
32
+ const compiled = compileScript(ts, runtime.emitted, name, plugins);
33
+ const moduleName = `$module${modules.length}`;
34
+ modules.push(moduleDeclaration(ts, moduleName, runtime, compiled));
35
+ byStart.set(template.getStart(rewrittenFile.sourceFile), createCall(ts, moduleName, runtime));
36
+ }
37
+ }
38
+ const visit = (node) => {
39
+ if (ts.isTaggedTemplateExpression(node) &&
40
+ ts.isIdentifier(node.tag) &&
41
+ node.tag.text === "cs" &&
42
+ node.pos >= 0) {
43
+ const runtime = byStart.get(node.getStart(rewrittenFile.sourceFile));
44
+ if (runtime) {
45
+ return ts.visitEachChild(runtime, visit, context);
46
+ }
47
+ }
48
+ return ts.visitEachChild(node, visit, context);
49
+ };
50
+ const visited = ts.visitNode(sourceFile, visit, ts.isSourceFile);
51
+ // After the imports, before anything that could run a script.
52
+ const imports = visited.statements.findIndex((statement) => !ts.isImportDeclaration(statement));
53
+ const at = imports === -1 ? visited.statements.length : imports;
54
+ return context.factory.updateSourceFile(visited, [
55
+ ...visited.statements.slice(0, at),
56
+ ...modules,
57
+ ...visited.statements.slice(at),
58
+ ]);
59
+ };
60
+ }
61
+ //# sourceMappingURL=transform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform.js","sourceRoot":"","sources":["../src/transform.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type ts from "typescript";
2
+ import { type TransformOptions } from "./transform.js";
3
+ /**
4
+ * One standalone file, run through the transform.
5
+ *
6
+ * The options are here because a file standing alone has nobody to ask for
7
+ * them. Everywhere a project is being built there is a `tsconfig.json` and the
8
+ * `tsc` and Bun plugins read the user's; this is the other case — one source,
9
+ * no project — which is what both an e2e fixture and a playground example are.
10
+ * They have to be compiled the same way for either to say anything about the
11
+ * other, and one exported function is how that stays true.
12
+ *
13
+ * `verbatimModuleSyntax` is the load-bearing option. Without it TypeScript
14
+ * elides an import the source does not appear to use — `state`, where the
15
+ * source says `$state` inside a template — while the `params` the transform
16
+ * writes still names it, and what comes out throws `state is not defined`.
17
+ *
18
+ * What comes back is a module: the imports are still imports, because the
19
+ * transform writes references to them that TypeScript has not seen and so
20
+ * cannot rewrite. A caller that needs something runnable without a module
21
+ * loader transpiles this again, to `require`/`exports`, in a second pass.
22
+ *
23
+ * `jsxImportSource` is the caller's, and the only one that is: which target a
24
+ * file draws with is not something a compiler knows, and a default here would
25
+ * be this package naming one target's package for every file it ever sees.
26
+ */
27
+ export declare function transpile(ts: typeof import("typescript"), fileName: string, sourceText: string, jsxImportSource: string, addDiagnostic?: (diagnostic: ts.Diagnostic) => void, options?: TransformOptions): string;
@@ -0,0 +1,41 @@
1
+ import { transform } from "./transform.js";
2
+ /**
3
+ * One standalone file, run through the transform.
4
+ *
5
+ * The options are here because a file standing alone has nobody to ask for
6
+ * them. Everywhere a project is being built there is a `tsconfig.json` and the
7
+ * `tsc` and Bun plugins read the user's; this is the other case — one source,
8
+ * no project — which is what both an e2e fixture and a playground example are.
9
+ * They have to be compiled the same way for either to say anything about the
10
+ * other, and one exported function is how that stays true.
11
+ *
12
+ * `verbatimModuleSyntax` is the load-bearing option. Without it TypeScript
13
+ * elides an import the source does not appear to use — `state`, where the
14
+ * source says `$state` inside a template — while the `params` the transform
15
+ * writes still names it, and what comes out throws `state is not defined`.
16
+ *
17
+ * What comes back is a module: the imports are still imports, because the
18
+ * transform writes references to them that TypeScript has not seen and so
19
+ * cannot rewrite. A caller that needs something runnable without a module
20
+ * loader transpiles this again, to `require`/`exports`, in a second pass.
21
+ *
22
+ * `jsxImportSource` is the caller's, and the only one that is: which target a
23
+ * file draws with is not something a compiler knows, and a default here would
24
+ * be this package naming one target's package for every file it ever sees.
25
+ */
26
+ export function transpile(ts, fileName, sourceText, jsxImportSource, addDiagnostic, options) {
27
+ const { outputText } = ts.transpileModule(sourceText, {
28
+ fileName,
29
+ compilerOptions: {
30
+ target: ts.ScriptTarget.ESNext,
31
+ module: ts.ModuleKind.ESNext,
32
+ jsx: ts.JsxEmit.ReactJSX,
33
+ jsxImportSource,
34
+ sourceMap: false,
35
+ verbatimModuleSyntax: true,
36
+ },
37
+ transformers: { before: [transform(ts, addDiagnostic, options)] },
38
+ });
39
+ return outputText;
40
+ }
41
+ //# sourceMappingURL=transpile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transpile.js","sourceRoot":"","sources":["../src/transpile.ts"],"names":[],"mappings":"AACA,OAAO,EAAyB,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAElE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,SAAS,CACvB,EAA+B,EAC/B,QAAgB,EAChB,UAAkB,EAClB,eAAuB,EACvB,aAAmD,EACnD,OAA0B;IAE1B,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,UAAU,EAAE;QACpD,QAAQ;QACR,eAAe,EAAE;YACf,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM;YAC9B,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM;YAC5B,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ;YACxB,eAAe;YACf,SAAS,EAAE,KAAK;YAChB,oBAAoB,EAAE,IAAI;SAC3B;QACD,YAAY,EAAE,EAAE,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC,EAAE;KAClE,CAAC,CAAC;IACH,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function mangle(identifier: string): string;
2
+ export declare function unmangle(text: string): string;
@@ -0,0 +1,9 @@
1
+ // The prefix the compiler adds to client-script identifiers when virtualizing.
2
+ const CS_PREFIX = "__cs_";
3
+ export function mangle(identifier) {
4
+ return `${CS_PREFIX}${identifier}`;
5
+ }
6
+ export function unmangle(text) {
7
+ return text.replaceAll(CS_PREFIX, "");
8
+ }
9
+ //# sourceMappingURL=unmangle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unmangle.js","sourceRoot":"","sources":["../src/unmangle.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,SAAS,GAAG,OAAO,CAAC;AAE1B,MAAM,UAAU,MAAM,CAAC,UAAkB;IACvC,OAAO,GAAG,SAAS,GAAG,UAAU,EAAE,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;AACxC,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { ClientScript, Splice } from "./parseFile.js";
2
+ import type { BindingResolution } from "./resolveBindings.js";
3
+ import type { Segment } from "./segmentsToString.js";
4
+ /**
5
+ * A script as the typechecker reads it: its own text, as written, wrapped as
6
+ * `cs.lift((() => …)())`, edited only where a name means something else on
7
+ * the client.
8
+ *
9
+ * - its own binding, renamed (`x` to `__cs_x`), so it can't hide a host binding
10
+ * a splice names; a shorthand keeps its property name (`x: __cs_x`)
11
+ * - a name nothing declares, read as the client's global (`cs.globalThis.x`)
12
+ * - a splice, as the host value the client is handed: `$x` as
13
+ * `cs.splice((x))`, `${…}` as `cs.splice(…)` around the host code
14
+ * - a splice written as a tag, `<$Card>`, as JSX on a name the host value is
15
+ * handed to: `(($Card) => <$Card …>…</$Card>)(cs.splice((Card)))`, and
16
+ * `(void (Card), …)` where it closes, for the closing tag's name
17
+ *
18
+ * Everything else, types included, is TypeScript's to read as written. Each
19
+ * piece maps back to the text it came from; what the wrapper adds maps to no
20
+ * editor feature.
21
+ */
22
+ export declare function virtualScript(ts: typeof import("typescript"), script: ClientScript, bindings: BindingResolution, awaits: boolean, renderSplice: (splice: Splice) => Segment[]): Segment[];
@@ -0,0 +1,305 @@
1
+ import { tagRoot } from "./tagRoot.js";
2
+ import { mangle } from "./unmangle.js";
3
+ // What the editor reads through a wrapper the virtual code adds: nothing.
4
+ const WRAPPER = { semantic: false, navigation: false };
5
+ // What it reads through a name the virtual code adds over a span of the
6
+ // script: only what is reported there. Hover and navigation stay with the
7
+ // script's own names inside it.
8
+ const REPORTED = { semantic: false, navigation: false };
9
+ // A host tag's name, written as a value: everything but its color, which stays
10
+ // the tag's, as JSX colors it.
11
+ const TAG_NAME = {
12
+ semantic: { shouldHighlight: () => false },
13
+ };
14
+ /**
15
+ * A script as the typechecker reads it: its own text, as written, wrapped as
16
+ * `cs.lift((() => …)())`, edited only where a name means something else on
17
+ * the client.
18
+ *
19
+ * - its own binding, renamed (`x` to `__cs_x`), so it can't hide a host binding
20
+ * a splice names; a shorthand keeps its property name (`x: __cs_x`)
21
+ * - a name nothing declares, read as the client's global (`cs.globalThis.x`)
22
+ * - a splice, as the host value the client is handed: `$x` as
23
+ * `cs.splice((x))`, `${…}` as `cs.splice(…)` around the host code
24
+ * - a splice written as a tag, `<$Card>`, as JSX on a name the host value is
25
+ * handed to: `(($Card) => <$Card …>…</$Card>)(cs.splice((Card)))`, and
26
+ * `(void (Card), …)` where it closes, for the closing tag's name
27
+ *
28
+ * Everything else, types included, is TypeScript's to read as written. Each
29
+ * piece maps back to the text it came from; what the wrapper adds maps to no
30
+ * editor feature.
31
+ */
32
+ export function virtualScript(ts, script, bindings, awaits, renderSplice) {
33
+ const file = script.fileWithPlaceholders;
34
+ const text = script.textWithPlaceholders;
35
+ const out = [];
36
+ const verbatim = (from, to) => {
37
+ if (to > from) {
38
+ out.push([
39
+ text.slice(from, to),
40
+ undefined,
41
+ script.toSourceOffset(from),
42
+ to - from,
43
+ ]);
44
+ }
45
+ };
46
+ const mapped = (written, node, data) => {
47
+ const { start, end } = script.toSourceRange(node);
48
+ out.push(data === undefined
49
+ ? [written, undefined, start, end - start]
50
+ : [written, undefined, start, end - start, data]);
51
+ };
52
+ // Text the virtual code adds, reported at `at` in the host file if at all.
53
+ const added = (written, at, data = WRAPPER) => {
54
+ out.push(at === undefined ? written : [written, undefined, at, 0, data]);
55
+ };
56
+ const emit = (node, from = node.getStart(file)) => {
57
+ if (ts.isIdentifier(node)) {
58
+ identifier(node);
59
+ return;
60
+ }
61
+ if ((ts.isJsxElement(node) || ts.isJsxSelfClosingElement(node)) &&
62
+ isHostTag(node)) {
63
+ hostTag(node);
64
+ return;
65
+ }
66
+ const children = node.getChildren(file);
67
+ if (children.length === 0) {
68
+ verbatim(from, node.getEnd());
69
+ return;
70
+ }
71
+ let at = from;
72
+ for (const child of children) {
73
+ if (child.getEnd() <= at) {
74
+ continue;
75
+ }
76
+ verbatim(at, child.getStart(file));
77
+ emit(child);
78
+ at = child.getEnd();
79
+ }
80
+ verbatim(at, node.getEnd());
81
+ };
82
+ const identifier = (node) => {
83
+ if (inTypePosition(ts, node)) {
84
+ verbatim(node.getStart(file), node.getEnd());
85
+ return;
86
+ }
87
+ const splice = script.splices[node.text];
88
+ if (splice !== undefined && splice.refs.includes(node)) {
89
+ // Parenthesized whole, so what it stands in reads it as one value: in
90
+ // `new $Animated.Value(0)`, `new` takes `$Animated.Value`, not the call.
91
+ const range = script.toSourceRange(node);
92
+ if (splice.kind === "braced") {
93
+ added("(cs.splice(", splice.expression.getStart(script.sourceFile));
94
+ out.push(...renderSplice(splice));
95
+ added("))", splice.expression.getEnd());
96
+ }
97
+ else {
98
+ // The name parenthesized too, as 1-char padding: `(count)` against
99
+ // `$count` starts the name where it follows the sigil, so a
100
+ // completion's replacement span round-trips to the bare name.
101
+ added("(cs.splice(", range.start);
102
+ mapped(`(${splice.expression.text})`, node);
103
+ added("))", range.end);
104
+ }
105
+ return;
106
+ }
107
+ const parent = node.parent;
108
+ const shorthand = (ts.isShorthandPropertyAssignment(parent) && parent.name === node) ||
109
+ (ts.isBindingElement(parent) &&
110
+ parent.name === node &&
111
+ parent.propertyName === undefined &&
112
+ parent.dotDotDotToken === undefined &&
113
+ ts.isObjectBindingPattern(parent.parent));
114
+ if (bindings.has(node)) {
115
+ if (shorthand) {
116
+ mapped(node.text, node);
117
+ added(": ");
118
+ }
119
+ mapped(mangle(node.text), node);
120
+ return;
121
+ }
122
+ if (node.text !== "undefined" && isReference(ts, node)) {
123
+ if (shorthand) {
124
+ mapped(node.text, node);
125
+ added(": ");
126
+ }
127
+ added("cs.globalThis.");
128
+ mapped(node.text, node);
129
+ return;
130
+ }
131
+ verbatim(node.getStart(file), node.getEnd());
132
+ };
133
+ // A tag that splices a host value, `<$Card>`, which the client is handed
134
+ // as a component.
135
+ const isHostTag = (node) => {
136
+ const root = tagRoot(ts, ts.isJsxElement(node) ? node.openingElement.tagName : node.tagName);
137
+ return (root !== undefined &&
138
+ script.splices[root.text]?.refs.includes(root) === true);
139
+ };
140
+ // A host tag is checked as JSX, as a tag is anywhere: on a parameter the
141
+ // host value is handed to, `(($Card) => <$Card …>…</$Card>)(cs.splice((Card)))`.
142
+ // JSX then checks it however the component is declared (a class, generic,
143
+ // overloaded) and allows what the framework allows on any tag (React's
144
+ // `key`). Its props and children are written as they were. The parameter
145
+ // takes the tag's written name, which a script can't otherwise bind, so an
146
+ // error about the tag names it as written, and is reported there; the name
147
+ // itself is read through `(Card)`, mapped to it, so definition, rename and
148
+ // references reach the host binding. Where the tag closes, `void (Card)`
149
+ // beside it does the same for the closing tag's name.
150
+ const hostTag = (node) => {
151
+ const opening = ts.isJsxElement(node) ? node.openingElement : node;
152
+ const tagName = opening.tagName;
153
+ // What the tag starts with, `$Card`, or `$Animated` in `<$Animated.View>`:
154
+ // the splice. The rest, `.View`, is written as it was.
155
+ const root = tagRoot(ts, tagName);
156
+ const tag = script.toSourceRange(root);
157
+ // The binding's name, parenthesized over its `$` as an unbraced splice is.
158
+ const name = `(${script.splices[root.text].expression.text})`;
159
+ // Where JSX stands, an expression is written in braces: a child of an
160
+ // element or fragment, or an attribute's value.
161
+ const parent = node.parent;
162
+ const braced = ts.isJsxAttribute(parent) ||
163
+ ts.isJsxElement(parent) ||
164
+ ts.isJsxFragment(parent);
165
+ if (braced) {
166
+ added("{");
167
+ }
168
+ const closing = ts.isJsxElement(node)
169
+ ? tagRoot(ts, node.closingElement.tagName)
170
+ : undefined;
171
+ if (closing !== undefined) {
172
+ added("(void ");
173
+ mapped(name, closing, TAG_NAME);
174
+ added(", ");
175
+ }
176
+ added(`((${root.text}) => <`);
177
+ mapped(root.text, root, REPORTED);
178
+ verbatim(root.getEnd(), tagName.getEnd());
179
+ // Its attributes and the opening's end, as written. What stands between
180
+ // the name and the first attribute maps to nothing: the end of the name is
181
+ // the name's, not the attribute's.
182
+ let at = tagName.getEnd();
183
+ for (const [index, attribute] of opening.attributes.properties.entries()) {
184
+ if (index === 0) {
185
+ added(text.slice(at, attribute.getStart(file)));
186
+ }
187
+ else {
188
+ verbatim(at, attribute.getStart(file));
189
+ }
190
+ emit(attribute);
191
+ at = attribute.getEnd();
192
+ }
193
+ if (opening.attributes.properties.length === 0) {
194
+ added(text.slice(at, opening.getEnd()));
195
+ }
196
+ else {
197
+ verbatim(at, opening.getEnd());
198
+ }
199
+ if (ts.isJsxElement(node)) {
200
+ at = opening.getEnd();
201
+ for (const child of node.children) {
202
+ verbatim(at, child.getStart(file));
203
+ emit(child);
204
+ at = child.getEnd();
205
+ }
206
+ verbatim(at, node.closingElement.getStart(file));
207
+ added("</");
208
+ mapped(root.text, closing, REPORTED);
209
+ verbatim(closing.getEnd(), node.closingElement.tagName.getEnd());
210
+ added(">");
211
+ }
212
+ added(")(cs.splice(", tag.start);
213
+ mapped(name, tagName, TAG_NAME);
214
+ added("))", tag.end);
215
+ if (ts.isJsxElement(node)) {
216
+ added(")");
217
+ }
218
+ if (braced) {
219
+ added("}");
220
+ }
221
+ };
222
+ // The wrapper the script is checked in, mapped to what it stands for: its
223
+ // opening to `cs\``, its close to the closing backtick, so where it meets the
224
+ // script is where the script starts and ends. No editor feature reads
225
+ // through it.
226
+ const tag = script.sourceNode.getStart(script.sourceFile);
227
+ const opened = script.sourceNode.template.getStart(script.sourceFile) + 1;
228
+ const closed = script.sourceNode.getEnd() - 1;
229
+ out.push([
230
+ awaits ? "cs.lift(await (async () => " : "cs.lift((() => ",
231
+ undefined,
232
+ tag,
233
+ opened - tag,
234
+ WRAPPER,
235
+ ]);
236
+ emit(file, 0);
237
+ out.push([")())", undefined, closed, 1, WRAPPER]);
238
+ return out;
239
+ }
240
+ // Whether a name is read as a value where it stands, rather than naming a
241
+ // property, an attribute, a label or what a declaration declares.
242
+ function isReference(ts, node) {
243
+ const parent = node.parent;
244
+ if ((ts.isPropertyAccessExpression(parent) ||
245
+ ts.isPropertyAssignment(parent) ||
246
+ ts.isMethodDeclaration(parent) ||
247
+ ts.isPropertyDeclaration(parent) ||
248
+ ts.isGetAccessorDeclaration(parent) ||
249
+ ts.isSetAccessorDeclaration(parent) ||
250
+ ts.isPropertySignature(parent) ||
251
+ ts.isMethodSignature(parent) ||
252
+ ts.isEnumMember(parent) ||
253
+ ts.isJsxAttribute(parent) ||
254
+ ts.isVariableDeclaration(parent) ||
255
+ ts.isParameter(parent) ||
256
+ ts.isFunctionDeclaration(parent) ||
257
+ ts.isFunctionExpression(parent) ||
258
+ ts.isClassDeclaration(parent) ||
259
+ ts.isClassExpression(parent) ||
260
+ ts.isTypeAliasDeclaration(parent) ||
261
+ ts.isInterfaceDeclaration(parent) ||
262
+ ts.isEnumDeclaration(parent) ||
263
+ ts.isTypeParameterDeclaration(parent)) &&
264
+ parent.name === node) {
265
+ return false;
266
+ }
267
+ if (ts.isBindingElement(parent)) {
268
+ return false; // its name declares, its property name names a property
269
+ }
270
+ if ((ts.isLabeledStatement(parent) ||
271
+ ts.isBreakStatement(parent) ||
272
+ ts.isContinueStatement(parent)) &&
273
+ parent.label === node) {
274
+ return false;
275
+ }
276
+ if ((ts.isJsxOpeningElement(parent) ||
277
+ ts.isJsxSelfClosingElement(parent) ||
278
+ ts.isJsxClosingElement(parent)) &&
279
+ parent.tagName === node) {
280
+ return false; // an intrinsic element's name, or a host tag's (above)
281
+ }
282
+ return !(ts.isQualifiedName(parent) ||
283
+ ts.isMetaProperty(parent) ||
284
+ ts.isJsxNamespacedName(parent));
285
+ }
286
+ // Whether a name stands in a type, which names types rather than values: all
287
+ // but what a `typeof` reads, and a class's `extends`.
288
+ function inTypePosition(ts, node) {
289
+ for (let at = node; at.parent !== undefined; at = at.parent) {
290
+ const parent = at.parent;
291
+ if (ts.isTypeQueryNode(parent)) {
292
+ return false;
293
+ }
294
+ if (ts.isExpressionWithTypeArguments(parent) &&
295
+ ts.isHeritageClause(parent.parent) &&
296
+ ts.isClassLike(parent.parent.parent)) {
297
+ return false;
298
+ }
299
+ if (ts.isTypeNode(parent)) {
300
+ return true;
301
+ }
302
+ }
303
+ return false;
304
+ }
305
+ //# sourceMappingURL=virtualScript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtualScript.js","sourceRoot":"","sources":["../src/virtualScript.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { SourceMapping } from "./buildMappings.js";
2
+ import type { Diagnostic } from "./diagnostics.js";
3
+ export interface Virtualized {
4
+ virtualCode: string;
5
+ mappings: SourceMapping[];
6
+ diagnostics: Diagnostic[];
7
+ }
8
+ export declare function virtualize(ts: typeof import("typescript"), filePath: string, sourceText: string): Virtualized;
@@ -0,0 +1,10 @@
1
+ import { parseSourceText } from "./parseFile.js";
2
+ import { printVirtualCode } from "./printVirtualCode.js";
3
+ import { rewriteFile } from "./rewriteFile.js";
4
+ export function virtualize(ts, filePath, sourceText) {
5
+ const parsedFile = parseSourceText(ts, filePath, sourceText);
6
+ const rewrittenFile = rewriteFile(ts, parsedFile);
7
+ const { virtualCode, mappings } = printVirtualCode(ts, parsedFile, rewrittenFile);
8
+ return { virtualCode, mappings, diagnostics: rewrittenFile.diagnostics };
9
+ }
10
+ //# sourceMappingURL=virtualize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtualize.js","sourceRoot":"","sources":["../src/virtualize.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAQ/C,MAAM,UAAU,UAAU,CACxB,EAA+B,EAC/B,QAAgB,EAChB,UAAkB;IAElB,MAAM,UAAU,GAAG,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IAE7D,MAAM,aAAa,GAAG,WAAW,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;IAElD,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,gBAAgB,CAChD,EAAE,EACF,UAAU,EACV,aAAa,CACd,CAAC;IAEF,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,CAAC,WAAW,EAAE,CAAC;AAC3E,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,61 @@
1
1
  {
2
2
  "name": "@backtickjs/compiler",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.1",
4
+ "description": "Internal: the compiler for Backtick client scripts, used by the build plugins, backtick-tsc and the editor tooling",
5
+ "keywords": [
6
+ "backtick",
7
+ "react-native",
8
+ "server-driven-ui",
9
+ "server-components",
10
+ "compiler",
11
+ "typescript"
12
+ ],
13
+ "homepage": "https://backtickjs.com",
14
+ "bugs": {
15
+ "url": "https://github.com/backtickjs/backtick/issues"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/backtickjs/backtick.git",
20
+ "directory": "packages/compiler"
21
+ },
22
+ "license": "MIT",
23
+ "author": "Jean-François Bisson <jf@backtickjs.com>",
24
+ "type": "module",
25
+ "main": "./dist/index.js",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "default": "./dist/index.js"
30
+ }
31
+ },
32
+ "files": [
33
+ "dist",
34
+ "!dist/._cache",
35
+ "src"
36
+ ],
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "peerDependencies": {
41
+ "typescript": "^6.0.3"
42
+ },
43
+ "dependencies": {
44
+ "@jridgewell/gen-mapping": "^0.3.13",
45
+ "@jridgewell/remapping": "^2.3.5",
46
+ "@jridgewell/trace-mapping": "^0.3.31"
47
+ },
48
+ "devDependencies": {
49
+ "prettier": "^3.6.2",
50
+ "typescript": "^6.0.3",
51
+ "@backtickjs/core": "0.1.1"
52
+ },
53
+ "scripts": {
54
+ "build": "tsc -b",
55
+ "dev": "tsc -b --watch",
56
+ "format": "prettier --write --ignore-unknown .",
57
+ "format:check": "prettier --check --ignore-unknown .",
58
+ "test": "node --test \"test/**/*.test.ts\"",
59
+ "clean": "rm -rf node_modules dist .turbo"
60
+ }
6
61
  }
@@ -0,0 +1,14 @@
1
+ // The subset of Volar's `CodeInformation` the compiler emits on its
2
+ // mappings; the language plugin layers the remaining feature flags on top.
3
+ export interface CodeInformation {
4
+ // gates hover and the other semantic features for positions resolving
5
+ // through the mapping; as an object, all of them but highlighting
6
+ semantic: boolean | { shouldHighlight(): boolean };
7
+ // gates completions for positions resolving through the mapping
8
+ completion?: boolean;
9
+ // gates go-to-definition, references, and rename for positions resolving
10
+ // through the mapping
11
+ navigation?: boolean;
12
+ // gates diagnostics resolving through the mapping
13
+ verification?: boolean;
14
+ }
@@ -0,0 +1,4 @@
1
+ export interface SourceRange {
2
+ readonly start: number;
3
+ readonly end: number;
4
+ }