@tamagui/compiler-core 0.0.0-bootstrap.0 → 3.0.0-beta.1093.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +57 -1
  3. package/dist/cjs/ast.cjs +108 -0
  4. package/dist/cjs/contracts.cjs +61 -0
  5. package/dist/cjs/diagnostics.cjs +68 -0
  6. package/dist/cjs/evaluate.cjs +602 -0
  7. package/dist/cjs/graph.cjs +335 -0
  8. package/dist/cjs/hash.cjs +48 -0
  9. package/dist/cjs/index.cjs +43 -0
  10. package/dist/cjs/ir.cjs +32 -0
  11. package/dist/cjs/lower.cjs +232 -0
  12. package/dist/cjs/materialize.cjs +222 -0
  13. package/dist/cjs/normalize.cjs +628 -0
  14. package/dist/cjs/output.cjs +148 -0
  15. package/dist/cjs/planCache.cjs +262 -0
  16. package/dist/cjs/session.cjs +127 -0
  17. package/dist/cjs/yuku.cjs +166 -0
  18. package/dist/cjs/zero.cjs +389 -0
  19. package/dist/esm/ast.mjs +79 -0
  20. package/dist/esm/ast.mjs.map +1 -0
  21. package/dist/esm/contracts.mjs +34 -0
  22. package/dist/esm/contracts.mjs.map +1 -0
  23. package/dist/esm/diagnostics.mjs +44 -0
  24. package/dist/esm/diagnostics.mjs.map +1 -0
  25. package/dist/esm/evaluate.mjs +576 -0
  26. package/dist/esm/evaluate.mjs.map +1 -0
  27. package/dist/esm/graph.mjs +313 -0
  28. package/dist/esm/graph.mjs.map +1 -0
  29. package/dist/esm/hash.mjs +26 -0
  30. package/dist/esm/hash.mjs.map +1 -0
  31. package/dist/esm/index.mjs +30 -0
  32. package/dist/esm/ir.mjs +12 -0
  33. package/dist/esm/ir.mjs.map +1 -0
  34. package/dist/esm/lower.mjs +210 -0
  35. package/dist/esm/lower.mjs.map +1 -0
  36. package/dist/esm/materialize.mjs +203 -0
  37. package/dist/esm/materialize.mjs.map +1 -0
  38. package/dist/esm/normalize.mjs +604 -0
  39. package/dist/esm/normalize.mjs.map +1 -0
  40. package/dist/esm/output.mjs +119 -0
  41. package/dist/esm/output.mjs.map +1 -0
  42. package/dist/esm/planCache.mjs +232 -0
  43. package/dist/esm/planCache.mjs.map +1 -0
  44. package/dist/esm/session.mjs +108 -0
  45. package/dist/esm/session.mjs.map +1 -0
  46. package/dist/esm/yuku.mjs +144 -0
  47. package/dist/esm/yuku.mjs.map +1 -0
  48. package/dist/esm/zero.mjs +354 -0
  49. package/dist/esm/zero.mjs.map +1 -0
  50. package/package.json +42 -4
  51. package/src/ast.ts +106 -0
  52. package/src/contracts.ts +150 -0
  53. package/src/diagnostics.ts +96 -0
  54. package/src/evaluate.ts +875 -0
  55. package/src/graph.ts +425 -0
  56. package/src/hash.ts +36 -0
  57. package/src/index.ts +15 -0
  58. package/src/ir.ts +156 -0
  59. package/src/lower.ts +435 -0
  60. package/src/materialize.ts +383 -0
  61. package/src/normalize.ts +834 -0
  62. package/src/output.ts +175 -0
  63. package/src/planCache.ts +362 -0
  64. package/src/session.ts +192 -0
  65. package/src/yuku.ts +197 -0
  66. package/src/zero.ts +609 -0
  67. package/types/ast.d.ts +11 -0
  68. package/types/ast.d.ts.map +1 -0
  69. package/types/contracts.d.ts +99 -0
  70. package/types/contracts.d.ts.map +1 -0
  71. package/types/diagnostics.d.ts +31 -0
  72. package/types/diagnostics.d.ts.map +1 -0
  73. package/types/evaluate.d.ts +48 -0
  74. package/types/evaluate.d.ts.map +1 -0
  75. package/types/graph.d.ts +51 -0
  76. package/types/graph.d.ts.map +1 -0
  77. package/types/hash.d.ts +8 -0
  78. package/types/hash.d.ts.map +1 -0
  79. package/types/index.d.ts +16 -0
  80. package/types/index.d.ts.map +1 -0
  81. package/types/ir.d.ts +120 -0
  82. package/types/ir.d.ts.map +1 -0
  83. package/types/lower.d.ts +99 -0
  84. package/types/lower.d.ts.map +1 -0
  85. package/types/materialize.d.ts +121 -0
  86. package/types/materialize.d.ts.map +1 -0
  87. package/types/normalize.d.ts +7 -0
  88. package/types/normalize.d.ts.map +1 -0
  89. package/types/output.d.ts +32 -0
  90. package/types/output.d.ts.map +1 -0
  91. package/types/planCache.d.ts +123 -0
  92. package/types/planCache.d.ts.map +1 -0
  93. package/types/session.d.ts +52 -0
  94. package/types/session.d.ts.map +1 -0
  95. package/types/yuku.d.ts +4 -0
  96. package/types/yuku.d.ts.map +1 -0
  97. package/types/zero.d.ts +99 -0
  98. package/types/zero.d.ts.map +1 -0
@@ -0,0 +1,604 @@
1
+ import { childNode, childNodes, findAstNode, identifierName, isAstNode, walkAst } from "./ast.mjs";
2
+ import { expressionReference, resolvedModuleId, spanOf } from "./contracts.mjs";
3
+ import { linkedBailout, localBailout } from "./diagnostics.mjs";
4
+ import { hostImportProvenance } from "./ir.mjs";
5
+
6
+ function finalizeElement(base, entries, bailouts) {
7
+ if (bailouts.length === 0) {
8
+ return {
9
+ ...base,
10
+ complete: true,
11
+ entries,
12
+ bailouts: []
13
+ };
14
+ }
15
+ return {
16
+ ...base,
17
+ complete: false,
18
+ bailedEntries: entries,
19
+ bailouts
20
+ };
21
+ }
22
+ function definitionFromDeclaration(id, name, declaration, parentOf) {
23
+ let identifier = declaration;
24
+ let initializer = null;
25
+ let constant = false;
26
+ if (declaration.type === "VariableDeclarator") {
27
+ identifier = childNode(declaration, "id") ?? declaration;
28
+ initializer = childNode(declaration, "init");
29
+ const parent = parentOf(declaration);
30
+ constant = parent?.type === "VariableDeclaration" && parent.kind === "const";
31
+ } else if (declaration.type === "Identifier") {
32
+ const declarator = parentOf(declaration);
33
+ if (declarator?.type === "VariableDeclarator" && childNode(declarator, "id")?.start === declaration.start) {
34
+ initializer = childNode(declarator, "init");
35
+ const parent = parentOf(declarator);
36
+ constant = parent?.type === "VariableDeclaration" && parent.kind === "const";
37
+ }
38
+ }
39
+ return {
40
+ id: resolvedModuleId(id),
41
+ name,
42
+ start: identifier.start,
43
+ end: identifier.end,
44
+ initializer,
45
+ constant
46
+ };
47
+ }
48
+ function importBinding(program, localName) {
49
+ for (const statement of childNodes(program, "body")) {
50
+ if (statement.type !== "ImportDeclaration") continue;
51
+ const source = childNode(statement, "source");
52
+ const sourceValue = source && typeof source.value === "string" ? source.value : null;
53
+ if (!sourceValue) continue;
54
+ for (const specifier of childNodes(statement, "specifiers")) {
55
+ if (identifierName(childNode(specifier, "local")) !== localName) continue;
56
+ if (specifier.type === "ImportDefaultSpecifier") {
57
+ return {
58
+ source: sourceValue,
59
+ imported: "default"
60
+ };
61
+ }
62
+ if (specifier.type === "ImportNamespaceSpecifier") {
63
+ return {
64
+ source: sourceValue,
65
+ imported: "*"
66
+ };
67
+ }
68
+ const imported = childNode(specifier, "imported");
69
+ const importedName = identifierName(imported) ?? (typeof imported?.value === "string" ? imported.value : null);
70
+ return importedName ? {
71
+ source: sourceValue,
72
+ imported: importedName
73
+ } : null;
74
+ }
75
+ }
76
+ return null;
77
+ }
78
+ function asStaticValue(node) {
79
+ if (!node) return void 0;
80
+ if (node.type === "NullLiteral") return null;
81
+ if (node.type === "Literal" || node.type.endsWith("Literal")) {
82
+ const value = node.value;
83
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null) {
84
+ return value;
85
+ }
86
+ }
87
+ return void 0;
88
+ }
89
+ function elementValue(id, node) {
90
+ const staticValue = asStaticValue(node);
91
+ return staticValue === void 0 ? expressionReference(id, node) : {
92
+ kind: "static",
93
+ value: staticValue,
94
+ span: spanOf(id, node)
95
+ };
96
+ }
97
+ function symbolDefinition(definition) {
98
+ if (!definition) return null;
99
+ return {
100
+ id: definition.id,
101
+ name: definition.name,
102
+ span: {
103
+ id: definition.id,
104
+ start: definition.start,
105
+ end: definition.end
106
+ },
107
+ initializer: definition.initializer ? expressionReference(definition.id, definition.initializer) : null,
108
+ constant: definition.constant
109
+ };
110
+ }
111
+ function componentFromNode(candidate, id, program, imports, node, bailouts) {
112
+ const literal = asStaticValue(node);
113
+ if (typeof literal === "string") {
114
+ return {
115
+ kind: "intrinsic",
116
+ name: literal,
117
+ span: spanOf(id, node),
118
+ closingSpan: null,
119
+ definition: null,
120
+ provenance: null
121
+ };
122
+ }
123
+ if ((node.type === "MemberExpression" || node.type === "JSXMemberExpression") && node.computed !== true) {
124
+ const objectName = identifierName(childNode(node, "object"));
125
+ const memberName = identifierName(childNode(node, "property"));
126
+ const binding2 = objectName ? importBinding(program, objectName) : null;
127
+ if (memberName && binding2?.imported === "html") {
128
+ const provenance2 = hostImportProvenance(imports, binding2.source, binding2.imported);
129
+ if (provenance2) {
130
+ return {
131
+ kind: "binding",
132
+ name: memberName,
133
+ span: spanOf(id, node),
134
+ closingSpan: null,
135
+ definition: null,
136
+ provenance: provenance2
137
+ };
138
+ }
139
+ }
140
+ }
141
+ const name = identifierName(node);
142
+ if (!name) {
143
+ bailouts.push(localBailout("local/unsupported-element-name", spanOf(id, node), `Element target ${node.type} is not a stable identifier or intrinsic tag`));
144
+ return null;
145
+ }
146
+ const intrinsic = /^[a-z]/.test(name);
147
+ const binding = intrinsic ? null : importBinding(program, name);
148
+ const provenance = binding ? hostImportProvenance(imports, binding.source, binding.imported) : null;
149
+ const definition = intrinsic ? null : symbolDefinition(candidate.definitionOf(id, name));
150
+ if (!intrinsic && !definition && !provenance) {
151
+ bailouts.push(linkedBailout("linked/unresolved-component-binding", spanOf(id, node), `Component binding ${name} has no linked definition`));
152
+ }
153
+ return {
154
+ kind: intrinsic ? "intrinsic" : "binding",
155
+ name,
156
+ span: spanOf(id, node),
157
+ closingSpan: null,
158
+ definition,
159
+ provenance
160
+ };
161
+ }
162
+ function jsxComponentNode(opening) {
163
+ return childNode(opening, "name");
164
+ }
165
+ function jsxEntries(id, element, opening, bailouts) {
166
+ const entries = [];
167
+ for (const attribute of childNodes(opening, "attributes")) {
168
+ if (attribute.type === "JSXSpreadAttribute") {
169
+ const argument = childNode(attribute, "argument");
170
+ if (argument) {
171
+ entries.push({
172
+ kind: "spread",
173
+ span: spanOf(id, attribute),
174
+ value: expressionReference(id, argument)
175
+ });
176
+ }
177
+ continue;
178
+ }
179
+ if (attribute.type !== "JSXAttribute") continue;
180
+ const nameNode = childNode(attribute, "name");
181
+ const name = identifierName(nameNode);
182
+ if (!name) {
183
+ bailouts.push(localBailout("local/unsupported-prop-key", spanOf(id, attribute), "Namespaced JSX attributes are not statically supported"));
184
+ continue;
185
+ }
186
+ const rawValue = childNode(attribute, "value");
187
+ let value;
188
+ if (!rawValue) {
189
+ value = {
190
+ kind: "static",
191
+ value: true,
192
+ span: spanOf(id, attribute)
193
+ };
194
+ } else if (rawValue.type === "JSXExpressionContainer") {
195
+ const expression = childNode(rawValue, "expression");
196
+ if (!expression || expression.type === "JSXEmptyExpression") {
197
+ bailouts.push(localBailout("local/unsupported-expression", spanOf(id, rawValue), `JSX prop ${name} has no expression`));
198
+ continue;
199
+ }
200
+ value = elementValue(id, expression);
201
+ } else {
202
+ value = elementValue(id, rawValue);
203
+ }
204
+ entries.push({
205
+ kind: "prop",
206
+ name,
207
+ span: spanOf(id, attribute),
208
+ value
209
+ });
210
+ }
211
+ for (const child of childNodes(element, "children")) {
212
+ let value;
213
+ if (child.type === "JSXText") {
214
+ if (typeof child.value !== "string" || child.value.trim() === "") continue;
215
+ value = {
216
+ kind: "static",
217
+ value: child.value,
218
+ span: spanOf(id, child)
219
+ };
220
+ } else if (child.type === "JSXExpressionContainer") {
221
+ const expression = childNode(child, "expression");
222
+ value = !expression || expression.type === "JSXEmptyExpression" ? {
223
+ kind: "empty",
224
+ span: spanOf(id, child)
225
+ } : elementValue(id, expression);
226
+ } else if (child.type === "JSXElement" || child.type === "JSXFragment") {
227
+ value = {
228
+ kind: "element",
229
+ span: spanOf(id, child)
230
+ };
231
+ } else {
232
+ bailouts.push(localBailout("local/unsupported-child", spanOf(id, child), `JSX child ${child.type} cannot be normalized`));
233
+ continue;
234
+ }
235
+ entries.push({
236
+ kind: "child",
237
+ span: spanOf(id, child),
238
+ value
239
+ });
240
+ }
241
+ return entries.sort((left, right) => left.span.start - right.span.start);
242
+ }
243
+ function propertyName(property) {
244
+ if (property.computed === true) return null;
245
+ const key = childNode(property, "key");
246
+ const name = identifierName(key);
247
+ if (name) return name;
248
+ const literal = asStaticValue(key);
249
+ return typeof literal === "string" || typeof literal === "number" ? String(literal) : null;
250
+ }
251
+ function runtimeChildEntries(id, program, node, bailouts) {
252
+ const rawNodes = node.type === "ArrayExpression" ? node.elements : null;
253
+ if (Array.isArray(rawNodes) && rawNodes.some((child) => child === null || !isAstNode(child))) {
254
+ bailouts.push(localBailout("local/unsupported-child", spanOf(id, node), "Sparse compiled children cannot be normalized without changing order"));
255
+ return [];
256
+ }
257
+ const nodes = Array.isArray(rawNodes) ? rawNodes.filter(isAstNode) : [node];
258
+ return nodes.flatMap((child) => {
259
+ if (child.type === "SpreadElement") {
260
+ bailouts.push(localBailout("local/unsupported-child", spanOf(id, child), "Spread children cannot be statically ordered"));
261
+ return [];
262
+ }
263
+ if (child.type === "CallExpression" && runtimeCall(program, child)) {
264
+ return [{
265
+ kind: "child",
266
+ span: spanOf(id, child),
267
+ value: {
268
+ kind: "element",
269
+ span: spanOf(id, child)
270
+ }
271
+ }];
272
+ }
273
+ return [{
274
+ kind: "child",
275
+ span: spanOf(id, child),
276
+ value: elementValue(id, child)
277
+ }];
278
+ });
279
+ }
280
+ function objectEntries(id, program, object, bailouts) {
281
+ const entries = [];
282
+ for (const property of childNodes(object, "properties")) {
283
+ if (property.type === "SpreadElement") {
284
+ const argument = childNode(property, "argument");
285
+ if (argument) {
286
+ const spread = {
287
+ kind: "spread",
288
+ span: spanOf(id, property),
289
+ value: expressionReference(id, argument)
290
+ };
291
+ entries.push(spread);
292
+ }
293
+ continue;
294
+ }
295
+ if (property.type !== "Property" && property.type !== "ObjectProperty") {
296
+ bailouts.push(localBailout("local/unsupported-prop-key", spanOf(id, property), `Runtime props entry ${property.type} is not a data property`));
297
+ continue;
298
+ }
299
+ const name = propertyName(property);
300
+ const valueNode = childNode(property, "value");
301
+ if (!name || !valueNode) {
302
+ bailouts.push(localBailout("local/unsupported-prop-key", spanOf(id, property), "Computed runtime prop keys are not statically supported"));
303
+ continue;
304
+ }
305
+ if (name === "children") {
306
+ entries.push(...runtimeChildEntries(id, program, valueNode, bailouts));
307
+ continue;
308
+ }
309
+ const prop = {
310
+ kind: "prop",
311
+ name,
312
+ span: spanOf(id, property),
313
+ value: elementValue(id, valueNode)
314
+ };
315
+ entries.push(prop);
316
+ }
317
+ return entries;
318
+ }
319
+ function runtimeCall(program, call) {
320
+ const callee = childNode(call, "callee");
321
+ if (!callee) return null;
322
+ const directName = identifierName(callee);
323
+ if (directName) {
324
+ const provenance2 = importBinding(program, directName);
325
+ if (provenance2?.source === "react/jsx-runtime" && (provenance2.imported === "jsx" || provenance2.imported === "jsxs")) {
326
+ return { form: "jsx-runtime" };
327
+ }
328
+ if (provenance2?.source === "react" && provenance2.imported === "createElement") {
329
+ return { form: "create-element" };
330
+ }
331
+ }
332
+ if (callee.type !== "MemberExpression" || callee.computed === true) return null;
333
+ const objectName = identifierName(childNode(callee, "object"));
334
+ const propertyName2 = identifierName(childNode(callee, "property"));
335
+ if (propertyName2 !== "createElement" || !objectName) return null;
336
+ const provenance = importBinding(program, objectName);
337
+ return provenance?.source === "react" && (provenance.imported === "default" || provenance.imported === "*") ? { form: "create-element" } : null;
338
+ }
339
+ function normalizeRuntimeElement(candidate, id, program, imports, call, runtime, bailouts) {
340
+ const bailoutStart = bailouts.length;
341
+ const args = childNodes(call, "arguments");
342
+ const target = args[0];
343
+ if (!target) {
344
+ bailouts.push(localBailout("local/invalid-element-call", spanOf(id, call), `${runtime.form} call has no element target`));
345
+ return null;
346
+ }
347
+ const component = componentFromNode(candidate, id, program, imports, target, bailouts);
348
+ if (!component) return null;
349
+ const entries = [];
350
+ const props = args[1];
351
+ if (props && asStaticValue(props) !== null) {
352
+ if (props.type === "ObjectExpression") {
353
+ entries.push(...objectEntries(id, program, props, bailouts));
354
+ } else {
355
+ entries.push({
356
+ kind: "spread",
357
+ span: spanOf(id, props),
358
+ value: expressionReference(id, props)
359
+ });
360
+ }
361
+ }
362
+ if (runtime.form === "create-element") {
363
+ for (const child of args.slice(2)) {
364
+ entries.push(...runtimeChildEntries(id, program, child, bailouts));
365
+ }
366
+ }
367
+ return finalizeElement({
368
+ kind: "element",
369
+ form: runtime.form,
370
+ id,
371
+ span: spanOf(id, call),
372
+ propsSpan: props ? spanOf(id, props) : null,
373
+ component
374
+ }, entries.sort((left, right) => left.span.start - right.span.start), bailouts.slice(bailoutStart));
375
+ }
376
+ function styledDefinitions(candidate, id, program, imports, bailouts) {
377
+ const definitions = [];
378
+ walkAst(program, (node) => {
379
+ if (node.type !== "VariableDeclarator") return;
380
+ const identifier = childNode(node, "id");
381
+ const name = identifierName(identifier);
382
+ const call = childNode(node, "init");
383
+ if (!name || !identifier || call?.type !== "CallExpression") return;
384
+ const callee = childNode(call, "callee");
385
+ const factoryName = callee && identifierName(callee);
386
+ if (!factoryName) return;
387
+ const binding = importBinding(program, factoryName);
388
+ if (!binding || binding.imported !== "styled") return;
389
+ const factory = hostImportProvenance(imports, binding.source, binding.imported);
390
+ if (!factory) return;
391
+ const definitionBailouts = [];
392
+ const args = childNodes(call, "arguments");
393
+ const baseNode = args[0];
394
+ const objectForm = args[1]?.type === "ObjectExpression";
395
+ const optionsNode = objectForm ? args[1] : args.length >= 3 ? args[2] : args[1];
396
+ if (!baseNode || !optionsNode) {
397
+ definitionBailouts.push(localBailout("local/unsupported-styled-definition", spanOf(id, call), `styled definition ${name} must provide a base and options object`));
398
+ bailouts.push(...definitionBailouts);
399
+ return;
400
+ }
401
+ const base = componentFromNode(candidate, id, program, imports, baseNode, definitionBailouts);
402
+ if (!base) {
403
+ bailouts.push(...definitionBailouts);
404
+ return;
405
+ }
406
+ const baseClassNode = objectForm ? null : args.length >= 3 ? args[1] : null;
407
+ const staticConfigNode = objectForm && args.length >= 3 ? args[2] : null;
408
+ const baseDefinition = {
409
+ kind: "styled-definition",
410
+ id,
411
+ name,
412
+ span: spanOf(id, call),
413
+ definitionSpan: spanOf(id, identifier),
414
+ factory,
415
+ base,
416
+ baseClassName: baseClassNode ? elementValue(id, baseClassNode) : null,
417
+ options: expressionReference(id, optionsNode),
418
+ staticConfig: staticConfigNode ? expressionReference(id, staticConfigNode) : null
419
+ };
420
+ definitions.push(definitionBailouts.length === 0 ? {
421
+ ...baseDefinition,
422
+ complete: true,
423
+ bailouts: []
424
+ } : {
425
+ ...baseDefinition,
426
+ complete: false,
427
+ bailouts: definitionBailouts
428
+ });
429
+ bailouts.push(...definitionBailouts);
430
+ });
431
+ return definitions.sort((left, right) => left.span.start - right.span.start);
432
+ }
433
+ const DOM_STYLE_FRONTENDS = /* @__PURE__ */ new Set([
434
+ "tamagui/dom",
435
+ "@tamagui/core/dom",
436
+ "@tamagui/tailwind"
437
+ ]);
438
+ const STYLE_FRONTENDS = /* @__PURE__ */ new Set([
439
+ ...DOM_STYLE_FRONTENDS,
440
+ "tamagui",
441
+ "@tamagui/core",
442
+ "@tamagui/web"
443
+ ]);
444
+ function domStyleDefinitions(id, program, imports) {
445
+ const definitions = [];
446
+ walkAst(program, (node) => {
447
+ if (node.type !== "VariableDeclarator") return;
448
+ const identifier = childNode(node, "id");
449
+ const name = identifierName(identifier);
450
+ const call = childNode(node, "init");
451
+ if (!name || !identifier || call?.type !== "CallExpression") return;
452
+ const callee = childNode(call, "callee");
453
+ const factoryName = callee && identifierName(callee);
454
+ if (!factoryName) return;
455
+ const binding = importBinding(program, factoryName);
456
+ if (!binding || binding.imported !== "style" || !STYLE_FRONTENDS.has(binding.source)) {
457
+ return;
458
+ }
459
+ const factory = hostImportProvenance(imports, binding.source, binding.imported);
460
+ const value = childNodes(call, "arguments")[0];
461
+ if (!factory || !value) return;
462
+ definitions.push({
463
+ kind: "dom-style-definition",
464
+ id,
465
+ name,
466
+ span: spanOf(id, call),
467
+ definitionSpan: spanOf(id, identifier),
468
+ factory,
469
+ value: expressionReference(id, value)
470
+ });
471
+ });
472
+ return definitions.sort((left, right) => left.span.start - right.span.start);
473
+ }
474
+ function domStyleArgument(candidate, id, program, node) {
475
+ let call = node;
476
+ if (node.type === "Identifier") {
477
+ const name = identifierName(node);
478
+ const definition = name ? candidate.definitionOf(id, name) : null;
479
+ if (!definition?.constant || !definition.initializer) return null;
480
+ call = definition.initializer;
481
+ }
482
+ if (call.type !== "CallExpression") return null;
483
+ const callee = childNode(call, "callee");
484
+ const factoryName = callee && identifierName(callee);
485
+ if (!factoryName) return null;
486
+ const binding = importBinding(program, factoryName);
487
+ if (!binding || binding.imported !== "style" || !STYLE_FRONTENDS.has(binding.source)) {
488
+ return null;
489
+ }
490
+ return childNodes(call, "arguments")[0] ?? null;
491
+ }
492
+ function domStyleProgram(candidate, id, program, node) {
493
+ if (node.type !== "ArrayExpression" || !Array.isArray(node.elements)) {
494
+ const argument = domStyleArgument(candidate, id, program, node);
495
+ return argument ? {
496
+ kind: "dom-style",
497
+ span: spanOf(id, node),
498
+ items: [{
499
+ condition: null,
500
+ value: expressionReference(id, argument)
501
+ }]
502
+ } : null;
503
+ }
504
+ const items = [];
505
+ for (const rawItem of node.elements) {
506
+ if (!isAstNode(rawItem)) return null;
507
+ let item = rawItem;
508
+ let condition = null;
509
+ if (item.type === "LogicalExpression" && item.operator === "&&") {
510
+ const left = childNode(item, "left");
511
+ const right = childNode(item, "right");
512
+ if (!left || !right) return null;
513
+ condition = expressionReference(id, left);
514
+ item = right;
515
+ }
516
+ const argument = domStyleArgument(candidate, id, program, item);
517
+ if (!argument) {
518
+ const staticValue = asStaticValue(item);
519
+ if (staticValue === false || staticValue === null) continue;
520
+ return null;
521
+ }
522
+ items.push({
523
+ condition,
524
+ value: expressionReference(id, argument)
525
+ });
526
+ }
527
+ return {
528
+ kind: "dom-style",
529
+ span: spanOf(id, node),
530
+ items
531
+ };
532
+ }
533
+ function normalizeElements(candidate, rawId, imports = []) {
534
+ const id = resolvedModuleId(rawId);
535
+ const program = candidate.programOf(id);
536
+ const elements = [];
537
+ const bailouts = [];
538
+ walkAst(program, (node) => {
539
+ if (node.type === "JSXElement") {
540
+ const bailoutStart = bailouts.length;
541
+ const opening = childNode(node, "openingElement");
542
+ const target = opening && jsxComponentNode(opening);
543
+ if (!opening || !target) return;
544
+ const component = componentFromNode(candidate, id, program, imports, target, bailouts);
545
+ if (!component) return;
546
+ const closingElement = childNode(node, "closingElement");
547
+ const closingName = closingElement && childNode(closingElement, "name");
548
+ if (closingName) component.closingSpan = spanOf(id, closingName);
549
+ const entries = jsxEntries(id, node, opening, bailouts);
550
+ for (const entry of entries) {
551
+ if (entry.kind !== "prop" || entry.name !== "style") continue;
552
+ const raw = entry.value.kind === "expression" ? nodeAtSpan(program, entry.value.start, entry.value.end) : null;
553
+ const styleProgram = raw && domStyleProgram(candidate, id, program, raw);
554
+ const argument = raw && domStyleArgument(candidate, id, program, raw);
555
+ if (styleProgram) entry.value = styleProgram;
556
+ else if (argument) entry.value = expressionReference(id, argument);
557
+ }
558
+ elements.push(finalizeElement({
559
+ kind: "element",
560
+ form: "jsx",
561
+ id,
562
+ span: spanOf(id, node),
563
+ propsSpan: spanOf(id, opening),
564
+ component
565
+ }, entries, bailouts.slice(bailoutStart)));
566
+ return;
567
+ }
568
+ if (node.type !== "CallExpression") return;
569
+ const runtime = runtimeCall(program, node);
570
+ if (!runtime) return;
571
+ const element = normalizeRuntimeElement(candidate, id, program, imports, node, runtime, bailouts);
572
+ if (element) {
573
+ const entries = element.complete ? element.entries : element.bailedEntries;
574
+ for (const entry of entries) {
575
+ if (entry.kind !== "prop" || entry.name !== "style") continue;
576
+ const raw = entry.value.kind === "expression" ? nodeAtSpan(program, entry.value.start, entry.value.end) : null;
577
+ const styleProgram = raw && domStyleProgram(candidate, id, program, raw);
578
+ const argument = raw && domStyleArgument(candidate, id, program, raw);
579
+ if (styleProgram) entry.value = styleProgram;
580
+ else if (argument) entry.value = expressionReference(id, argument);
581
+ }
582
+ elements.push(element);
583
+ }
584
+ });
585
+ return {
586
+ elements: elements.sort((left, right) => left.span.start - right.span.start),
587
+ styledDefinitions: styledDefinitions(candidate, id, program, imports, bailouts),
588
+ domStyleDefinitions: domStyleDefinitions(id, program, imports),
589
+ bailouts: bailouts.sort((left, right) => left.span.start - right.span.start)
590
+ };
591
+ }
592
+ function nodeAtSpan(program, start, end) {
593
+ return findAstNode(program, (node) => node.start === start && node.end === end, {
594
+ start,
595
+ end
596
+ });
597
+ }
598
+ function asAstNode(value, label) {
599
+ if (!isAstNode(value)) throw new Error(`${label} is not an AST node`);
600
+ return value;
601
+ }
602
+
603
+ export { asAstNode, definitionFromDeclaration, nodeAtSpan, normalizeElements };
604
+ //# sourceMappingURL=normalize.mjs.map