@zeus-js/compiler 0.1.0 → 0.1.1-beta.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/compiler.cjs +4 -1780
- package/dist/compiler.d.ts +35 -127
- package/dist/compiler.esm-bundler.js +4 -1781
- package/dist/compiler.prod.cjs +4 -1780
- package/package.json +9 -21
- package/dist/compiler.esm-browser.js +0 -19825
- package/dist/compiler.esm-browser.prod.js +0 -11
- package/dist/compiler.global.js +0 -19858
- package/dist/compiler.global.prod.js +0 -11
|
@@ -1,1786 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* compiler v0.1.
|
|
2
|
+
* compiler v0.1.1-beta.1
|
|
3
3
|
* (c) 2026 baicie
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
**/
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
import * as t from "@babel/types";
|
|
9
|
-
import { parseExpression } from "@babel/parser";
|
|
10
|
-
import { attrBindingIR, componentIR, dynamicTextIR, elementIR, eventBindingIR, expressionIR, forIR, fragmentIR, hostIR, id, identifierIR, propBindingIR, ref, refBindingIR, showIR, slotIR, staticAttrIR, textIR } from "@zeus-js/compiler-shared";
|
|
11
|
-
export * from "@zeus-js/compiler-shared";
|
|
12
|
-
//#region packages/core/compiler/src/codegen/support/imports.ts
|
|
13
|
-
/**
|
|
14
|
-
* Runtime helpers registration and program injection.
|
|
15
|
-
*
|
|
16
|
-
* Manages the collection of runtime helper imports (template, insert, setAttr,
|
|
17
|
-
* createComponent, delegateEvents, etc.) and generates the necessary import
|
|
18
|
-
* declarations at the top of the program.
|
|
19
|
-
*/
|
|
20
|
-
const DEFAULT_RENDERER_MODULE = "@zeus-js/runtime-dom";
|
|
21
|
-
function getImportKey(moduleName, imported) {
|
|
22
|
-
return `${moduleName}:${imported}`;
|
|
23
|
-
}
|
|
24
|
-
function getRendererConfig(path, renderer = "dom") {
|
|
25
|
-
var _hub$file;
|
|
26
|
-
const hub = path.hub;
|
|
27
|
-
return {
|
|
28
|
-
renderer,
|
|
29
|
-
moduleName: (hub === null || hub === void 0 || (_hub$file = hub.file) === null || _hub$file === void 0 || (_hub$file = _hub$file.metadata) === null || _hub$file === void 0 || (_hub$file = _hub$file.zeus) === null || _hub$file === void 0 || (_hub$file = _hub$file.config) === null || _hub$file === void 0 ? void 0 : _hub$file.moduleName) || "@zeus-js/runtime-dom"
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
function registerImportMethod(path, imported, moduleName = getRendererConfig(path, "dom").moduleName) {
|
|
33
|
-
const data = getProgramScopeData(path);
|
|
34
|
-
const importMethods = data.importMethods || (data.importMethods = /* @__PURE__ */ new Map());
|
|
35
|
-
const key = getImportKey(moduleName, imported);
|
|
36
|
-
const cached = importMethods.get(key);
|
|
37
|
-
if (cached) return t.cloneNode(cached.local);
|
|
38
|
-
const local = getProgramPath(path).scope.generateUidIdentifier(imported);
|
|
39
|
-
importMethods.set(key, {
|
|
40
|
-
imported,
|
|
41
|
-
local,
|
|
42
|
-
moduleName
|
|
43
|
-
});
|
|
44
|
-
return t.cloneNode(local);
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Generates import declarations for all collected runtime helpers and
|
|
48
|
-
* prepends them to the program body.
|
|
49
|
-
*/
|
|
50
|
-
function appendImportMethods(path) {
|
|
51
|
-
const importMethods = path.scope.data.importMethods;
|
|
52
|
-
if (!(importMethods === null || importMethods === void 0 ? void 0 : importMethods.size)) return;
|
|
53
|
-
const grouped = /* @__PURE__ */ new Map();
|
|
54
|
-
for (const record of importMethods.values()) {
|
|
55
|
-
const records = grouped.get(record.moduleName);
|
|
56
|
-
if (records) records.push(record);
|
|
57
|
-
else grouped.set(record.moduleName, [record]);
|
|
58
|
-
}
|
|
59
|
-
const declarations = [];
|
|
60
|
-
for (const [moduleName, records] of grouped) declarations.push(t.importDeclaration(records.map((record) => t.importSpecifier(t.cloneNode(record.local), t.identifier(record.imported))), t.stringLiteral(moduleName)));
|
|
61
|
-
path.unshiftContainer("body", declarations);
|
|
62
|
-
}
|
|
63
|
-
function getProgramScopeData(path) {
|
|
64
|
-
return path.scope.getProgramParent().path.scope.data;
|
|
65
|
-
}
|
|
66
|
-
function getProgramPath(path) {
|
|
67
|
-
return path.scope.getProgramParent().path;
|
|
68
|
-
}
|
|
69
|
-
//#endregion
|
|
70
|
-
//#region packages/core/compiler/src/codegen/support/templates.ts
|
|
71
|
-
/**
|
|
72
|
-
* Template registration, scope data management, and program injection.
|
|
73
|
-
*
|
|
74
|
-
* Tracks all compiled templates across the program scope, registers template
|
|
75
|
-
* variable declarations (tmpl$0, tmpl$1, ...), and generates the template
|
|
76
|
-
* registration calls at the top of the program.
|
|
77
|
-
*/
|
|
78
|
-
/**
|
|
79
|
-
* Retrieves all registered templates for a given renderer.
|
|
80
|
-
*/
|
|
81
|
-
function getTemplates(path, renderer = "dom") {
|
|
82
|
-
var _scopeData$templates$, _scopeData$templates;
|
|
83
|
-
return (_scopeData$templates$ = (_scopeData$templates = path.scope.data.templates) === null || _scopeData$templates === void 0 ? void 0 : _scopeData$templates.filter((t) => t.renderer === renderer)) !== null && _scopeData$templates$ !== void 0 ? _scopeData$templates$ : [];
|
|
84
|
-
}
|
|
85
|
-
function escapeStringForTemplate(value) {
|
|
86
|
-
return value.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
87
|
-
}
|
|
88
|
-
function isMathMLTemplate(template) {
|
|
89
|
-
return /^<(math|annotation|annotation-xml|maction|merror|mfrac|mi|mmultiscripts|mn|mo|mover|mpadded|mphantom|mprescripts|mroot|mrow|ms|mspace|msqrt|mstyle|msub|msubsup|msup|mtable|mtd|mtext|mtr|munder|munderover|semantics|menclose|mfenced)(\s|>)/.test(template);
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Generates `var tmpl$0 = template(...), tmpl$1 = template(...)` declarations
|
|
93
|
-
* and unshifts them to the top of the program.
|
|
94
|
-
*/
|
|
95
|
-
function appendTemplates(path) {
|
|
96
|
-
const templates = getTemplates(path, "dom");
|
|
97
|
-
if (!templates.length) return;
|
|
98
|
-
const templateMethod = registerImportMethod(path, "template", getRendererConfig(path, "dom").moduleName);
|
|
99
|
-
const declarators = templates.map((template) => {
|
|
100
|
-
const html = template.templateWithClosingTags || template.template;
|
|
101
|
-
const tmpl = {
|
|
102
|
-
cooked: html,
|
|
103
|
-
raw: escapeStringForTemplate(html)
|
|
104
|
-
};
|
|
105
|
-
const shouldUseImportNode = Boolean(template.isCE || template.isImportNode);
|
|
106
|
-
const isMathML = isMathMLTemplate(html);
|
|
107
|
-
const args = [t.templateLiteral([t.templateElement(tmpl, true)], [])];
|
|
108
|
-
if (template.isSVG || shouldUseImportNode || isMathML) args.push(t.booleanLiteral(shouldUseImportNode), t.booleanLiteral(Boolean(template.isSVG)), t.booleanLiteral(isMathML));
|
|
109
|
-
return t.variableDeclarator(t.cloneNode(template.id), t.addComment(t.callExpression(t.cloneNode(templateMethod), args), "leading", "#__PURE__"));
|
|
110
|
-
});
|
|
111
|
-
path.node.body.unshift(t.variableDeclaration("var", declarators));
|
|
112
|
-
}
|
|
113
|
-
//#endregion
|
|
114
|
-
//#region packages/core/compiler/src/codegen/support/events.ts
|
|
115
|
-
/**
|
|
116
|
-
* Event registration and delegation.
|
|
117
|
-
*
|
|
118
|
-
* Tracks all event handlers encountered during JSX transform and generates
|
|
119
|
-
* a single delegateEvents call at the end of the program (if any events
|
|
120
|
-
* were found).
|
|
121
|
-
*/
|
|
122
|
-
/**
|
|
123
|
-
* Registers an event name in the program scope.
|
|
124
|
-
* Events are deduplicated — registering the same event name multiple times
|
|
125
|
-
* only keeps it once.
|
|
126
|
-
*/
|
|
127
|
-
function registerEvent(path, eventName) {
|
|
128
|
-
const scopeData = path.scope.getProgramParent().path.scope.data;
|
|
129
|
-
(scopeData.events || (scopeData.events = /* @__PURE__ */ new Set())).add(eventName);
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Generates a delegateEvents(...) call at the end of the program body.
|
|
133
|
-
*
|
|
134
|
-
* This implements the event delegation pattern: instead of attaching individual
|
|
135
|
-
* addEventListener calls, we register event names with the runtime so it can
|
|
136
|
-
* attach a single delegated listener at the root.
|
|
137
|
-
*/
|
|
138
|
-
function appendEvents(path) {
|
|
139
|
-
const events = path.scope.data.events;
|
|
140
|
-
if (!(events === null || events === void 0 ? void 0 : events.size)) return;
|
|
141
|
-
path.node.body.push(t.expressionStatement(t.callExpression(registerImportMethod(path, "delegateEvents", getRendererConfig(path, "dom").moduleName), [t.arrayExpression(Array.from(events).map((eventName) => t.stringLiteral(eventName)))])));
|
|
142
|
-
}
|
|
143
|
-
//#endregion
|
|
144
|
-
//#region packages/core/compiler/src/config/index.ts
|
|
145
|
-
const DEFAULT_OPTIONS = {
|
|
146
|
-
moduleName: DEFAULT_RENDERER_MODULE,
|
|
147
|
-
generate: "dom",
|
|
148
|
-
hydratable: false,
|
|
149
|
-
delegateEvents: true,
|
|
150
|
-
delegatedEvents: [],
|
|
151
|
-
builtIns: [],
|
|
152
|
-
wrapConditionals: true,
|
|
153
|
-
omitNestedClosingTags: false,
|
|
154
|
-
omitLastClosingTag: true,
|
|
155
|
-
omitQuotes: true,
|
|
156
|
-
contextToCustomElements: false,
|
|
157
|
-
staticMarker: "@once",
|
|
158
|
-
effectWrapper: "effect",
|
|
159
|
-
memoWrapper: "memo",
|
|
160
|
-
validate: true,
|
|
161
|
-
inlineStyles: true
|
|
162
|
-
};
|
|
163
|
-
/**
|
|
164
|
-
* Resolve the compiler options by merging the default options with the provided options.
|
|
165
|
-
* @param options - The compiler options to resolve.
|
|
166
|
-
* @returns The resolved compiler options.
|
|
167
|
-
*/
|
|
168
|
-
function resolveConfig(options) {
|
|
169
|
-
return extend(DEFAULT_OPTIONS, options);
|
|
170
|
-
}
|
|
171
|
-
//#endregion
|
|
172
|
-
//#region packages/core/compiler/src/context/CompilerContext.ts
|
|
173
|
-
var CompilerContext = class {
|
|
174
|
-
constructor(options, programPath) {
|
|
175
|
-
this.options = options;
|
|
176
|
-
this.programPath = programPath;
|
|
177
|
-
}
|
|
178
|
-
runtimeModule() {
|
|
179
|
-
return this.options.moduleName || "@zeus-js/runtime-dom";
|
|
180
|
-
}
|
|
181
|
-
uid(name) {
|
|
182
|
-
return this.programPath.scope.generateUidIdentifier(name);
|
|
183
|
-
}
|
|
184
|
-
importRuntime(imported) {
|
|
185
|
-
const moduleName = this.runtimeModule();
|
|
186
|
-
const scopeData = this.programPath.scope.data;
|
|
187
|
-
const importMethods = scopeData.importMethods || (scopeData.importMethods = /* @__PURE__ */ new Map());
|
|
188
|
-
const key = `${moduleName}:${imported}`;
|
|
189
|
-
const cached = importMethods.get(key);
|
|
190
|
-
if (cached) return t.cloneNode(cached.local);
|
|
191
|
-
const local = this.uid(imported);
|
|
192
|
-
importMethods.set(key, {
|
|
193
|
-
moduleName,
|
|
194
|
-
imported,
|
|
195
|
-
local
|
|
196
|
-
});
|
|
197
|
-
return t.cloneNode(local);
|
|
198
|
-
}
|
|
199
|
-
registerTemplate(html, isSVG = false) {
|
|
200
|
-
const scopeData = this.programPath.scope.data;
|
|
201
|
-
const templateMap = scopeData.templateMap || (scopeData.templateMap = /* @__PURE__ */ new Map());
|
|
202
|
-
const templates = scopeData.templates || (scopeData.templates = []);
|
|
203
|
-
const cached = templateMap.get(html);
|
|
204
|
-
if (cached) return {
|
|
205
|
-
id: t.cloneNode(cached.id),
|
|
206
|
-
html,
|
|
207
|
-
isSVG: Boolean(cached.isSVG)
|
|
208
|
-
};
|
|
209
|
-
const id = this.uid("tmpl$");
|
|
210
|
-
templateMap.set(html, {
|
|
211
|
-
id,
|
|
212
|
-
template: html,
|
|
213
|
-
templateWithClosingTags: html,
|
|
214
|
-
renderer: "dom",
|
|
215
|
-
isSVG,
|
|
216
|
-
isCE: html.includes("-"),
|
|
217
|
-
isImportNode: /^<(img|iframe)(\s|>)/.test(html)
|
|
218
|
-
});
|
|
219
|
-
templates.push(templateMap.get(html));
|
|
220
|
-
return {
|
|
221
|
-
id: t.cloneNode(id),
|
|
222
|
-
html,
|
|
223
|
-
isSVG
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
};
|
|
227
|
-
function getCompilerContext(path, options) {
|
|
228
|
-
return new CompilerContext(options, path.scope.getProgramParent().path);
|
|
229
|
-
}
|
|
230
|
-
//#endregion
|
|
231
|
-
//#region packages/core/compiler/src/context/defineElementSetups.ts
|
|
232
|
-
const ZEUS_PUBLIC_MODULE = "@zeus-js/zeus";
|
|
233
|
-
function collectDefineElementSetups(path, runtimeModule) {
|
|
234
|
-
const setups = /* @__PURE__ */ new WeakSet();
|
|
235
|
-
const trustedModules = /* @__PURE__ */ new Set([
|
|
236
|
-
DEFAULT_RENDERER_MODULE,
|
|
237
|
-
ZEUS_PUBLIC_MODULE,
|
|
238
|
-
runtimeModule
|
|
239
|
-
]);
|
|
240
|
-
for (const statement of path.node.body) {
|
|
241
|
-
if (!t.isImportDeclaration(statement) || !trustedModules.has(statement.source.value)) continue;
|
|
242
|
-
for (const specifier of statement.specifiers) {
|
|
243
|
-
if (!isDefineElementImport(specifier)) continue;
|
|
244
|
-
const binding = path.scope.getBinding(specifier.local.name);
|
|
245
|
-
if (!binding || binding.path.node !== specifier) continue;
|
|
246
|
-
for (const reference of binding.referencePaths) collectSetupFromReference(reference, setups);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
getProgramScopeData(path).defineElementSetups = setups;
|
|
250
|
-
}
|
|
251
|
-
function isDefineElementRenderRoot(path) {
|
|
252
|
-
var _returnPath$getFuncti;
|
|
253
|
-
const setups = getProgramScopeData(path).defineElementSetups;
|
|
254
|
-
const functionPath = path.getFunctionParent();
|
|
255
|
-
if (!setups || !functionPath || !t.isFunction(functionPath.node) || !setups.has(functionPath.node)) return false;
|
|
256
|
-
const root = skipTransparentExpressionWrappers(path);
|
|
257
|
-
if (functionPath.isArrowFunctionExpression() && functionPath.node.body === root.node) return true;
|
|
258
|
-
const returnPath = root.parentPath;
|
|
259
|
-
return Boolean((returnPath === null || returnPath === void 0 ? void 0 : returnPath.isReturnStatement()) && returnPath.node.argument === root.node && ((_returnPath$getFuncti = returnPath.getFunctionParent()) === null || _returnPath$getFuncti === void 0 ? void 0 : _returnPath$getFuncti.node) === functionPath.node);
|
|
260
|
-
}
|
|
261
|
-
function isDefineElementImport(specifier) {
|
|
262
|
-
if (!t.isImportSpecifier(specifier)) return false;
|
|
263
|
-
const imported = specifier.imported;
|
|
264
|
-
return t.isIdentifier(imported) && imported.name === "defineElement" || t.isStringLiteral(imported) && imported.value === "defineElement";
|
|
265
|
-
}
|
|
266
|
-
function collectSetupFromReference(reference, setups) {
|
|
267
|
-
const call = reference.parentPath;
|
|
268
|
-
if (reference.key !== "callee" || !(call === null || call === void 0 ? void 0 : call.isCallExpression()) || call.node.callee !== reference.node) return;
|
|
269
|
-
const setup = call.get("arguments")[2];
|
|
270
|
-
if (!setup) return;
|
|
271
|
-
const setupFunction = resolveSetupFunction(setup, /* @__PURE__ */ new Set());
|
|
272
|
-
if (setupFunction) setups.add(setupFunction);
|
|
273
|
-
}
|
|
274
|
-
function resolveSetupFunction(path, visitedBindings) {
|
|
275
|
-
const setupPath = unwrapTransparentExpressionWrappers(path);
|
|
276
|
-
if (setupPath.isArrowFunctionExpression() || setupPath.isFunctionExpression()) return setupPath.node;
|
|
277
|
-
if (!setupPath.isIdentifier()) return void 0;
|
|
278
|
-
const binding = setupPath.scope.getBinding(setupPath.node.name);
|
|
279
|
-
if (!(binding === null || binding === void 0 ? void 0 : binding.constant) || visitedBindings.has(binding)) return void 0;
|
|
280
|
-
visitedBindings.add(binding);
|
|
281
|
-
if (binding.path.isFunctionDeclaration()) return binding.path.node;
|
|
282
|
-
if (!binding.path.isVariableDeclarator()) return void 0;
|
|
283
|
-
const init = binding.path.get("init");
|
|
284
|
-
if (Array.isArray(init) || !init.node) return void 0;
|
|
285
|
-
return resolveSetupFunction(init, visitedBindings);
|
|
286
|
-
}
|
|
287
|
-
function unwrapTransparentExpressionWrappers(path) {
|
|
288
|
-
let current = path;
|
|
289
|
-
while (isTransparentExpressionWrapper(current.node)) current = current.get("expression");
|
|
290
|
-
return current;
|
|
291
|
-
}
|
|
292
|
-
function skipTransparentExpressionWrappers(path) {
|
|
293
|
-
let current = path;
|
|
294
|
-
while (current.parentPath && wrapsExpression(current.parentPath, current)) current = current.parentPath;
|
|
295
|
-
return current;
|
|
296
|
-
}
|
|
297
|
-
function wrapsExpression(parent, child) {
|
|
298
|
-
const node = parent.node;
|
|
299
|
-
return isTransparentExpressionWrapper(node) && node.expression === child.node;
|
|
300
|
-
}
|
|
301
|
-
function isTransparentExpressionWrapper(node) {
|
|
302
|
-
return t.isParenthesizedExpression(node) || t.isTSAsExpression(node) || t.isTSSatisfiesExpression(node) || t.isTSTypeAssertion(node) || t.isTypeCastExpression(node) || t.isTSNonNullExpression(node);
|
|
303
|
-
}
|
|
304
|
-
//#endregion
|
|
305
|
-
//#region packages/core/compiler/src/utils/constant.ts
|
|
306
|
-
const VoidElements = [
|
|
307
|
-
"area",
|
|
308
|
-
"base",
|
|
309
|
-
"br",
|
|
310
|
-
"col",
|
|
311
|
-
"embed",
|
|
312
|
-
"hr",
|
|
313
|
-
"img",
|
|
314
|
-
"input",
|
|
315
|
-
"keygen",
|
|
316
|
-
"link",
|
|
317
|
-
"menuitem",
|
|
318
|
-
"meta",
|
|
319
|
-
"param",
|
|
320
|
-
"source",
|
|
321
|
-
"track",
|
|
322
|
-
"wbr"
|
|
323
|
-
];
|
|
324
|
-
//#endregion
|
|
325
|
-
//#region packages/core/compiler/src/utils/html.ts
|
|
326
|
-
function escapeHTML(value, attr = false) {
|
|
327
|
-
let result = value.replace(/&/g, "&");
|
|
328
|
-
if (attr) return result.replace(/"/g, """).replace(/>/g, ">");
|
|
329
|
-
return result.replace(/</g, "<");
|
|
330
|
-
}
|
|
331
|
-
function trimJSXText(value) {
|
|
332
|
-
return value.replace(/\r\n?/g, "\n").split("\n").map((line) => line.trim()).filter(Boolean).join(" ");
|
|
333
|
-
}
|
|
334
|
-
const rawTextElements = /* @__PURE__ */ new Set([
|
|
335
|
-
"script",
|
|
336
|
-
"style",
|
|
337
|
-
"textarea",
|
|
338
|
-
"title"
|
|
339
|
-
]);
|
|
340
|
-
function isRawTextElement(tagName) {
|
|
341
|
-
return rawTextElements.has(tagName);
|
|
342
|
-
}
|
|
343
|
-
//#endregion
|
|
344
|
-
//#region packages/core/compiler/src/utils/metadata.ts
|
|
345
|
-
function setZeusMetadata(state, config) {
|
|
346
|
-
const metadata = state.file.metadata;
|
|
347
|
-
metadata.zeus = extend({}, metadata.zeus, { config });
|
|
348
|
-
return metadata.zeus;
|
|
349
|
-
}
|
|
350
|
-
//#endregion
|
|
351
|
-
//#region packages/core/compiler/src/program.ts
|
|
352
|
-
/**
|
|
353
|
-
* Program visitor — entry and exit point for the entire transform pass.
|
|
354
|
-
*
|
|
355
|
-
* - Program.enter: initializes file metadata
|
|
356
|
-
* - Program.exit: injects all collected codegen artifacts (templates, events, imports)
|
|
357
|
-
*/
|
|
358
|
-
function enterProgram(config, path, state) {
|
|
359
|
-
setZeusMetadata(state, config);
|
|
360
|
-
collectDefineElementSetups(path, config.moduleName);
|
|
361
|
-
}
|
|
362
|
-
function exitProgram(config, path, state) {
|
|
363
|
-
if (state.get("skip")) return;
|
|
364
|
-
appendTemplates(path);
|
|
365
|
-
appendEvents(path);
|
|
366
|
-
appendImportMethods(path);
|
|
367
|
-
}
|
|
368
|
-
function createProgramVisitor(config) {
|
|
369
|
-
return {
|
|
370
|
-
enter(path, state) {
|
|
371
|
-
enterProgram(config, path, state);
|
|
372
|
-
},
|
|
373
|
-
exit(path, state) {
|
|
374
|
-
exitProgram(config, path, state);
|
|
375
|
-
}
|
|
376
|
-
};
|
|
377
|
-
}
|
|
378
|
-
//#endregion
|
|
379
|
-
//#region \0@oxc-project+runtime@0.137.0/helpers/esm/typeof.js
|
|
380
|
-
function _typeof(o) {
|
|
381
|
-
"@babel/helpers - typeof";
|
|
382
|
-
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
|
383
|
-
return typeof o;
|
|
384
|
-
} : function(o) {
|
|
385
|
-
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
386
|
-
}, _typeof(o);
|
|
387
|
-
}
|
|
388
|
-
//#endregion
|
|
389
|
-
//#region \0@oxc-project+runtime@0.137.0/helpers/esm/toPrimitive.js
|
|
390
|
-
function toPrimitive(t, r) {
|
|
391
|
-
if ("object" != _typeof(t) || !t) return t;
|
|
392
|
-
var e = t[Symbol.toPrimitive];
|
|
393
|
-
if (void 0 !== e) {
|
|
394
|
-
var i = e.call(t, r || "default");
|
|
395
|
-
if ("object" != _typeof(i)) return i;
|
|
396
|
-
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
397
|
-
}
|
|
398
|
-
return ("string" === r ? String : Number)(t);
|
|
399
|
-
}
|
|
400
|
-
//#endregion
|
|
401
|
-
//#region \0@oxc-project+runtime@0.137.0/helpers/esm/toPropertyKey.js
|
|
402
|
-
function toPropertyKey(t) {
|
|
403
|
-
var i = toPrimitive(t, "string");
|
|
404
|
-
return "symbol" == _typeof(i) ? i : i + "";
|
|
405
|
-
}
|
|
406
|
-
//#endregion
|
|
407
|
-
//#region \0@oxc-project+runtime@0.137.0/helpers/esm/defineProperty.js
|
|
408
|
-
function _defineProperty(e, r, t) {
|
|
409
|
-
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
410
|
-
value: t,
|
|
411
|
-
enumerable: !0,
|
|
412
|
-
configurable: !0,
|
|
413
|
-
writable: !0
|
|
414
|
-
}) : e[r] = t, e;
|
|
415
|
-
}
|
|
416
|
-
//#endregion
|
|
417
|
-
//#region \0@oxc-project+runtime@0.137.0/helpers/esm/objectSpread2.js
|
|
418
|
-
function ownKeys(e, r) {
|
|
419
|
-
var t = Object.keys(e);
|
|
420
|
-
if (Object.getOwnPropertySymbols) {
|
|
421
|
-
var o = Object.getOwnPropertySymbols(e);
|
|
422
|
-
r && (o = o.filter(function(r) {
|
|
423
|
-
return Object.getOwnPropertyDescriptor(e, r).enumerable;
|
|
424
|
-
})), t.push.apply(t, o);
|
|
425
|
-
}
|
|
426
|
-
return t;
|
|
427
|
-
}
|
|
428
|
-
function _objectSpread2(e) {
|
|
429
|
-
for (var r = 1; r < arguments.length; r++) {
|
|
430
|
-
var t = null != arguments[r] ? arguments[r] : {};
|
|
431
|
-
r % 2 ? ownKeys(Object(t), !0).forEach(function(r) {
|
|
432
|
-
_defineProperty(e, r, t[r]);
|
|
433
|
-
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r) {
|
|
434
|
-
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
return e;
|
|
438
|
-
}
|
|
439
|
-
//#endregion
|
|
440
|
-
//#region packages/core/compiler/src/adapters/babel/expression.ts
|
|
441
|
-
function lowerExpressionIR(path) {
|
|
442
|
-
return expressionIR(path.getSource() || path.toString(), sourceSpanFromBabelNode(path.node));
|
|
443
|
-
}
|
|
444
|
-
function expressionIRFromCode(code, node) {
|
|
445
|
-
return expressionIR(code, sourceSpanFromBabelNode(node));
|
|
446
|
-
}
|
|
447
|
-
function parseExpressionIR(expression) {
|
|
448
|
-
var _expression$span;
|
|
449
|
-
const start = (_expression$span = expression.span) === null || _expression$span === void 0 ? void 0 : _expression$span.start;
|
|
450
|
-
const sourceStart = typeof (start === null || start === void 0 ? void 0 : start.offset) === "number" ? {
|
|
451
|
-
startLine: start.line,
|
|
452
|
-
startColumn: start.column,
|
|
453
|
-
startIndex: start.offset
|
|
454
|
-
} : {};
|
|
455
|
-
return parseExpression(expression.code, _objectSpread2({
|
|
456
|
-
sourceType: "module",
|
|
457
|
-
plugins: ["typescript", "jsx"]
|
|
458
|
-
}, sourceStart));
|
|
459
|
-
}
|
|
460
|
-
function sourceSpanFromBabelNode(node) {
|
|
461
|
-
if (!(node === null || node === void 0 ? void 0 : node.loc)) return void 0;
|
|
462
|
-
return {
|
|
463
|
-
start: sourcePosition(node.loc.start.line, node.loc.start.column, node.start),
|
|
464
|
-
end: sourcePosition(node.loc.end.line, node.loc.end.column, node.end)
|
|
465
|
-
};
|
|
466
|
-
}
|
|
467
|
-
function sourcePosition(line, column, offset) {
|
|
468
|
-
return typeof offset === "number" ? {
|
|
469
|
-
line,
|
|
470
|
-
column,
|
|
471
|
-
offset
|
|
472
|
-
} : {
|
|
473
|
-
line,
|
|
474
|
-
column
|
|
475
|
-
};
|
|
476
|
-
}
|
|
477
|
-
//#endregion
|
|
478
|
-
//#region packages/core/compiler/src/codegen/dom/emitBinding.ts
|
|
479
|
-
function emitBindings(node, context) {
|
|
480
|
-
const statements = [];
|
|
481
|
-
for (const attr of node.attrs) {
|
|
482
|
-
if (attr.kind === "AttrBinding") statements.push(emitAttrBinding(node, attr, context));
|
|
483
|
-
if (attr.kind === "EventBinding") statements.push(emitEventBinding(node, attr, context));
|
|
484
|
-
if (attr.kind === "PropBinding") statements.push(emitPropBinding(node, attr, context));
|
|
485
|
-
if (attr.kind === "RefBinding") statements.push(emitRefBinding(node, attr, context));
|
|
486
|
-
}
|
|
487
|
-
if (isRawTextElement(node.tagName) && hasRuntimeRawText$1(node.children)) {
|
|
488
|
-
statements.push(emitRawTextBinding(node, context));
|
|
489
|
-
return statements;
|
|
490
|
-
}
|
|
491
|
-
for (const child of node.children) statements.push(...emitChildBinding(child, context));
|
|
492
|
-
return statements;
|
|
493
|
-
}
|
|
494
|
-
function emitRawTextBinding(node, context) {
|
|
495
|
-
return t.expressionStatement(t.callExpression(context.importRuntime("bindTextContent"), [t.identifier(node.ref.name), t.arrowFunctionExpression([], emitRawTextValue(node.children))]));
|
|
496
|
-
}
|
|
497
|
-
function hasRuntimeRawText$1(children) {
|
|
498
|
-
return children.some((child) => {
|
|
499
|
-
if (child.kind === "Text") return false;
|
|
500
|
-
if (child.kind === "Fragment") return hasRuntimeRawText$1(child.children);
|
|
501
|
-
return true;
|
|
502
|
-
});
|
|
503
|
-
}
|
|
504
|
-
function emitRawTextValue(children) {
|
|
505
|
-
const values = children.flatMap((child) => {
|
|
506
|
-
switch (child.kind) {
|
|
507
|
-
case "Text": return [t.stringLiteral(child.value)];
|
|
508
|
-
case "DynamicText": return [parseExpressionIR(child.expr)];
|
|
509
|
-
case "Fragment": return [emitRawTextValue(child.children)];
|
|
510
|
-
default: return [];
|
|
511
|
-
}
|
|
512
|
-
});
|
|
513
|
-
if (values.length === 0) return t.stringLiteral("");
|
|
514
|
-
if (values.length === 1) return values[0];
|
|
515
|
-
return t.arrayExpression(values);
|
|
516
|
-
}
|
|
517
|
-
function emitChildBinding(node, context) {
|
|
518
|
-
switch (node.kind) {
|
|
519
|
-
case "DynamicText": return emitDynamicText(node, context);
|
|
520
|
-
case "Component": return emitComponentInsert(node, context);
|
|
521
|
-
case "Show": return emitMarkerMount(node, context, emitMountShow(node, context));
|
|
522
|
-
case "For": return emitMarkerMount(node, context, emitMountFor(node, context));
|
|
523
|
-
case "Slot": return emitMarkerInsert(node, context, emitSlot(node, context));
|
|
524
|
-
case "Element": return emitBindings(node, context);
|
|
525
|
-
case "Fragment": return node.children.flatMap((child) => emitChildBinding(child, context));
|
|
526
|
-
default: return [];
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
function emitAttrBinding(target, binding, context) {
|
|
530
|
-
const name = normalizeAttrName(binding.name);
|
|
531
|
-
if (name === "class") return t.expressionStatement(t.callExpression(context.importRuntime("bindClass"), [t.identifier(target.ref.name), emitGetter(parseExpressionIR(binding.expr))]));
|
|
532
|
-
if (name === "style") return t.expressionStatement(t.callExpression(context.importRuntime("bindStyle"), [t.identifier(target.ref.name), emitGetter(parseExpressionIR(binding.expr))]));
|
|
533
|
-
return t.expressionStatement(t.callExpression(context.importRuntime("bindAttr"), [
|
|
534
|
-
t.identifier(target.ref.name),
|
|
535
|
-
t.stringLiteral(name),
|
|
536
|
-
emitGetter(parseExpressionIR(binding.expr))
|
|
537
|
-
]));
|
|
538
|
-
}
|
|
539
|
-
function normalizeAttrName(name) {
|
|
540
|
-
return name === "className" ? "class" : name;
|
|
541
|
-
}
|
|
542
|
-
function emitEventBinding(target, binding, context) {
|
|
543
|
-
registerEvent(context.programPath, binding.eventName);
|
|
544
|
-
return t.expressionStatement(t.callExpression(context.importRuntime("bindEvent"), [
|
|
545
|
-
t.identifier(target.ref.name),
|
|
546
|
-
t.stringLiteral(binding.eventName),
|
|
547
|
-
normalizeEventHandler(parseExpressionIR(binding.handler), context)
|
|
548
|
-
]));
|
|
549
|
-
}
|
|
550
|
-
function normalizeEventHandler(handler, context) {
|
|
551
|
-
if (t.isMemberExpression(handler) || t.isOptionalMemberExpression(handler)) {
|
|
552
|
-
const event = context.uid("event$");
|
|
553
|
-
return t.arrowFunctionExpression([t.identifier(event.name)], t.optionalCallExpression(t.cloneNode(handler), [t.identifier(event.name)], true));
|
|
554
|
-
}
|
|
555
|
-
return handler;
|
|
556
|
-
}
|
|
557
|
-
function emitPropBinding(target, binding, context) {
|
|
558
|
-
return t.expressionStatement(t.callExpression(context.importRuntime("bindProp"), [
|
|
559
|
-
t.identifier(target.ref.name),
|
|
560
|
-
t.stringLiteral(binding.name),
|
|
561
|
-
emitGetter(parseExpressionIR(binding.expr))
|
|
562
|
-
]));
|
|
563
|
-
}
|
|
564
|
-
function emitGetter(expr) {
|
|
565
|
-
if (t.isArrowFunctionExpression(expr) || t.isFunctionExpression(expr)) return expr;
|
|
566
|
-
return t.arrowFunctionExpression([], expr);
|
|
567
|
-
}
|
|
568
|
-
function emitRefBinding(target, binding, context) {
|
|
569
|
-
return t.expressionStatement(t.callExpression(context.importRuntime("bindRef"), [t.identifier(target.ref.name), parseExpressionIR(binding.expr)]));
|
|
570
|
-
}
|
|
571
|
-
function emitDynamicText(node, context) {
|
|
572
|
-
if (!node.domPath || node.domPath.kind !== "Marker") return [];
|
|
573
|
-
const textRef = context.uid("text$");
|
|
574
|
-
const expression = parseExpressionIR(node.expr);
|
|
575
|
-
if (node.once) return [t.variableDeclaration("const", [t.variableDeclarator(textRef, t.callExpression(t.memberExpression(t.identifier("document"), t.identifier("createTextNode")), [t.callExpression(t.identifier("String"), [expression])]))]), t.expressionStatement(t.callExpression(context.importRuntime("insert"), [
|
|
576
|
-
t.identifier(node.domPath.parent.name),
|
|
577
|
-
textRef,
|
|
578
|
-
t.identifier(node.ref.name)
|
|
579
|
-
]))];
|
|
580
|
-
return [
|
|
581
|
-
t.variableDeclaration("const", [t.variableDeclarator(textRef, t.callExpression(t.memberExpression(t.identifier("document"), t.identifier("createTextNode")), [t.stringLiteral("")]))]),
|
|
582
|
-
t.expressionStatement(t.callExpression(context.importRuntime("insert"), [
|
|
583
|
-
t.identifier(node.domPath.parent.name),
|
|
584
|
-
textRef,
|
|
585
|
-
t.identifier(node.ref.name)
|
|
586
|
-
])),
|
|
587
|
-
t.expressionStatement(t.callExpression(context.importRuntime("bindText"), [textRef, t.arrowFunctionExpression([], expression)]))
|
|
588
|
-
];
|
|
589
|
-
}
|
|
590
|
-
function emitComponentInsert(node, context) {
|
|
591
|
-
return emitMarkerInsert(node, context, emitComponent(node, context));
|
|
592
|
-
}
|
|
593
|
-
function emitMarkerInsert(node, context, value) {
|
|
594
|
-
if (!node.domPath || node.domPath.kind !== "Marker") return [];
|
|
595
|
-
return [t.expressionStatement(t.callExpression(context.importRuntime("insert"), [
|
|
596
|
-
t.identifier(node.domPath.parent.name),
|
|
597
|
-
value,
|
|
598
|
-
t.identifier(node.ref.name)
|
|
599
|
-
]))];
|
|
600
|
-
}
|
|
601
|
-
function emitMarkerMount(node, context, mountCall) {
|
|
602
|
-
if (!node.domPath || node.domPath.kind !== "Marker") return [];
|
|
603
|
-
return [t.expressionStatement(mountCall)];
|
|
604
|
-
}
|
|
605
|
-
//#endregion
|
|
606
|
-
//#region packages/core/compiler/src/codegen/dom/emitDomPath.ts
|
|
607
|
-
function emitPhysicalDomPath(path) {
|
|
608
|
-
switch (path.kind) {
|
|
609
|
-
case "Root": throw new Error("Root path is emitted from template clone directly");
|
|
610
|
-
case "FirstChild": return t.memberExpression(t.identifier(path.parent.name), t.identifier("firstChild"));
|
|
611
|
-
case "NextSibling": return t.memberExpression(t.identifier(path.previous.name), t.identifier("nextSibling"));
|
|
612
|
-
case "ChildNode": return t.memberExpression(t.memberExpression(t.identifier(path.parent.name), t.identifier("childNodes")), t.numericLiteral(path.index), true);
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
//#endregion
|
|
616
|
-
//#region packages/core/compiler/src/passes/collectTemplates.ts
|
|
617
|
-
function collectTemplates(node, context) {
|
|
618
|
-
if (node.kind === "Element") {
|
|
619
|
-
context.registerTemplate(renderTemplateHTML(node), node.flags.isSVG);
|
|
620
|
-
return;
|
|
621
|
-
}
|
|
622
|
-
if (node.kind === "Fragment") for (const child of node.children) {
|
|
623
|
-
if (child.kind !== "Element") continue;
|
|
624
|
-
context.registerTemplate(renderTemplateHTML(child), child.flags.isSVG);
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
function normalizeStaticAttrName(name) {
|
|
628
|
-
return name === "className" ? "class" : name;
|
|
629
|
-
}
|
|
630
|
-
function renderTemplateHTML(node) {
|
|
631
|
-
const attrs = node.attrs.filter((attr) => attr.kind === "StaticAttribute").map((attr) => {
|
|
632
|
-
if (attr.kind !== "StaticAttribute") return "";
|
|
633
|
-
const name = normalizeStaticAttrName(attr.name);
|
|
634
|
-
if (attr.value === true) return ` ${name}`;
|
|
635
|
-
return ` ${name}="${escapeAttr(attr.value)}"`;
|
|
636
|
-
}).join("");
|
|
637
|
-
if (node.flags.isVoid) return `<${node.tagName}${attrs}>`;
|
|
638
|
-
if (isRawTextElement(node.tagName) && hasRuntimeRawText(node.children)) return `<${node.tagName}${attrs}></${node.tagName}>`;
|
|
639
|
-
return `<${node.tagName}${attrs}>${node.children.map(renderChildTemplate).join("")}</${node.tagName}>`;
|
|
640
|
-
}
|
|
641
|
-
function hasRuntimeRawText(children) {
|
|
642
|
-
return children.some((child) => {
|
|
643
|
-
if (child.kind === "Text") return false;
|
|
644
|
-
if (child.kind === "Fragment") return hasRuntimeRawText(child.children);
|
|
645
|
-
return true;
|
|
646
|
-
});
|
|
647
|
-
}
|
|
648
|
-
function renderChildTemplate(node) {
|
|
649
|
-
switch (node.kind) {
|
|
650
|
-
case "Element": return renderTemplateHTML(node);
|
|
651
|
-
case "Text": return node.value;
|
|
652
|
-
case "DynamicText":
|
|
653
|
-
case "Component":
|
|
654
|
-
case "Show":
|
|
655
|
-
case "For":
|
|
656
|
-
case "Slot": return "<!>";
|
|
657
|
-
case "Host": return node.child ? renderChildTemplate(node.child) : "";
|
|
658
|
-
case "Fragment": return node.children.map(renderChildTemplate).join("");
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
function escapeAttr(value) {
|
|
662
|
-
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<");
|
|
663
|
-
}
|
|
664
|
-
//#endregion
|
|
665
|
-
//#region packages/core/compiler/src/codegen/dom/emitTemplate.ts
|
|
666
|
-
function emitTemplateClone(node, context) {
|
|
667
|
-
const html = renderTemplateHTML(node);
|
|
668
|
-
const template = context.registerTemplate(html, node.flags.isSVG);
|
|
669
|
-
const templateCall = t.callExpression(t.cloneNode(template.id), []);
|
|
670
|
-
return t.memberExpression(templateCall, t.identifier("firstChild"));
|
|
671
|
-
}
|
|
672
|
-
//#endregion
|
|
673
|
-
//#region packages/core/compiler/src/codegen/dom/emitElement.ts
|
|
674
|
-
function emitElement(node, context) {
|
|
675
|
-
if (!hasRuntimeWork(node)) return emitTemplateClone(node, context);
|
|
676
|
-
const statements = [
|
|
677
|
-
t.variableDeclaration("const", [t.variableDeclarator(t.identifier(node.ref.name), emitTemplateClone(node, context))]),
|
|
678
|
-
...emitDomRefDeclarations(node.children, context),
|
|
679
|
-
...emitBindings(node, context),
|
|
680
|
-
t.returnStatement(t.identifier(node.ref.name))
|
|
681
|
-
];
|
|
682
|
-
return t.callExpression(t.arrowFunctionExpression([], t.blockStatement(statements)), []);
|
|
683
|
-
}
|
|
684
|
-
function emitDomRefDeclarations(children, context) {
|
|
685
|
-
const statements = [];
|
|
686
|
-
const declared = /* @__PURE__ */ new Set();
|
|
687
|
-
const refNodeMap = collectRefNodeMap(children);
|
|
688
|
-
for (const child of children) collectRequiredDomRefDeclaration(child, statements, context, refNodeMap, declared);
|
|
689
|
-
return statements;
|
|
690
|
-
}
|
|
691
|
-
function collectRefNodeMap(children) {
|
|
692
|
-
const map = /* @__PURE__ */ new Map();
|
|
693
|
-
for (const child of children) collectRefNode(child, map);
|
|
694
|
-
return map;
|
|
695
|
-
}
|
|
696
|
-
function collectRefNode(node, map) {
|
|
697
|
-
switch (node.kind) {
|
|
698
|
-
case "Element":
|
|
699
|
-
map.set(node.ref.name, node);
|
|
700
|
-
for (const child of node.children) collectRefNode(child, map);
|
|
701
|
-
return;
|
|
702
|
-
case "DynamicText":
|
|
703
|
-
case "Component":
|
|
704
|
-
case "Show":
|
|
705
|
-
case "For":
|
|
706
|
-
case "Slot":
|
|
707
|
-
map.set(node.ref.name, node);
|
|
708
|
-
return;
|
|
709
|
-
case "Fragment":
|
|
710
|
-
for (const child of node.children) collectRefNode(child, map);
|
|
711
|
-
return;
|
|
712
|
-
case "Host":
|
|
713
|
-
if (node.child) collectRefNode(node.child, map);
|
|
714
|
-
return;
|
|
715
|
-
default: return;
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
function collectRequiredDomRefDeclaration(node, statements, context, refNodeMap, declared) {
|
|
719
|
-
switch (node.kind) {
|
|
720
|
-
case "Element":
|
|
721
|
-
if (needsDomRefDeclaration(node)) emitDomRefDeclarationWithDeps(node, statements, context, refNodeMap, declared);
|
|
722
|
-
for (const child of node.children) collectRequiredDomRefDeclaration(child, statements, context, refNodeMap, declared);
|
|
723
|
-
return;
|
|
724
|
-
case "DynamicText":
|
|
725
|
-
case "Component":
|
|
726
|
-
case "Show":
|
|
727
|
-
case "For":
|
|
728
|
-
case "Slot":
|
|
729
|
-
emitDomRefDeclarationWithDeps(node, statements, context, refNodeMap, declared);
|
|
730
|
-
return;
|
|
731
|
-
case "Fragment":
|
|
732
|
-
for (const child of node.children) collectRequiredDomRefDeclaration(child, statements, context, refNodeMap, declared);
|
|
733
|
-
return;
|
|
734
|
-
case "Host":
|
|
735
|
-
if (node.child) collectRequiredDomRefDeclaration(node.child, statements, context, refNodeMap, declared);
|
|
736
|
-
return;
|
|
737
|
-
default: return;
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
function emitDomRefDeclarationWithDeps(node, statements, context, refNodeMap, declared) {
|
|
741
|
-
if (declared.has(node.ref.name)) return;
|
|
742
|
-
if (!node.physicalDomPath) throw new Error(`${node.kind} physical DOM path is not assigned`);
|
|
743
|
-
emitPhysicalDomPathDependencies(node.physicalDomPath, statements, context, refNodeMap, declared);
|
|
744
|
-
statements.push(createDomRefDeclaration(node, context));
|
|
745
|
-
declared.add(node.ref.name);
|
|
746
|
-
}
|
|
747
|
-
function emitPhysicalDomPathDependencies(path, statements, context, refNodeMap, declared) {
|
|
748
|
-
switch (path.kind) {
|
|
749
|
-
case "Root": return;
|
|
750
|
-
case "FirstChild":
|
|
751
|
-
emitRefDependency(path.parent, statements, context, refNodeMap, declared);
|
|
752
|
-
return;
|
|
753
|
-
case "ChildNode":
|
|
754
|
-
emitRefDependency(path.parent, statements, context, refNodeMap, declared);
|
|
755
|
-
return;
|
|
756
|
-
case "NextSibling":
|
|
757
|
-
emitRefDependency(path.previous, statements, context, refNodeMap, declared);
|
|
758
|
-
return;
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
function emitRefDependency(ref, statements, context, refNodeMap, declared) {
|
|
762
|
-
const dep = refNodeMap.get(ref.name);
|
|
763
|
-
if (!dep) return;
|
|
764
|
-
emitDomRefDeclarationWithDeps(dep, statements, context, refNodeMap, declared);
|
|
765
|
-
}
|
|
766
|
-
function createDomRefDeclaration(node, _context) {
|
|
767
|
-
if (!node.physicalDomPath) throw new Error(`${node.kind} physical DOM path is not assigned`);
|
|
768
|
-
return t.variableDeclaration("const", [t.variableDeclarator(t.identifier(node.ref.name), emitPhysicalDomPath(node.physicalDomPath))]);
|
|
769
|
-
}
|
|
770
|
-
function needsDomRefDeclaration(node) {
|
|
771
|
-
if (!node.physicalDomPath) return false;
|
|
772
|
-
if (node.attrs.some((attr) => attr.kind === "AttrBinding" || attr.kind === "PropBinding" || attr.kind === "EventBinding" || attr.kind === "RefBinding")) return true;
|
|
773
|
-
return node.children.some((child) => {
|
|
774
|
-
switch (child.kind) {
|
|
775
|
-
case "DynamicText":
|
|
776
|
-
case "Component":
|
|
777
|
-
case "Show":
|
|
778
|
-
case "For":
|
|
779
|
-
case "Slot": return true;
|
|
780
|
-
case "Element": return needsDomRefDeclaration(child);
|
|
781
|
-
case "Fragment": return child.children.some((inner) => inner.kind === "Element" ? needsDomRefDeclaration(inner) : inner.kind !== "Text");
|
|
782
|
-
case "Host": return child.child ? innerKind(child.child) : false;
|
|
783
|
-
default: return false;
|
|
784
|
-
}
|
|
785
|
-
});
|
|
786
|
-
}
|
|
787
|
-
function innerKind(node) {
|
|
788
|
-
switch (node.kind) {
|
|
789
|
-
case "Element": return needsDomRefDeclaration(node);
|
|
790
|
-
case "Text": return false;
|
|
791
|
-
default: return true;
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
function hasRuntimeWork(node) {
|
|
795
|
-
return node.attrs.some((attr) => attr.kind === "AttrBinding" || attr.kind === "PropBinding" || attr.kind === "EventBinding" || attr.kind === "RefBinding") || node.children.some(hasChildRuntimeWork);
|
|
796
|
-
}
|
|
797
|
-
function hasChildRuntimeWork(node) {
|
|
798
|
-
switch (node.kind) {
|
|
799
|
-
case "DynamicText":
|
|
800
|
-
case "Component":
|
|
801
|
-
case "Show":
|
|
802
|
-
case "For":
|
|
803
|
-
case "Slot": return true;
|
|
804
|
-
case "Element": return hasRuntimeWork(node);
|
|
805
|
-
case "Fragment": return node.children.some(hasChildRuntimeWork);
|
|
806
|
-
case "Host": return node.child ? hasChildRuntimeWork(node.child) : false;
|
|
807
|
-
default: return false;
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
//#endregion
|
|
811
|
-
//#region packages/core/compiler/src/codegen/dom/emitFragment.ts
|
|
812
|
-
function emitFragment(node, context) {
|
|
813
|
-
return t.arrayExpression(node.children.map((child) => emitDOM(child, context)));
|
|
814
|
-
}
|
|
815
|
-
//#endregion
|
|
816
|
-
//#region packages/core/compiler/src/codegen/dom/emitNodeExpression.ts
|
|
817
|
-
function emitNodeExpression(node, context) {
|
|
818
|
-
switch (node.kind) {
|
|
819
|
-
case "Text": return t.stringLiteral(node.value);
|
|
820
|
-
case "DynamicText": return parseExpressionIR(node.expr);
|
|
821
|
-
case "Element": return emitElement(node, context);
|
|
822
|
-
case "Component": return emitComponent(node, context);
|
|
823
|
-
case "Fragment": return emitFragment(node, context);
|
|
824
|
-
case "Show": return emitShow(node, context);
|
|
825
|
-
case "For": return emitFor(node, context);
|
|
826
|
-
case "Host": return emitHost(node, context);
|
|
827
|
-
case "Slot": return emitSlot(node, context);
|
|
828
|
-
default: return t.nullLiteral();
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
//#endregion
|
|
832
|
-
//#region packages/core/compiler/src/codegen/dom/emitComponent.ts
|
|
833
|
-
function emitComponent(node, context) {
|
|
834
|
-
const props = t.objectExpression(node.props.map((prop) => emitComponentProp(prop, context)));
|
|
835
|
-
return t.callExpression(context.importRuntime("createComponent"), [parseExpressionIR(node.callee), props]);
|
|
836
|
-
}
|
|
837
|
-
function emitComponentProp(prop, context) {
|
|
838
|
-
const key = createObjectKey$1(prop.name);
|
|
839
|
-
if (Array.isArray(prop.value)) return t.objectMethod("get", key, [], t.blockStatement([t.returnStatement(emitChildrenProp(prop.value, context))]));
|
|
840
|
-
const value = parseExpressionIR(prop.value);
|
|
841
|
-
if (isStaticPropValue(value)) return t.objectProperty(key, value);
|
|
842
|
-
return t.objectMethod("get", key, [], t.blockStatement([t.returnStatement(value)]));
|
|
843
|
-
}
|
|
844
|
-
function emitChildrenProp(children, context) {
|
|
845
|
-
const nodes = children.map((child) => emitNodeExpression(child, context));
|
|
846
|
-
if (nodes.length === 1) return nodes[0];
|
|
847
|
-
return t.arrayExpression(nodes);
|
|
848
|
-
}
|
|
849
|
-
function isStaticPropValue(value) {
|
|
850
|
-
return t.isStringLiteral(value) || t.isNumericLiteral(value) || t.isBooleanLiteral(value) || t.isNullLiteral(value);
|
|
851
|
-
}
|
|
852
|
-
function createObjectKey$1(key) {
|
|
853
|
-
return t.isValidIdentifier(key) ? t.identifier(key) : t.stringLiteral(key);
|
|
854
|
-
}
|
|
855
|
-
//#endregion
|
|
856
|
-
//#region packages/core/compiler/src/codegen/dom/emitBuiltin.ts
|
|
857
|
-
function emitShow(node, context) {
|
|
858
|
-
const props = [t.objectProperty(t.identifier("when"), parseExpressionIR(node.when)), t.objectProperty(t.identifier("children"), t.arrowFunctionExpression([], emitChildrenProp(node.children, context)))];
|
|
859
|
-
if (node.fallback) props.push(t.objectProperty(t.identifier("fallback"), Array.isArray(node.fallback) ? t.arrowFunctionExpression([], emitChildrenProp(node.fallback, context)) : parseExpressionIR(node.fallback)));
|
|
860
|
-
return t.callExpression(context.importRuntime("createComponent"), [context.importRuntime("Show"), t.objectExpression(props)]);
|
|
861
|
-
}
|
|
862
|
-
function emitMountShow(node, context) {
|
|
863
|
-
const path = node.domPath;
|
|
864
|
-
if (!path || path.kind !== "Marker") throw new Error("Show DOM path is not assigned");
|
|
865
|
-
return t.callExpression(context.importRuntime("mountShow"), [
|
|
866
|
-
t.identifier(path.parent.name),
|
|
867
|
-
emitMarkerIdentifier(node),
|
|
868
|
-
t.arrowFunctionExpression([], parseExpressionIR(node.when)),
|
|
869
|
-
t.arrowFunctionExpression([], emitChildrenProp(node.children, context)),
|
|
870
|
-
node.fallback ? Array.isArray(node.fallback) ? t.arrowFunctionExpression([], emitChildrenProp(node.fallback, context)) : t.arrowFunctionExpression([], parseExpressionIR(node.fallback)) : t.identifier("undefined")
|
|
871
|
-
]);
|
|
872
|
-
}
|
|
873
|
-
function emitFor(node, context) {
|
|
874
|
-
const params = [t.identifier(node.item.name)];
|
|
875
|
-
if (node.index) params.push(t.identifier(node.index.name));
|
|
876
|
-
const props = [t.objectProperty(t.identifier("each"), parseExpressionIR(node.each)), t.objectProperty(t.identifier("children"), t.arrowFunctionExpression(params, emitChildrenProp(node.body, context)))];
|
|
877
|
-
if (node.by) props.push(t.objectProperty(t.identifier("by"), parseExpressionIR(node.by)));
|
|
878
|
-
return t.callExpression(context.importRuntime("createComponent"), [context.importRuntime("For"), t.objectExpression(props)]);
|
|
879
|
-
}
|
|
880
|
-
function emitMountFor(node, context) {
|
|
881
|
-
const params = [t.identifier(node.item.name)];
|
|
882
|
-
if (node.index) params.push(t.identifier(node.index.name));
|
|
883
|
-
const path = node.domPath;
|
|
884
|
-
if (!path || path.kind !== "Marker") throw new Error("For DOM path is not assigned");
|
|
885
|
-
return t.callExpression(context.importRuntime("mountFor"), [
|
|
886
|
-
t.identifier(path.parent.name),
|
|
887
|
-
emitMarkerIdentifier(node),
|
|
888
|
-
t.arrowFunctionExpression([], parseExpressionIR(node.each)),
|
|
889
|
-
node.by ? parseExpressionIR(node.by) : t.identifier("undefined"),
|
|
890
|
-
t.arrowFunctionExpression(params, emitChildrenProp(node.body, context))
|
|
891
|
-
]);
|
|
892
|
-
}
|
|
893
|
-
function emitHost(node, context) {
|
|
894
|
-
const props = buildHostProps(node, context);
|
|
895
|
-
const hostIdent = context.importRuntime("Host");
|
|
896
|
-
if (!node.child) return t.callExpression(hostIdent, [t.objectExpression(props)]);
|
|
897
|
-
const childExpr = emitNodeExpression(node.child, context);
|
|
898
|
-
const hostCall = t.callExpression(hostIdent, [t.objectExpression(props)]);
|
|
899
|
-
return t.callExpression(t.arrowFunctionExpression([], t.blockStatement([t.expressionStatement(hostCall), t.returnStatement(childExpr)])), []);
|
|
900
|
-
}
|
|
901
|
-
function buildHostProps(node, context) {
|
|
902
|
-
const props = [];
|
|
903
|
-
for (const attr of node.attrs) {
|
|
904
|
-
const key = createObjectKey(attr.name);
|
|
905
|
-
const expression = parseExpressionIR(attr.expr);
|
|
906
|
-
if (isStaticValue(expression) || isGetterExpression(expression)) props.push(t.objectProperty(key, expression));
|
|
907
|
-
else props.push(t.objectProperty(key, t.arrowFunctionExpression([], expression)));
|
|
908
|
-
}
|
|
909
|
-
return props;
|
|
910
|
-
}
|
|
911
|
-
function isStaticValue(expr) {
|
|
912
|
-
return t.isStringLiteral(expr) || t.isNumericLiteral(expr) || t.isBooleanLiteral(expr) || t.isNullLiteral(expr);
|
|
913
|
-
}
|
|
914
|
-
function isGetterExpression(expr) {
|
|
915
|
-
return t.isArrowFunctionExpression(expr) || t.isFunctionExpression(expr);
|
|
916
|
-
}
|
|
917
|
-
function createObjectKey(name) {
|
|
918
|
-
return t.isValidIdentifier(name) ? t.identifier(name) : t.stringLiteral(name);
|
|
919
|
-
}
|
|
920
|
-
function emitSlot(node, context) {
|
|
921
|
-
return t.callExpression(context.importRuntime("createSlot"), [node.name ? t.stringLiteral(node.name) : t.identifier("undefined"), node.fallback.length > 0 ? t.arrowFunctionExpression([], emitChildrenProp(node.fallback, context)) : t.identifier("undefined")]);
|
|
922
|
-
}
|
|
923
|
-
function emitMarkerIdentifier(node) {
|
|
924
|
-
return t.identifier(node.ref.name);
|
|
925
|
-
}
|
|
926
|
-
//#endregion
|
|
927
|
-
//#region packages/core/compiler/src/codegen/dom/index.ts
|
|
928
|
-
function emitDOM(node, context) {
|
|
929
|
-
switch (node.kind) {
|
|
930
|
-
case "Element": return emitElement(node, context);
|
|
931
|
-
case "Fragment": return emitFragment(node, context);
|
|
932
|
-
case "Component": return emitComponent(node, context);
|
|
933
|
-
case "Show": return emitShow(node, context);
|
|
934
|
-
case "For": return emitFor(node, context);
|
|
935
|
-
case "Host": return emitHost(node, context);
|
|
936
|
-
case "Slot": return emitSlot(node, context);
|
|
937
|
-
case "DynamicText": return t.arrowFunctionExpression([], parseExpressionIR(node.expr));
|
|
938
|
-
default: throw new Error(`Unsupported root IR node: ${node.kind}`);
|
|
939
|
-
}
|
|
940
|
-
}
|
|
941
|
-
//#endregion
|
|
942
|
-
//#region packages/core/compiler/src/diagnostics/codes.ts
|
|
943
|
-
const CompilerErrorCode = {
|
|
944
|
-
UNSUPPORTED_SPREAD_ATTRIBUTE: "ZEUS_UNSUPPORTED_SPREAD_ATTRIBUTE",
|
|
945
|
-
UNSUPPORTED_SPREAD_CHILD: "ZEUS_UNSUPPORTED_SPREAD_CHILD",
|
|
946
|
-
UNSUPPORTED_FRAGMENT: "ZEUS_UNSUPPORTED_FRAGMENT",
|
|
947
|
-
UNSUPPORTED_FRAGMENT_CHILD: "ZEUS_UNSUPPORTED_FRAGMENT_CHILD",
|
|
948
|
-
UNSUPPORTED_COMPONENT_PROP: "ZEUS_UNSUPPORTED_COMPONENT_PROP",
|
|
949
|
-
EMPTY_EXPRESSION: "ZEUS_EMPTY_EXPRESSION",
|
|
950
|
-
INVALID_TRANSFORM_RESULT: "ZEUS_INVALID_TRANSFORM_RESULT",
|
|
951
|
-
UNSUPPORTED_NODE: "ZEUS_UNSUPPORTED_NODE",
|
|
952
|
-
INVALID_BUILTIN_USAGE: "ZEUS_INVALID_BUILTIN_USAGE",
|
|
953
|
-
INVALID_REF_USAGE: "ZEUS_INVALID_REF_USAGE"
|
|
954
|
-
};
|
|
955
|
-
//#endregion
|
|
956
|
-
//#region packages/core/compiler/src/diagnostics/CompilerDiagnostic.ts
|
|
957
|
-
function createCompilerDiagnostic(input) {
|
|
958
|
-
var _input$severity;
|
|
959
|
-
return _objectSpread2(_objectSpread2(_objectSpread2({
|
|
960
|
-
code: input.code,
|
|
961
|
-
severity: (_input$severity = input.severity) !== null && _input$severity !== void 0 ? _input$severity : "error",
|
|
962
|
-
message: input.message
|
|
963
|
-
}, input.hint === void 0 ? {} : { hint: input.hint }), input.filename === void 0 ? {} : { filename: input.filename }), input.span === void 0 ? {} : { span: input.span });
|
|
964
|
-
}
|
|
965
|
-
function formatCompilerDiagnostic(diagnostic) {
|
|
966
|
-
const hint = diagnostic.hint ? `\nHint: ${diagnostic.hint}` : "";
|
|
967
|
-
return `[${diagnostic.code}] ${diagnostic.message}${hint}`;
|
|
968
|
-
}
|
|
969
|
-
//#endregion
|
|
970
|
-
//#region packages/core/compiler/src/diagnostics/CompilerError.ts
|
|
971
|
-
var CompilerError = class extends Error {
|
|
972
|
-
constructor(options) {
|
|
973
|
-
const diagnostic = createCompilerDiagnostic(_objectSpread2(_objectSpread2({}, options), {}, { severity: "error" }));
|
|
974
|
-
super(formatCompilerDiagnostic(diagnostic));
|
|
975
|
-
this.name = "ZeusCompilerError";
|
|
976
|
-
this.diagnostic = diagnostic;
|
|
977
|
-
this.code = diagnostic.code;
|
|
978
|
-
this.severity = "error";
|
|
979
|
-
this.hint = diagnostic.hint;
|
|
980
|
-
this.filename = diagnostic.filename;
|
|
981
|
-
this.span = diagnostic.span;
|
|
982
|
-
this.loc = diagnostic.span ? {
|
|
983
|
-
line: diagnostic.span.start.line,
|
|
984
|
-
column: diagnostic.span.start.column
|
|
985
|
-
} : void 0;
|
|
986
|
-
}
|
|
987
|
-
};
|
|
988
|
-
//#endregion
|
|
989
|
-
//#region packages/core/compiler/src/adapters/babel/diagnostic.ts
|
|
990
|
-
function createBabelCompilerError(path, options) {
|
|
991
|
-
var _hub$file;
|
|
992
|
-
const hub = path.hub;
|
|
993
|
-
return new CompilerError(_objectSpread2(_objectSpread2({}, options), {}, {
|
|
994
|
-
filename: hub === null || hub === void 0 || (_hub$file = hub.file) === null || _hub$file === void 0 || (_hub$file = _hub$file.opts) === null || _hub$file === void 0 ? void 0 : _hub$file.filename,
|
|
995
|
-
span: sourceSpanFromBabelNode(path.node)
|
|
996
|
-
}));
|
|
997
|
-
}
|
|
998
|
-
//#endregion
|
|
999
|
-
//#region packages/core/compiler/src/parse/jsx.ts
|
|
1000
|
-
/**
|
|
1001
|
-
* JSX AST parsing utilities.
|
|
1002
|
-
*
|
|
1003
|
-
* Low-level helpers for extracting and interpreting information from Babel's
|
|
1004
|
-
* JSX AST nodes — tag names, attribute names, and path type guards.
|
|
1005
|
-
* These do NOT produce IR or Babel AST; they only read the JSX tree.
|
|
1006
|
-
*/
|
|
1007
|
-
function jsxElementNameToString(node) {
|
|
1008
|
-
if (t.isJSXMemberExpression(node)) return `${jsxElementNameToString(node.object)}.${node.property.name}`;
|
|
1009
|
-
if (t.isJSXIdentifier(node) || t.isIdentifier(node)) return node.name;
|
|
1010
|
-
return `${node.namespace.name}:${node.name.name}`;
|
|
1011
|
-
}
|
|
1012
|
-
function getTagName(node) {
|
|
1013
|
-
return jsxElementNameToString(node.openingElement.name);
|
|
1014
|
-
}
|
|
1015
|
-
function getJSXAttrName(name) {
|
|
1016
|
-
if (t.isJSXNamespacedName(name)) return `${name.namespace.name}:${name.name.name}`;
|
|
1017
|
-
return name.name;
|
|
1018
|
-
}
|
|
1019
|
-
function isComponentTag(tagName) {
|
|
1020
|
-
return /^[A-Z]/.test(tagName) || tagName.includes(".");
|
|
1021
|
-
}
|
|
1022
|
-
function toEventName(name) {
|
|
1023
|
-
return name.slice(2).toLowerCase();
|
|
1024
|
-
}
|
|
1025
|
-
//#endregion
|
|
1026
|
-
//#region packages/core/compiler/src/lower/lowerAttribute.ts
|
|
1027
|
-
function lowerAttribute(path, _context) {
|
|
1028
|
-
if (path.isJSXSpreadAttribute() || t.isJSXSpreadAttribute(path.node)) throw createBabelCompilerError(path, {
|
|
1029
|
-
code: CompilerErrorCode.UNSUPPORTED_SPREAD_ATTRIBUTE,
|
|
1030
|
-
message: "Spread attributes are not supported in Zeus MVP.",
|
|
1031
|
-
hint: "Use explicit attributes instead, for example <div id={id} />."
|
|
1032
|
-
});
|
|
1033
|
-
const node = path.node;
|
|
1034
|
-
const name = getJSXAttrName(node.name);
|
|
1035
|
-
const value = path.get("value");
|
|
1036
|
-
if (!value.node) {
|
|
1037
|
-
if (name === "ref") throw createBabelCompilerError(path, {
|
|
1038
|
-
code: CompilerErrorCode.EMPTY_EXPRESSION,
|
|
1039
|
-
message: "ref attribute requires an expression.",
|
|
1040
|
-
hint: "Use <div ref={target} /> instead."
|
|
1041
|
-
});
|
|
1042
|
-
return staticAttrIR(name, true);
|
|
1043
|
-
}
|
|
1044
|
-
if (value.isStringLiteral()) {
|
|
1045
|
-
if (name === "ref") throw createBabelCompilerError(path, {
|
|
1046
|
-
code: CompilerErrorCode.INVALID_REF_USAGE,
|
|
1047
|
-
message: "String refs are not supported in Zeus.",
|
|
1048
|
-
hint: "Use a state holder or callback ref: <div ref={el} />."
|
|
1049
|
-
});
|
|
1050
|
-
return staticAttrIR(name, value.node.value);
|
|
1051
|
-
}
|
|
1052
|
-
if (value.isJSXExpressionContainer()) {
|
|
1053
|
-
const expression = value.get("expression");
|
|
1054
|
-
if (expression.isJSXEmptyExpression()) throw createBabelCompilerError(path, {
|
|
1055
|
-
code: CompilerErrorCode.EMPTY_EXPRESSION,
|
|
1056
|
-
message: `Attribute "${name}" expression cannot be empty.`
|
|
1057
|
-
});
|
|
1058
|
-
if (!expression.isExpression()) return null;
|
|
1059
|
-
const expr = lowerExpressionIR(expression);
|
|
1060
|
-
if (name === "ref") return refBindingIR(expr);
|
|
1061
|
-
if (name.startsWith("on") && name.length > 2) return eventBindingIR(toEventName(name), expr);
|
|
1062
|
-
if (name.startsWith("prop:")) return propBindingIR(name.slice(5), expr);
|
|
1063
|
-
return attrBindingIR(name, expr);
|
|
1064
|
-
}
|
|
1065
|
-
return null;
|
|
1066
|
-
}
|
|
1067
|
-
//#endregion
|
|
1068
|
-
//#region packages/core/compiler/src/lower/lowerChildren.ts
|
|
1069
|
-
function lowerChildren(children, context) {
|
|
1070
|
-
const result = [];
|
|
1071
|
-
for (const child of children) {
|
|
1072
|
-
if (child.isJSXText()) {
|
|
1073
|
-
const text = trimJSXText(child.node.value);
|
|
1074
|
-
if (text) result.push(textIR(escapeHTML(text)));
|
|
1075
|
-
continue;
|
|
1076
|
-
}
|
|
1077
|
-
if (child.isJSXExpressionContainer()) {
|
|
1078
|
-
const expression = child.get("expression");
|
|
1079
|
-
if (expression.isJSXEmptyExpression()) continue;
|
|
1080
|
-
if (expression.isExpression()) result.push(dynamicTextIR(lowerExpressionIR(expression), ref(context.uid("anchor$").name)));
|
|
1081
|
-
continue;
|
|
1082
|
-
}
|
|
1083
|
-
if (child.isJSXElement() || child.isJSXFragment()) {
|
|
1084
|
-
result.push(lowerJSX(child, context));
|
|
1085
|
-
continue;
|
|
1086
|
-
}
|
|
1087
|
-
}
|
|
1088
|
-
return result;
|
|
1089
|
-
}
|
|
1090
|
-
//#endregion
|
|
1091
|
-
//#region packages/core/compiler/src/lower/lowerBuiltin.ts
|
|
1092
|
-
const HOST_SKIP_PROPS = /* @__PURE__ */ new Set([
|
|
1093
|
-
"key",
|
|
1094
|
-
"__slot",
|
|
1095
|
-
"__anchor"
|
|
1096
|
-
]);
|
|
1097
|
-
function isBuiltinTag(tagName) {
|
|
1098
|
-
return tagName === "Show" || tagName === "For" || tagName === "Host" || tagName === "Slot";
|
|
1099
|
-
}
|
|
1100
|
-
function lowerBuiltin(path, context) {
|
|
1101
|
-
const tagName = path.node.openingElement.name;
|
|
1102
|
-
if (!t.isJSXIdentifier(tagName)) throw createBabelCompilerError(path, {
|
|
1103
|
-
code: CompilerErrorCode.INVALID_BUILTIN_USAGE,
|
|
1104
|
-
message: "Built-in JSX nodes do not support member expressions."
|
|
1105
|
-
});
|
|
1106
|
-
switch (tagName.name) {
|
|
1107
|
-
case "Show": return lowerShow(path, context);
|
|
1108
|
-
case "For": return lowerFor(path, context);
|
|
1109
|
-
case "Host": return lowerHost(path, context);
|
|
1110
|
-
case "Slot": return lowerSlot(path, context);
|
|
1111
|
-
default: throw createBabelCompilerError(path, {
|
|
1112
|
-
code: CompilerErrorCode.INVALID_BUILTIN_USAGE,
|
|
1113
|
-
message: `Unsupported built-in <${tagName.name}>.`
|
|
1114
|
-
});
|
|
1115
|
-
}
|
|
1116
|
-
}
|
|
1117
|
-
function lowerShow(path, context) {
|
|
1118
|
-
const when = requiredExpressionAttr(path, "when");
|
|
1119
|
-
const fallback = optionalShowFallbackAttr(path, context);
|
|
1120
|
-
return showIR({
|
|
1121
|
-
ref: ref(context.uid("show$").name),
|
|
1122
|
-
when,
|
|
1123
|
-
fallback,
|
|
1124
|
-
children: lowerChildren(path.get("children"), context)
|
|
1125
|
-
});
|
|
1126
|
-
}
|
|
1127
|
-
function optionalShowFallbackAttr(path, context) {
|
|
1128
|
-
const attr = path.get("openingElement").get("attributes").find((attrPath) => {
|
|
1129
|
-
if (!attrPath.isJSXAttribute()) return false;
|
|
1130
|
-
return getJSXAttrName(attrPath.node.name) === "fallback";
|
|
1131
|
-
});
|
|
1132
|
-
if (!(attr === null || attr === void 0 ? void 0 : attr.isJSXAttribute())) return void 0;
|
|
1133
|
-
const value = attr.get("value");
|
|
1134
|
-
if (!value.node) return expressionIRFromCode("true", attr.node);
|
|
1135
|
-
if (value.isStringLiteral()) return expressionIRFromCode(JSON.stringify(value.node.value), value.node);
|
|
1136
|
-
if (!value.isJSXExpressionContainer()) return void 0;
|
|
1137
|
-
const expression = value.get("expression");
|
|
1138
|
-
if (expression.isJSXEmptyExpression()) return void 0;
|
|
1139
|
-
if (expression.isJSXElement() || expression.isJSXFragment()) return [lowerJSX(expression, context)];
|
|
1140
|
-
if (expression.isExpression()) return lowerExpressionIR(expression);
|
|
1141
|
-
}
|
|
1142
|
-
function lowerFor(path, context) {
|
|
1143
|
-
const each = requiredExpressionAttr(path, "each");
|
|
1144
|
-
const by = optionalExpressionAttr(path, "by");
|
|
1145
|
-
const render = getOnlyRenderFunction(path);
|
|
1146
|
-
const item = getParamIdentifier(render, 0, "item");
|
|
1147
|
-
const index = getParamIdentifier(render, 1);
|
|
1148
|
-
const bodyPath = render.get("body");
|
|
1149
|
-
const body = [];
|
|
1150
|
-
if (bodyPath.isJSXElement() || bodyPath.isJSXFragment()) body.push(lowerJSX(bodyPath, context));
|
|
1151
|
-
else if (bodyPath.isExpression()) body.push(dynamicTextIR(lowerExpressionIR(bodyPath), ref(context.uid("anchor$").name)));
|
|
1152
|
-
return forIR({
|
|
1153
|
-
ref: ref(context.uid("for$").name),
|
|
1154
|
-
each,
|
|
1155
|
-
by,
|
|
1156
|
-
item,
|
|
1157
|
-
index,
|
|
1158
|
-
body
|
|
1159
|
-
});
|
|
1160
|
-
}
|
|
1161
|
-
function lowerSlot(path, context) {
|
|
1162
|
-
const name = optionalStringAttr(path, "name");
|
|
1163
|
-
return slotIR({
|
|
1164
|
-
ref: ref(context.uid("slot$").name),
|
|
1165
|
-
name,
|
|
1166
|
-
fallback: lowerChildren(path.get("children"), context),
|
|
1167
|
-
span: sourceSpanFromBabelNode(path.node)
|
|
1168
|
-
});
|
|
1169
|
-
}
|
|
1170
|
-
function requiredExpressionAttr(path, name) {
|
|
1171
|
-
const value = optionalExpressionAttr(path, name);
|
|
1172
|
-
if (!value) throw createBabelCompilerError(path, {
|
|
1173
|
-
code: CompilerErrorCode.INVALID_BUILTIN_USAGE,
|
|
1174
|
-
message: `<${getBuiltinName(path)}> requires "${name}".`
|
|
1175
|
-
});
|
|
1176
|
-
return value;
|
|
1177
|
-
}
|
|
1178
|
-
function optionalExpressionAttr(path, name) {
|
|
1179
|
-
const attr = path.get("openingElement").get("attributes").find((attrPath) => {
|
|
1180
|
-
if (!attrPath.isJSXAttribute()) return false;
|
|
1181
|
-
return getJSXAttrName(attrPath.node.name) === name;
|
|
1182
|
-
});
|
|
1183
|
-
if (!(attr === null || attr === void 0 ? void 0 : attr.isJSXAttribute())) return void 0;
|
|
1184
|
-
const value = attr.get("value");
|
|
1185
|
-
if (!value.node) return expressionIRFromCode("true", attr.node);
|
|
1186
|
-
if (value.isStringLiteral()) return expressionIRFromCode(JSON.stringify(value.node.value), value.node);
|
|
1187
|
-
if (!value.isJSXExpressionContainer()) return void 0;
|
|
1188
|
-
const expression = value.get("expression");
|
|
1189
|
-
if (expression.isExpression()) return lowerExpressionIR(expression);
|
|
1190
|
-
}
|
|
1191
|
-
function optionalStringAttr(path, name) {
|
|
1192
|
-
const attr = path.get("openingElement").get("attributes").find((attrPath) => {
|
|
1193
|
-
if (!attrPath.isJSXAttribute()) return false;
|
|
1194
|
-
return getJSXAttrName(attrPath.node.name) === name;
|
|
1195
|
-
});
|
|
1196
|
-
if (!(attr === null || attr === void 0 ? void 0 : attr.isJSXAttribute())) return void 0;
|
|
1197
|
-
const value = attr.node.value;
|
|
1198
|
-
if (!value) return "";
|
|
1199
|
-
if (t.isStringLiteral(value)) return value.value;
|
|
1200
|
-
}
|
|
1201
|
-
function getOnlyRenderFunction(path) {
|
|
1202
|
-
const expressions = path.get("children").filter((child) => child.isJSXExpressionContainer()).map((child) => child.get("expression")).filter((expression) => expression.isArrowFunctionExpression() || expression.isFunctionExpression());
|
|
1203
|
-
if (expressions.length !== 1) throw createBabelCompilerError(path, {
|
|
1204
|
-
code: CompilerErrorCode.INVALID_BUILTIN_USAGE,
|
|
1205
|
-
message: "<For> requires exactly one render function child."
|
|
1206
|
-
});
|
|
1207
|
-
return expressions[0];
|
|
1208
|
-
}
|
|
1209
|
-
function getParamIdentifier(path, index, fallback) {
|
|
1210
|
-
const param = path.node.params[index];
|
|
1211
|
-
if (t.isIdentifier(param)) return identifierIR(param.name, sourceSpanFromBabelNode(param));
|
|
1212
|
-
if (fallback) return identifierIR(fallback);
|
|
1213
|
-
}
|
|
1214
|
-
function getBuiltinName(path) {
|
|
1215
|
-
const name = path.node.openingElement.name;
|
|
1216
|
-
return t.isJSXIdentifier(name) ? name.name : "Builtin";
|
|
1217
|
-
}
|
|
1218
|
-
function isEventLikeProp(key) {
|
|
1219
|
-
return /^on[A-Z]/.test(key) || key.startsWith("on:");
|
|
1220
|
-
}
|
|
1221
|
-
function normalizeHostAttrName(name) {
|
|
1222
|
-
switch (name) {
|
|
1223
|
-
case "className": return "class";
|
|
1224
|
-
case "htmlFor": return "for";
|
|
1225
|
-
case "tabIndex": return "tabindex";
|
|
1226
|
-
case "readOnly": return "readonly";
|
|
1227
|
-
default: return name;
|
|
1228
|
-
}
|
|
1229
|
-
}
|
|
1230
|
-
function lowerHost(path, context) {
|
|
1231
|
-
const attrs = [];
|
|
1232
|
-
const rawChildren = lowerChildren(path.get("children"), context);
|
|
1233
|
-
for (const attrPath of path.get("openingElement").get("attributes")) {
|
|
1234
|
-
const node = attrPath.node;
|
|
1235
|
-
if (t.isJSXSpreadAttribute(node)) throw createBabelCompilerError(attrPath, {
|
|
1236
|
-
code: CompilerErrorCode.UNSUPPORTED_COMPONENT_PROP,
|
|
1237
|
-
message: "Spread props are not supported on Host in Phase 1."
|
|
1238
|
-
});
|
|
1239
|
-
if (!attrPath.isJSXAttribute()) continue;
|
|
1240
|
-
const name = getJSXAttrName(node.name);
|
|
1241
|
-
if (HOST_SKIP_PROPS.has(name)) continue;
|
|
1242
|
-
if (name === "children") continue;
|
|
1243
|
-
if (name === "ref") {
|
|
1244
|
-
const value = attrPath.get("value");
|
|
1245
|
-
if (value.isJSXExpressionContainer()) {
|
|
1246
|
-
const expr = value.get("expression");
|
|
1247
|
-
if (expr.isExpression()) attrs.push({
|
|
1248
|
-
id: id(),
|
|
1249
|
-
kind: "HostAttr",
|
|
1250
|
-
name: "ref",
|
|
1251
|
-
expr: lowerExpressionIR(expr)
|
|
1252
|
-
});
|
|
1253
|
-
}
|
|
1254
|
-
continue;
|
|
1255
|
-
}
|
|
1256
|
-
if (isEventLikeProp(name)) continue;
|
|
1257
|
-
const value = attrPath.get("value");
|
|
1258
|
-
if (!value.node) attrs.push({
|
|
1259
|
-
id: id(),
|
|
1260
|
-
kind: "HostAttr",
|
|
1261
|
-
name: normalizeHostAttrName(name),
|
|
1262
|
-
expr: expressionIRFromCode("true", node)
|
|
1263
|
-
});
|
|
1264
|
-
else if (value.isStringLiteral()) attrs.push({
|
|
1265
|
-
id: id(),
|
|
1266
|
-
kind: "HostAttr",
|
|
1267
|
-
name: normalizeHostAttrName(name),
|
|
1268
|
-
expr: expressionIRFromCode(JSON.stringify(value.node.value), value.node)
|
|
1269
|
-
});
|
|
1270
|
-
else if (value.isJSXExpressionContainer()) {
|
|
1271
|
-
const expression = value.get("expression");
|
|
1272
|
-
if (expression.isExpression()) attrs.push({
|
|
1273
|
-
id: id(),
|
|
1274
|
-
kind: "HostAttr",
|
|
1275
|
-
name: normalizeHostAttrName(name),
|
|
1276
|
-
expr: lowerExpressionIR(expression)
|
|
1277
|
-
});
|
|
1278
|
-
}
|
|
1279
|
-
}
|
|
1280
|
-
return hostIR({
|
|
1281
|
-
attrs,
|
|
1282
|
-
child: rawChildren.length === 0 ? void 0 : rawChildren.length === 1 ? rawChildren[0] : fragmentIR(rawChildren),
|
|
1283
|
-
span: sourceSpanFromBabelNode(path.node)
|
|
1284
|
-
});
|
|
1285
|
-
}
|
|
1286
|
-
//#endregion
|
|
1287
|
-
//#region packages/core/compiler/src/lower/lowerComponent.ts
|
|
1288
|
-
function lowerComponent(path, context) {
|
|
1289
|
-
const tag = convertComponentIdentifier(path.node.openingElement.name);
|
|
1290
|
-
const props = [];
|
|
1291
|
-
for (const attr of path.get("openingElement").get("attributes")) {
|
|
1292
|
-
const node = attr.node;
|
|
1293
|
-
if (t.isJSXSpreadAttribute(node)) throw createBabelCompilerError(attr, {
|
|
1294
|
-
code: CompilerErrorCode.UNSUPPORTED_COMPONENT_PROP,
|
|
1295
|
-
message: "Spread props are not supported in Zeus MVP."
|
|
1296
|
-
});
|
|
1297
|
-
const name = getJSXAttrName(node.name);
|
|
1298
|
-
const value = attr.get("value");
|
|
1299
|
-
if (!value.node) {
|
|
1300
|
-
props.push({
|
|
1301
|
-
name,
|
|
1302
|
-
value: expressionIRFromCode("true", node)
|
|
1303
|
-
});
|
|
1304
|
-
continue;
|
|
1305
|
-
}
|
|
1306
|
-
if (value.isStringLiteral()) {
|
|
1307
|
-
props.push({
|
|
1308
|
-
name,
|
|
1309
|
-
value: expressionIRFromCode(JSON.stringify(value.node.value), value.node)
|
|
1310
|
-
});
|
|
1311
|
-
continue;
|
|
1312
|
-
}
|
|
1313
|
-
if (value.isJSXExpressionContainer()) {
|
|
1314
|
-
const expression = value.get("expression");
|
|
1315
|
-
if (expression.isJSXEmptyExpression()) throw createBabelCompilerError(attr, {
|
|
1316
|
-
code: CompilerErrorCode.EMPTY_EXPRESSION,
|
|
1317
|
-
message: `Component prop "${name}" expression cannot be empty.`
|
|
1318
|
-
});
|
|
1319
|
-
if (expression.isExpression()) props.push({
|
|
1320
|
-
name,
|
|
1321
|
-
value: lowerExpressionIR(expression)
|
|
1322
|
-
});
|
|
1323
|
-
}
|
|
1324
|
-
}
|
|
1325
|
-
const children = lowerChildren(path.get("children"), context);
|
|
1326
|
-
if (children.length > 0) props.push({
|
|
1327
|
-
name: "children",
|
|
1328
|
-
value: children
|
|
1329
|
-
});
|
|
1330
|
-
return componentIR({
|
|
1331
|
-
ref: ref(context.uid("cmp$").name),
|
|
1332
|
-
callee: tag,
|
|
1333
|
-
props
|
|
1334
|
-
});
|
|
1335
|
-
}
|
|
1336
|
-
function convertComponentIdentifier(node) {
|
|
1337
|
-
return expressionIRFromCode(componentIdentifierCode(node), node);
|
|
1338
|
-
}
|
|
1339
|
-
function componentIdentifierCode(node) {
|
|
1340
|
-
if (t.isJSXIdentifier(node)) {
|
|
1341
|
-
if (node.name === "this") return "this";
|
|
1342
|
-
return t.isValidIdentifier(node.name) ? node.name : JSON.stringify(node.name);
|
|
1343
|
-
}
|
|
1344
|
-
if (t.isJSXMemberExpression(node)) {
|
|
1345
|
-
const object = componentIdentifierCode(node.object);
|
|
1346
|
-
const property = node.property.name;
|
|
1347
|
-
return t.isValidIdentifier(property) ? `${object}.${property}` : `${object}[${JSON.stringify(property)}]`;
|
|
1348
|
-
}
|
|
1349
|
-
if (t.isJSXNamespacedName(node)) return JSON.stringify(`${node.namespace.name}:${node.name.name}`);
|
|
1350
|
-
return JSON.stringify("");
|
|
1351
|
-
}
|
|
1352
|
-
//#endregion
|
|
1353
|
-
//#region packages/core/compiler/src/lower/lowerElement.ts
|
|
1354
|
-
function lowerElement(path, context) {
|
|
1355
|
-
const tagName = getTagName(path.node);
|
|
1356
|
-
if (isBuiltinTag(tagName)) return lowerBuiltin(path, context);
|
|
1357
|
-
if (isComponentTag(tagName)) return lowerComponent(path, context);
|
|
1358
|
-
const attrs = path.get("openingElement").get("attributes").map((attr) => lowerAttribute(attr, context)).filter(Boolean);
|
|
1359
|
-
return elementIR({
|
|
1360
|
-
ref: ref(context.uid("el$").name),
|
|
1361
|
-
tagName,
|
|
1362
|
-
attrs,
|
|
1363
|
-
children: VoidElements.includes(tagName) ? [] : lowerChildren(path.get("children"), context),
|
|
1364
|
-
flags: {
|
|
1365
|
-
isVoid: VoidElements.includes(tagName),
|
|
1366
|
-
isCustomElement: tagName.includes("-")
|
|
1367
|
-
}
|
|
1368
|
-
});
|
|
1369
|
-
}
|
|
1370
|
-
//#endregion
|
|
1371
|
-
//#region packages/core/compiler/src/lower/lowerFragment.ts
|
|
1372
|
-
function lowerFragment(path, context) {
|
|
1373
|
-
return fragmentIR(lowerChildren(path.get("children"), context));
|
|
1374
|
-
}
|
|
1375
|
-
//#endregion
|
|
1376
|
-
//#region packages/core/compiler/src/lower/lowerJSX.ts
|
|
1377
|
-
function lowerJSX(path, context) {
|
|
1378
|
-
if (path.isJSXElement()) return lowerElement(path, context);
|
|
1379
|
-
if (path.isJSXFragment()) return lowerFragment(path, context);
|
|
1380
|
-
throw new Error("Unsupported JSX node");
|
|
1381
|
-
}
|
|
1382
|
-
//#endregion
|
|
1383
|
-
//#region packages/core/compiler/src/passes/normalizeChildren.ts
|
|
1384
|
-
function normalizeChildren(node) {
|
|
1385
|
-
visit$2(node);
|
|
1386
|
-
return node;
|
|
1387
|
-
}
|
|
1388
|
-
function visit$2(node) {
|
|
1389
|
-
switch (node.kind) {
|
|
1390
|
-
case "Element":
|
|
1391
|
-
case "Fragment":
|
|
1392
|
-
node.children = node.children.filter((child) => {
|
|
1393
|
-
if (child.kind === "Text") return child.value.length > 0;
|
|
1394
|
-
return true;
|
|
1395
|
-
});
|
|
1396
|
-
for (const child of node.children) visit$2(child);
|
|
1397
|
-
return;
|
|
1398
|
-
case "Host":
|
|
1399
|
-
if (node.child) visit$2(node.child);
|
|
1400
|
-
return;
|
|
1401
|
-
case "Component":
|
|
1402
|
-
for (const prop of node.props) {
|
|
1403
|
-
if (!Array.isArray(prop.value)) continue;
|
|
1404
|
-
prop.value = prop.value.filter((child) => {
|
|
1405
|
-
if (child.kind === "Text") return child.value.length > 0;
|
|
1406
|
-
return true;
|
|
1407
|
-
});
|
|
1408
|
-
for (const child of prop.value) visit$2(child);
|
|
1409
|
-
}
|
|
1410
|
-
return;
|
|
1411
|
-
case "Slot":
|
|
1412
|
-
node.fallback = node.fallback.filter((child) => {
|
|
1413
|
-
if (child.kind === "Text") return child.value.length > 0;
|
|
1414
|
-
return true;
|
|
1415
|
-
});
|
|
1416
|
-
for (const child of node.fallback) visit$2(child);
|
|
1417
|
-
return;
|
|
1418
|
-
case "Show":
|
|
1419
|
-
for (const child of node.children) visit$2(child);
|
|
1420
|
-
if (Array.isArray(node.fallback)) {
|
|
1421
|
-
node.fallback = node.fallback.filter((child) => {
|
|
1422
|
-
if (child.kind === "Text") return child.value.length > 0;
|
|
1423
|
-
return true;
|
|
1424
|
-
});
|
|
1425
|
-
for (const child of node.fallback) visit$2(child);
|
|
1426
|
-
}
|
|
1427
|
-
return;
|
|
1428
|
-
case "For":
|
|
1429
|
-
for (const child of node.body) visit$2(child);
|
|
1430
|
-
return;
|
|
1431
|
-
case "Text":
|
|
1432
|
-
case "DynamicText": return;
|
|
1433
|
-
}
|
|
1434
|
-
}
|
|
1435
|
-
//#endregion
|
|
1436
|
-
//#region packages/core/compiler/src/passes/assignDomPaths.ts
|
|
1437
|
-
function assignDomPaths(node) {
|
|
1438
|
-
visitNode$1(node);
|
|
1439
|
-
return node;
|
|
1440
|
-
}
|
|
1441
|
-
function visitNode$1(node, parent) {
|
|
1442
|
-
switch (node.kind) {
|
|
1443
|
-
case "Element":
|
|
1444
|
-
assignElementPath(node, parent);
|
|
1445
|
-
assignChildPaths(node);
|
|
1446
|
-
return;
|
|
1447
|
-
case "Fragment":
|
|
1448
|
-
for (const child of node.children) visitNode$1(child, parent);
|
|
1449
|
-
return;
|
|
1450
|
-
case "Component":
|
|
1451
|
-
for (const prop of node.props) {
|
|
1452
|
-
if (!Array.isArray(prop.value)) continue;
|
|
1453
|
-
for (const child of prop.value) visitNode$1(child);
|
|
1454
|
-
}
|
|
1455
|
-
return;
|
|
1456
|
-
case "Show":
|
|
1457
|
-
for (const child of node.children) visitNode$1(child);
|
|
1458
|
-
if (Array.isArray(node.fallback)) for (const child of node.fallback) visitNode$1(child);
|
|
1459
|
-
return;
|
|
1460
|
-
case "For":
|
|
1461
|
-
for (const child of node.body) visitNode$1(child);
|
|
1462
|
-
return;
|
|
1463
|
-
case "Host":
|
|
1464
|
-
if (node.child) visitNode$1(node.child, parent);
|
|
1465
|
-
return;
|
|
1466
|
-
case "Slot":
|
|
1467
|
-
for (const child of node.fallback) visitNode$1(child);
|
|
1468
|
-
return;
|
|
1469
|
-
case "Text":
|
|
1470
|
-
case "DynamicText": return;
|
|
1471
|
-
}
|
|
1472
|
-
}
|
|
1473
|
-
function assignElementPath(node, parent) {
|
|
1474
|
-
if (!parent) {
|
|
1475
|
-
node.domPath = { kind: "Root" };
|
|
1476
|
-
return;
|
|
1477
|
-
}
|
|
1478
|
-
const templateChildren = parent.children.filter(isTemplateChild);
|
|
1479
|
-
const index = templateChildren.indexOf(node);
|
|
1480
|
-
if (index === -1) return;
|
|
1481
|
-
if (index === 0) {
|
|
1482
|
-
node.domPath = {
|
|
1483
|
-
kind: "FirstChild",
|
|
1484
|
-
parent: parent.ref
|
|
1485
|
-
};
|
|
1486
|
-
return;
|
|
1487
|
-
}
|
|
1488
|
-
const previous = templateChildren[index - 1];
|
|
1489
|
-
if (previous.kind === "Element") {
|
|
1490
|
-
node.domPath = {
|
|
1491
|
-
kind: "NextSibling",
|
|
1492
|
-
previous: previous.ref
|
|
1493
|
-
};
|
|
1494
|
-
return;
|
|
1495
|
-
}
|
|
1496
|
-
node.domPath = {
|
|
1497
|
-
kind: "Child",
|
|
1498
|
-
parent: parent.ref,
|
|
1499
|
-
index
|
|
1500
|
-
};
|
|
1501
|
-
}
|
|
1502
|
-
function assignChildPaths(parent) {
|
|
1503
|
-
let markerIndex = 0;
|
|
1504
|
-
for (const child of parent.children) {
|
|
1505
|
-
if (isMarkerTemplateNode(child)) {
|
|
1506
|
-
assignMarkerPath(child, parent.ref, markerIndex++);
|
|
1507
|
-
visitNode$1(child);
|
|
1508
|
-
continue;
|
|
1509
|
-
}
|
|
1510
|
-
visitNode$1(child, parent);
|
|
1511
|
-
}
|
|
1512
|
-
}
|
|
1513
|
-
function assignMarkerPath(node, parent, index) {
|
|
1514
|
-
node.domPath = {
|
|
1515
|
-
kind: "Marker",
|
|
1516
|
-
parent,
|
|
1517
|
-
index
|
|
1518
|
-
};
|
|
1519
|
-
}
|
|
1520
|
-
function isTemplateChild(node) {
|
|
1521
|
-
return node.kind === "Element" || node.kind === "DynamicText" || node.kind === "Component" || node.kind === "Show" || node.kind === "For" || node.kind === "Slot";
|
|
1522
|
-
}
|
|
1523
|
-
function isMarkerTemplateNode(node) {
|
|
1524
|
-
return node.kind === "DynamicText" || node.kind === "Component" || node.kind === "Show" || node.kind === "For" || node.kind === "Slot";
|
|
1525
|
-
}
|
|
1526
|
-
//#endregion
|
|
1527
|
-
//#region packages/core/compiler/src/passes/assignPhysicalDomPaths.ts
|
|
1528
|
-
function assignPhysicalDomPaths(node) {
|
|
1529
|
-
visitNode(node);
|
|
1530
|
-
return node;
|
|
1531
|
-
}
|
|
1532
|
-
function visitNode(node, parent) {
|
|
1533
|
-
switch (node.kind) {
|
|
1534
|
-
case "Element":
|
|
1535
|
-
assignElementPhysicalPath(node, parent);
|
|
1536
|
-
assignChildrenPhysicalPaths(node);
|
|
1537
|
-
return;
|
|
1538
|
-
case "Fragment":
|
|
1539
|
-
for (const child of node.children) visitNode(child, parent);
|
|
1540
|
-
return;
|
|
1541
|
-
case "Host":
|
|
1542
|
-
if (node.child) visitNode(node.child, parent);
|
|
1543
|
-
return;
|
|
1544
|
-
case "Show":
|
|
1545
|
-
for (const child of node.children) visitNode(child);
|
|
1546
|
-
if (Array.isArray(node.fallback)) for (const child of node.fallback) visitNode(child);
|
|
1547
|
-
return;
|
|
1548
|
-
case "For":
|
|
1549
|
-
for (const child of node.body) visitNode(child);
|
|
1550
|
-
return;
|
|
1551
|
-
case "Slot":
|
|
1552
|
-
for (const child of node.fallback) visitNode(child);
|
|
1553
|
-
return;
|
|
1554
|
-
case "Component":
|
|
1555
|
-
for (const prop of node.props) {
|
|
1556
|
-
if (!Array.isArray(prop.value)) continue;
|
|
1557
|
-
for (const child of prop.value) visitNode(child);
|
|
1558
|
-
}
|
|
1559
|
-
return;
|
|
1560
|
-
case "Text":
|
|
1561
|
-
case "DynamicText": return;
|
|
1562
|
-
}
|
|
1563
|
-
}
|
|
1564
|
-
function assignElementPhysicalPath(node, parent) {
|
|
1565
|
-
if (!parent) {
|
|
1566
|
-
node.physicalDomPath = { kind: "Root" };
|
|
1567
|
-
return;
|
|
1568
|
-
}
|
|
1569
|
-
const physicalChildren = flattenPhysicalChildren(parent.children);
|
|
1570
|
-
const index = physicalChildren.indexOf(node);
|
|
1571
|
-
if (index < 0) return;
|
|
1572
|
-
node.physicalDomPath = createPhysicalPath(parent.ref, physicalChildren, index);
|
|
1573
|
-
}
|
|
1574
|
-
function assignChildrenPhysicalPaths(parent) {
|
|
1575
|
-
const physicalChildren = flattenPhysicalChildren(parent.children);
|
|
1576
|
-
for (let index = 0; index < physicalChildren.length; index++) {
|
|
1577
|
-
const child = physicalChildren[index];
|
|
1578
|
-
if (child.kind === "TextPlaceholder") continue;
|
|
1579
|
-
child.physicalDomPath = createPhysicalPath(parent.ref, physicalChildren, index);
|
|
1580
|
-
}
|
|
1581
|
-
for (const child of parent.children) visitNode(child, parent);
|
|
1582
|
-
}
|
|
1583
|
-
function createPhysicalPath(parent, children, index) {
|
|
1584
|
-
if (index === 0) return {
|
|
1585
|
-
kind: "FirstChild",
|
|
1586
|
-
parent
|
|
1587
|
-
};
|
|
1588
|
-
const previous = findPreviousRefNode(children, index);
|
|
1589
|
-
if (previous) return {
|
|
1590
|
-
kind: "NextSibling",
|
|
1591
|
-
previous: previous.ref
|
|
1592
|
-
};
|
|
1593
|
-
return {
|
|
1594
|
-
kind: "ChildNode",
|
|
1595
|
-
parent,
|
|
1596
|
-
index
|
|
1597
|
-
};
|
|
1598
|
-
}
|
|
1599
|
-
function findPreviousRefNode(children, index) {
|
|
1600
|
-
for (let i = index - 1; i >= 0; i--) {
|
|
1601
|
-
const node = children[i];
|
|
1602
|
-
if (node.kind === "TextPlaceholder") continue;
|
|
1603
|
-
return node;
|
|
1604
|
-
}
|
|
1605
|
-
}
|
|
1606
|
-
function flattenPhysicalChildren(children) {
|
|
1607
|
-
const result = [];
|
|
1608
|
-
for (const child of children) appendPhysicalChild(result, child);
|
|
1609
|
-
return result;
|
|
1610
|
-
}
|
|
1611
|
-
function appendPhysicalChild(result, node) {
|
|
1612
|
-
switch (node.kind) {
|
|
1613
|
-
case "Text":
|
|
1614
|
-
if (node.value.length > 0) result.push({ kind: "TextPlaceholder" });
|
|
1615
|
-
return;
|
|
1616
|
-
case "Element":
|
|
1617
|
-
case "DynamicText":
|
|
1618
|
-
case "Component":
|
|
1619
|
-
case "Show":
|
|
1620
|
-
case "For":
|
|
1621
|
-
case "Slot":
|
|
1622
|
-
result.push(node);
|
|
1623
|
-
return;
|
|
1624
|
-
case "Fragment":
|
|
1625
|
-
for (const child of node.children) appendPhysicalChild(result, child);
|
|
1626
|
-
return;
|
|
1627
|
-
case "Host":
|
|
1628
|
-
if (node.child) appendPhysicalChild(result, node.child);
|
|
1629
|
-
return;
|
|
1630
|
-
}
|
|
1631
|
-
}
|
|
1632
|
-
//#endregion
|
|
1633
|
-
//#region packages/core/compiler/src/passes/validateBuiltins.ts
|
|
1634
|
-
function validateBuiltins(node, options) {
|
|
1635
|
-
visit$1(node, {
|
|
1636
|
-
isDefineElementRenderRoot: options.isDefineElementRenderRoot,
|
|
1637
|
-
filename: options.filename,
|
|
1638
|
-
insideHost: false,
|
|
1639
|
-
root: true
|
|
1640
|
-
});
|
|
1641
|
-
}
|
|
1642
|
-
function visit$1(node, state) {
|
|
1643
|
-
switch (node.kind) {
|
|
1644
|
-
case "Host":
|
|
1645
|
-
if (!state.isDefineElementRenderRoot || !state.root) throw new CompilerError({
|
|
1646
|
-
code: CompilerErrorCode.INVALID_BUILTIN_USAGE,
|
|
1647
|
-
message: "<Host> can only be used as a defineElement root boundary.",
|
|
1648
|
-
filename: state.filename,
|
|
1649
|
-
span: node.span,
|
|
1650
|
-
hint: "Return <Host> directly from the defineElement setup function."
|
|
1651
|
-
});
|
|
1652
|
-
if (node.child) visit$1(node.child, _objectSpread2(_objectSpread2({}, state), {}, {
|
|
1653
|
-
insideHost: true,
|
|
1654
|
-
root: false
|
|
1655
|
-
}));
|
|
1656
|
-
return;
|
|
1657
|
-
case "Slot":
|
|
1658
|
-
if (!state.insideHost) throw new CompilerError({
|
|
1659
|
-
code: CompilerErrorCode.INVALID_BUILTIN_USAGE,
|
|
1660
|
-
message: "<Slot> can only be used inside the defineElement Host boundary.",
|
|
1661
|
-
filename: state.filename,
|
|
1662
|
-
span: node.span,
|
|
1663
|
-
hint: "Place <Slot> inside the root <Host> returned by defineElement setup."
|
|
1664
|
-
});
|
|
1665
|
-
for (const child of node.fallback) visit$1(child, _objectSpread2(_objectSpread2({}, state), {}, { root: false }));
|
|
1666
|
-
return;
|
|
1667
|
-
case "Element":
|
|
1668
|
-
case "Fragment":
|
|
1669
|
-
for (const child of node.children) visit$1(child, _objectSpread2(_objectSpread2({}, state), {}, { root: false }));
|
|
1670
|
-
return;
|
|
1671
|
-
case "Component":
|
|
1672
|
-
for (const prop of node.props) {
|
|
1673
|
-
if (!Array.isArray(prop.value)) continue;
|
|
1674
|
-
for (const child of prop.value) visit$1(child, _objectSpread2(_objectSpread2({}, state), {}, { root: false }));
|
|
1675
|
-
}
|
|
1676
|
-
return;
|
|
1677
|
-
case "Show":
|
|
1678
|
-
for (const child of node.children) visit$1(child, _objectSpread2(_objectSpread2({}, state), {}, { root: false }));
|
|
1679
|
-
if (Array.isArray(node.fallback)) for (const child of node.fallback) visit$1(child, _objectSpread2(_objectSpread2({}, state), {}, { root: false }));
|
|
1680
|
-
return;
|
|
1681
|
-
case "For":
|
|
1682
|
-
for (const child of node.body) visit$1(child, _objectSpread2(_objectSpread2({}, state), {}, { root: false }));
|
|
1683
|
-
return;
|
|
1684
|
-
default: return;
|
|
1685
|
-
}
|
|
1686
|
-
}
|
|
1687
|
-
//#endregion
|
|
1688
|
-
//#region packages/core/compiler/src/passes/analyzeBindings.ts
|
|
1689
|
-
function analyzeBindings(node) {
|
|
1690
|
-
const analysis = {
|
|
1691
|
-
dynamicText: 0,
|
|
1692
|
-
dynamicAttrs: 0,
|
|
1693
|
-
events: 0,
|
|
1694
|
-
components: 0
|
|
1695
|
-
};
|
|
1696
|
-
visit(node, analysis);
|
|
1697
|
-
return analysis;
|
|
1698
|
-
}
|
|
1699
|
-
function visit(node, analysis) {
|
|
1700
|
-
switch (node.kind) {
|
|
1701
|
-
case "Element":
|
|
1702
|
-
for (const attr of node.attrs) {
|
|
1703
|
-
if (attr.kind === "AttrBinding" || attr.kind === "PropBinding") analysis.dynamicAttrs++;
|
|
1704
|
-
if (attr.kind === "EventBinding") analysis.events++;
|
|
1705
|
-
}
|
|
1706
|
-
for (const child of node.children) visit(child, analysis);
|
|
1707
|
-
return;
|
|
1708
|
-
case "DynamicText":
|
|
1709
|
-
analysis.dynamicText++;
|
|
1710
|
-
return;
|
|
1711
|
-
case "Component":
|
|
1712
|
-
analysis.components++;
|
|
1713
|
-
for (const prop of node.props) {
|
|
1714
|
-
if (!Array.isArray(prop.value)) continue;
|
|
1715
|
-
for (const child of prop.value) visit(child, analysis);
|
|
1716
|
-
}
|
|
1717
|
-
return;
|
|
1718
|
-
case "Fragment":
|
|
1719
|
-
for (const child of node.children) visit(child, analysis);
|
|
1720
|
-
return;
|
|
1721
|
-
case "Host":
|
|
1722
|
-
if (node.child) visit(node.child, analysis);
|
|
1723
|
-
return;
|
|
1724
|
-
case "Slot":
|
|
1725
|
-
for (const child of node.fallback) visit(child, analysis);
|
|
1726
|
-
return;
|
|
1727
|
-
case "Show":
|
|
1728
|
-
for (const child of node.children) visit(child, analysis);
|
|
1729
|
-
if (Array.isArray(node.fallback)) for (const child of node.fallback) visit(child, analysis);
|
|
1730
|
-
return;
|
|
1731
|
-
case "For":
|
|
1732
|
-
for (const child of node.body) visit(child, analysis);
|
|
1733
|
-
return;
|
|
1734
|
-
case "Text": return;
|
|
1735
|
-
}
|
|
1736
|
-
}
|
|
1737
|
-
//#endregion
|
|
1738
|
-
//#region packages/core/compiler/src/transform/index.ts
|
|
1739
|
-
function transformJSX(path, state, config) {
|
|
1740
|
-
if (state.get("skip")) return;
|
|
1741
|
-
if (!path.isJSXElement() && !path.isJSXFragment()) return;
|
|
1742
|
-
const context = getCompilerContext(path, config);
|
|
1743
|
-
const ir = lowerJSX(path, context);
|
|
1744
|
-
normalizeChildren(ir);
|
|
1745
|
-
validateBuiltins(ir, {
|
|
1746
|
-
isDefineElementRenderRoot: isDefineElementRenderRoot(path),
|
|
1747
|
-
filename: state.filename
|
|
1748
|
-
});
|
|
1749
|
-
assignDomPaths(ir);
|
|
1750
|
-
assignPhysicalDomPaths(ir);
|
|
1751
|
-
analyzeBindings(ir);
|
|
1752
|
-
collectTemplates(ir, context);
|
|
1753
|
-
path.replaceWith(emitDOM(ir, context));
|
|
1754
|
-
}
|
|
1755
|
-
//#endregion
|
|
1756
|
-
//#region packages/core/compiler/src/visitor.ts
|
|
1757
|
-
function createVisitor(config) {
|
|
1758
|
-
return {
|
|
1759
|
-
JSXElement(path, state) {
|
|
1760
|
-
transformJSX(path, state, config);
|
|
1761
|
-
},
|
|
1762
|
-
JSXFragment(path, state) {
|
|
1763
|
-
transformJSX(path, state, config);
|
|
1764
|
-
},
|
|
1765
|
-
Program: createProgramVisitor(config)
|
|
1766
|
-
};
|
|
1767
|
-
}
|
|
1768
|
-
//#endregion
|
|
1769
|
-
//#region packages/core/compiler/src/index.ts
|
|
1770
|
-
function hasParserPlugin(plugins, name) {
|
|
1771
|
-
return plugins.some((plugin) => (Array.isArray(plugin) ? plugin[0] : plugin) === name);
|
|
1772
|
-
}
|
|
1773
|
-
var src_default = declare((api, options) => {
|
|
1774
|
-
api.assertVersion(8);
|
|
1775
|
-
return {
|
|
1776
|
-
name: "babel-plugin-zeus-compiler",
|
|
1777
|
-
manipulateOptions(_opts, parserOpts) {
|
|
1778
|
-
var _parserOpts$plugins;
|
|
1779
|
-
(_parserOpts$plugins = parserOpts.plugins) !== null && _parserOpts$plugins !== void 0 || (parserOpts.plugins = []);
|
|
1780
|
-
if (!hasParserPlugin(parserOpts.plugins, "jsx")) parserOpts.plugins.push("jsx");
|
|
1781
|
-
},
|
|
1782
|
-
visitor: createVisitor(resolveConfig(options))
|
|
1783
|
-
};
|
|
1784
|
-
});
|
|
6
|
+
import { createRequire } from "node:module";
|
|
7
|
+
const transformModule = createRequire(import.meta.url)("@zeus-js/compiler-native").transformModule;
|
|
1785
8
|
//#endregion
|
|
1786
|
-
export {
|
|
9
|
+
export { transformModule as default, transformModule };
|