@vobs/compiler 1.1.0 → 1.2.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.
- package/dist/compile.cjs +1149 -0
- package/dist/compile.cjs.map +1 -0
- package/dist/compile.d.cts +8 -0
- package/dist/compile.d.ts +8 -0
- package/dist/compile.js +1141 -0
- package/dist/compile.js.map +1 -0
- package/dist/i18n-extractor.cjs +51 -0
- package/dist/i18n-extractor.cjs.map +1 -0
- package/dist/i18n-extractor.d.cts +16 -0
- package/dist/i18n-extractor.d.ts +16 -0
- package/dist/i18n-extractor.js +45 -0
- package/dist/i18n-extractor.js.map +1 -0
- package/dist/index.cjs +1187 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +1178 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.cjs +4 -0
- package/dist/plugin.cjs.map +1 -0
- package/dist/plugin.d.cts +70 -0
- package/dist/plugin.d.ts +70 -0
- package/dist/plugin.js +3 -0
- package/dist/plugin.js.map +1 -0
- package/package.json +30 -6
- package/src/compile.test.ts +32 -0
- package/src/compile.ts +81 -6
package/dist/compile.cjs
ADDED
|
@@ -0,0 +1,1149 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var ts = require('typescript');
|
|
4
|
+
var error = require('@vobs/runtime/error');
|
|
5
|
+
|
|
6
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
|
|
8
|
+
var ts__default = /*#__PURE__*/_interopDefault(ts);
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
12
|
+
function createCompiler(options = {}) {
|
|
13
|
+
const basePlugins = options.plugins ?? [];
|
|
14
|
+
return {
|
|
15
|
+
compile(code, overrides = {}) {
|
|
16
|
+
return compile(code, {
|
|
17
|
+
...overrides,
|
|
18
|
+
plugins: [...basePlugins, ...overrides.plugins ?? []]
|
|
19
|
+
});
|
|
20
|
+
},
|
|
21
|
+
compileWithSourceMap(code, overrides = {}) {
|
|
22
|
+
return compileWithSourceMap(code, {
|
|
23
|
+
...overrides,
|
|
24
|
+
plugins: [...basePlugins, ...overrides.plugins ?? []]
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
__name(createCompiler, "createCompiler");
|
|
30
|
+
function compile(code, options = {}) {
|
|
31
|
+
const result = compileWithSourceMap(code, options);
|
|
32
|
+
const firstError = result.diagnostics.find((diagnostic) => diagnostic.severity === "error");
|
|
33
|
+
if (firstError) {
|
|
34
|
+
throw new error.VobsError({
|
|
35
|
+
code: firstError.code,
|
|
36
|
+
layer: "compiler",
|
|
37
|
+
message: firstError.message,
|
|
38
|
+
location: firstError.location,
|
|
39
|
+
codeFrame: firstError.codeFrame,
|
|
40
|
+
fix: firstError.fix
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return result.code;
|
|
44
|
+
}
|
|
45
|
+
__name(compile, "compile");
|
|
46
|
+
function compileWithSourceMap(code, options = {}) {
|
|
47
|
+
const filename = options.filename ?? "component.tsx";
|
|
48
|
+
let sourceFile = ts__default.default.createSourceFile(
|
|
49
|
+
filename,
|
|
50
|
+
code,
|
|
51
|
+
ts__default.default.ScriptTarget.Latest,
|
|
52
|
+
true,
|
|
53
|
+
ts__default.default.ScriptKind.TSX
|
|
54
|
+
);
|
|
55
|
+
const state = {
|
|
56
|
+
generatedId: 0,
|
|
57
|
+
filename,
|
|
58
|
+
sourceFile,
|
|
59
|
+
statementSources: /* @__PURE__ */ new WeakMap(),
|
|
60
|
+
takenNames: collectDeclaredNames(sourceFile),
|
|
61
|
+
helperAliases: /* @__PURE__ */ new Map(),
|
|
62
|
+
templates: /* @__PURE__ */ new Map(),
|
|
63
|
+
sourceLocation: options.sourceLocation ?? true,
|
|
64
|
+
stateAliases: collectStateAliases(sourceFile),
|
|
65
|
+
localBindings: collectLocallyDeclaredNames(sourceFile),
|
|
66
|
+
diagnostics: []
|
|
67
|
+
};
|
|
68
|
+
const cleanFilename = filename.split(/[?#]/u, 1)[0] || filename;
|
|
69
|
+
const diagnostics = ts__default.default.transpileModule(code, {
|
|
70
|
+
// Vite appends query strings (for example `?direct`) to module IDs;
|
|
71
|
+
// strip them so TypeScript still recognizes TSX syntax for diagnostics.
|
|
72
|
+
fileName: cleanFilename,
|
|
73
|
+
reportDiagnostics: true,
|
|
74
|
+
compilerOptions: { jsx: ts__default.default.JsxEmit.Preserve, target: ts__default.default.ScriptTarget.Latest }
|
|
75
|
+
}).diagnostics?.map((diagnostic) => toCompilerDiagnostic(diagnostic, sourceFile, cleanFilename)) ?? [];
|
|
76
|
+
const plugins = options.plugins ?? [];
|
|
77
|
+
validatePlugins(plugins);
|
|
78
|
+
const context = {
|
|
79
|
+
filename,
|
|
80
|
+
factory: ts__default.default.factory,
|
|
81
|
+
addRuntimeImport(name) {
|
|
82
|
+
resolveHelperName(state, name);
|
|
83
|
+
},
|
|
84
|
+
helperRef: /* @__PURE__ */ __name((name) => helperRef(state, name), "helperRef")
|
|
85
|
+
};
|
|
86
|
+
for (const plugin of plugins) plugin.analyze?.(sourceFile, context);
|
|
87
|
+
for (const plugin of plugins) {
|
|
88
|
+
sourceFile = plugin.transform?.program?.(sourceFile, context) ?? sourceFile;
|
|
89
|
+
}
|
|
90
|
+
for (const plugin of plugins) sourceFile = transformPluginNodes(sourceFile, plugin, context);
|
|
91
|
+
const statements = sourceFile.statements.map(
|
|
92
|
+
(statement) => ts__default.default.isImportDeclaration(statement) ? rebuildImport(state, statement) : transformStatement(state, statement)
|
|
93
|
+
);
|
|
94
|
+
const templateDeclarations = createTemplateDeclarations(state);
|
|
95
|
+
const resultFile = ts__default.default.factory.updateSourceFile(sourceFile, [
|
|
96
|
+
...createRuntimeImports(state),
|
|
97
|
+
...templateDeclarations,
|
|
98
|
+
...statements
|
|
99
|
+
]);
|
|
100
|
+
const generated = ts__default.default.createPrinter().printFile(resultFile);
|
|
101
|
+
return {
|
|
102
|
+
code: generated,
|
|
103
|
+
map: buildSourceMap(state, filename, code, generated, resultFile),
|
|
104
|
+
diagnostics: [...diagnostics, ...state.diagnostics]
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
__name(compileWithSourceMap, "compileWithSourceMap");
|
|
108
|
+
function toCompilerDiagnostic(diagnostic, sourceFile, filename) {
|
|
109
|
+
const start = diagnostic.start ?? 0;
|
|
110
|
+
const length = diagnostic.length ?? 1;
|
|
111
|
+
const message = ts__default.default.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
|
|
112
|
+
const { line, column, codeFrame } = buildCodeFrame(sourceFile, start, length);
|
|
113
|
+
return {
|
|
114
|
+
code: `VOBS_C${String(diagnostic.code).padStart(3, "0")}`,
|
|
115
|
+
severity: diagnostic.category === ts__default.default.DiagnosticCategory.Warning ? "warning" : "error",
|
|
116
|
+
message,
|
|
117
|
+
location: { file: filename, line, column },
|
|
118
|
+
codeFrame
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
__name(toCompilerDiagnostic, "toCompilerDiagnostic");
|
|
122
|
+
function buildCodeFrame(sourceFile, start, length) {
|
|
123
|
+
const position = sourceFile.getLineAndCharacterOfPosition(start);
|
|
124
|
+
const lineText = sourceFile.text.split(/\r?\n/u)[position.line] ?? "";
|
|
125
|
+
const markerLength = Math.max(1, Math.min(length, Math.max(1, lineText.length - position.character)));
|
|
126
|
+
return {
|
|
127
|
+
line: position.line + 1,
|
|
128
|
+
column: position.character + 1,
|
|
129
|
+
codeFrame: `${position.line + 1} | ${lineText}
|
|
130
|
+
${" ".repeat(String(position.line + 1).length + 3 + position.character)}${"^".repeat(markerLength)}`
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
__name(buildCodeFrame, "buildCodeFrame");
|
|
134
|
+
function reportUnsupportedTag(state, tagName) {
|
|
135
|
+
const sourceFile = tagName.getSourceFile() ?? state.sourceFile;
|
|
136
|
+
if (!sourceFile) return;
|
|
137
|
+
const label = tagName.getText();
|
|
138
|
+
const kindNote = tagName.kind === ts__default.default.SyntaxKind.JsxNamespacedName ? "\uFF08JSX \u547D\u540D\u7A7A\u95F4\u6807\u7B7E\uFF09" : "";
|
|
139
|
+
const { line, column, codeFrame } = buildCodeFrame(sourceFile, tagName.getStart(sourceFile), tagName.getWidth(sourceFile));
|
|
140
|
+
state.diagnostics.push({
|
|
141
|
+
code: "VOBS_C101",
|
|
142
|
+
severity: "error",
|
|
143
|
+
message: `\u4E0D\u652F\u6301\u7684 JSX \u6807\u7B7E\u5F62\u6001\uFF1A<${label}>${kindNote}\u3002\u7EC4\u4EF6\u5FC5\u987B\u662F\u5927\u5199\u5F00\u5934\u7684\u6807\u8BC6\u7B26\uFF0CDOM \u5143\u7D20\u5FC5\u987B\u662F\u5C0F\u5199\u6807\u7B7E\u540D\u3002`,
|
|
144
|
+
location: { file: state.filename, line, column },
|
|
145
|
+
codeFrame,
|
|
146
|
+
fix: `\u628A <${label}> \u6539\u4E3A <Component /> \u5F62\u5F0F\u7684\u7EC4\u4EF6\u6216\u5C0F\u5199 DOM \u6807\u7B7E\uFF1BFragment \u8BF7\u4F7F\u7528 <Fragment> \u6216 <>...</>\u3002`
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
__name(reportUnsupportedTag, "reportUnsupportedTag");
|
|
150
|
+
function buildSourceMap(state, filename, source, generated, resultFile) {
|
|
151
|
+
const reparsed = ts__default.default.createSourceFile(filename, generated, ts__default.default.ScriptTarget.Latest, true, ts__default.default.ScriptKind.TSX);
|
|
152
|
+
const segments = [];
|
|
153
|
+
walkPairedTrees(state, resultFile, reparsed, reparsed, segments);
|
|
154
|
+
segments.sort((a, b) => a.genLine - b.genLine || a.genCol - b.genCol);
|
|
155
|
+
return {
|
|
156
|
+
version: 3,
|
|
157
|
+
file: filename,
|
|
158
|
+
sources: [filename],
|
|
159
|
+
sourcesContent: [source],
|
|
160
|
+
names: [],
|
|
161
|
+
mappings: encodeMappings(segments, generated.split("\n").length)
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
__name(buildSourceMap, "buildSourceMap");
|
|
165
|
+
function statementLists(node) {
|
|
166
|
+
if (ts__default.default.isSourceFile(node) || ts__default.default.isBlock(node) || ts__default.default.isModuleBlock(node)) return node.statements;
|
|
167
|
+
if (ts__default.default.isCaseClause(node) || ts__default.default.isDefaultClause(node)) return node.statements;
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
__name(statementLists, "statementLists");
|
|
171
|
+
function walkPairedTrees(state, original, generated, reparsed, segments) {
|
|
172
|
+
const originalStatements = statementLists(original);
|
|
173
|
+
const generatedStatements = statementLists(generated);
|
|
174
|
+
if (originalStatements && generatedStatements) {
|
|
175
|
+
if (originalStatements.length !== generatedStatements.length) return;
|
|
176
|
+
for (let index = 0; index < originalStatements.length; index++) {
|
|
177
|
+
const originalStatement = originalStatements[index];
|
|
178
|
+
const generatedStatement = generatedStatements[index];
|
|
179
|
+
recordSegment(state, originalStatement, generatedStatement, reparsed, segments);
|
|
180
|
+
walkPairedTrees(state, originalStatement, generatedStatement, reparsed, segments);
|
|
181
|
+
}
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const originalChildren = [];
|
|
185
|
+
const generatedChildren = [];
|
|
186
|
+
ts__default.default.forEachChild(original, (node) => {
|
|
187
|
+
originalChildren.push(node);
|
|
188
|
+
});
|
|
189
|
+
ts__default.default.forEachChild(generated, (node) => {
|
|
190
|
+
generatedChildren.push(node);
|
|
191
|
+
});
|
|
192
|
+
if (originalChildren.length !== generatedChildren.length) return;
|
|
193
|
+
for (let index = 0; index < originalChildren.length; index++) {
|
|
194
|
+
walkPairedTrees(state, originalChildren[index], generatedChildren[index], reparsed, segments);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
__name(walkPairedTrees, "walkPairedTrees");
|
|
198
|
+
function recordSegment(state, originalStatement, generatedStatement, reparsed, segments) {
|
|
199
|
+
const source = state.statementSources.get(originalStatement) ?? positionOfOriginalStatement(state, originalStatement);
|
|
200
|
+
if (!source) return;
|
|
201
|
+
const position = reparsed.getLineAndCharacterOfPosition(generatedStatement.getStart(reparsed));
|
|
202
|
+
segments.push({
|
|
203
|
+
genLine: position.line,
|
|
204
|
+
genCol: position.character,
|
|
205
|
+
srcLine: source.line,
|
|
206
|
+
srcCol: source.column
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
__name(recordSegment, "recordSegment");
|
|
210
|
+
function positionOfOriginalStatement(state, statement) {
|
|
211
|
+
if (statement.pos < 0 || !state.sourceFile) return null;
|
|
212
|
+
const { line, character } = state.sourceFile.getLineAndCharacterOfPosition(
|
|
213
|
+
statement.getStart(state.sourceFile)
|
|
214
|
+
);
|
|
215
|
+
return { line, column: character };
|
|
216
|
+
}
|
|
217
|
+
__name(positionOfOriginalStatement, "positionOfOriginalStatement");
|
|
218
|
+
function encodeMappings(segments, lineCount) {
|
|
219
|
+
const lines = Array.from({ length: lineCount }, () => []);
|
|
220
|
+
let prevGenLine = -1;
|
|
221
|
+
let prevGenCol = 0;
|
|
222
|
+
let prevSrcLine = 0;
|
|
223
|
+
let prevSrcCol = 0;
|
|
224
|
+
for (const segment of segments) {
|
|
225
|
+
if (segment.genLine !== prevGenLine) {
|
|
226
|
+
prevGenCol = 0;
|
|
227
|
+
prevGenLine = segment.genLine;
|
|
228
|
+
}
|
|
229
|
+
const values = [
|
|
230
|
+
segment.genCol - prevGenCol,
|
|
231
|
+
0,
|
|
232
|
+
segment.srcLine - prevSrcLine,
|
|
233
|
+
segment.srcCol - prevSrcCol
|
|
234
|
+
];
|
|
235
|
+
lines[segment.genLine].push(values.map(encodeVlq).join(""));
|
|
236
|
+
prevGenCol = segment.genCol;
|
|
237
|
+
prevSrcLine = segment.srcLine;
|
|
238
|
+
prevSrcCol = segment.srcCol;
|
|
239
|
+
}
|
|
240
|
+
return lines.map((line) => line.join(",")).join(";");
|
|
241
|
+
}
|
|
242
|
+
__name(encodeMappings, "encodeMappings");
|
|
243
|
+
var base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
244
|
+
function encodeVlq(value) {
|
|
245
|
+
let encoded = value < 0 ? -value << 1 | 1 : value << 1;
|
|
246
|
+
let result = "";
|
|
247
|
+
do {
|
|
248
|
+
let digit = encoded & 31;
|
|
249
|
+
encoded >>>= 5;
|
|
250
|
+
if (encoded > 0) digit |= 32;
|
|
251
|
+
result += base64Chars[digit];
|
|
252
|
+
} while (encoded > 0);
|
|
253
|
+
return result;
|
|
254
|
+
}
|
|
255
|
+
__name(encodeVlq, "encodeVlq");
|
|
256
|
+
function validatePlugins(plugins) {
|
|
257
|
+
const names = /* @__PURE__ */ new Set();
|
|
258
|
+
for (const plugin of plugins) {
|
|
259
|
+
if (!plugin.name) throw new error.VobsError({ code: "VOBS_C007", layer: "compiler", message: "\u7F16\u8BD1\u5668\u63D2\u4EF6\u5FC5\u987B\u63D0\u4F9B name", fix: "\u4E3A\u63D2\u4EF6\u6DFB\u52A0\u7A33\u5B9A\u4E14\u552F\u4E00\u7684 name\u3002" });
|
|
260
|
+
if (names.has(plugin.name)) throw new error.VobsError({ code: "VOBS_C007", layer: "compiler", message: `\u68C0\u6D4B\u5230\u91CD\u590D\u63D2\u4EF6: ${plugin.name}`, fix: "\u4E3A\u6BCF\u4E2A\u7F16\u8BD1\u5668\u63D2\u4EF6\u4F7F\u7528\u552F\u4E00\u7684 name\u3002" });
|
|
261
|
+
names.add(plugin.name);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
__name(validatePlugins, "validatePlugins");
|
|
265
|
+
function transformPluginNodes(sourceFile, plugin, context) {
|
|
266
|
+
const transformNode = plugin.transform?.node ?? plugin.transformNode;
|
|
267
|
+
if (!transformNode) return sourceFile;
|
|
268
|
+
const transformer = /* @__PURE__ */ __name((transformContext) => (root) => {
|
|
269
|
+
const visit = /* @__PURE__ */ __name((node) => {
|
|
270
|
+
const replacement = transformNode(node, context);
|
|
271
|
+
if (replacement === null) return void 0;
|
|
272
|
+
return ts__default.default.visitEachChild(replacement ?? node, visit, transformContext);
|
|
273
|
+
}, "visit");
|
|
274
|
+
return ts__default.default.visitNode(root, visit);
|
|
275
|
+
}, "transformer");
|
|
276
|
+
const result = ts__default.default.transform(sourceFile, [transformer]);
|
|
277
|
+
try {
|
|
278
|
+
return result.transformed[0];
|
|
279
|
+
} finally {
|
|
280
|
+
result.dispose();
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
__name(transformPluginNodes, "transformPluginNodes");
|
|
284
|
+
function collectDeclaredNames(sourceFile) {
|
|
285
|
+
const names = /* @__PURE__ */ new Set();
|
|
286
|
+
const visit = /* @__PURE__ */ __name((node) => {
|
|
287
|
+
if (ts__default.default.isIdentifier(node) && isBindingName(node)) names.add(node.text);
|
|
288
|
+
ts__default.default.forEachChild(node, visit);
|
|
289
|
+
}, "visit");
|
|
290
|
+
visit(sourceFile);
|
|
291
|
+
return names;
|
|
292
|
+
}
|
|
293
|
+
__name(collectDeclaredNames, "collectDeclaredNames");
|
|
294
|
+
function collectStateAliases(sourceFile) {
|
|
295
|
+
const aliases = /* @__PURE__ */ new Set();
|
|
296
|
+
for (const statement of sourceFile.statements) {
|
|
297
|
+
if (!ts__default.default.isImportDeclaration(statement) || !ts__default.default.isStringLiteral(statement.moduleSpecifier)) continue;
|
|
298
|
+
const module = statement.moduleSpecifier.text;
|
|
299
|
+
if (module !== "@vobs/reactivity" && module !== "@vobs/vobs") continue;
|
|
300
|
+
const clause = statement.importClause;
|
|
301
|
+
if (!clause?.namedBindings || !ts__default.default.isNamedImports(clause.namedBindings)) continue;
|
|
302
|
+
for (const element of clause.namedBindings.elements) {
|
|
303
|
+
if (element.propertyName ? element.propertyName.text === "state" : element.name.text === "state") {
|
|
304
|
+
aliases.add(element.name.text);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return aliases;
|
|
309
|
+
}
|
|
310
|
+
__name(collectStateAliases, "collectStateAliases");
|
|
311
|
+
function collectLocallyDeclaredNames(sourceFile) {
|
|
312
|
+
const names = /* @__PURE__ */ new Set();
|
|
313
|
+
const visit = /* @__PURE__ */ __name((node) => {
|
|
314
|
+
if (ts__default.default.isImportDeclaration(node)) return;
|
|
315
|
+
if (ts__default.default.isIdentifier(node) && isBindingName(node)) names.add(node.text);
|
|
316
|
+
ts__default.default.forEachChild(node, visit);
|
|
317
|
+
}, "visit");
|
|
318
|
+
visit(sourceFile);
|
|
319
|
+
return names;
|
|
320
|
+
}
|
|
321
|
+
__name(collectLocallyDeclaredNames, "collectLocallyDeclaredNames");
|
|
322
|
+
function isBindingName(node) {
|
|
323
|
+
const parent = node.parent;
|
|
324
|
+
if (!parent) return false;
|
|
325
|
+
if (ts__default.default.isPropertyAccessExpression(parent) && parent.name === node) return false;
|
|
326
|
+
if (ts__default.default.isQualifiedName(parent) && parent.right === node) return false;
|
|
327
|
+
if (ts__default.default.isJsxAttribute(parent)) return false;
|
|
328
|
+
return parent.name === node;
|
|
329
|
+
}
|
|
330
|
+
__name(isBindingName, "isBindingName");
|
|
331
|
+
function resolveHelperName(state, name) {
|
|
332
|
+
const existing = state.helperAliases.get(name);
|
|
333
|
+
if (existing) return existing;
|
|
334
|
+
let alias = name;
|
|
335
|
+
if (state.takenNames.has(alias)) {
|
|
336
|
+
alias = `_vobs_${name}`;
|
|
337
|
+
let suffix = 1;
|
|
338
|
+
while (state.takenNames.has(alias)) alias = `_vobs_${name}_${suffix++}`;
|
|
339
|
+
}
|
|
340
|
+
state.helperAliases.set(name, alias);
|
|
341
|
+
return alias;
|
|
342
|
+
}
|
|
343
|
+
__name(resolveHelperName, "resolveHelperName");
|
|
344
|
+
function helperRef(state, name) {
|
|
345
|
+
return ts__default.default.factory.createIdentifier(resolveHelperName(state, name));
|
|
346
|
+
}
|
|
347
|
+
__name(helperRef, "helperRef");
|
|
348
|
+
function createRuntimeImports(state) {
|
|
349
|
+
const modules = /* @__PURE__ */ new Map();
|
|
350
|
+
for (const [name, alias] of state.helperAliases) {
|
|
351
|
+
const module = name === "insertResourceBoundary" ? "@vobs/resource" : "@vobs/vobs";
|
|
352
|
+
const imported = modules.get(module) ?? [];
|
|
353
|
+
imported.push(ts__default.default.factory.createImportSpecifier(
|
|
354
|
+
false,
|
|
355
|
+
alias === name ? void 0 : ts__default.default.factory.createIdentifier(name),
|
|
356
|
+
ts__default.default.factory.createIdentifier(alias)
|
|
357
|
+
));
|
|
358
|
+
modules.set(module, imported);
|
|
359
|
+
}
|
|
360
|
+
return [...modules.entries()].map(([module, imported]) => ts__default.default.factory.createImportDeclaration(
|
|
361
|
+
void 0,
|
|
362
|
+
ts__default.default.factory.createImportClause(
|
|
363
|
+
false,
|
|
364
|
+
void 0,
|
|
365
|
+
ts__default.default.factory.createNamedImports(imported)
|
|
366
|
+
),
|
|
367
|
+
ts__default.default.factory.createStringLiteral(module)
|
|
368
|
+
));
|
|
369
|
+
}
|
|
370
|
+
__name(createRuntimeImports, "createRuntimeImports");
|
|
371
|
+
function rebuildImport(state, node) {
|
|
372
|
+
if (!ts__default.default.isStringLiteral(node.moduleSpecifier)) return node;
|
|
373
|
+
return tagStatement(state, ts__default.default.factory.createImportDeclaration(
|
|
374
|
+
node.modifiers,
|
|
375
|
+
node.importClause,
|
|
376
|
+
ts__default.default.factory.createStringLiteral(node.moduleSpecifier.text),
|
|
377
|
+
node.attributes
|
|
378
|
+
), node);
|
|
379
|
+
}
|
|
380
|
+
__name(rebuildImport, "rebuildImport");
|
|
381
|
+
function transformStatement(state, node) {
|
|
382
|
+
if (ts__default.default.isFunctionDeclaration(node) && node.body) {
|
|
383
|
+
return tagStatement(state, ts__default.default.factory.updateFunctionDeclaration(
|
|
384
|
+
node,
|
|
385
|
+
node.modifiers,
|
|
386
|
+
node.asteriskToken,
|
|
387
|
+
node.name,
|
|
388
|
+
node.typeParameters,
|
|
389
|
+
node.parameters,
|
|
390
|
+
node.type,
|
|
391
|
+
transformBlock(state, node.body)
|
|
392
|
+
), node);
|
|
393
|
+
}
|
|
394
|
+
if (ts__default.default.isVariableStatement(node)) return transformVariableStatement(state, node);
|
|
395
|
+
if (ts__default.default.isExportAssignment(node) && containsJsx(node.expression)) {
|
|
396
|
+
return tagStatement(state, ts__default.default.factory.updateExportAssignment(node, node.modifiers, transformEmbeddedExpression(state, node.expression)), node);
|
|
397
|
+
}
|
|
398
|
+
if (ts__default.default.isExpressionStatement(node) && containsJsx(node.expression)) {
|
|
399
|
+
return tagStatement(state, ts__default.default.factory.updateExpressionStatement(node, transformEmbeddedExpression(state, node.expression)), node);
|
|
400
|
+
}
|
|
401
|
+
if (ts__default.default.isReturnStatement(node) && node.expression && containsJsx(node.expression)) {
|
|
402
|
+
return tagStatement(state, ts__default.default.factory.updateReturnStatement(node, transformEmbeddedExpression(state, node.expression)), node);
|
|
403
|
+
}
|
|
404
|
+
return node;
|
|
405
|
+
}
|
|
406
|
+
__name(transformStatement, "transformStatement");
|
|
407
|
+
function transformVariableStatement(state, node) {
|
|
408
|
+
let changed = false;
|
|
409
|
+
const declarations = node.declarationList.declarations.map((declaration) => {
|
|
410
|
+
const initializer = declaration.initializer;
|
|
411
|
+
if (!initializer) return declaration;
|
|
412
|
+
let nextInitializer = inferStateDebugName(state, declaration, initializer) ?? initializer;
|
|
413
|
+
if (containsJsx(nextInitializer)) {
|
|
414
|
+
nextInitializer = transformEmbeddedExpression(state, nextInitializer);
|
|
415
|
+
}
|
|
416
|
+
if (nextInitializer === initializer) return declaration;
|
|
417
|
+
changed = true;
|
|
418
|
+
return ts__default.default.factory.updateVariableDeclaration(
|
|
419
|
+
declaration,
|
|
420
|
+
declaration.name,
|
|
421
|
+
declaration.exclamationToken,
|
|
422
|
+
declaration.type,
|
|
423
|
+
nextInitializer
|
|
424
|
+
);
|
|
425
|
+
});
|
|
426
|
+
if (!changed) return node;
|
|
427
|
+
return tagStatement(state, ts__default.default.factory.updateVariableStatement(
|
|
428
|
+
node,
|
|
429
|
+
node.modifiers,
|
|
430
|
+
ts__default.default.factory.updateVariableDeclarationList(node.declarationList, declarations)
|
|
431
|
+
), node);
|
|
432
|
+
}
|
|
433
|
+
__name(transformVariableStatement, "transformVariableStatement");
|
|
434
|
+
function inferStateDebugName(state, declaration, initializer) {
|
|
435
|
+
if (state.stateAliases.size === 0) return void 0;
|
|
436
|
+
if (!ts__default.default.isIdentifier(declaration.name)) return void 0;
|
|
437
|
+
let call = initializer;
|
|
438
|
+
while (ts__default.default.isParenthesizedExpression(call) || ts__default.default.isAsExpression(call) || ts__default.default.isTypeAssertionExpression(call) || ts__default.default.isSatisfiesExpression(call)) {
|
|
439
|
+
call = call.expression;
|
|
440
|
+
}
|
|
441
|
+
if (!ts__default.default.isCallExpression(call)) return void 0;
|
|
442
|
+
const callee = call.expression;
|
|
443
|
+
if (!ts__default.default.isIdentifier(callee) || !state.stateAliases.has(callee.text)) return void 0;
|
|
444
|
+
if (state.localBindings.has(callee.text)) return void 0;
|
|
445
|
+
if (call.arguments.length !== 1) return void 0;
|
|
446
|
+
return ts__default.default.factory.createCallExpression(callee, call.typeArguments, [
|
|
447
|
+
...call.arguments,
|
|
448
|
+
ts__default.default.factory.createStringLiteral(declaration.name.text)
|
|
449
|
+
]);
|
|
450
|
+
}
|
|
451
|
+
__name(inferStateDebugName, "inferStateDebugName");
|
|
452
|
+
function containsJsx(expression) {
|
|
453
|
+
let found = false;
|
|
454
|
+
const visit = /* @__PURE__ */ __name((node) => {
|
|
455
|
+
if (isJsxExpression(node)) {
|
|
456
|
+
found = true;
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
ts__default.default.forEachChild(node, visit);
|
|
460
|
+
}, "visit");
|
|
461
|
+
visit(expression);
|
|
462
|
+
return found;
|
|
463
|
+
}
|
|
464
|
+
__name(containsJsx, "containsJsx");
|
|
465
|
+
function transformBlock(state, block) {
|
|
466
|
+
const statements = block.statements.map((statement) => {
|
|
467
|
+
if (!ts__default.default.isReturnStatement(statement) || !statement.expression) return transformStatement(state, statement);
|
|
468
|
+
const expression = ts__default.default.isParenthesizedExpression(statement.expression) ? statement.expression.expression : statement.expression;
|
|
469
|
+
return isJsxExpression(expression) ? tagStatement(state, ts__default.default.factory.updateReturnStatement(statement, transformJsxExpression(state, expression)), statement) : statement;
|
|
470
|
+
});
|
|
471
|
+
return ts__default.default.factory.updateBlock(block, statements);
|
|
472
|
+
}
|
|
473
|
+
__name(transformBlock, "transformBlock");
|
|
474
|
+
function isJsxExpression(node) {
|
|
475
|
+
return ts__default.default.isJsxElement(node) || ts__default.default.isJsxSelfClosingElement(node) || ts__default.default.isJsxFragment(node);
|
|
476
|
+
}
|
|
477
|
+
__name(isJsxExpression, "isJsxExpression");
|
|
478
|
+
function transformJsxExpression(state, node) {
|
|
479
|
+
if (ts__default.default.isJsxFragment(node)) return transformFragment(state, node.children);
|
|
480
|
+
if (ts__default.default.isJsxElement(node)) {
|
|
481
|
+
return transformElement(state, node, node.openingElement.tagName, node.openingElement.attributes, node.children);
|
|
482
|
+
}
|
|
483
|
+
return transformElement(state, node, node.tagName, node.attributes, []);
|
|
484
|
+
}
|
|
485
|
+
__name(transformJsxExpression, "transformJsxExpression");
|
|
486
|
+
function transformElement(state, node, tagName, attributes, children) {
|
|
487
|
+
if (isFragmentTag(tagName)) return transformFragment(state, children);
|
|
488
|
+
if (!ts__default.default.isIdentifier(tagName)) {
|
|
489
|
+
reportUnsupportedTag(state, tagName);
|
|
490
|
+
}
|
|
491
|
+
if (ts__default.default.isIdentifier(tagName) && tagName.text === "ResourceBoundary") {
|
|
492
|
+
return transformResourceBoundary(state, node, attributes, children);
|
|
493
|
+
}
|
|
494
|
+
if (ts__default.default.isIdentifier(tagName) && tagName.text === "AsyncBoundary") {
|
|
495
|
+
return transformAsyncBoundary(state, node, attributes, children);
|
|
496
|
+
}
|
|
497
|
+
if (ts__default.default.isIdentifier(tagName) && tagName.text === "ErrorBoundary") {
|
|
498
|
+
return transformErrorBoundary(state, node, attributes, children);
|
|
499
|
+
}
|
|
500
|
+
if (ts__default.default.isIdentifier(tagName) && tagName.text === "Profiler") {
|
|
501
|
+
return transformProfiler(state, node, attributes, children);
|
|
502
|
+
}
|
|
503
|
+
if (ts__default.default.isIdentifier(tagName) && /^[A-Z]/.test(tagName.text)) {
|
|
504
|
+
const args = [
|
|
505
|
+
ts__default.default.factory.createCallExpression(helperRef(state, "resolveComponent"), void 0, [
|
|
506
|
+
tagName,
|
|
507
|
+
ts__default.default.factory.createStringLiteral(state.filename),
|
|
508
|
+
ts__default.default.factory.createStringLiteral(tagName.text)
|
|
509
|
+
]),
|
|
510
|
+
createComponentProps(state, attributes, children)
|
|
511
|
+
];
|
|
512
|
+
if (state.sourceLocation) args.push(createSourceLocation(tagName));
|
|
513
|
+
return ts__default.default.factory.createCallExpression(helperRef(state, "createComponent"), void 0, args);
|
|
514
|
+
}
|
|
515
|
+
if (isStaticElement(tagName, attributes, children)) {
|
|
516
|
+
return ts__default.default.factory.createCallExpression(
|
|
517
|
+
helperRef(state, "cloneTemplate"),
|
|
518
|
+
void 0,
|
|
519
|
+
[registerTemplate(state, serializeStaticHtml(node))]
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
const elementName = tagName.getText();
|
|
523
|
+
const elementId = nextIdentifier(state, "_el");
|
|
524
|
+
const statements = [
|
|
525
|
+
createConstStatement(
|
|
526
|
+
state,
|
|
527
|
+
elementId,
|
|
528
|
+
ts__default.default.factory.createCallExpression(
|
|
529
|
+
helperRef(state, "createElement"),
|
|
530
|
+
void 0,
|
|
531
|
+
[ts__default.default.factory.createStringLiteral(elementName)]
|
|
532
|
+
),
|
|
533
|
+
node
|
|
534
|
+
)
|
|
535
|
+
];
|
|
536
|
+
appendAttributes(state, statements, elementId, attributes);
|
|
537
|
+
appendChildren(state, statements, elementId, children);
|
|
538
|
+
statements.push(tagStatement(state, ts__default.default.factory.createReturnStatement(elementId), node));
|
|
539
|
+
return ts__default.default.factory.createCallExpression(
|
|
540
|
+
ts__default.default.factory.createArrowFunction(
|
|
541
|
+
void 0,
|
|
542
|
+
void 0,
|
|
543
|
+
[],
|
|
544
|
+
void 0,
|
|
545
|
+
ts__default.default.factory.createToken(ts__default.default.SyntaxKind.EqualsGreaterThanToken),
|
|
546
|
+
ts__default.default.factory.createBlock(statements, true)
|
|
547
|
+
),
|
|
548
|
+
void 0,
|
|
549
|
+
[]
|
|
550
|
+
);
|
|
551
|
+
}
|
|
552
|
+
__name(transformElement, "transformElement");
|
|
553
|
+
function isFragmentTag(tagName) {
|
|
554
|
+
return tagName.getText() === "Fragment" || tagName.getText() === "Vobs.Fragment";
|
|
555
|
+
}
|
|
556
|
+
__name(isFragmentTag, "isFragmentTag");
|
|
557
|
+
function transformFragment(state, children) {
|
|
558
|
+
const parent = nextIdentifier(state, "_fragmentParent");
|
|
559
|
+
const anchor = nextIdentifier(state, "_fragmentAnchor");
|
|
560
|
+
const statements = [];
|
|
561
|
+
appendChildren(state, statements, parent, children, anchor);
|
|
562
|
+
return ts__default.default.factory.createCallExpression(
|
|
563
|
+
helperRef(state, "createFragment"),
|
|
564
|
+
void 0,
|
|
565
|
+
[ts__default.default.factory.createArrowFunction(
|
|
566
|
+
void 0,
|
|
567
|
+
void 0,
|
|
568
|
+
[
|
|
569
|
+
ts__default.default.factory.createParameterDeclaration(void 0, void 0, parent),
|
|
570
|
+
ts__default.default.factory.createParameterDeclaration(void 0, void 0, anchor)
|
|
571
|
+
],
|
|
572
|
+
void 0,
|
|
573
|
+
ts__default.default.factory.createToken(ts__default.default.SyntaxKind.EqualsGreaterThanToken),
|
|
574
|
+
ts__default.default.factory.createBlock(statements, true)
|
|
575
|
+
)]
|
|
576
|
+
);
|
|
577
|
+
}
|
|
578
|
+
__name(transformFragment, "transformFragment");
|
|
579
|
+
function transformResourceBoundary(state, node, attributes, children) {
|
|
580
|
+
const resource = getAttributeExpression(attributes, "resource");
|
|
581
|
+
if (!resource) throw new error.VobsError({ code: "VOBS_C002", layer: "compiler", message: "ResourceBoundary \u5FC5\u987B\u63D0\u4F9B resource \u5C5E\u6027", fix: "\u4E3A ResourceBoundary \u6DFB\u52A0 resource={resource}\u3002" });
|
|
582
|
+
const options = [
|
|
583
|
+
ts__default.default.factory.createPropertyAssignment("resource", transformEmbeddedExpression(state, resource)),
|
|
584
|
+
ts__default.default.factory.createPropertyAssignment("children", createBoundaryFactory(state, children))
|
|
585
|
+
];
|
|
586
|
+
appendBoundaryOptionalProperty(state, options, attributes, "loading");
|
|
587
|
+
appendBoundaryOptionalProperty(state, options, attributes, "empty");
|
|
588
|
+
appendBoundaryOptionalProperty(state, options, attributes, "fallback");
|
|
589
|
+
return createBoundaryFragment(state, node, "insertResourceBoundary", options);
|
|
590
|
+
}
|
|
591
|
+
__name(transformResourceBoundary, "transformResourceBoundary");
|
|
592
|
+
function transformErrorBoundary(state, node, attributes, children) {
|
|
593
|
+
const fallback = getAttributeExpression(attributes, "fallback");
|
|
594
|
+
if (!fallback) throw new error.VobsError({ code: "VOBS_C002", layer: "compiler", message: "ErrorBoundary \u5FC5\u987B\u63D0\u4F9B fallback \u5C5E\u6027", fix: "\u4E3A ErrorBoundary \u6DFB\u52A0 fallback={(error, retry) => ...}\u3002" });
|
|
595
|
+
return createBoundaryFragment(state, node, "insertErrorBoundary", [
|
|
596
|
+
ts__default.default.factory.createPropertyAssignment("children", createBoundaryFactory(state, children)),
|
|
597
|
+
ts__default.default.factory.createPropertyAssignment("fallback", transformEmbeddedExpression(state, fallback))
|
|
598
|
+
]);
|
|
599
|
+
}
|
|
600
|
+
__name(transformErrorBoundary, "transformErrorBoundary");
|
|
601
|
+
function transformAsyncBoundary(state, node, attributes, children) {
|
|
602
|
+
const promise = getAttributeExpression(attributes, "promise");
|
|
603
|
+
if (!promise) throw new error.VobsError({ code: "VOBS_C002", layer: "compiler", message: "AsyncBoundary \u5FC5\u987B\u63D0\u4F9B promise \u5C5E\u6027", fix: "\u4E3A AsyncBoundary \u6DFB\u52A0 promise={promise}\u3002" });
|
|
604
|
+
const options = [
|
|
605
|
+
ts__default.default.factory.createPropertyAssignment("promise", transformEmbeddedExpression(state, promise)),
|
|
606
|
+
ts__default.default.factory.createPropertyAssignment("children", createAsyncFactory(state, children))
|
|
607
|
+
];
|
|
608
|
+
appendBoundaryOptionalProperty(state, options, attributes, "loading");
|
|
609
|
+
appendBoundaryOptionalProperty(state, options, attributes, "fallback");
|
|
610
|
+
const resetKey = getAttributeExpression(attributes, "resetKey");
|
|
611
|
+
if (resetKey) options.push(ts__default.default.factory.createPropertyAssignment("resetKey", createGetter(resetKey)));
|
|
612
|
+
return createBoundaryFragment(state, node, "insertAsyncBoundary", options);
|
|
613
|
+
}
|
|
614
|
+
__name(transformAsyncBoundary, "transformAsyncBoundary");
|
|
615
|
+
function transformProfiler(state, node, attributes, children) {
|
|
616
|
+
const idAttribute = attributes.properties.find((attribute) => ts__default.default.isJsxAttribute(attribute) && attribute.name.getText() === "id");
|
|
617
|
+
const id = idAttribute && ts__default.default.isJsxAttribute(idAttribute) && idAttribute.initializer && ts__default.default.isStringLiteral(idAttribute.initializer) ? ts__default.default.factory.createStringLiteral(idAttribute.initializer.text) : idAttribute && ts__default.default.isJsxAttribute(idAttribute) && idAttribute.initializer && ts__default.default.isJsxExpression(idAttribute.initializer) ? idAttribute.initializer.expression : null;
|
|
618
|
+
if (!id) throw new error.VobsError({ code: "VOBS_C002", layer: "compiler", message: "Profiler \u5FC5\u987B\u63D0\u4F9B id \u5C5E\u6027", fix: '\u4E3A Profiler \u6DFB\u52A0 id="ComponentName"\u3002' });
|
|
619
|
+
const options = [
|
|
620
|
+
ts__default.default.factory.createPropertyAssignment("id", transformEmbeddedExpression(state, id)),
|
|
621
|
+
ts__default.default.factory.createPropertyAssignment("children", createBoundaryFactory(state, children))
|
|
622
|
+
];
|
|
623
|
+
appendBoundaryOptionalProperty(state, options, attributes, "onRender");
|
|
624
|
+
return createBoundaryFragment(state, node, "insertProfiler", options);
|
|
625
|
+
}
|
|
626
|
+
__name(transformProfiler, "transformProfiler");
|
|
627
|
+
function createBoundaryFragment(state, node, helper, options) {
|
|
628
|
+
const parent = nextIdentifier(state, "_boundaryParent");
|
|
629
|
+
const anchor = nextIdentifier(state, "_boundaryAnchor");
|
|
630
|
+
return ts__default.default.factory.createCallExpression(
|
|
631
|
+
helperRef(state, "createFragment"),
|
|
632
|
+
void 0,
|
|
633
|
+
[ts__default.default.factory.createArrowFunction(
|
|
634
|
+
void 0,
|
|
635
|
+
void 0,
|
|
636
|
+
[
|
|
637
|
+
ts__default.default.factory.createParameterDeclaration(void 0, void 0, parent),
|
|
638
|
+
ts__default.default.factory.createParameterDeclaration(void 0, void 0, anchor)
|
|
639
|
+
],
|
|
640
|
+
void 0,
|
|
641
|
+
ts__default.default.factory.createToken(ts__default.default.SyntaxKind.EqualsGreaterThanToken),
|
|
642
|
+
ts__default.default.factory.createBlock([callStatement(state, helper, [
|
|
643
|
+
parent,
|
|
644
|
+
anchor,
|
|
645
|
+
ts__default.default.factory.createObjectLiteralExpression(options, true)
|
|
646
|
+
], node)], true)
|
|
647
|
+
)]
|
|
648
|
+
);
|
|
649
|
+
}
|
|
650
|
+
__name(createBoundaryFragment, "createBoundaryFragment");
|
|
651
|
+
function createBoundaryFactory(state, children) {
|
|
652
|
+
const content = transformFragment(state, children);
|
|
653
|
+
return ts__default.default.factory.createArrowFunction(
|
|
654
|
+
void 0,
|
|
655
|
+
void 0,
|
|
656
|
+
[],
|
|
657
|
+
void 0,
|
|
658
|
+
ts__default.default.factory.createToken(ts__default.default.SyntaxKind.EqualsGreaterThanToken),
|
|
659
|
+
content
|
|
660
|
+
);
|
|
661
|
+
}
|
|
662
|
+
__name(createBoundaryFactory, "createBoundaryFactory");
|
|
663
|
+
function createAsyncFactory(state, children) {
|
|
664
|
+
const value = ts__default.default.factory.createIdentifier("value");
|
|
665
|
+
const expressionChild = children.length === 1 && children[0].kind === ts__default.default.SyntaxKind.JsxExpression ? children[0].expression : void 0;
|
|
666
|
+
if (expressionChild && ts__default.default.isArrowFunction(expressionChild)) {
|
|
667
|
+
const transformed = transformEmbeddedExpression(state, expressionChild);
|
|
668
|
+
return transformed;
|
|
669
|
+
}
|
|
670
|
+
const content = transformFragment(state, children);
|
|
671
|
+
return ts__default.default.factory.createArrowFunction(void 0, void 0, [
|
|
672
|
+
ts__default.default.factory.createParameterDeclaration(void 0, void 0, value)
|
|
673
|
+
], void 0, ts__default.default.factory.createToken(ts__default.default.SyntaxKind.EqualsGreaterThanToken), content);
|
|
674
|
+
}
|
|
675
|
+
__name(createAsyncFactory, "createAsyncFactory");
|
|
676
|
+
function appendBoundaryOptionalProperty(state, properties, attributes, name) {
|
|
677
|
+
const expression = getAttributeExpression(attributes, name);
|
|
678
|
+
if (expression) {
|
|
679
|
+
const transformed = transformEmbeddedExpression(state, expression);
|
|
680
|
+
const value = isJsxExpression(unwrapExpression(expression)) ? createGetter(transformed) : transformed;
|
|
681
|
+
properties.push(ts__default.default.factory.createPropertyAssignment(name, value));
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
__name(appendBoundaryOptionalProperty, "appendBoundaryOptionalProperty");
|
|
685
|
+
function getAttributeExpression(attributes, name) {
|
|
686
|
+
for (const attribute of attributes.properties) {
|
|
687
|
+
if (!ts__default.default.isJsxAttribute(attribute) || attribute.name.getText() !== name) continue;
|
|
688
|
+
if (attribute.initializer && ts__default.default.isJsxExpression(attribute.initializer)) {
|
|
689
|
+
return attribute.initializer.expression ?? null;
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
return null;
|
|
693
|
+
}
|
|
694
|
+
__name(getAttributeExpression, "getAttributeExpression");
|
|
695
|
+
function transformEmbeddedExpression(state, expression) {
|
|
696
|
+
const result = ts__default.default.transform(expression, [(context) => (root) => {
|
|
697
|
+
const visit = /* @__PURE__ */ __name((node) => {
|
|
698
|
+
if (ts__default.default.isJsxElement(node) || ts__default.default.isJsxSelfClosingElement(node) || ts__default.default.isJsxFragment(node)) {
|
|
699
|
+
return transformJsxExpression(state, node);
|
|
700
|
+
}
|
|
701
|
+
return ts__default.default.visitEachChild(node, visit, context);
|
|
702
|
+
}, "visit");
|
|
703
|
+
return ts__default.default.visitNode(root, visit);
|
|
704
|
+
}]);
|
|
705
|
+
try {
|
|
706
|
+
return result.transformed[0];
|
|
707
|
+
} finally {
|
|
708
|
+
result.dispose();
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
__name(transformEmbeddedExpression, "transformEmbeddedExpression");
|
|
712
|
+
function isStaticElement(tagName, attributes, children) {
|
|
713
|
+
if (!ts__default.default.isIdentifier(tagName) || !/^[a-z]/.test(tagName.text)) return false;
|
|
714
|
+
for (const attribute of attributes.properties) {
|
|
715
|
+
if (ts__default.default.isJsxSpreadAttribute(attribute)) return false;
|
|
716
|
+
if (!ts__default.default.isJsxAttribute(attribute)) return false;
|
|
717
|
+
const name = attribute.name.getText();
|
|
718
|
+
if (name === "key" || name === "ref" || name.startsWith("on")) return false;
|
|
719
|
+
if (isPropertyAttribute(name)) return false;
|
|
720
|
+
const initializer = attribute.initializer;
|
|
721
|
+
if (initializer && !ts__default.default.isStringLiteral(initializer)) return false;
|
|
722
|
+
}
|
|
723
|
+
for (const child of children) {
|
|
724
|
+
if (ts__default.default.isJsxText(child)) continue;
|
|
725
|
+
if (ts__default.default.isJsxElement(child) || ts__default.default.isJsxSelfClosingElement(child)) {
|
|
726
|
+
const nested = ts__default.default.isJsxElement(child) ? { tagName: child.openingElement.tagName, attributes: child.openingElement.attributes, children: child.children } : { tagName: child.tagName, attributes: child.attributes, children: [] };
|
|
727
|
+
if (!isStaticElement(nested.tagName, nested.attributes, nested.children)) return false;
|
|
728
|
+
continue;
|
|
729
|
+
}
|
|
730
|
+
return false;
|
|
731
|
+
}
|
|
732
|
+
return true;
|
|
733
|
+
}
|
|
734
|
+
__name(isStaticElement, "isStaticElement");
|
|
735
|
+
function serializeStaticHtml(node) {
|
|
736
|
+
const { tagName, attributes, children } = ts__default.default.isJsxElement(node) ? { tagName: node.openingElement.tagName, attributes: node.openingElement.attributes, children: node.children } : { tagName: node.tagName, attributes: node.attributes, children: [] };
|
|
737
|
+
return serializeStaticElement(tagName, attributes, children);
|
|
738
|
+
}
|
|
739
|
+
__name(serializeStaticHtml, "serializeStaticHtml");
|
|
740
|
+
function serializeStaticElement(tagName, attributes, children) {
|
|
741
|
+
const name = tagName.getText();
|
|
742
|
+
let html = `<${name}`;
|
|
743
|
+
for (const attribute of attributes.properties) {
|
|
744
|
+
if (!ts__default.default.isJsxAttribute(attribute)) continue;
|
|
745
|
+
const attributeName = attribute.name.getText() === "className" ? "class" : attribute.name.getText();
|
|
746
|
+
const initializer = attribute.initializer;
|
|
747
|
+
if (!initializer) {
|
|
748
|
+
html += ` ${attributeName}=""`;
|
|
749
|
+
continue;
|
|
750
|
+
}
|
|
751
|
+
if (ts__default.default.isStringLiteral(initializer)) {
|
|
752
|
+
html += ` ${attributeName}="${escapeHtmlAttribute(initializer.text)}"`;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
html += ">";
|
|
756
|
+
for (const child of children) {
|
|
757
|
+
if (ts__default.default.isJsxText(child)) {
|
|
758
|
+
const text = child.text.replace(/\s+/g, " ").trimStart();
|
|
759
|
+
if (text.trim()) html += escapeHtmlText(text);
|
|
760
|
+
continue;
|
|
761
|
+
}
|
|
762
|
+
if (ts__default.default.isJsxElement(child)) {
|
|
763
|
+
html += serializeStaticElement(
|
|
764
|
+
child.openingElement.tagName,
|
|
765
|
+
child.openingElement.attributes,
|
|
766
|
+
child.children
|
|
767
|
+
);
|
|
768
|
+
continue;
|
|
769
|
+
}
|
|
770
|
+
if (ts__default.default.isJsxSelfClosingElement(child)) {
|
|
771
|
+
html += serializeStaticElement(child.tagName, child.attributes, []);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
html += `</${name}>`;
|
|
775
|
+
return html;
|
|
776
|
+
}
|
|
777
|
+
__name(serializeStaticElement, "serializeStaticElement");
|
|
778
|
+
function escapeHtmlAttribute(value) {
|
|
779
|
+
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<");
|
|
780
|
+
}
|
|
781
|
+
__name(escapeHtmlAttribute, "escapeHtmlAttribute");
|
|
782
|
+
function escapeHtmlText(value) {
|
|
783
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
784
|
+
}
|
|
785
|
+
__name(escapeHtmlText, "escapeHtmlText");
|
|
786
|
+
function registerTemplate(state, html) {
|
|
787
|
+
const existing = state.templates.get(html);
|
|
788
|
+
if (existing) return existing;
|
|
789
|
+
const identifier = nextIdentifier(state, "_tpl");
|
|
790
|
+
state.templates.set(html, identifier);
|
|
791
|
+
return identifier;
|
|
792
|
+
}
|
|
793
|
+
__name(registerTemplate, "registerTemplate");
|
|
794
|
+
function createTemplateDeclarations(state) {
|
|
795
|
+
return [...state.templates.entries()].map(
|
|
796
|
+
([html, identifier]) => ts__default.default.factory.createVariableStatement(void 0, ts__default.default.factory.createVariableDeclarationList([
|
|
797
|
+
ts__default.default.factory.createVariableDeclaration(identifier, void 0, void 0, ts__default.default.factory.createCallExpression(
|
|
798
|
+
helperRef(state, "createTemplate"),
|
|
799
|
+
void 0,
|
|
800
|
+
[ts__default.default.factory.createStringLiteral(html)]
|
|
801
|
+
))
|
|
802
|
+
], ts__default.default.NodeFlags.Const))
|
|
803
|
+
);
|
|
804
|
+
}
|
|
805
|
+
__name(createTemplateDeclarations, "createTemplateDeclarations");
|
|
806
|
+
function appendAttributes(state, statements, element, attributes) {
|
|
807
|
+
const staticProps = [];
|
|
808
|
+
const hasSpread = attributes.properties.some((attribute) => ts__default.default.isJsxSpreadAttribute(attribute));
|
|
809
|
+
for (const attribute of attributes.properties) {
|
|
810
|
+
if (ts__default.default.isJsxSpreadAttribute(attribute)) {
|
|
811
|
+
statements.push(callStatement(state, "spreadProps", [element, transformEmbeddedExpression(state, attribute.expression)], attribute));
|
|
812
|
+
continue;
|
|
813
|
+
}
|
|
814
|
+
if (!ts__default.default.isJsxAttribute(attribute)) continue;
|
|
815
|
+
const name = attribute.name.getText();
|
|
816
|
+
if (name === "key") continue;
|
|
817
|
+
if (name === "ref") {
|
|
818
|
+
const initializer2 = attribute.initializer;
|
|
819
|
+
if (initializer2 && ts__default.default.isJsxExpression(initializer2) && initializer2.expression) {
|
|
820
|
+
statements.push(callStatement(state, "setRef", [element, transformEmbeddedExpression(state, initializer2.expression)], attribute));
|
|
821
|
+
}
|
|
822
|
+
continue;
|
|
823
|
+
}
|
|
824
|
+
const initializer = attribute.initializer;
|
|
825
|
+
if (name.startsWith("on") && initializer && ts__default.default.isJsxExpression(initializer) && initializer.expression) {
|
|
826
|
+
statements.push(callStatement(state, "addEventListener", [
|
|
827
|
+
element,
|
|
828
|
+
ts__default.default.factory.createStringLiteral(name.slice(2).toLowerCase()),
|
|
829
|
+
initializer.expression
|
|
830
|
+
], attribute));
|
|
831
|
+
continue;
|
|
832
|
+
}
|
|
833
|
+
if (!initializer) {
|
|
834
|
+
if (hasSpread) {
|
|
835
|
+
statements.push(callStatement(state, isPropertyAttribute(name) ? "setProperty" : "setAttribute", [element, ts__default.default.factory.createStringLiteral(isPropertyAttribute(name) ? name : name === "className" ? "class" : name), isPropertyAttribute(name) ? ts__default.default.factory.createTrue() : ts__default.default.factory.createStringLiteral("")], attribute));
|
|
836
|
+
continue;
|
|
837
|
+
}
|
|
838
|
+
if (isPropertyAttribute(name)) staticProps.push(createStaticProperty(name, ts__default.default.factory.createTrue()));
|
|
839
|
+
else staticProps.push(createStaticProperty(name === "className" ? "class" : name, ts__default.default.factory.createStringLiteral("")));
|
|
840
|
+
continue;
|
|
841
|
+
}
|
|
842
|
+
if (ts__default.default.isStringLiteral(initializer)) {
|
|
843
|
+
if (hasSpread) {
|
|
844
|
+
statements.push(callStatement(state, isPropertyAttribute(name) ? "setProperty" : "setAttribute", [element, ts__default.default.factory.createStringLiteral(isPropertyAttribute(name) ? name : name === "className" ? "class" : name), ts__default.default.factory.createStringLiteral(initializer.text)], attribute));
|
|
845
|
+
continue;
|
|
846
|
+
}
|
|
847
|
+
staticProps.push(createStaticProperty(
|
|
848
|
+
isPropertyAttribute(name) ? name : name === "className" ? "class" : name,
|
|
849
|
+
ts__default.default.factory.createStringLiteral(initializer.text)
|
|
850
|
+
));
|
|
851
|
+
continue;
|
|
852
|
+
}
|
|
853
|
+
const attributeName = name === "className" ? "class" : name;
|
|
854
|
+
const propertyAttribute = isPropertyAttribute(name);
|
|
855
|
+
if (ts__default.default.isJsxExpression(initializer) && initializer.expression) {
|
|
856
|
+
statements.push(callStatement(state, propertyAttribute ? "bindProperty" : "bindAttribute", [
|
|
857
|
+
element,
|
|
858
|
+
ts__default.default.factory.createStringLiteral(propertyAttribute ? name : attributeName),
|
|
859
|
+
createGetter(initializer.expression)
|
|
860
|
+
], attribute));
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
if (staticProps.length) statements.splice(1, 0, callStatement(state, "setStaticProps", [
|
|
864
|
+
element,
|
|
865
|
+
ts__default.default.factory.createObjectLiteralExpression(staticProps, true)
|
|
866
|
+
], attributes));
|
|
867
|
+
}
|
|
868
|
+
__name(appendAttributes, "appendAttributes");
|
|
869
|
+
function createStaticProperty(name, value) {
|
|
870
|
+
return ts__default.default.factory.createPropertyAssignment(ts__default.default.factory.createStringLiteral(name), value);
|
|
871
|
+
}
|
|
872
|
+
__name(createStaticProperty, "createStaticProperty");
|
|
873
|
+
function isPropertyAttribute(name) {
|
|
874
|
+
return name === "value" || name === "checked" || name === "selected" || name === "disabled" || name === "multiple" || name === "readOnly" || name === "required" || name === "autofocus" || name === "hidden" || name === "tabIndex";
|
|
875
|
+
}
|
|
876
|
+
__name(isPropertyAttribute, "isPropertyAttribute");
|
|
877
|
+
function appendChildren(state, statements, element, children, anchor = ts__default.default.factory.createNull()) {
|
|
878
|
+
for (const child of children) {
|
|
879
|
+
if (ts__default.default.isJsxText(child)) {
|
|
880
|
+
const text = child.text.replace(/\s+/g, " ").trimStart();
|
|
881
|
+
if (text.trim()) {
|
|
882
|
+
statements.push(callStatement(state, "insertBefore", [
|
|
883
|
+
element,
|
|
884
|
+
ts__default.default.factory.createCallExpression(helperRef(state, "createText"), void 0, [
|
|
885
|
+
ts__default.default.factory.createStringLiteral(text)
|
|
886
|
+
]),
|
|
887
|
+
anchor
|
|
888
|
+
], child));
|
|
889
|
+
}
|
|
890
|
+
continue;
|
|
891
|
+
}
|
|
892
|
+
if (ts__default.default.isJsxElement(child) || ts__default.default.isJsxSelfClosingElement(child) || ts__default.default.isJsxFragment(child)) {
|
|
893
|
+
statements.push(callStatement(state, "insertBefore", [
|
|
894
|
+
element,
|
|
895
|
+
transformJsxExpression(state, child),
|
|
896
|
+
anchor
|
|
897
|
+
], child));
|
|
898
|
+
continue;
|
|
899
|
+
}
|
|
900
|
+
if (child.kind === ts__default.default.SyntaxKind.JsxExpression) {
|
|
901
|
+
const expression = child.expression;
|
|
902
|
+
if (!expression) continue;
|
|
903
|
+
const list = transformListExpression(state, element, expression, anchor);
|
|
904
|
+
if (list) {
|
|
905
|
+
statements.push(callStatement(state, "insertList", list, child));
|
|
906
|
+
continue;
|
|
907
|
+
}
|
|
908
|
+
const dynamic = transformDynamicExpression(state, expression);
|
|
909
|
+
if (dynamic) {
|
|
910
|
+
statements.push(callStatement(state, "insertDynamic", [element, anchor, dynamic], child));
|
|
911
|
+
continue;
|
|
912
|
+
}
|
|
913
|
+
if (!containsJsx(expression) && !ts__default.default.isIdentifier(expression)) {
|
|
914
|
+
const textId = nextIdentifier(state, "_text");
|
|
915
|
+
statements.push(createConstStatement(state, textId, ts__default.default.factory.createCallExpression(helperRef(state, "createText"), void 0, [ts__default.default.factory.createStringLiteral("")]), child));
|
|
916
|
+
statements.push(callStatement(state, "insertBefore", [element, textId, anchor], child));
|
|
917
|
+
statements.push(callStatement(state, "bindText", [textId, createGetter(expression)], child));
|
|
918
|
+
continue;
|
|
919
|
+
}
|
|
920
|
+
const value = transformEmbeddedExpression(state, expression);
|
|
921
|
+
statements.push(callStatement(state, "insertDynamicValue", [element, anchor, createGetter(value)], child));
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
__name(appendChildren, "appendChildren");
|
|
926
|
+
function createComponentProps(state, attributes, children) {
|
|
927
|
+
const properties = [];
|
|
928
|
+
for (const attribute of attributes.properties) {
|
|
929
|
+
if (ts__default.default.isJsxSpreadAttribute(attribute)) {
|
|
930
|
+
properties.push(ts__default.default.factory.createSpreadAssignment(attribute.expression));
|
|
931
|
+
continue;
|
|
932
|
+
}
|
|
933
|
+
const name = propertyName(attribute.name.getText());
|
|
934
|
+
if (attribute.name.getText() === "key") continue;
|
|
935
|
+
const initializer = attribute.initializer;
|
|
936
|
+
if (!initializer) {
|
|
937
|
+
properties.push(ts__default.default.factory.createPropertyAssignment(name, ts__default.default.factory.createTrue()));
|
|
938
|
+
} else if (ts__default.default.isStringLiteral(initializer)) {
|
|
939
|
+
properties.push(ts__default.default.factory.createPropertyAssignment(name, ts__default.default.factory.createStringLiteral(initializer.text)));
|
|
940
|
+
} else if (ts__default.default.isJsxExpression(initializer) && initializer.expression) {
|
|
941
|
+
properties.push(createGetterProperty(name, transformEmbeddedExpression(state, initializer.expression)));
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
const childExpressions = children.flatMap((child) => childToComponentExpression(state, child));
|
|
945
|
+
if (childExpressions.length === 1) {
|
|
946
|
+
properties.push(createGetterProperty("children", childExpressions[0]));
|
|
947
|
+
} else if (childExpressions.length > 1) {
|
|
948
|
+
properties.push(createGetterProperty("children", ts__default.default.factory.createArrayLiteralExpression(childExpressions)));
|
|
949
|
+
}
|
|
950
|
+
return ts__default.default.factory.createObjectLiteralExpression(properties, true);
|
|
951
|
+
}
|
|
952
|
+
__name(createComponentProps, "createComponentProps");
|
|
953
|
+
function createSourceLocation(node) {
|
|
954
|
+
const sourceFile = node.getSourceFile();
|
|
955
|
+
const position = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
956
|
+
return ts__default.default.factory.createObjectLiteralExpression([
|
|
957
|
+
ts__default.default.factory.createPropertyAssignment("file", ts__default.default.factory.createStringLiteral(sourceFile.fileName)),
|
|
958
|
+
ts__default.default.factory.createPropertyAssignment("line", ts__default.default.factory.createNumericLiteral(position.line + 1)),
|
|
959
|
+
ts__default.default.factory.createPropertyAssignment("column", ts__default.default.factory.createNumericLiteral(position.character + 1))
|
|
960
|
+
], true);
|
|
961
|
+
}
|
|
962
|
+
__name(createSourceLocation, "createSourceLocation");
|
|
963
|
+
function transformDynamicExpression(state, expression) {
|
|
964
|
+
if (ts__default.default.isBinaryExpression(expression) && expression.operatorToken.kind === ts__default.default.SyntaxKind.AmpersandAmpersandToken) {
|
|
965
|
+
const right = unwrapExpression(expression.right);
|
|
966
|
+
if (!isJsxExpression(right)) return null;
|
|
967
|
+
return createGetter(ts__default.default.factory.createConditionalExpression(
|
|
968
|
+
expression.left,
|
|
969
|
+
ts__default.default.factory.createToken(ts__default.default.SyntaxKind.QuestionToken),
|
|
970
|
+
transformJsxExpression(state, right),
|
|
971
|
+
ts__default.default.factory.createToken(ts__default.default.SyntaxKind.ColonToken),
|
|
972
|
+
ts__default.default.factory.createNull()
|
|
973
|
+
));
|
|
974
|
+
}
|
|
975
|
+
if (ts__default.default.isConditionalExpression(expression)) {
|
|
976
|
+
const whenTrue = transformDynamicBranch(state, expression.whenTrue);
|
|
977
|
+
const whenFalse = transformDynamicBranch(state, expression.whenFalse);
|
|
978
|
+
if (!whenTrue && !whenFalse) return null;
|
|
979
|
+
return createGetter(ts__default.default.factory.createConditionalExpression(
|
|
980
|
+
expression.condition,
|
|
981
|
+
ts__default.default.factory.createToken(ts__default.default.SyntaxKind.QuestionToken),
|
|
982
|
+
whenTrue ?? ts__default.default.factory.createNull(),
|
|
983
|
+
ts__default.default.factory.createToken(ts__default.default.SyntaxKind.ColonToken),
|
|
984
|
+
whenFalse ?? ts__default.default.factory.createNull()
|
|
985
|
+
));
|
|
986
|
+
}
|
|
987
|
+
return null;
|
|
988
|
+
}
|
|
989
|
+
__name(transformDynamicExpression, "transformDynamicExpression");
|
|
990
|
+
function transformDynamicBranch(state, expression) {
|
|
991
|
+
const branch = unwrapExpression(expression);
|
|
992
|
+
if (isJsxExpression(branch)) return transformJsxExpression(state, branch);
|
|
993
|
+
if (branch.kind === ts__default.default.SyntaxKind.NullKeyword || branch.kind === ts__default.default.SyntaxKind.FalseKeyword) return branch;
|
|
994
|
+
return null;
|
|
995
|
+
}
|
|
996
|
+
__name(transformDynamicBranch, "transformDynamicBranch");
|
|
997
|
+
function transformListExpression(state, parent, expression, anchor) {
|
|
998
|
+
if (!ts__default.default.isCallExpression(expression) || expression.arguments.length !== 1) return null;
|
|
999
|
+
if (!ts__default.default.isPropertyAccessExpression(expression.expression) || expression.expression.name.text !== "map") return null;
|
|
1000
|
+
const callback = expression.arguments[0];
|
|
1001
|
+
if (!ts__default.default.isArrowFunction(callback) && !ts__default.default.isFunctionExpression(callback)) return null;
|
|
1002
|
+
const body = unwrapExpression(callback.body);
|
|
1003
|
+
if (!isJsxExpression(body) || ts__default.default.isJsxFragment(body)) return null;
|
|
1004
|
+
const key = findKeyExpression(body);
|
|
1005
|
+
const renderItem = transformListCallback(callback, transformJsxExpression(state, body));
|
|
1006
|
+
const args = [
|
|
1007
|
+
parent,
|
|
1008
|
+
anchor,
|
|
1009
|
+
createGetter(expression.expression.expression),
|
|
1010
|
+
renderItem
|
|
1011
|
+
];
|
|
1012
|
+
if (key) args.push(createKeyCallback(callback, key));
|
|
1013
|
+
return args;
|
|
1014
|
+
}
|
|
1015
|
+
__name(transformListExpression, "transformListExpression");
|
|
1016
|
+
function transformListCallback(callback, body) {
|
|
1017
|
+
if (ts__default.default.isArrowFunction(callback)) {
|
|
1018
|
+
return ts__default.default.factory.updateArrowFunction(
|
|
1019
|
+
callback,
|
|
1020
|
+
callback.modifiers,
|
|
1021
|
+
callback.typeParameters,
|
|
1022
|
+
callback.parameters,
|
|
1023
|
+
callback.type,
|
|
1024
|
+
callback.equalsGreaterThanToken,
|
|
1025
|
+
body
|
|
1026
|
+
);
|
|
1027
|
+
}
|
|
1028
|
+
return ts__default.default.factory.updateFunctionExpression(
|
|
1029
|
+
callback,
|
|
1030
|
+
callback.modifiers,
|
|
1031
|
+
callback.asteriskToken,
|
|
1032
|
+
callback.name,
|
|
1033
|
+
callback.typeParameters,
|
|
1034
|
+
callback.parameters,
|
|
1035
|
+
callback.type,
|
|
1036
|
+
ts__default.default.factory.createBlock([ts__default.default.factory.createReturnStatement(body)], true)
|
|
1037
|
+
);
|
|
1038
|
+
}
|
|
1039
|
+
__name(transformListCallback, "transformListCallback");
|
|
1040
|
+
function createKeyCallback(callback, key) {
|
|
1041
|
+
return ts__default.default.factory.createArrowFunction(
|
|
1042
|
+
void 0,
|
|
1043
|
+
void 0,
|
|
1044
|
+
callback.parameters,
|
|
1045
|
+
void 0,
|
|
1046
|
+
ts__default.default.factory.createToken(ts__default.default.SyntaxKind.EqualsGreaterThanToken),
|
|
1047
|
+
key
|
|
1048
|
+
);
|
|
1049
|
+
}
|
|
1050
|
+
__name(createKeyCallback, "createKeyCallback");
|
|
1051
|
+
function findKeyExpression(node) {
|
|
1052
|
+
const attributes = ts__default.default.isJsxElement(node) ? node.openingElement.attributes : node.attributes;
|
|
1053
|
+
for (const attribute of attributes.properties) {
|
|
1054
|
+
if (!ts__default.default.isJsxAttribute(attribute) || attribute.name.getText() !== "key") continue;
|
|
1055
|
+
if (attribute.initializer && ts__default.default.isJsxExpression(attribute.initializer)) {
|
|
1056
|
+
return attribute.initializer.expression ?? null;
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
return null;
|
|
1060
|
+
}
|
|
1061
|
+
__name(findKeyExpression, "findKeyExpression");
|
|
1062
|
+
function unwrapExpression(node) {
|
|
1063
|
+
return ts__default.default.isParenthesizedExpression(node) ? node.expression : node;
|
|
1064
|
+
}
|
|
1065
|
+
__name(unwrapExpression, "unwrapExpression");
|
|
1066
|
+
function childToComponentExpression(state, child) {
|
|
1067
|
+
if (ts__default.default.isJsxText(child)) {
|
|
1068
|
+
const text = child.text.replace(/\s+/g, " ").trim();
|
|
1069
|
+
return text ? [ts__default.default.factory.createStringLiteral(text)] : [];
|
|
1070
|
+
}
|
|
1071
|
+
if (ts__default.default.isJsxElement(child) || ts__default.default.isJsxSelfClosingElement(child) || ts__default.default.isJsxFragment(child)) {
|
|
1072
|
+
return [transformJsxExpression(state, child)];
|
|
1073
|
+
}
|
|
1074
|
+
if (child.kind === ts__default.default.SyntaxKind.JsxExpression) {
|
|
1075
|
+
const expression = child.expression;
|
|
1076
|
+
return expression ? [transformEmbeddedExpression(state, expression)] : [];
|
|
1077
|
+
}
|
|
1078
|
+
return [];
|
|
1079
|
+
}
|
|
1080
|
+
__name(childToComponentExpression, "childToComponentExpression");
|
|
1081
|
+
function propertyName(name) {
|
|
1082
|
+
return /^[$A-Z_a-z][$\w]*$/u.test(name) ? ts__default.default.factory.createIdentifier(name) : ts__default.default.factory.createStringLiteral(name);
|
|
1083
|
+
}
|
|
1084
|
+
__name(propertyName, "propertyName");
|
|
1085
|
+
function createGetter(expression) {
|
|
1086
|
+
return ts__default.default.factory.createArrowFunction(
|
|
1087
|
+
void 0,
|
|
1088
|
+
void 0,
|
|
1089
|
+
[],
|
|
1090
|
+
void 0,
|
|
1091
|
+
ts__default.default.factory.createToken(ts__default.default.SyntaxKind.EqualsGreaterThanToken),
|
|
1092
|
+
expression
|
|
1093
|
+
);
|
|
1094
|
+
}
|
|
1095
|
+
__name(createGetter, "createGetter");
|
|
1096
|
+
function createGetterProperty(name, expression) {
|
|
1097
|
+
return ts__default.default.factory.createGetAccessorDeclaration(
|
|
1098
|
+
void 0,
|
|
1099
|
+
typeof name === "string" ? propertyName(name) : name,
|
|
1100
|
+
[],
|
|
1101
|
+
void 0,
|
|
1102
|
+
ts__default.default.factory.createBlock([ts__default.default.factory.createReturnStatement(expression)], true)
|
|
1103
|
+
);
|
|
1104
|
+
}
|
|
1105
|
+
__name(createGetterProperty, "createGetterProperty");
|
|
1106
|
+
function callStatement(state, name, args, source) {
|
|
1107
|
+
const statement = ts__default.default.factory.createExpressionStatement(
|
|
1108
|
+
ts__default.default.factory.createCallExpression(helperRef(state, name), void 0, args)
|
|
1109
|
+
);
|
|
1110
|
+
return source ? tagStatement(state, statement, source) : statement;
|
|
1111
|
+
}
|
|
1112
|
+
__name(callStatement, "callStatement");
|
|
1113
|
+
function createConstStatement(state, name, initializer, source) {
|
|
1114
|
+
const statement = ts__default.default.factory.createVariableStatement(
|
|
1115
|
+
void 0,
|
|
1116
|
+
ts__default.default.factory.createVariableDeclarationList([
|
|
1117
|
+
ts__default.default.factory.createVariableDeclaration(name, void 0, void 0, initializer)
|
|
1118
|
+
], ts__default.default.NodeFlags.Const)
|
|
1119
|
+
);
|
|
1120
|
+
return source ? tagStatement(state, statement, source) : statement;
|
|
1121
|
+
}
|
|
1122
|
+
__name(createConstStatement, "createConstStatement");
|
|
1123
|
+
function tagStatement(state, statement, source) {
|
|
1124
|
+
const position = positionOfNode(state, source);
|
|
1125
|
+
if (position) state.statementSources.set(statement, position);
|
|
1126
|
+
return statement;
|
|
1127
|
+
}
|
|
1128
|
+
__name(tagStatement, "tagStatement");
|
|
1129
|
+
function positionOfNode(state, node) {
|
|
1130
|
+
const sourceFile = node.getSourceFile() ?? state.sourceFile;
|
|
1131
|
+
if (!sourceFile || node.pos < 0) return null;
|
|
1132
|
+
const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
1133
|
+
return { line, column: character };
|
|
1134
|
+
}
|
|
1135
|
+
__name(positionOfNode, "positionOfNode");
|
|
1136
|
+
function nextIdentifier(state, prefix) {
|
|
1137
|
+
let name;
|
|
1138
|
+
do {
|
|
1139
|
+
name = `${prefix}${state.generatedId++}`;
|
|
1140
|
+
} while (state.takenNames.has(name));
|
|
1141
|
+
return ts__default.default.factory.createIdentifier(name);
|
|
1142
|
+
}
|
|
1143
|
+
__name(nextIdentifier, "nextIdentifier");
|
|
1144
|
+
|
|
1145
|
+
exports.compile = compile;
|
|
1146
|
+
exports.compileWithSourceMap = compileWithSourceMap;
|
|
1147
|
+
exports.createCompiler = createCompiler;
|
|
1148
|
+
//# sourceMappingURL=compile.cjs.map
|
|
1149
|
+
//# sourceMappingURL=compile.cjs.map
|