@csszyx/compiler 0.9.0 → 0.9.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/index.cjs +1033 -47
- package/dist/index.d.cts +102 -2
- package/dist/index.d.mts +102 -2
- package/dist/index.mjs +1035 -50
- package/dist/shared/{compiler.CUn8HGmA.mjs → compiler.CIBwOKUt.mjs} +58 -6
- package/dist/shared/{compiler.DZgazEy8.cjs → compiler.DItEsgH4.cjs} +58 -6
- package/dist/transform-core.cjs +1 -1
- package/dist/transform-core.mjs +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { init, version, transform_sz } from '@csszyx/core';
|
|
2
|
-
import { t as transform, C as COLOR_PROPERTIES, P as PROPERTY_MAP, g as getCSSVariableName, a as PropertyCategory, K as KNOWN_VARIANTS, b as getVariantPrefix, c as getPropertyCategory, s as stripInvalidColorStrings } from './shared/compiler.
|
|
3
|
-
export { B as BOOLEAN_SHORTHANDS, d as PROPERTY_CATEGORY_MAP, S as SUGGESTION_MAP, i as isValidSzProp, n as normalizeClassName } from './shared/compiler.
|
|
1
|
+
import { init, version, transform_sz, encode } from '@csszyx/core';
|
|
2
|
+
import { t as transform, C as COLOR_PROPERTIES, P as PROPERTY_MAP, g as getCSSVariableName, a as PropertyCategory, K as KNOWN_VARIANTS, b as getVariantPrefix, c as getPropertyCategory, s as stripInvalidColorStrings } from './shared/compiler.CIBwOKUt.mjs';
|
|
3
|
+
export { B as BOOLEAN_SHORTHANDS, d as PROPERTY_CATEGORY_MAP, S as SUGGESTION_MAP, i as isValidSzProp, n as normalizeClassName } from './shared/compiler.CIBwOKUt.mjs';
|
|
4
|
+
import { parseSync } from 'oxc-parser';
|
|
4
5
|
import * as t from '@babel/types';
|
|
5
6
|
import { createHash } from 'node:crypto';
|
|
6
7
|
import * as babel from '@babel/core';
|
|
7
8
|
import MagicString from 'magic-string';
|
|
8
|
-
import { parseSync } from 'oxc-parser';
|
|
9
9
|
import { transformBatch, CsszyxNativeUnavailableError } from '@csszyx/core/native';
|
|
10
10
|
|
|
11
11
|
const AST_BUDGET = 5e4;
|
|
@@ -65,6 +65,7 @@ function transformSourceCode(source, filename, options) {
|
|
|
65
65
|
const rawClassNames = /* @__PURE__ */ new Set();
|
|
66
66
|
const diagnostics = [];
|
|
67
67
|
const recoveryTokens = /* @__PURE__ */ new Map();
|
|
68
|
+
const cssVariableMap = /* @__PURE__ */ new Map();
|
|
68
69
|
if (!source.includes("sz")) {
|
|
69
70
|
return {
|
|
70
71
|
code: source,
|
|
@@ -75,7 +76,8 @@ function transformSourceCode(source, filename, options) {
|
|
|
75
76
|
classes: collectedClasses,
|
|
76
77
|
rawClassNames,
|
|
77
78
|
diagnostics,
|
|
78
|
-
recoveryTokens
|
|
79
|
+
recoveryTokens,
|
|
80
|
+
cssVariableMap
|
|
79
81
|
};
|
|
80
82
|
}
|
|
81
83
|
try {
|
|
@@ -737,7 +739,8 @@ function transformSourceCode(source, filename, options) {
|
|
|
737
739
|
classes: collectedClasses,
|
|
738
740
|
rawClassNames,
|
|
739
741
|
diagnostics,
|
|
740
|
-
recoveryTokens
|
|
742
|
+
recoveryTokens,
|
|
743
|
+
cssVariableMap
|
|
741
744
|
};
|
|
742
745
|
} catch (e) {
|
|
743
746
|
if (e instanceof ASTBudgetExceededError) {
|
|
@@ -753,7 +756,8 @@ function transformSourceCode(source, filename, options) {
|
|
|
753
756
|
classes: collectedClasses,
|
|
754
757
|
rawClassNames,
|
|
755
758
|
diagnostics,
|
|
756
|
-
recoveryTokens
|
|
759
|
+
recoveryTokens,
|
|
760
|
+
cssVariableMap
|
|
757
761
|
};
|
|
758
762
|
}
|
|
759
763
|
}
|
|
@@ -1305,6 +1309,271 @@ class CsszyxCompiler {
|
|
|
1305
1309
|
}
|
|
1306
1310
|
}
|
|
1307
1311
|
|
|
1312
|
+
const CSS_VAR_REFERENCE_RE = /var\(\s*(--[\w-]+)/g;
|
|
1313
|
+
function scanGlobalVarUsages(source, filename = "file.tsx", options = {}) {
|
|
1314
|
+
if (!source.includes("--") && !source.includes("var(")) {
|
|
1315
|
+
return [];
|
|
1316
|
+
}
|
|
1317
|
+
const parsed = parseSync(filename, source);
|
|
1318
|
+
if (parsed.errors.length > 0) {
|
|
1319
|
+
throw new Error(
|
|
1320
|
+
`oxc-parser errors in ${filename}: ${parsed.errors.map((error) => error.message).join("; ")}`
|
|
1321
|
+
);
|
|
1322
|
+
}
|
|
1323
|
+
const tokenFilter = options.tokens ? new Set(options.tokens) : null;
|
|
1324
|
+
const constantStrings = collectStringConstants(parsed.program);
|
|
1325
|
+
const diagnostics = [];
|
|
1326
|
+
walk$1(parsed.program, (node, ancestors) => {
|
|
1327
|
+
if (node.type === "CallExpression") {
|
|
1328
|
+
collectStyleMethodDiagnostic(
|
|
1329
|
+
node,
|
|
1330
|
+
source,
|
|
1331
|
+
filename,
|
|
1332
|
+
constantStrings,
|
|
1333
|
+
tokenFilter,
|
|
1334
|
+
diagnostics
|
|
1335
|
+
);
|
|
1336
|
+
return;
|
|
1337
|
+
}
|
|
1338
|
+
if (node.type !== "JSXAttribute") {
|
|
1339
|
+
return;
|
|
1340
|
+
}
|
|
1341
|
+
const attrName = jsxAttributeName(node);
|
|
1342
|
+
if (attrName === "style") {
|
|
1343
|
+
collectJsxStyleDiagnostics(
|
|
1344
|
+
node,
|
|
1345
|
+
source,
|
|
1346
|
+
filename,
|
|
1347
|
+
constantStrings,
|
|
1348
|
+
tokenFilter,
|
|
1349
|
+
diagnostics
|
|
1350
|
+
);
|
|
1351
|
+
return;
|
|
1352
|
+
}
|
|
1353
|
+
if (attrName === "className") {
|
|
1354
|
+
collectClassNameDiagnostics(node, source, filename, tokenFilter, diagnostics);
|
|
1355
|
+
return;
|
|
1356
|
+
}
|
|
1357
|
+
if (attrName === "sz" && ancestors.some((parent) => parent.type === "JSXAttribute")) {
|
|
1358
|
+
return;
|
|
1359
|
+
}
|
|
1360
|
+
});
|
|
1361
|
+
return diagnostics;
|
|
1362
|
+
}
|
|
1363
|
+
function collectStringConstants(root) {
|
|
1364
|
+
const constants = /* @__PURE__ */ new Map();
|
|
1365
|
+
walk$1(root, (node) => {
|
|
1366
|
+
if (node.type !== "VariableDeclarator") {
|
|
1367
|
+
return;
|
|
1368
|
+
}
|
|
1369
|
+
const id = node.id;
|
|
1370
|
+
const init = node.init;
|
|
1371
|
+
if (id?.type !== "Identifier" || !init) {
|
|
1372
|
+
return;
|
|
1373
|
+
}
|
|
1374
|
+
const name = id.name;
|
|
1375
|
+
const value = literalStringValue$1(init);
|
|
1376
|
+
if (typeof name === "string" && value !== null) {
|
|
1377
|
+
constants.set(name, value);
|
|
1378
|
+
}
|
|
1379
|
+
});
|
|
1380
|
+
return constants;
|
|
1381
|
+
}
|
|
1382
|
+
function collectStyleMethodDiagnostic(node, source, filename, constants, tokenFilter, diagnostics) {
|
|
1383
|
+
const method = memberMethodName(node.callee);
|
|
1384
|
+
if (!method || !["setProperty", "getPropertyValue", "removeProperty"].includes(method)) {
|
|
1385
|
+
return;
|
|
1386
|
+
}
|
|
1387
|
+
const firstArg = node.arguments?.[0];
|
|
1388
|
+
const name = firstArg ? resolveString(firstArg, constants) : null;
|
|
1389
|
+
if (!name?.startsWith("--") || !shouldReportToken(name, tokenFilter)) {
|
|
1390
|
+
return;
|
|
1391
|
+
}
|
|
1392
|
+
const kind = method === "setProperty" ? "style-set-property" : method === "getPropertyValue" ? "style-get-property" : "style-remove-property";
|
|
1393
|
+
diagnostics.push(createDiagnostic(kind, name, node, source, filename));
|
|
1394
|
+
}
|
|
1395
|
+
function collectJsxStyleDiagnostics(attr, source, filename, constants, tokenFilter, diagnostics) {
|
|
1396
|
+
const expression = jsxExpression(attr);
|
|
1397
|
+
if (expression?.type !== "ObjectExpression") {
|
|
1398
|
+
return;
|
|
1399
|
+
}
|
|
1400
|
+
for (const prop of expression.properties ?? []) {
|
|
1401
|
+
if (prop.type !== "Property") {
|
|
1402
|
+
continue;
|
|
1403
|
+
}
|
|
1404
|
+
const name = propertyKeyString(prop, constants);
|
|
1405
|
+
if (name?.startsWith("--") && shouldReportToken(name, tokenFilter)) {
|
|
1406
|
+
diagnostics.push(createDiagnostic("jsx-style-key", name, prop, source, filename));
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
function collectClassNameDiagnostics(attr, source, filename, tokenFilter, diagnostics) {
|
|
1411
|
+
for (const value of jsxAttributeStringValues(attr)) {
|
|
1412
|
+
for (const name of extractVarReferences(value)) {
|
|
1413
|
+
if (shouldReportToken(name, tokenFilter)) {
|
|
1414
|
+
diagnostics.push(
|
|
1415
|
+
createDiagnostic("class-string-var-reference", name, attr, source, filename)
|
|
1416
|
+
);
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
function jsxAttributeName(attr) {
|
|
1422
|
+
const name = attr.name;
|
|
1423
|
+
return name?.type === "JSXIdentifier" ? name.name ?? null : null;
|
|
1424
|
+
}
|
|
1425
|
+
function jsxExpression(attr) {
|
|
1426
|
+
const value = attr.value;
|
|
1427
|
+
if (value?.type !== "JSXExpressionContainer") {
|
|
1428
|
+
return null;
|
|
1429
|
+
}
|
|
1430
|
+
return value.expression ?? null;
|
|
1431
|
+
}
|
|
1432
|
+
function jsxAttributeStringValues(attr) {
|
|
1433
|
+
const value = attr.value;
|
|
1434
|
+
if (!value) {
|
|
1435
|
+
return [];
|
|
1436
|
+
}
|
|
1437
|
+
const direct = literalStringValue$1(value);
|
|
1438
|
+
if (direct !== null) {
|
|
1439
|
+
return [direct];
|
|
1440
|
+
}
|
|
1441
|
+
const expression = jsxExpression(attr);
|
|
1442
|
+
if (!expression) {
|
|
1443
|
+
return [];
|
|
1444
|
+
}
|
|
1445
|
+
const exprValue = literalStringValue$1(expression);
|
|
1446
|
+
if (exprValue !== null) {
|
|
1447
|
+
return [exprValue];
|
|
1448
|
+
}
|
|
1449
|
+
if (expression.type === "TemplateLiteral") {
|
|
1450
|
+
return templateStaticParts(expression);
|
|
1451
|
+
}
|
|
1452
|
+
return [];
|
|
1453
|
+
}
|
|
1454
|
+
function resolveString(node, constants) {
|
|
1455
|
+
const literal = literalStringValue$1(node);
|
|
1456
|
+
if (literal !== null) {
|
|
1457
|
+
return literal;
|
|
1458
|
+
}
|
|
1459
|
+
if (node.type === "Identifier") {
|
|
1460
|
+
const name = node.name;
|
|
1461
|
+
return typeof name === "string" ? constants.get(name) ?? null : null;
|
|
1462
|
+
}
|
|
1463
|
+
return null;
|
|
1464
|
+
}
|
|
1465
|
+
function literalStringValue$1(node) {
|
|
1466
|
+
if (node.type !== "Literal") {
|
|
1467
|
+
return null;
|
|
1468
|
+
}
|
|
1469
|
+
const value = node.value;
|
|
1470
|
+
return typeof value === "string" ? value : null;
|
|
1471
|
+
}
|
|
1472
|
+
function propertyKeyString(property, constants) {
|
|
1473
|
+
const key = property.key;
|
|
1474
|
+
const computed = property.computed === true;
|
|
1475
|
+
if (!key) {
|
|
1476
|
+
return null;
|
|
1477
|
+
}
|
|
1478
|
+
if (computed) {
|
|
1479
|
+
return resolveString(key, constants);
|
|
1480
|
+
}
|
|
1481
|
+
if (key.type === "Identifier") {
|
|
1482
|
+
const name = key.name;
|
|
1483
|
+
return typeof name === "string" ? name : null;
|
|
1484
|
+
}
|
|
1485
|
+
return literalStringValue$1(key);
|
|
1486
|
+
}
|
|
1487
|
+
function memberMethodName(callee) {
|
|
1488
|
+
if (callee?.type !== "MemberExpression") {
|
|
1489
|
+
return null;
|
|
1490
|
+
}
|
|
1491
|
+
const property = callee.property;
|
|
1492
|
+
if (!property) {
|
|
1493
|
+
return null;
|
|
1494
|
+
}
|
|
1495
|
+
if (property.type === "Identifier") {
|
|
1496
|
+
const name = property.name;
|
|
1497
|
+
return typeof name === "string" ? name : null;
|
|
1498
|
+
}
|
|
1499
|
+
return literalStringValue$1(property);
|
|
1500
|
+
}
|
|
1501
|
+
function templateStaticParts(node) {
|
|
1502
|
+
const quasis = node.quasis ?? [];
|
|
1503
|
+
const parts = [];
|
|
1504
|
+
for (const quasi of quasis) {
|
|
1505
|
+
const value = quasi.value;
|
|
1506
|
+
const cooked = value?.cooked;
|
|
1507
|
+
const raw = value?.raw;
|
|
1508
|
+
if (typeof cooked === "string") {
|
|
1509
|
+
parts.push(cooked);
|
|
1510
|
+
} else if (typeof raw === "string") {
|
|
1511
|
+
parts.push(raw);
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
return parts;
|
|
1515
|
+
}
|
|
1516
|
+
function extractVarReferences(value) {
|
|
1517
|
+
const refs = /* @__PURE__ */ new Set();
|
|
1518
|
+
for (const match of value.matchAll(CSS_VAR_REFERENCE_RE)) {
|
|
1519
|
+
refs.add(match[1]);
|
|
1520
|
+
}
|
|
1521
|
+
return [...refs].sort();
|
|
1522
|
+
}
|
|
1523
|
+
function shouldReportToken(name, tokenFilter) {
|
|
1524
|
+
return tokenFilter === null || tokenFilter.has(name);
|
|
1525
|
+
}
|
|
1526
|
+
function createDiagnostic(kind, name, node, source, filename) {
|
|
1527
|
+
return {
|
|
1528
|
+
kind,
|
|
1529
|
+
name,
|
|
1530
|
+
location: offsetToLocation(source, node.start, filename),
|
|
1531
|
+
message: `${name} is used outside csszyx-owned global variable alias rewrites (${kind}).`
|
|
1532
|
+
};
|
|
1533
|
+
}
|
|
1534
|
+
function offsetToLocation(source, offset, filename) {
|
|
1535
|
+
let line = 1;
|
|
1536
|
+
let column = 1;
|
|
1537
|
+
for (let index = 0; index < offset; index++) {
|
|
1538
|
+
if (source.charCodeAt(index) === 10) {
|
|
1539
|
+
line++;
|
|
1540
|
+
column = 1;
|
|
1541
|
+
} else {
|
|
1542
|
+
column++;
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
return { filePath: filename, line, column };
|
|
1546
|
+
}
|
|
1547
|
+
function walk$1(node, visit, ancestors = []) {
|
|
1548
|
+
if (!isOxcNode$1(node)) {
|
|
1549
|
+
return;
|
|
1550
|
+
}
|
|
1551
|
+
visit(node, ancestors);
|
|
1552
|
+
ancestors.push(node);
|
|
1553
|
+
for (const key of Object.keys(node)) {
|
|
1554
|
+
if (isAstMetadataKey$1(key)) {
|
|
1555
|
+
continue;
|
|
1556
|
+
}
|
|
1557
|
+
const child = node[key];
|
|
1558
|
+
if (Array.isArray(child)) {
|
|
1559
|
+
for (const item of child) {
|
|
1560
|
+
walk$1(item, visit, ancestors);
|
|
1561
|
+
}
|
|
1562
|
+
} else if (child && typeof child === "object") {
|
|
1563
|
+
walk$1(child, visit, ancestors);
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
ancestors.pop();
|
|
1567
|
+
}
|
|
1568
|
+
function isOxcNode$1(value) {
|
|
1569
|
+
return Boolean(
|
|
1570
|
+
value && typeof value === "object" && typeof value.type === "string"
|
|
1571
|
+
);
|
|
1572
|
+
}
|
|
1573
|
+
function isAstMetadataKey$1(key) {
|
|
1574
|
+
return key === "loc" || key === "range" || key === "start" || key === "end" || key === "type";
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1308
1577
|
function findLCA(nodeA, nodeB, parentMap) {
|
|
1309
1578
|
const ancestorsA = /* @__PURE__ */ new Set();
|
|
1310
1579
|
let current = nodeA;
|
|
@@ -1638,6 +1907,155 @@ function injectRecoveryToken(attributes, token) {
|
|
|
1638
1907
|
};
|
|
1639
1908
|
}
|
|
1640
1909
|
|
|
1910
|
+
const DEFAULT_MAX_DEPTH = 5;
|
|
1911
|
+
function planComponentVariableHoistsWithDiagnostics(nodes, usages, options = {}) {
|
|
1912
|
+
const maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
1913
|
+
const nodeById = new Map(nodes.map((node) => [node.id, node]));
|
|
1914
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1915
|
+
for (const usage of usages) {
|
|
1916
|
+
const groupKey = `${usage.name}\0${usage.valueKey}`;
|
|
1917
|
+
const group = groups.get(groupKey);
|
|
1918
|
+
if (group) {
|
|
1919
|
+
group.push(usage);
|
|
1920
|
+
} else {
|
|
1921
|
+
groups.set(groupKey, [usage]);
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
const plans = [];
|
|
1925
|
+
const diagnostics = [];
|
|
1926
|
+
for (const group of groups.values()) {
|
|
1927
|
+
if (group.length < 2) {
|
|
1928
|
+
continue;
|
|
1929
|
+
}
|
|
1930
|
+
const targetElementId = findLowestCommonAncestor(
|
|
1931
|
+
group.map((usage) => usage.elementId),
|
|
1932
|
+
nodeById
|
|
1933
|
+
);
|
|
1934
|
+
if (!targetElementId) {
|
|
1935
|
+
diagnostics.push(buildHoistDiagnostic(group, "no-lca"));
|
|
1936
|
+
continue;
|
|
1937
|
+
}
|
|
1938
|
+
const target = nodeById.get(targetElementId);
|
|
1939
|
+
if (!target || target.canHost === false) {
|
|
1940
|
+
diagnostics.push(buildHoistDiagnostic(group, "non-host-ancestor"));
|
|
1941
|
+
continue;
|
|
1942
|
+
}
|
|
1943
|
+
if (group.some(
|
|
1944
|
+
(usage) => distanceToAncestor(usage.elementId, targetElementId, nodeById) > maxDepth
|
|
1945
|
+
)) {
|
|
1946
|
+
diagnostics.push(buildHoistDiagnostic(group, "max-depth", maxDepth));
|
|
1947
|
+
continue;
|
|
1948
|
+
}
|
|
1949
|
+
plans.push({
|
|
1950
|
+
name: group[0].name,
|
|
1951
|
+
valueKey: group[0].valueKey,
|
|
1952
|
+
targetElementId,
|
|
1953
|
+
usageIds: group.map((usage) => usage.id)
|
|
1954
|
+
});
|
|
1955
|
+
}
|
|
1956
|
+
return { plans, diagnostics };
|
|
1957
|
+
}
|
|
1958
|
+
function buildHoistDiagnostic(group, reason, maxDepth) {
|
|
1959
|
+
return {
|
|
1960
|
+
name: group[0]?.name ?? "",
|
|
1961
|
+
reason,
|
|
1962
|
+
usageCount: group.length,
|
|
1963
|
+
...maxDepth === void 0 ? {} : { maxDepth }
|
|
1964
|
+
};
|
|
1965
|
+
}
|
|
1966
|
+
function findLowestCommonAncestor(elementIds, nodeById) {
|
|
1967
|
+
const [first, ...rest] = elementIds;
|
|
1968
|
+
if (!first) {
|
|
1969
|
+
return null;
|
|
1970
|
+
}
|
|
1971
|
+
let currentAncestors = ancestorChain(first, nodeById);
|
|
1972
|
+
for (const elementId of rest) {
|
|
1973
|
+
const nextAncestors = new Set(ancestorChain(elementId, nodeById));
|
|
1974
|
+
currentAncestors = currentAncestors.filter((id) => nextAncestors.has(id));
|
|
1975
|
+
if (currentAncestors.length === 0) {
|
|
1976
|
+
return null;
|
|
1977
|
+
}
|
|
1978
|
+
}
|
|
1979
|
+
return currentAncestors[0] ?? null;
|
|
1980
|
+
}
|
|
1981
|
+
function ancestorChain(elementId, nodeById) {
|
|
1982
|
+
const chain = [];
|
|
1983
|
+
let current = elementId;
|
|
1984
|
+
while (current) {
|
|
1985
|
+
const node = nodeById.get(current);
|
|
1986
|
+
if (!node) {
|
|
1987
|
+
break;
|
|
1988
|
+
}
|
|
1989
|
+
chain.push(current);
|
|
1990
|
+
current = node.parentId;
|
|
1991
|
+
}
|
|
1992
|
+
return chain;
|
|
1993
|
+
}
|
|
1994
|
+
function distanceToAncestor(elementId, ancestorId, nodeById) {
|
|
1995
|
+
let distance = 0;
|
|
1996
|
+
let current = elementId;
|
|
1997
|
+
while (current) {
|
|
1998
|
+
if (current === ancestorId) {
|
|
1999
|
+
return distance;
|
|
2000
|
+
}
|
|
2001
|
+
const node = nodeById.get(current);
|
|
2002
|
+
if (!node) {
|
|
2003
|
+
break;
|
|
2004
|
+
}
|
|
2005
|
+
current = node.parentId;
|
|
2006
|
+
distance++;
|
|
2007
|
+
}
|
|
2008
|
+
return Number.POSITIVE_INFINITY;
|
|
2009
|
+
}
|
|
2010
|
+
|
|
2011
|
+
function planCSSVariableNames(usages, options = {}) {
|
|
2012
|
+
const componentNames = /* @__PURE__ */ new Map();
|
|
2013
|
+
const scopedNamesByElement = /* @__PURE__ */ new Map();
|
|
2014
|
+
const reservedNames = options.reservedNames ?? /* @__PURE__ */ new Set();
|
|
2015
|
+
return usages.map((usage) => {
|
|
2016
|
+
if (usage.tier === "component") {
|
|
2017
|
+
const key2 = canonicalUsageKey(usage);
|
|
2018
|
+
let name2 = componentNames.get(key2);
|
|
2019
|
+
if (!name2) {
|
|
2020
|
+
name2 = allocateVariableName("--c", componentNames.size, reservedNames);
|
|
2021
|
+
componentNames.set(key2, name2);
|
|
2022
|
+
}
|
|
2023
|
+
return { ...usage, name: name2 };
|
|
2024
|
+
}
|
|
2025
|
+
const elementId = usage.elementId ?? "";
|
|
2026
|
+
const elementNames = getOrCreate(scopedNamesByElement, elementId, () => /* @__PURE__ */ new Map());
|
|
2027
|
+
const key = canonicalUsageKey(usage);
|
|
2028
|
+
let name = elementNames.get(key);
|
|
2029
|
+
if (!name) {
|
|
2030
|
+
name = allocateVariableName("--s", elementNames.size, reservedNames);
|
|
2031
|
+
elementNames.set(key, name);
|
|
2032
|
+
}
|
|
2033
|
+
return { ...usage, name };
|
|
2034
|
+
});
|
|
2035
|
+
}
|
|
2036
|
+
function allocateVariableName(prefix, startIndex, reservedNames) {
|
|
2037
|
+
let index = startIndex;
|
|
2038
|
+
while (true) {
|
|
2039
|
+
const name = `${prefix}${encode(index)}`;
|
|
2040
|
+
if (!reservedNames.has(name)) {
|
|
2041
|
+
return name;
|
|
2042
|
+
}
|
|
2043
|
+
index++;
|
|
2044
|
+
}
|
|
2045
|
+
}
|
|
2046
|
+
function canonicalUsageKey(usage) {
|
|
2047
|
+
return `${usage.variantChain ?? ""}\0${usage.propertyKey}`;
|
|
2048
|
+
}
|
|
2049
|
+
function getOrCreate(map, key, create) {
|
|
2050
|
+
const existing = map.get(key);
|
|
2051
|
+
if (existing) {
|
|
2052
|
+
return existing;
|
|
2053
|
+
}
|
|
2054
|
+
const value = create();
|
|
2055
|
+
map.set(key, value);
|
|
2056
|
+
return value;
|
|
2057
|
+
}
|
|
2058
|
+
|
|
1641
2059
|
class OxcNotImplementedError extends Error {
|
|
1642
2060
|
/**
|
|
1643
2061
|
* @param slice The Phase D slice expected to implement this path.
|
|
@@ -1653,6 +2071,8 @@ function transformOxc(source, filename, options) {
|
|
|
1653
2071
|
const rawClassNames = /* @__PURE__ */ new Set();
|
|
1654
2072
|
const diagnostics = [];
|
|
1655
2073
|
const recoveryTokens = /* @__PURE__ */ new Map();
|
|
2074
|
+
const cssVariableMap = /* @__PURE__ */ new Map();
|
|
2075
|
+
const globalVarAliases = normalizeGlobalVarAliases$1(options?.globalVarAliases);
|
|
1656
2076
|
if (!source.includes("sz")) {
|
|
1657
2077
|
return {
|
|
1658
2078
|
code: source,
|
|
@@ -1663,7 +2083,8 @@ function transformOxc(source, filename, options) {
|
|
|
1663
2083
|
classes,
|
|
1664
2084
|
rawClassNames,
|
|
1665
2085
|
diagnostics,
|
|
1666
|
-
recoveryTokens
|
|
2086
|
+
recoveryTokens,
|
|
2087
|
+
cssVariableMap
|
|
1667
2088
|
};
|
|
1668
2089
|
}
|
|
1669
2090
|
const effectiveFilename = filename ?? "file.tsx";
|
|
@@ -1678,6 +2099,18 @@ function transformOxc(source, filename, options) {
|
|
|
1678
2099
|
const edits = new MagicString(source);
|
|
1679
2100
|
const objectBindings = collectObjectBindings(parsed.program);
|
|
1680
2101
|
const conditionalBindings = collectConditionalBindings(parsed.program);
|
|
2102
|
+
const reservedCSSVariableNames = options?.mangleVars ? collectStaticStyleCustomPropertyNames(parsed.program) : void 0;
|
|
2103
|
+
const componentHoists = options?.mangleVars ? planOxcComponentVariableHoists(
|
|
2104
|
+
parsed.program,
|
|
2105
|
+
effectiveFilename,
|
|
2106
|
+
objectBindings,
|
|
2107
|
+
source,
|
|
2108
|
+
options.mangleVarHoistMaxDepth,
|
|
2109
|
+
reservedCSSVariableNames
|
|
2110
|
+
) : null;
|
|
2111
|
+
if (componentHoists) {
|
|
2112
|
+
diagnostics.push(...componentHoists.diagnostics);
|
|
2113
|
+
}
|
|
1681
2114
|
let transformed = false;
|
|
1682
2115
|
let usesRuntime = false;
|
|
1683
2116
|
let usesMerge = false;
|
|
@@ -1703,6 +2136,24 @@ function transformOxc(source, filename, options) {
|
|
|
1703
2136
|
let szRecoverAttr = null;
|
|
1704
2137
|
let alreadyTagged = false;
|
|
1705
2138
|
let lastAttr = null;
|
|
2139
|
+
let appliedHoistedStyleProps = false;
|
|
2140
|
+
const elementId = elementIdForOpening(openingNode);
|
|
2141
|
+
const hoistedStyleProps = componentHoists?.stylePropsByTarget.get(elementId) ?? [];
|
|
2142
|
+
const applyHoistedStyleProps = () => {
|
|
2143
|
+
if (appliedHoistedStyleProps || hoistedStyleProps.length === 0) {
|
|
2144
|
+
return;
|
|
2145
|
+
}
|
|
2146
|
+
applyStyleProps(
|
|
2147
|
+
edits,
|
|
2148
|
+
source,
|
|
2149
|
+
styleAttr,
|
|
2150
|
+
lastAttr,
|
|
2151
|
+
hoistedStyleProps,
|
|
2152
|
+
openingNode.name.end
|
|
2153
|
+
);
|
|
2154
|
+
appliedHoistedStyleProps = true;
|
|
2155
|
+
transformed = true;
|
|
2156
|
+
};
|
|
1706
2157
|
for (const attrRaw of attrs) {
|
|
1707
2158
|
if (attrRaw.type !== "JSXAttribute") {
|
|
1708
2159
|
continue;
|
|
@@ -1763,6 +2214,7 @@ function transformOxc(source, filename, options) {
|
|
|
1763
2214
|
}
|
|
1764
2215
|
}
|
|
1765
2216
|
if (szAttrs.length === 0) {
|
|
2217
|
+
applyHoistedStyleProps();
|
|
1766
2218
|
return;
|
|
1767
2219
|
}
|
|
1768
2220
|
const szDerived = [];
|
|
@@ -1799,7 +2251,9 @@ function transformOxc(source, filename, options) {
|
|
|
1799
2251
|
effectiveFilename,
|
|
1800
2252
|
objectBindings,
|
|
1801
2253
|
source,
|
|
1802
|
-
classes
|
|
2254
|
+
classes,
|
|
2255
|
+
globalVarAliases,
|
|
2256
|
+
cssVariableMap
|
|
1803
2257
|
);
|
|
1804
2258
|
if (conditionalClassExpr) {
|
|
1805
2259
|
if (classNameAttr || szAttrs.length > 1) {
|
|
@@ -1821,7 +2275,11 @@ function transformOxc(source, filename, options) {
|
|
|
1821
2275
|
const bound = objectBindings.get(identifierName);
|
|
1822
2276
|
if (bound) {
|
|
1823
2277
|
const result2 = transform(
|
|
1824
|
-
|
|
2278
|
+
applyGlobalVarAliasesToSzObject(
|
|
2279
|
+
astObjectToSzObject(bound, effectiveFilename, objectBindings),
|
|
2280
|
+
globalVarAliases,
|
|
2281
|
+
cssVariableMap
|
|
2282
|
+
)
|
|
1825
2283
|
);
|
|
1826
2284
|
for (const c of result2.className.split(/\s+/)) {
|
|
1827
2285
|
if (c) {
|
|
@@ -1838,7 +2296,9 @@ function transformOxc(source, filename, options) {
|
|
|
1838
2296
|
effectiveFilename,
|
|
1839
2297
|
objectBindings,
|
|
1840
2298
|
source,
|
|
1841
|
-
classes
|
|
2299
|
+
classes,
|
|
2300
|
+
globalVarAliases,
|
|
2301
|
+
cssVariableMap
|
|
1842
2302
|
);
|
|
1843
2303
|
if (conditionalClassExpr) {
|
|
1844
2304
|
if (classNameAttr || szAttrs.length > 1) {
|
|
@@ -1860,7 +2320,9 @@ function transformOxc(source, filename, options) {
|
|
|
1860
2320
|
const arrayClasses = astArrayToStaticClasses(
|
|
1861
2321
|
expression,
|
|
1862
2322
|
effectiveFilename,
|
|
1863
|
-
objectBindings
|
|
2323
|
+
objectBindings,
|
|
2324
|
+
globalVarAliases,
|
|
2325
|
+
cssVariableMap
|
|
1864
2326
|
);
|
|
1865
2327
|
if (arrayClasses === null) {
|
|
1866
2328
|
collectArrayCandidateClasses(
|
|
@@ -1898,7 +2360,9 @@ function transformOxc(source, filename, options) {
|
|
|
1898
2360
|
effectiveFilename,
|
|
1899
2361
|
objectBindings,
|
|
1900
2362
|
source,
|
|
1901
|
-
classes
|
|
2363
|
+
classes,
|
|
2364
|
+
globalVarAliases,
|
|
2365
|
+
cssVariableMap
|
|
1902
2366
|
);
|
|
1903
2367
|
if (conditionalSpreadClassExpr) {
|
|
1904
2368
|
if (classNameAttr || szAttrs.length > 1) {
|
|
@@ -1918,9 +2382,15 @@ function transformOxc(source, filename, options) {
|
|
|
1918
2382
|
expression,
|
|
1919
2383
|
effectiveFilename,
|
|
1920
2384
|
objectBindings,
|
|
1921
|
-
source
|
|
2385
|
+
source,
|
|
2386
|
+
options,
|
|
2387
|
+
componentHoists?.usageNamesByElement.get(elementId),
|
|
2388
|
+
cssVariableMap,
|
|
2389
|
+
reservedCSSVariableNames,
|
|
2390
|
+
globalVarAliases
|
|
1922
2391
|
);
|
|
1923
2392
|
if (partial && szAttrs.length === 1) {
|
|
2393
|
+
const mergedStyleProps = hoistedStyleProps.length > 0 ? [...hoistedStyleProps, ...partial.styleProps] : partial.styleProps;
|
|
1924
2394
|
if (classNameAttr?.value?.type === "JSXExpressionContainer") {
|
|
1925
2395
|
const classExpression = classNameAttr.value.expression;
|
|
1926
2396
|
const classExpressionSource = source.slice(
|
|
@@ -1933,7 +2403,15 @@ function transformOxc(source, filename, options) {
|
|
|
1933
2403
|
`className={_szMerge(${classExpressionSource}, ${JSON.stringify(partial.className)})}`
|
|
1934
2404
|
);
|
|
1935
2405
|
edits.remove(whitespaceStart(source, szAttr.start), szAttr.end);
|
|
1936
|
-
applyStyleProps(
|
|
2406
|
+
applyStyleProps(
|
|
2407
|
+
edits,
|
|
2408
|
+
source,
|
|
2409
|
+
styleAttr,
|
|
2410
|
+
lastAttr,
|
|
2411
|
+
mergedStyleProps,
|
|
2412
|
+
openingNode.name.end
|
|
2413
|
+
);
|
|
2414
|
+
appliedHoistedStyleProps = true;
|
|
1937
2415
|
for (const c of partial.className.split(/\s+/)) {
|
|
1938
2416
|
if (c) {
|
|
1939
2417
|
classes.add(c);
|
|
@@ -1957,7 +2435,15 @@ function transformOxc(source, filename, options) {
|
|
|
1957
2435
|
} else {
|
|
1958
2436
|
edits.overwrite(szAttr.start, szAttr.end, partial.classNameAttr);
|
|
1959
2437
|
}
|
|
1960
|
-
applyStyleProps(
|
|
2438
|
+
applyStyleProps(
|
|
2439
|
+
edits,
|
|
2440
|
+
source,
|
|
2441
|
+
styleAttr,
|
|
2442
|
+
lastAttr,
|
|
2443
|
+
mergedStyleProps,
|
|
2444
|
+
openingNode.name.end
|
|
2445
|
+
);
|
|
2446
|
+
appliedHoistedStyleProps = true;
|
|
1961
2447
|
for (const c of partial.className.split(/\s+/)) {
|
|
1962
2448
|
if (c) {
|
|
1963
2449
|
classes.add(c);
|
|
@@ -1973,7 +2459,9 @@ function transformOxc(source, filename, options) {
|
|
|
1973
2459
|
}
|
|
1974
2460
|
throw err;
|
|
1975
2461
|
}
|
|
1976
|
-
const result = transform(
|
|
2462
|
+
const result = transform(
|
|
2463
|
+
applyGlobalVarAliasesToSzObject(szObj, globalVarAliases, cssVariableMap)
|
|
2464
|
+
);
|
|
1977
2465
|
for (const c of result.className.split(/\s+/)) {
|
|
1978
2466
|
if (c) {
|
|
1979
2467
|
szDerived.push(c);
|
|
@@ -2006,6 +2494,7 @@ function transformOxc(source, filename, options) {
|
|
|
2006
2494
|
transformed = true;
|
|
2007
2495
|
return;
|
|
2008
2496
|
}
|
|
2497
|
+
applyHoistedStyleProps();
|
|
2009
2498
|
const existingRaw = classNameAttr ? stringLiteralValue(classNameAttr.value) : null;
|
|
2010
2499
|
const mergedClasses = [
|
|
2011
2500
|
...existingRaw ? existingRaw.split(/\s+/).filter(Boolean) : [],
|
|
@@ -2040,7 +2529,8 @@ function transformOxc(source, filename, options) {
|
|
|
2040
2529
|
classes,
|
|
2041
2530
|
rawClassNames,
|
|
2042
2531
|
diagnostics,
|
|
2043
|
-
recoveryTokens
|
|
2532
|
+
recoveryTokens,
|
|
2533
|
+
cssVariableMap
|
|
2044
2534
|
};
|
|
2045
2535
|
}
|
|
2046
2536
|
function stringLiteralValue(value) {
|
|
@@ -2149,7 +2639,7 @@ function astObjectToSzObject(node, filename, bindings) {
|
|
|
2149
2639
|
}
|
|
2150
2640
|
return result;
|
|
2151
2641
|
}
|
|
2152
|
-
function astArrayToStaticClasses(node, filename, bindings) {
|
|
2642
|
+
function astArrayToStaticClasses(node, filename, bindings, globalVarAliases, cssVariableMap) {
|
|
2153
2643
|
const out = [];
|
|
2154
2644
|
for (const element of node.elements) {
|
|
2155
2645
|
if (!element || isFalsyLiteral(element)) {
|
|
@@ -2166,7 +2656,13 @@ function astArrayToStaticClasses(node, filename, bindings) {
|
|
|
2166
2656
|
}
|
|
2167
2657
|
let result;
|
|
2168
2658
|
try {
|
|
2169
|
-
result = transform(
|
|
2659
|
+
result = transform(
|
|
2660
|
+
applyGlobalVarAliasesToSzObject(
|
|
2661
|
+
astObjectToSzObject(objectNode, filename, bindings),
|
|
2662
|
+
globalVarAliases,
|
|
2663
|
+
cssVariableMap
|
|
2664
|
+
)
|
|
2665
|
+
);
|
|
2170
2666
|
} catch (err) {
|
|
2171
2667
|
if (err instanceof OxcNotImplementedError) {
|
|
2172
2668
|
return null;
|
|
@@ -2263,7 +2759,7 @@ function resolveObjectExpression(node, bindings) {
|
|
|
2263
2759
|
}
|
|
2264
2760
|
return null;
|
|
2265
2761
|
}
|
|
2266
|
-
function buildConditionalSpreadClassExpression(node, filename, bindings, source, classes) {
|
|
2762
|
+
function buildConditionalSpreadClassExpression(node, filename, bindings, source, classes, globalVarAliases, cssVariableMap) {
|
|
2267
2763
|
let conditionalSpread = null;
|
|
2268
2764
|
const otherProps = [];
|
|
2269
2765
|
for (const prop of node.properties) {
|
|
@@ -2286,14 +2782,18 @@ function buildConditionalSpreadClassExpression(node, filename, bindings, source,
|
|
|
2286
2782
|
otherProps,
|
|
2287
2783
|
node,
|
|
2288
2784
|
filename,
|
|
2289
|
-
bindings
|
|
2785
|
+
bindings,
|
|
2786
|
+
globalVarAliases,
|
|
2787
|
+
cssVariableMap
|
|
2290
2788
|
);
|
|
2291
2789
|
const alternate = compileConditionalSpreadBranch(
|
|
2292
2790
|
conditionalSpread.alternate,
|
|
2293
2791
|
otherProps,
|
|
2294
2792
|
node,
|
|
2295
2793
|
filename,
|
|
2296
|
-
bindings
|
|
2794
|
+
bindings,
|
|
2795
|
+
globalVarAliases,
|
|
2796
|
+
cssVariableMap
|
|
2297
2797
|
);
|
|
2298
2798
|
if (consequent === null || alternate === null) {
|
|
2299
2799
|
return null;
|
|
@@ -2306,7 +2806,7 @@ function buildConditionalSpreadClassExpression(node, filename, bindings, source,
|
|
|
2306
2806
|
const testSource = source.slice(conditionalSpread.test.start, conditionalSpread.test.end);
|
|
2307
2807
|
return `${testSource} ? ${JSON.stringify(consequent)} : ${JSON.stringify(alternate)}`;
|
|
2308
2808
|
}
|
|
2309
|
-
function compileConditionalSpreadBranch(branch, otherProps, sourceNode, filename, bindings) {
|
|
2809
|
+
function compileConditionalSpreadBranch(branch, otherProps, sourceNode, filename, bindings, globalVarAliases, cssVariableMap) {
|
|
2310
2810
|
const branchObject = resolveObjectExpression(branch, bindings);
|
|
2311
2811
|
if (!branchObject) {
|
|
2312
2812
|
return null;
|
|
@@ -2318,7 +2818,13 @@ function compileConditionalSpreadBranch(branch, otherProps, sourceNode, filename
|
|
|
2318
2818
|
filename,
|
|
2319
2819
|
bindings
|
|
2320
2820
|
);
|
|
2321
|
-
return transform(
|
|
2821
|
+
return transform(
|
|
2822
|
+
applyGlobalVarAliasesToSzObject(
|
|
2823
|
+
{ ...branchValue, ...overrides },
|
|
2824
|
+
globalVarAliases,
|
|
2825
|
+
cssVariableMap
|
|
2826
|
+
)
|
|
2827
|
+
).className;
|
|
2322
2828
|
} catch (err) {
|
|
2323
2829
|
if (err instanceof OxcNotImplementedError) {
|
|
2324
2830
|
return null;
|
|
@@ -2326,8 +2832,15 @@ function compileConditionalSpreadBranch(branch, otherProps, sourceNode, filename
|
|
|
2326
2832
|
throw err;
|
|
2327
2833
|
}
|
|
2328
2834
|
}
|
|
2329
|
-
function buildPartialObjectTransform(node, filename, bindings, source) {
|
|
2330
|
-
const partial = evaluatePartialObject(
|
|
2835
|
+
function buildPartialObjectTransform(node, filename, bindings, source, options, hoistedNames, cssVariableMap, reservedNames, globalVarAliases = /* @__PURE__ */ new Map()) {
|
|
2836
|
+
const partial = evaluatePartialObject(
|
|
2837
|
+
node,
|
|
2838
|
+
filename,
|
|
2839
|
+
bindings,
|
|
2840
|
+
source,
|
|
2841
|
+
globalVarAliases,
|
|
2842
|
+
cssVariableMap
|
|
2843
|
+
);
|
|
2331
2844
|
if (!partial || partial.dynamicProps.size === 0 && partial.conditionalClasses.length === 0) {
|
|
2332
2845
|
return null;
|
|
2333
2846
|
}
|
|
@@ -2336,11 +2849,17 @@ function buildPartialObjectTransform(node, filename, bindings, source) {
|
|
|
2336
2849
|
}
|
|
2337
2850
|
const classParts = [];
|
|
2338
2851
|
if (Object.keys(partial.staticProps).length > 0) {
|
|
2339
|
-
const { className: className2 } = transform(
|
|
2852
|
+
const { className: className2 } = transform(
|
|
2853
|
+
applyGlobalVarAliasesToSzObject(partial.staticProps, globalVarAliases, cssVariableMap)
|
|
2854
|
+
);
|
|
2340
2855
|
if (className2) {
|
|
2341
2856
|
classParts.push(className2);
|
|
2342
2857
|
}
|
|
2343
2858
|
}
|
|
2859
|
+
if (options?.mangleVars) {
|
|
2860
|
+
applyHoistedVariableNames(partial, hoistedNames, cssVariableMap);
|
|
2861
|
+
applyScopedVariablePlan(partial, hoistedNames, cssVariableMap, reservedNames);
|
|
2862
|
+
}
|
|
2344
2863
|
for (const [, info] of partial.dynamicProps) {
|
|
2345
2864
|
classParts.push(buildCSSVarClassName(info));
|
|
2346
2865
|
}
|
|
@@ -2349,12 +2868,351 @@ function buildPartialObjectTransform(node, filename, bindings, source) {
|
|
|
2349
2868
|
}
|
|
2350
2869
|
const className = classParts.filter(Boolean).join(" ");
|
|
2351
2870
|
const classNameAttr = partial.conditionalClasses.length > 0 ? `className={${buildConditionalClassSource(classParts, partial.conditionalClasses, source)}}` : `className="${className}"`;
|
|
2352
|
-
const styleProps = [...partial.dynamicProps.
|
|
2353
|
-
(info) => `${JSON.stringify(info.varName)}: ${generateStyleValueSource(info, source)}`
|
|
2871
|
+
const styleProps = [...partial.dynamicProps.entries()].filter(([id]) => !hoistedNames?.has(id)).map(
|
|
2872
|
+
([, info]) => `${JSON.stringify(info.varName)}: ${generateStyleValueSource(info, source)}`
|
|
2354
2873
|
);
|
|
2355
2874
|
return { className, classNameAttr, styleProps, usesColorVar: partial.usesColorVar };
|
|
2356
2875
|
}
|
|
2357
|
-
function
|
|
2876
|
+
function applyHoistedVariableNames(partial, hoistedNames, cssVariableMap) {
|
|
2877
|
+
if (!hoistedNames) {
|
|
2878
|
+
return;
|
|
2879
|
+
}
|
|
2880
|
+
for (const [id, name] of hoistedNames) {
|
|
2881
|
+
const info = partial.dynamicProps.get(id);
|
|
2882
|
+
if (info) {
|
|
2883
|
+
addCssVariableMapping(cssVariableMap, info.varName, name);
|
|
2884
|
+
info.varName = name;
|
|
2885
|
+
}
|
|
2886
|
+
}
|
|
2887
|
+
}
|
|
2888
|
+
function applyScopedVariablePlan(partial, hoistedNames, cssVariableMap, reservedNames) {
|
|
2889
|
+
const entries = [...partial.dynamicProps.entries()].filter(([id]) => !hoistedNames?.has(id));
|
|
2890
|
+
const plan = planCSSVariableNames(
|
|
2891
|
+
entries.map(([id]) => ({
|
|
2892
|
+
id,
|
|
2893
|
+
tier: "scoped",
|
|
2894
|
+
elementId: "self",
|
|
2895
|
+
propertyKey: id
|
|
2896
|
+
})),
|
|
2897
|
+
{ reservedNames }
|
|
2898
|
+
);
|
|
2899
|
+
for (const planned of plan) {
|
|
2900
|
+
const info = partial.dynamicProps.get(planned.id);
|
|
2901
|
+
if (info) {
|
|
2902
|
+
addCssVariableMapping(cssVariableMap, info.varName, planned.name);
|
|
2903
|
+
info.varName = planned.name;
|
|
2904
|
+
}
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
function addCssVariableMapping(cssVariableMap, original, mangled) {
|
|
2908
|
+
if (!cssVariableMap) {
|
|
2909
|
+
return;
|
|
2910
|
+
}
|
|
2911
|
+
const existing = cssVariableMap.get(original);
|
|
2912
|
+
if (!existing) {
|
|
2913
|
+
cssVariableMap.set(original, mangled);
|
|
2914
|
+
return;
|
|
2915
|
+
}
|
|
2916
|
+
const values = Array.isArray(existing) ? existing : [existing];
|
|
2917
|
+
if (!values.includes(mangled)) {
|
|
2918
|
+
cssVariableMap.set(original, [...values, mangled]);
|
|
2919
|
+
}
|
|
2920
|
+
}
|
|
2921
|
+
function normalizeGlobalVarAliases$1(input) {
|
|
2922
|
+
if (!input) {
|
|
2923
|
+
return /* @__PURE__ */ new Map();
|
|
2924
|
+
}
|
|
2925
|
+
const entries = input instanceof Map ? input.entries() : Array.isArray(input) ? input : Object.entries(input);
|
|
2926
|
+
const aliases = /* @__PURE__ */ new Map();
|
|
2927
|
+
for (const [original, alias] of entries) {
|
|
2928
|
+
if (original.startsWith("--") && alias.startsWith("--")) {
|
|
2929
|
+
aliases.set(original, alias);
|
|
2930
|
+
}
|
|
2931
|
+
}
|
|
2932
|
+
return aliases;
|
|
2933
|
+
}
|
|
2934
|
+
function applyGlobalVarAliasesToSzObject(object, globalVarAliases, cssVariableMap) {
|
|
2935
|
+
if (globalVarAliases.size === 0) {
|
|
2936
|
+
return object;
|
|
2937
|
+
}
|
|
2938
|
+
const rewritten = {};
|
|
2939
|
+
for (const [key, value] of Object.entries(object)) {
|
|
2940
|
+
rewritten[key] = applyGlobalVarAliasesToSzValue(value, globalVarAliases, cssVariableMap);
|
|
2941
|
+
}
|
|
2942
|
+
return rewritten;
|
|
2943
|
+
}
|
|
2944
|
+
function applyGlobalVarAliasesToSzValue(value, globalVarAliases, cssVariableMap) {
|
|
2945
|
+
if (typeof value === "string") {
|
|
2946
|
+
const alias = globalVarAliases.get(value);
|
|
2947
|
+
if (alias) {
|
|
2948
|
+
addCssVariableMapping(cssVariableMap, value, alias);
|
|
2949
|
+
return alias;
|
|
2950
|
+
}
|
|
2951
|
+
return value;
|
|
2952
|
+
}
|
|
2953
|
+
if (typeof value === "object") {
|
|
2954
|
+
return applyGlobalVarAliasesToSzObject(value, globalVarAliases, cssVariableMap);
|
|
2955
|
+
}
|
|
2956
|
+
return value;
|
|
2957
|
+
}
|
|
2958
|
+
function planOxcComponentVariableHoists(root, filename, bindings, source, maxDepth, reservedNames) {
|
|
2959
|
+
const nodes = [];
|
|
2960
|
+
const candidates = [];
|
|
2961
|
+
collectOxcHoistCandidates(root, null, nodes, candidates, filename, bindings, source);
|
|
2962
|
+
if (candidates.length < 2) {
|
|
2963
|
+
return {
|
|
2964
|
+
stylePropsByTarget: /* @__PURE__ */ new Map(),
|
|
2965
|
+
usageNamesByElement: /* @__PURE__ */ new Map(),
|
|
2966
|
+
diagnostics: []
|
|
2967
|
+
};
|
|
2968
|
+
}
|
|
2969
|
+
const plannedNames = planCSSVariableNames(
|
|
2970
|
+
candidates.map((candidate) => ({
|
|
2971
|
+
id: candidate.id,
|
|
2972
|
+
tier: "component",
|
|
2973
|
+
elementId: candidate.elementId,
|
|
2974
|
+
propertyKey: candidate.propertyKey,
|
|
2975
|
+
variantChain: candidate.variantChain || void 0
|
|
2976
|
+
})),
|
|
2977
|
+
{ reservedNames }
|
|
2978
|
+
);
|
|
2979
|
+
const nameByUsage = new Map(plannedNames.map((entry) => [entry.id, entry.name]));
|
|
2980
|
+
const candidateById = new Map(candidates.map((candidate) => [candidate.id, candidate]));
|
|
2981
|
+
const hoistUsages = candidates.map((candidate) => ({
|
|
2982
|
+
id: candidate.id,
|
|
2983
|
+
elementId: candidate.elementId,
|
|
2984
|
+
name: nameByUsage.get(candidate.id) ?? candidate.info.varName,
|
|
2985
|
+
valueKey: candidate.valueKey
|
|
2986
|
+
}));
|
|
2987
|
+
const analysis = planComponentVariableHoistsWithDiagnostics(nodes, hoistUsages, {
|
|
2988
|
+
maxDepth
|
|
2989
|
+
});
|
|
2990
|
+
const plans = analysis.plans;
|
|
2991
|
+
const stylePropsByTarget = /* @__PURE__ */ new Map();
|
|
2992
|
+
const usageNamesByElement = /* @__PURE__ */ new Map();
|
|
2993
|
+
for (const plan of plans) {
|
|
2994
|
+
const [firstUsageId] = plan.usageIds;
|
|
2995
|
+
const firstCandidate = firstUsageId ? candidateById.get(firstUsageId) : void 0;
|
|
2996
|
+
if (!firstCandidate) {
|
|
2997
|
+
continue;
|
|
2998
|
+
}
|
|
2999
|
+
appendMapArray(
|
|
3000
|
+
stylePropsByTarget,
|
|
3001
|
+
plan.targetElementId,
|
|
3002
|
+
`${JSON.stringify(plan.name)}: ${firstCandidate.valueSource}`
|
|
3003
|
+
);
|
|
3004
|
+
for (const usageId of plan.usageIds) {
|
|
3005
|
+
const candidate = candidateById.get(usageId);
|
|
3006
|
+
if (!candidate) {
|
|
3007
|
+
continue;
|
|
3008
|
+
}
|
|
3009
|
+
getOrCreateMap(usageNamesByElement, candidate.elementId).set(
|
|
3010
|
+
candidate.dynamicKey,
|
|
3011
|
+
plan.name
|
|
3012
|
+
);
|
|
3013
|
+
}
|
|
3014
|
+
}
|
|
3015
|
+
return {
|
|
3016
|
+
stylePropsByTarget,
|
|
3017
|
+
usageNamesByElement,
|
|
3018
|
+
diagnostics: analysis.diagnostics.map(formatHoistSkipDiagnostic)
|
|
3019
|
+
};
|
|
3020
|
+
}
|
|
3021
|
+
function formatHoistSkipDiagnostic(diagnostic) {
|
|
3022
|
+
const suffix = diagnostic.reason === "max-depth" && diagnostic.maxDepth !== void 0 ? ` (maxDepth ${diagnostic.maxDepth})` : "";
|
|
3023
|
+
return `[csszyx] mangleVars skipped component CSS variable hoist for ${diagnostic.name} across ${diagnostic.usageCount} usages: ${diagnostic.reason}${suffix}`;
|
|
3024
|
+
}
|
|
3025
|
+
function collectOxcHoistCandidates(node, parentElementId, nodes, candidates, filename, bindings, source) {
|
|
3026
|
+
if (node.type === "JSXElement") {
|
|
3027
|
+
const element = node;
|
|
3028
|
+
const opening = element.openingElement;
|
|
3029
|
+
const elementId = elementIdForOpening(opening);
|
|
3030
|
+
nodes.push({
|
|
3031
|
+
id: elementId,
|
|
3032
|
+
parentId: parentElementId,
|
|
3033
|
+
canHost: canHostHoistedStyleProps(opening)
|
|
3034
|
+
});
|
|
3035
|
+
collectOpeningHoistCandidates(opening, elementId, candidates, filename, bindings, source);
|
|
3036
|
+
for (const child of element.children) {
|
|
3037
|
+
collectOxcHoistCandidates(
|
|
3038
|
+
child,
|
|
3039
|
+
elementId,
|
|
3040
|
+
nodes,
|
|
3041
|
+
candidates,
|
|
3042
|
+
filename,
|
|
3043
|
+
bindings,
|
|
3044
|
+
source
|
|
3045
|
+
);
|
|
3046
|
+
}
|
|
3047
|
+
return;
|
|
3048
|
+
}
|
|
3049
|
+
if (node.type === "JSXFragment") {
|
|
3050
|
+
const fragment = node;
|
|
3051
|
+
const elementId = `f${node.start}`;
|
|
3052
|
+
nodes.push({ id: elementId, parentId: parentElementId, canHost: false });
|
|
3053
|
+
for (const child of fragment.children) {
|
|
3054
|
+
collectOxcHoistCandidates(
|
|
3055
|
+
child,
|
|
3056
|
+
elementId,
|
|
3057
|
+
nodes,
|
|
3058
|
+
candidates,
|
|
3059
|
+
filename,
|
|
3060
|
+
bindings,
|
|
3061
|
+
source
|
|
3062
|
+
);
|
|
3063
|
+
}
|
|
3064
|
+
return;
|
|
3065
|
+
}
|
|
3066
|
+
for (const key of Object.keys(node)) {
|
|
3067
|
+
if (isAstMetadataKey(key)) {
|
|
3068
|
+
continue;
|
|
3069
|
+
}
|
|
3070
|
+
const child = node[key];
|
|
3071
|
+
if (Array.isArray(child)) {
|
|
3072
|
+
for (const item of child) {
|
|
3073
|
+
if (isOxcNode(item)) {
|
|
3074
|
+
collectOxcHoistCandidates(
|
|
3075
|
+
item,
|
|
3076
|
+
parentElementId,
|
|
3077
|
+
nodes,
|
|
3078
|
+
candidates,
|
|
3079
|
+
filename,
|
|
3080
|
+
bindings,
|
|
3081
|
+
source
|
|
3082
|
+
);
|
|
3083
|
+
}
|
|
3084
|
+
}
|
|
3085
|
+
} else if (isOxcNode(child)) {
|
|
3086
|
+
collectOxcHoistCandidates(
|
|
3087
|
+
child,
|
|
3088
|
+
parentElementId,
|
|
3089
|
+
nodes,
|
|
3090
|
+
candidates,
|
|
3091
|
+
filename,
|
|
3092
|
+
bindings,
|
|
3093
|
+
source
|
|
3094
|
+
);
|
|
3095
|
+
}
|
|
3096
|
+
}
|
|
3097
|
+
}
|
|
3098
|
+
function collectOpeningHoistCandidates(opening, elementId, candidates, filename, bindings, source) {
|
|
3099
|
+
for (const attrRaw of opening.attributes ?? []) {
|
|
3100
|
+
if (attrRaw.type !== "JSXAttribute") {
|
|
3101
|
+
continue;
|
|
3102
|
+
}
|
|
3103
|
+
const attr = attrRaw;
|
|
3104
|
+
if (attr.name?.name !== "sz" || attr.value?.type !== "JSXExpressionContainer") {
|
|
3105
|
+
continue;
|
|
3106
|
+
}
|
|
3107
|
+
const expression = attr.value.expression;
|
|
3108
|
+
if (expression.type !== "ObjectExpression") {
|
|
3109
|
+
continue;
|
|
3110
|
+
}
|
|
3111
|
+
const partial = evaluatePartialObject(
|
|
3112
|
+
expression,
|
|
3113
|
+
filename,
|
|
3114
|
+
bindings,
|
|
3115
|
+
source,
|
|
3116
|
+
/* @__PURE__ */ new Map(),
|
|
3117
|
+
void 0
|
|
3118
|
+
);
|
|
3119
|
+
if (!partial || partial.conditionalClasses.length > 0) {
|
|
3120
|
+
continue;
|
|
3121
|
+
}
|
|
3122
|
+
for (const [dynamicKey, info] of partial.dynamicProps) {
|
|
3123
|
+
candidates.push({
|
|
3124
|
+
id: `${elementId}:${dynamicKey}`,
|
|
3125
|
+
elementId,
|
|
3126
|
+
dynamicKey,
|
|
3127
|
+
propertyKey: dynamicKey,
|
|
3128
|
+
variantChain: info.variantChain,
|
|
3129
|
+
valueSource: generateStyleValueSource(info, source),
|
|
3130
|
+
valueKey: buildDynamicValueKey(info, source),
|
|
3131
|
+
info
|
|
3132
|
+
});
|
|
3133
|
+
}
|
|
3134
|
+
}
|
|
3135
|
+
}
|
|
3136
|
+
function elementIdForOpening(opening) {
|
|
3137
|
+
return `e${opening.start}`;
|
|
3138
|
+
}
|
|
3139
|
+
function canHostHoistedStyleProps(opening) {
|
|
3140
|
+
if (!isDomJsxOpening(opening)) {
|
|
3141
|
+
return false;
|
|
3142
|
+
}
|
|
3143
|
+
const styleAttr = findJsxAttribute(opening, "style");
|
|
3144
|
+
return !styleAttr || styleAttr.value?.type === "JSXExpressionContainer";
|
|
3145
|
+
}
|
|
3146
|
+
function isDomJsxOpening(opening) {
|
|
3147
|
+
if (opening.name.type !== "JSXIdentifier") {
|
|
3148
|
+
return false;
|
|
3149
|
+
}
|
|
3150
|
+
const name = String(opening.name.name);
|
|
3151
|
+
return name.length > 0 && name.charAt(0) === name.charAt(0).toLowerCase();
|
|
3152
|
+
}
|
|
3153
|
+
function findJsxAttribute(opening, name) {
|
|
3154
|
+
for (const attrRaw of opening.attributes ?? []) {
|
|
3155
|
+
if (attrRaw.type === "JSXAttribute") {
|
|
3156
|
+
const attr = attrRaw;
|
|
3157
|
+
if (attr.name?.name === name) {
|
|
3158
|
+
return attr;
|
|
3159
|
+
}
|
|
3160
|
+
}
|
|
3161
|
+
}
|
|
3162
|
+
return null;
|
|
3163
|
+
}
|
|
3164
|
+
function collectStaticStyleCustomPropertyNames(node) {
|
|
3165
|
+
const names = /* @__PURE__ */ new Set();
|
|
3166
|
+
walk(node, (child) => {
|
|
3167
|
+
if (child.type !== "JSXOpeningElement") {
|
|
3168
|
+
return;
|
|
3169
|
+
}
|
|
3170
|
+
const styleAttr = findJsxAttribute(child, "style");
|
|
3171
|
+
if (styleAttr?.value?.type !== "JSXExpressionContainer") {
|
|
3172
|
+
return;
|
|
3173
|
+
}
|
|
3174
|
+
const expression = styleAttr.value.expression;
|
|
3175
|
+
if (expression.type !== "ObjectExpression") {
|
|
3176
|
+
return;
|
|
3177
|
+
}
|
|
3178
|
+
for (const propRaw of expression.properties ?? []) {
|
|
3179
|
+
if (propRaw.type !== "Property") {
|
|
3180
|
+
continue;
|
|
3181
|
+
}
|
|
3182
|
+
const key = propRaw.key;
|
|
3183
|
+
const name = literalStringValue(key);
|
|
3184
|
+
if (name?.startsWith("--")) {
|
|
3185
|
+
names.add(name);
|
|
3186
|
+
}
|
|
3187
|
+
}
|
|
3188
|
+
});
|
|
3189
|
+
return names;
|
|
3190
|
+
}
|
|
3191
|
+
function literalStringValue(node) {
|
|
3192
|
+
if (node.type !== "Literal") {
|
|
3193
|
+
return null;
|
|
3194
|
+
}
|
|
3195
|
+
const value = node.value;
|
|
3196
|
+
return typeof value === "string" ? value : null;
|
|
3197
|
+
}
|
|
3198
|
+
function appendMapArray(map, key, value) {
|
|
3199
|
+
const existing = map.get(key);
|
|
3200
|
+
if (existing) {
|
|
3201
|
+
existing.push(value);
|
|
3202
|
+
} else {
|
|
3203
|
+
map.set(key, [value]);
|
|
3204
|
+
}
|
|
3205
|
+
}
|
|
3206
|
+
function getOrCreateMap(map, key) {
|
|
3207
|
+
const existing = map.get(key);
|
|
3208
|
+
if (existing) {
|
|
3209
|
+
return existing;
|
|
3210
|
+
}
|
|
3211
|
+
const value = /* @__PURE__ */ new Map();
|
|
3212
|
+
map.set(key, value);
|
|
3213
|
+
return value;
|
|
3214
|
+
}
|
|
3215
|
+
function evaluatePartialObject(node, filename, bindings, source, globalVarAliases, cssVariableMap, variantChain = "") {
|
|
2358
3216
|
const staticProps = {};
|
|
2359
3217
|
const dynamicProps = /* @__PURE__ */ new Map();
|
|
2360
3218
|
const conditionalClasses = [];
|
|
@@ -2411,6 +3269,8 @@ function evaluatePartialObject(node, filename, bindings, source, variantChain =
|
|
|
2411
3269
|
filename,
|
|
2412
3270
|
bindings,
|
|
2413
3271
|
source,
|
|
3272
|
+
globalVarAliases,
|
|
3273
|
+
cssVariableMap,
|
|
2414
3274
|
nestedVariant
|
|
2415
3275
|
);
|
|
2416
3276
|
if (!nested) {
|
|
@@ -2431,8 +3291,20 @@ function evaluatePartialObject(node, filename, bindings, source, variantChain =
|
|
|
2431
3291
|
const consequent = extractStaticLiteralValue(conditional.consequent);
|
|
2432
3292
|
const alternate = extractStaticLiteralValue(conditional.alternate);
|
|
2433
3293
|
if (consequent !== null && alternate !== null) {
|
|
2434
|
-
const { className: consequentClasses } = transform(
|
|
2435
|
-
|
|
3294
|
+
const { className: consequentClasses } = transform(
|
|
3295
|
+
applyGlobalVarAliasesToSzObject(
|
|
3296
|
+
{ [key]: consequent },
|
|
3297
|
+
globalVarAliases,
|
|
3298
|
+
cssVariableMap
|
|
3299
|
+
)
|
|
3300
|
+
);
|
|
3301
|
+
const { className: alternateClasses } = transform(
|
|
3302
|
+
applyGlobalVarAliasesToSzObject(
|
|
3303
|
+
{ [key]: alternate },
|
|
3304
|
+
globalVarAliases,
|
|
3305
|
+
cssVariableMap
|
|
3306
|
+
)
|
|
3307
|
+
);
|
|
2436
3308
|
conditionalClasses.push({
|
|
2437
3309
|
test: conditional.test,
|
|
2438
3310
|
consequent: prefixVariantClasses(consequentClasses, variantChain),
|
|
@@ -2461,14 +3333,15 @@ function evaluatePartialObject(node, filename, bindings, source, variantChain =
|
|
|
2461
3333
|
}
|
|
2462
3334
|
return { staticProps, dynamicProps, conditionalClasses, usesColorVar };
|
|
2463
3335
|
}
|
|
2464
|
-
function applyStyleProps(edits, source, styleAttr, lastAttr, styleProps) {
|
|
3336
|
+
function applyStyleProps(edits, source, styleAttr, lastAttr, styleProps, fallbackInsertOffset) {
|
|
2465
3337
|
if (styleProps.length === 0) {
|
|
2466
3338
|
return;
|
|
2467
3339
|
}
|
|
2468
3340
|
const propsSource = styleProps.join(", ");
|
|
2469
3341
|
if (!styleAttr) {
|
|
2470
|
-
|
|
2471
|
-
|
|
3342
|
+
const insertOffset = lastAttr?.end ?? fallbackInsertOffset;
|
|
3343
|
+
if (insertOffset !== void 0) {
|
|
3344
|
+
edits.appendRight(insertOffset, ` style={{${propsSource}}}`);
|
|
2472
3345
|
}
|
|
2473
3346
|
return;
|
|
2474
3347
|
}
|
|
@@ -2494,6 +3367,67 @@ function generateStyleValueSource(info, source) {
|
|
|
2494
3367
|
return `\`\${${expressionSource}}\``;
|
|
2495
3368
|
}
|
|
2496
3369
|
}
|
|
3370
|
+
function buildDynamicValueKey(info, source) {
|
|
3371
|
+
const expressionSource = normalizeDynamicExpressionKey(
|
|
3372
|
+
source.slice(info.expression.start, info.expression.end)
|
|
3373
|
+
);
|
|
3374
|
+
switch (info.category) {
|
|
3375
|
+
case PropertyCategory.SPACING:
|
|
3376
|
+
return `spacing:${expressionSource}`;
|
|
3377
|
+
case PropertyCategory.COLOR:
|
|
3378
|
+
return `color:${expressionSource}`;
|
|
3379
|
+
case PropertyCategory.ANGLE:
|
|
3380
|
+
return `angle:${expressionSource}`;
|
|
3381
|
+
case PropertyCategory.DURATION:
|
|
3382
|
+
return `duration:${expressionSource}`;
|
|
3383
|
+
default:
|
|
3384
|
+
return `pass:${expressionSource}`;
|
|
3385
|
+
}
|
|
3386
|
+
}
|
|
3387
|
+
function normalizeDynamicExpressionKey(expressionSource) {
|
|
3388
|
+
let normalized = expressionSource.trim();
|
|
3389
|
+
while (hasRedundantOuterParens(normalized)) {
|
|
3390
|
+
normalized = normalized.slice(1, -1).trim();
|
|
3391
|
+
}
|
|
3392
|
+
return normalized;
|
|
3393
|
+
}
|
|
3394
|
+
function hasRedundantOuterParens(expressionSource) {
|
|
3395
|
+
if (!expressionSource.startsWith("(") || !expressionSource.endsWith(")")) {
|
|
3396
|
+
return false;
|
|
3397
|
+
}
|
|
3398
|
+
let depth = 0;
|
|
3399
|
+
let quote = null;
|
|
3400
|
+
let escaped = false;
|
|
3401
|
+
for (let index = 0; index < expressionSource.length; index++) {
|
|
3402
|
+
const char = expressionSource[index];
|
|
3403
|
+
if (quote) {
|
|
3404
|
+
if (escaped) {
|
|
3405
|
+
escaped = false;
|
|
3406
|
+
} else if (char === "\\") {
|
|
3407
|
+
escaped = true;
|
|
3408
|
+
} else if (char === quote) {
|
|
3409
|
+
quote = null;
|
|
3410
|
+
}
|
|
3411
|
+
continue;
|
|
3412
|
+
}
|
|
3413
|
+
if (char === '"' || char === "'" || char === "`") {
|
|
3414
|
+
quote = char;
|
|
3415
|
+
continue;
|
|
3416
|
+
}
|
|
3417
|
+
if (char === "(") {
|
|
3418
|
+
depth++;
|
|
3419
|
+
} else if (char === ")") {
|
|
3420
|
+
depth--;
|
|
3421
|
+
if (depth === 0 && index !== expressionSource.length - 1) {
|
|
3422
|
+
return false;
|
|
3423
|
+
}
|
|
3424
|
+
}
|
|
3425
|
+
if (depth < 0) {
|
|
3426
|
+
return false;
|
|
3427
|
+
}
|
|
3428
|
+
}
|
|
3429
|
+
return depth === 0;
|
|
3430
|
+
}
|
|
2497
3431
|
function buildCSSVarClassName(info) {
|
|
2498
3432
|
const variantPrefix = info.variantChain ? `${getVariantPrefix(info.variantChain)}:` : "";
|
|
2499
3433
|
return `${variantPrefix}${info.twPrefix}-(${info.varName})`;
|
|
@@ -2526,9 +3460,21 @@ function prefixVariantClasses(className, variantChain) {
|
|
|
2526
3460
|
function isRuntimeExpression(node) {
|
|
2527
3461
|
return node.type === "Identifier" || node.type === "MemberExpression" || node.type === "CallExpression" || node.type === "ConditionalExpression" || node.type === "TemplateLiteral" || node.type === "BinaryExpression" || node.type === "LogicalExpression";
|
|
2528
3462
|
}
|
|
2529
|
-
function buildStaticConditionalClassExpression(node, filename, bindings, source, classes) {
|
|
2530
|
-
const consequent = resolveStaticClassString(
|
|
2531
|
-
|
|
3463
|
+
function buildStaticConditionalClassExpression(node, filename, bindings, source, classes, globalVarAliases, cssVariableMap) {
|
|
3464
|
+
const consequent = resolveStaticClassString(
|
|
3465
|
+
node.consequent,
|
|
3466
|
+
filename,
|
|
3467
|
+
bindings,
|
|
3468
|
+
globalVarAliases,
|
|
3469
|
+
cssVariableMap
|
|
3470
|
+
);
|
|
3471
|
+
const alternate = resolveStaticClassString(
|
|
3472
|
+
node.alternate,
|
|
3473
|
+
filename,
|
|
3474
|
+
bindings,
|
|
3475
|
+
globalVarAliases,
|
|
3476
|
+
cssVariableMap
|
|
3477
|
+
);
|
|
2532
3478
|
if (consequent === null || alternate === null) {
|
|
2533
3479
|
return null;
|
|
2534
3480
|
}
|
|
@@ -2540,7 +3486,7 @@ function buildStaticConditionalClassExpression(node, filename, bindings, source,
|
|
|
2540
3486
|
const testSource = source.slice(node.test.start, node.test.end);
|
|
2541
3487
|
return `${testSource} ? ${JSON.stringify(consequent)} : ${JSON.stringify(alternate)}`;
|
|
2542
3488
|
}
|
|
2543
|
-
function resolveStaticClassString(node, filename, bindings) {
|
|
3489
|
+
function resolveStaticClassString(node, filename, bindings, globalVarAliases, cssVariableMap) {
|
|
2544
3490
|
const unwrapped = unwrapExpression(node);
|
|
2545
3491
|
let objectNode = null;
|
|
2546
3492
|
if (unwrapped.type === "ObjectExpression") {
|
|
@@ -2552,7 +3498,13 @@ function resolveStaticClassString(node, filename, bindings) {
|
|
|
2552
3498
|
return null;
|
|
2553
3499
|
}
|
|
2554
3500
|
try {
|
|
2555
|
-
return transform(
|
|
3501
|
+
return transform(
|
|
3502
|
+
applyGlobalVarAliasesToSzObject(
|
|
3503
|
+
astObjectToSzObject(objectNode, filename, bindings),
|
|
3504
|
+
globalVarAliases,
|
|
3505
|
+
cssVariableMap
|
|
3506
|
+
)
|
|
3507
|
+
).className;
|
|
2556
3508
|
} catch (err) {
|
|
2557
3509
|
if (err instanceof OxcNotImplementedError) {
|
|
2558
3510
|
return null;
|
|
@@ -2667,17 +3619,22 @@ function unwrapExpression(node) {
|
|
|
2667
3619
|
}
|
|
2668
3620
|
return current;
|
|
2669
3621
|
}
|
|
3622
|
+
function isOxcNode(value) {
|
|
3623
|
+
return Boolean(
|
|
3624
|
+
value && typeof value === "object" && typeof value.type === "string"
|
|
3625
|
+
);
|
|
3626
|
+
}
|
|
3627
|
+
function isAstMetadataKey(key) {
|
|
3628
|
+
return key === "loc" || key === "range" || key === "start" || key === "end" || key === "type";
|
|
3629
|
+
}
|
|
2670
3630
|
function walk(node, visit) {
|
|
2671
|
-
if (!node
|
|
3631
|
+
if (!isOxcNode(node)) {
|
|
2672
3632
|
return;
|
|
2673
3633
|
}
|
|
2674
3634
|
const typed = node;
|
|
2675
|
-
if (typeof typed.type !== "string") {
|
|
2676
|
-
return;
|
|
2677
|
-
}
|
|
2678
3635
|
visit(typed);
|
|
2679
3636
|
for (const key of Object.keys(typed)) {
|
|
2680
|
-
if (key
|
|
3637
|
+
if (isAstMetadataKey(key)) {
|
|
2681
3638
|
continue;
|
|
2682
3639
|
}
|
|
2683
3640
|
const child = typed[key];
|
|
@@ -2701,7 +3658,7 @@ class OxcRustNotImplementedError extends Error {
|
|
|
2701
3658
|
}
|
|
2702
3659
|
}
|
|
2703
3660
|
function transformRust(source, filename, options) {
|
|
2704
|
-
const [result] = transformRustBatch([{ filename, source }]);
|
|
3661
|
+
const [result] = transformRustBatch([{ filename, source }], options);
|
|
2705
3662
|
if (!result) {
|
|
2706
3663
|
throw new OxcRustNotImplementedError("native transform returned no result");
|
|
2707
3664
|
}
|
|
@@ -2728,7 +3685,12 @@ function transformRustBatch(files, options) {
|
|
|
2728
3685
|
files.map((file, index) => ({
|
|
2729
3686
|
filename: file.filename ?? `file-${index}.tsx`,
|
|
2730
3687
|
source: file.source
|
|
2731
|
-
}))
|
|
3688
|
+
})),
|
|
3689
|
+
{
|
|
3690
|
+
mangleVars: options?.mangleVars === true,
|
|
3691
|
+
mangleVarHoistMaxDepth: options?.mangleVarHoistMaxDepth,
|
|
3692
|
+
globalVarAliases: normalizeGlobalVarAliases(options?.globalVarAliases)
|
|
3693
|
+
}
|
|
2732
3694
|
).map(fromNativeResult);
|
|
2733
3695
|
} catch (err) {
|
|
2734
3696
|
if (err instanceof OxcRustNotImplementedError) {
|
|
@@ -2742,6 +3704,13 @@ function transformRustBatch(files, options) {
|
|
|
2742
3704
|
throw err;
|
|
2743
3705
|
}
|
|
2744
3706
|
}
|
|
3707
|
+
function normalizeGlobalVarAliases(input) {
|
|
3708
|
+
if (!input) {
|
|
3709
|
+
return [];
|
|
3710
|
+
}
|
|
3711
|
+
const entries = input instanceof Map ? input.entries() : Array.isArray(input) ? input : Object.entries(input);
|
|
3712
|
+
return [...entries].filter(([original, alias]) => original.startsWith("--") && alias.startsWith("--")).map(([original, alias]) => ({ original, alias }));
|
|
3713
|
+
}
|
|
2745
3714
|
function fromNativeResult(result) {
|
|
2746
3715
|
return {
|
|
2747
3716
|
code: result.code,
|
|
@@ -2761,9 +3730,25 @@ function fromNativeResult(result) {
|
|
|
2761
3730
|
path: data.path
|
|
2762
3731
|
}
|
|
2763
3732
|
])
|
|
2764
|
-
)
|
|
3733
|
+
),
|
|
3734
|
+
cssVariableMap: aggregateCssVariableMap(result.cssVariableMap ?? [])
|
|
2765
3735
|
};
|
|
2766
3736
|
}
|
|
3737
|
+
function aggregateCssVariableMap(entries) {
|
|
3738
|
+
const map = /* @__PURE__ */ new Map();
|
|
3739
|
+
for (const entry of entries) {
|
|
3740
|
+
const existing = map.get(entry.original);
|
|
3741
|
+
if (!existing) {
|
|
3742
|
+
map.set(entry.original, entry.mangled);
|
|
3743
|
+
continue;
|
|
3744
|
+
}
|
|
3745
|
+
const values = Array.isArray(existing) ? existing : [existing];
|
|
3746
|
+
if (!values.includes(entry.mangled)) {
|
|
3747
|
+
map.set(entry.original, [...values, entry.mangled]);
|
|
3748
|
+
}
|
|
3749
|
+
}
|
|
3750
|
+
return map;
|
|
3751
|
+
}
|
|
2767
3752
|
|
|
2768
3753
|
const VERSION = "0.0.0";
|
|
2769
3754
|
const DEFAULT_COMPILER_OPTIONS = {
|
|
@@ -2778,4 +3763,4 @@ function mergeOptions(options = {}) {
|
|
|
2778
3763
|
};
|
|
2779
3764
|
}
|
|
2780
3765
|
|
|
2781
|
-
export { COLOR_PROPERTIES, CsszyxCompiler, DEFAULT_COMPILER_OPTIONS, KNOWN_VARIANTS, ManifestBuilder, OxcNotImplementedError, OxcRustNotImplementedError, PROPERTY_MAP, PropertyCategory, VERSION, buildParentMap, createRecoveryToken, ensureRustTransformAvailable, generateRecoveryToken, getCSSVariableName, getPropertyCategory, hoistCSSVariables, injectRecoveryToken, isValidRecoveryMode, mergeOptions, parseManifest, serializeManifest, transform, transformOxc, transformRust, transformRustBatch, transformSourceCode, validateManifest, validateSzRecover };
|
|
3766
|
+
export { COLOR_PROPERTIES, CsszyxCompiler, DEFAULT_COMPILER_OPTIONS, KNOWN_VARIANTS, ManifestBuilder, OxcNotImplementedError, OxcRustNotImplementedError, PROPERTY_MAP, PropertyCategory, VERSION, buildParentMap, createRecoveryToken, ensureRustTransformAvailable, generateRecoveryToken, getCSSVariableName, getPropertyCategory, hoistCSSVariables, injectRecoveryToken, isValidRecoveryMode, mergeOptions, parseManifest, scanGlobalVarUsages, serializeManifest, transform, transformOxc, transformRust, transformRustBatch, transformSourceCode, validateManifest, validateSzRecover };
|