@csszyx/compiler 0.9.0 → 0.9.2
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 +1034 -47
- package/dist/index.d.cts +106 -3
- package/dist/index.d.mts +106 -3
- package/dist/index.mjs +1035 -50
- package/dist/shared/{compiler.DZgazEy8.cjs → compiler.BfDLUvcf.cjs} +78 -9
- package/dist/shared/{compiler.CUn8HGmA.mjs → compiler.wyFFQW-b.mjs} +78 -10
- package/dist/transform-core.cjs +2 -1
- package/dist/transform-core.d.cts +2 -1
- package/dist/transform-core.d.mts +2 -1
- package/dist/transform-core.mjs +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const core = require('@csszyx/core');
|
|
4
|
-
const transformCore = require('./shared/compiler.
|
|
4
|
+
const transformCore = require('./shared/compiler.BfDLUvcf.cjs');
|
|
5
|
+
const oxcParser = require('oxc-parser');
|
|
5
6
|
const t = require('@babel/types');
|
|
6
7
|
const node_crypto = require('node:crypto');
|
|
7
8
|
const babel = require('@babel/core');
|
|
8
9
|
const MagicString = require('magic-string');
|
|
9
|
-
const oxcParser = require('oxc-parser');
|
|
10
10
|
const native = require('@csszyx/core/native');
|
|
11
11
|
|
|
12
12
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
@@ -84,6 +84,7 @@ function transformSourceCode(source, filename, options) {
|
|
|
84
84
|
const rawClassNames = /* @__PURE__ */ new Set();
|
|
85
85
|
const diagnostics = [];
|
|
86
86
|
const recoveryTokens = /* @__PURE__ */ new Map();
|
|
87
|
+
const cssVariableMap = /* @__PURE__ */ new Map();
|
|
87
88
|
if (!source.includes("sz")) {
|
|
88
89
|
return {
|
|
89
90
|
code: source,
|
|
@@ -94,7 +95,8 @@ function transformSourceCode(source, filename, options) {
|
|
|
94
95
|
classes: collectedClasses,
|
|
95
96
|
rawClassNames,
|
|
96
97
|
diagnostics,
|
|
97
|
-
recoveryTokens
|
|
98
|
+
recoveryTokens,
|
|
99
|
+
cssVariableMap
|
|
98
100
|
};
|
|
99
101
|
}
|
|
100
102
|
try {
|
|
@@ -756,7 +758,8 @@ function transformSourceCode(source, filename, options) {
|
|
|
756
758
|
classes: collectedClasses,
|
|
757
759
|
rawClassNames,
|
|
758
760
|
diagnostics,
|
|
759
|
-
recoveryTokens
|
|
761
|
+
recoveryTokens,
|
|
762
|
+
cssVariableMap
|
|
760
763
|
};
|
|
761
764
|
} catch (e) {
|
|
762
765
|
if (e instanceof ASTBudgetExceededError) {
|
|
@@ -772,7 +775,8 @@ function transformSourceCode(source, filename, options) {
|
|
|
772
775
|
classes: collectedClasses,
|
|
773
776
|
rawClassNames,
|
|
774
777
|
diagnostics,
|
|
775
|
-
recoveryTokens
|
|
778
|
+
recoveryTokens,
|
|
779
|
+
cssVariableMap
|
|
776
780
|
};
|
|
777
781
|
}
|
|
778
782
|
}
|
|
@@ -1324,6 +1328,271 @@ class CsszyxCompiler {
|
|
|
1324
1328
|
}
|
|
1325
1329
|
}
|
|
1326
1330
|
|
|
1331
|
+
const CSS_VAR_REFERENCE_RE = /var\(\s*(--[\w-]+)/g;
|
|
1332
|
+
function scanGlobalVarUsages(source, filename = "file.tsx", options = {}) {
|
|
1333
|
+
if (!source.includes("--") && !source.includes("var(")) {
|
|
1334
|
+
return [];
|
|
1335
|
+
}
|
|
1336
|
+
const parsed = oxcParser.parseSync(filename, source);
|
|
1337
|
+
if (parsed.errors.length > 0) {
|
|
1338
|
+
throw new Error(
|
|
1339
|
+
`oxc-parser errors in ${filename}: ${parsed.errors.map((error) => error.message).join("; ")}`
|
|
1340
|
+
);
|
|
1341
|
+
}
|
|
1342
|
+
const tokenFilter = options.tokens ? new Set(options.tokens) : null;
|
|
1343
|
+
const constantStrings = collectStringConstants(parsed.program);
|
|
1344
|
+
const diagnostics = [];
|
|
1345
|
+
walk$1(parsed.program, (node, ancestors) => {
|
|
1346
|
+
if (node.type === "CallExpression") {
|
|
1347
|
+
collectStyleMethodDiagnostic(
|
|
1348
|
+
node,
|
|
1349
|
+
source,
|
|
1350
|
+
filename,
|
|
1351
|
+
constantStrings,
|
|
1352
|
+
tokenFilter,
|
|
1353
|
+
diagnostics
|
|
1354
|
+
);
|
|
1355
|
+
return;
|
|
1356
|
+
}
|
|
1357
|
+
if (node.type !== "JSXAttribute") {
|
|
1358
|
+
return;
|
|
1359
|
+
}
|
|
1360
|
+
const attrName = jsxAttributeName(node);
|
|
1361
|
+
if (attrName === "style") {
|
|
1362
|
+
collectJsxStyleDiagnostics(
|
|
1363
|
+
node,
|
|
1364
|
+
source,
|
|
1365
|
+
filename,
|
|
1366
|
+
constantStrings,
|
|
1367
|
+
tokenFilter,
|
|
1368
|
+
diagnostics
|
|
1369
|
+
);
|
|
1370
|
+
return;
|
|
1371
|
+
}
|
|
1372
|
+
if (attrName === "className") {
|
|
1373
|
+
collectClassNameDiagnostics(node, source, filename, tokenFilter, diagnostics);
|
|
1374
|
+
return;
|
|
1375
|
+
}
|
|
1376
|
+
if (attrName === "sz" && ancestors.some((parent) => parent.type === "JSXAttribute")) {
|
|
1377
|
+
return;
|
|
1378
|
+
}
|
|
1379
|
+
});
|
|
1380
|
+
return diagnostics;
|
|
1381
|
+
}
|
|
1382
|
+
function collectStringConstants(root) {
|
|
1383
|
+
const constants = /* @__PURE__ */ new Map();
|
|
1384
|
+
walk$1(root, (node) => {
|
|
1385
|
+
if (node.type !== "VariableDeclarator") {
|
|
1386
|
+
return;
|
|
1387
|
+
}
|
|
1388
|
+
const id = node.id;
|
|
1389
|
+
const init = node.init;
|
|
1390
|
+
if (id?.type !== "Identifier" || !init) {
|
|
1391
|
+
return;
|
|
1392
|
+
}
|
|
1393
|
+
const name = id.name;
|
|
1394
|
+
const value = literalStringValue$1(init);
|
|
1395
|
+
if (typeof name === "string" && value !== null) {
|
|
1396
|
+
constants.set(name, value);
|
|
1397
|
+
}
|
|
1398
|
+
});
|
|
1399
|
+
return constants;
|
|
1400
|
+
}
|
|
1401
|
+
function collectStyleMethodDiagnostic(node, source, filename, constants, tokenFilter, diagnostics) {
|
|
1402
|
+
const method = memberMethodName(node.callee);
|
|
1403
|
+
if (!method || !["setProperty", "getPropertyValue", "removeProperty"].includes(method)) {
|
|
1404
|
+
return;
|
|
1405
|
+
}
|
|
1406
|
+
const firstArg = node.arguments?.[0];
|
|
1407
|
+
const name = firstArg ? resolveString(firstArg, constants) : null;
|
|
1408
|
+
if (!name?.startsWith("--") || !shouldReportToken(name, tokenFilter)) {
|
|
1409
|
+
return;
|
|
1410
|
+
}
|
|
1411
|
+
const kind = method === "setProperty" ? "style-set-property" : method === "getPropertyValue" ? "style-get-property" : "style-remove-property";
|
|
1412
|
+
diagnostics.push(createDiagnostic(kind, name, node, source, filename));
|
|
1413
|
+
}
|
|
1414
|
+
function collectJsxStyleDiagnostics(attr, source, filename, constants, tokenFilter, diagnostics) {
|
|
1415
|
+
const expression = jsxExpression(attr);
|
|
1416
|
+
if (expression?.type !== "ObjectExpression") {
|
|
1417
|
+
return;
|
|
1418
|
+
}
|
|
1419
|
+
for (const prop of expression.properties ?? []) {
|
|
1420
|
+
if (prop.type !== "Property") {
|
|
1421
|
+
continue;
|
|
1422
|
+
}
|
|
1423
|
+
const name = propertyKeyString(prop, constants);
|
|
1424
|
+
if (name?.startsWith("--") && shouldReportToken(name, tokenFilter)) {
|
|
1425
|
+
diagnostics.push(createDiagnostic("jsx-style-key", name, prop, source, filename));
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
function collectClassNameDiagnostics(attr, source, filename, tokenFilter, diagnostics) {
|
|
1430
|
+
for (const value of jsxAttributeStringValues(attr)) {
|
|
1431
|
+
for (const name of extractVarReferences(value)) {
|
|
1432
|
+
if (shouldReportToken(name, tokenFilter)) {
|
|
1433
|
+
diagnostics.push(
|
|
1434
|
+
createDiagnostic("class-string-var-reference", name, attr, source, filename)
|
|
1435
|
+
);
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
function jsxAttributeName(attr) {
|
|
1441
|
+
const name = attr.name;
|
|
1442
|
+
return name?.type === "JSXIdentifier" ? name.name ?? null : null;
|
|
1443
|
+
}
|
|
1444
|
+
function jsxExpression(attr) {
|
|
1445
|
+
const value = attr.value;
|
|
1446
|
+
if (value?.type !== "JSXExpressionContainer") {
|
|
1447
|
+
return null;
|
|
1448
|
+
}
|
|
1449
|
+
return value.expression ?? null;
|
|
1450
|
+
}
|
|
1451
|
+
function jsxAttributeStringValues(attr) {
|
|
1452
|
+
const value = attr.value;
|
|
1453
|
+
if (!value) {
|
|
1454
|
+
return [];
|
|
1455
|
+
}
|
|
1456
|
+
const direct = literalStringValue$1(value);
|
|
1457
|
+
if (direct !== null) {
|
|
1458
|
+
return [direct];
|
|
1459
|
+
}
|
|
1460
|
+
const expression = jsxExpression(attr);
|
|
1461
|
+
if (!expression) {
|
|
1462
|
+
return [];
|
|
1463
|
+
}
|
|
1464
|
+
const exprValue = literalStringValue$1(expression);
|
|
1465
|
+
if (exprValue !== null) {
|
|
1466
|
+
return [exprValue];
|
|
1467
|
+
}
|
|
1468
|
+
if (expression.type === "TemplateLiteral") {
|
|
1469
|
+
return templateStaticParts(expression);
|
|
1470
|
+
}
|
|
1471
|
+
return [];
|
|
1472
|
+
}
|
|
1473
|
+
function resolveString(node, constants) {
|
|
1474
|
+
const literal = literalStringValue$1(node);
|
|
1475
|
+
if (literal !== null) {
|
|
1476
|
+
return literal;
|
|
1477
|
+
}
|
|
1478
|
+
if (node.type === "Identifier") {
|
|
1479
|
+
const name = node.name;
|
|
1480
|
+
return typeof name === "string" ? constants.get(name) ?? null : null;
|
|
1481
|
+
}
|
|
1482
|
+
return null;
|
|
1483
|
+
}
|
|
1484
|
+
function literalStringValue$1(node) {
|
|
1485
|
+
if (node.type !== "Literal") {
|
|
1486
|
+
return null;
|
|
1487
|
+
}
|
|
1488
|
+
const value = node.value;
|
|
1489
|
+
return typeof value === "string" ? value : null;
|
|
1490
|
+
}
|
|
1491
|
+
function propertyKeyString(property, constants) {
|
|
1492
|
+
const key = property.key;
|
|
1493
|
+
const computed = property.computed === true;
|
|
1494
|
+
if (!key) {
|
|
1495
|
+
return null;
|
|
1496
|
+
}
|
|
1497
|
+
if (computed) {
|
|
1498
|
+
return resolveString(key, constants);
|
|
1499
|
+
}
|
|
1500
|
+
if (key.type === "Identifier") {
|
|
1501
|
+
const name = key.name;
|
|
1502
|
+
return typeof name === "string" ? name : null;
|
|
1503
|
+
}
|
|
1504
|
+
return literalStringValue$1(key);
|
|
1505
|
+
}
|
|
1506
|
+
function memberMethodName(callee) {
|
|
1507
|
+
if (callee?.type !== "MemberExpression") {
|
|
1508
|
+
return null;
|
|
1509
|
+
}
|
|
1510
|
+
const property = callee.property;
|
|
1511
|
+
if (!property) {
|
|
1512
|
+
return null;
|
|
1513
|
+
}
|
|
1514
|
+
if (property.type === "Identifier") {
|
|
1515
|
+
const name = property.name;
|
|
1516
|
+
return typeof name === "string" ? name : null;
|
|
1517
|
+
}
|
|
1518
|
+
return literalStringValue$1(property);
|
|
1519
|
+
}
|
|
1520
|
+
function templateStaticParts(node) {
|
|
1521
|
+
const quasis = node.quasis ?? [];
|
|
1522
|
+
const parts = [];
|
|
1523
|
+
for (const quasi of quasis) {
|
|
1524
|
+
const value = quasi.value;
|
|
1525
|
+
const cooked = value?.cooked;
|
|
1526
|
+
const raw = value?.raw;
|
|
1527
|
+
if (typeof cooked === "string") {
|
|
1528
|
+
parts.push(cooked);
|
|
1529
|
+
} else if (typeof raw === "string") {
|
|
1530
|
+
parts.push(raw);
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
return parts;
|
|
1534
|
+
}
|
|
1535
|
+
function extractVarReferences(value) {
|
|
1536
|
+
const refs = /* @__PURE__ */ new Set();
|
|
1537
|
+
for (const match of value.matchAll(CSS_VAR_REFERENCE_RE)) {
|
|
1538
|
+
refs.add(match[1]);
|
|
1539
|
+
}
|
|
1540
|
+
return [...refs].sort();
|
|
1541
|
+
}
|
|
1542
|
+
function shouldReportToken(name, tokenFilter) {
|
|
1543
|
+
return tokenFilter === null || tokenFilter.has(name);
|
|
1544
|
+
}
|
|
1545
|
+
function createDiagnostic(kind, name, node, source, filename) {
|
|
1546
|
+
return {
|
|
1547
|
+
kind,
|
|
1548
|
+
name,
|
|
1549
|
+
location: offsetToLocation(source, node.start, filename),
|
|
1550
|
+
message: `${name} is used outside csszyx-owned global variable alias rewrites (${kind}).`
|
|
1551
|
+
};
|
|
1552
|
+
}
|
|
1553
|
+
function offsetToLocation(source, offset, filename) {
|
|
1554
|
+
let line = 1;
|
|
1555
|
+
let column = 1;
|
|
1556
|
+
for (let index = 0; index < offset; index++) {
|
|
1557
|
+
if (source.charCodeAt(index) === 10) {
|
|
1558
|
+
line++;
|
|
1559
|
+
column = 1;
|
|
1560
|
+
} else {
|
|
1561
|
+
column++;
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
return { filePath: filename, line, column };
|
|
1565
|
+
}
|
|
1566
|
+
function walk$1(node, visit, ancestors = []) {
|
|
1567
|
+
if (!isOxcNode$1(node)) {
|
|
1568
|
+
return;
|
|
1569
|
+
}
|
|
1570
|
+
visit(node, ancestors);
|
|
1571
|
+
ancestors.push(node);
|
|
1572
|
+
for (const key of Object.keys(node)) {
|
|
1573
|
+
if (isAstMetadataKey$1(key)) {
|
|
1574
|
+
continue;
|
|
1575
|
+
}
|
|
1576
|
+
const child = node[key];
|
|
1577
|
+
if (Array.isArray(child)) {
|
|
1578
|
+
for (const item of child) {
|
|
1579
|
+
walk$1(item, visit, ancestors);
|
|
1580
|
+
}
|
|
1581
|
+
} else if (child && typeof child === "object") {
|
|
1582
|
+
walk$1(child, visit, ancestors);
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
ancestors.pop();
|
|
1586
|
+
}
|
|
1587
|
+
function isOxcNode$1(value) {
|
|
1588
|
+
return Boolean(
|
|
1589
|
+
value && typeof value === "object" && typeof value.type === "string"
|
|
1590
|
+
);
|
|
1591
|
+
}
|
|
1592
|
+
function isAstMetadataKey$1(key) {
|
|
1593
|
+
return key === "loc" || key === "range" || key === "start" || key === "end" || key === "type";
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1327
1596
|
function findLCA(nodeA, nodeB, parentMap) {
|
|
1328
1597
|
const ancestorsA = /* @__PURE__ */ new Set();
|
|
1329
1598
|
let current = nodeA;
|
|
@@ -1657,6 +1926,155 @@ function injectRecoveryToken(attributes, token) {
|
|
|
1657
1926
|
};
|
|
1658
1927
|
}
|
|
1659
1928
|
|
|
1929
|
+
const DEFAULT_MAX_DEPTH = 5;
|
|
1930
|
+
function planComponentVariableHoistsWithDiagnostics(nodes, usages, options = {}) {
|
|
1931
|
+
const maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
1932
|
+
const nodeById = new Map(nodes.map((node) => [node.id, node]));
|
|
1933
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1934
|
+
for (const usage of usages) {
|
|
1935
|
+
const groupKey = `${usage.name}\0${usage.valueKey}`;
|
|
1936
|
+
const group = groups.get(groupKey);
|
|
1937
|
+
if (group) {
|
|
1938
|
+
group.push(usage);
|
|
1939
|
+
} else {
|
|
1940
|
+
groups.set(groupKey, [usage]);
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
const plans = [];
|
|
1944
|
+
const diagnostics = [];
|
|
1945
|
+
for (const group of groups.values()) {
|
|
1946
|
+
if (group.length < 2) {
|
|
1947
|
+
continue;
|
|
1948
|
+
}
|
|
1949
|
+
const targetElementId = findLowestCommonAncestor(
|
|
1950
|
+
group.map((usage) => usage.elementId),
|
|
1951
|
+
nodeById
|
|
1952
|
+
);
|
|
1953
|
+
if (!targetElementId) {
|
|
1954
|
+
diagnostics.push(buildHoistDiagnostic(group, "no-lca"));
|
|
1955
|
+
continue;
|
|
1956
|
+
}
|
|
1957
|
+
const target = nodeById.get(targetElementId);
|
|
1958
|
+
if (!target || target.canHost === false) {
|
|
1959
|
+
diagnostics.push(buildHoistDiagnostic(group, "non-host-ancestor"));
|
|
1960
|
+
continue;
|
|
1961
|
+
}
|
|
1962
|
+
if (group.some(
|
|
1963
|
+
(usage) => distanceToAncestor(usage.elementId, targetElementId, nodeById) > maxDepth
|
|
1964
|
+
)) {
|
|
1965
|
+
diagnostics.push(buildHoistDiagnostic(group, "max-depth", maxDepth));
|
|
1966
|
+
continue;
|
|
1967
|
+
}
|
|
1968
|
+
plans.push({
|
|
1969
|
+
name: group[0].name,
|
|
1970
|
+
valueKey: group[0].valueKey,
|
|
1971
|
+
targetElementId,
|
|
1972
|
+
usageIds: group.map((usage) => usage.id)
|
|
1973
|
+
});
|
|
1974
|
+
}
|
|
1975
|
+
return { plans, diagnostics };
|
|
1976
|
+
}
|
|
1977
|
+
function buildHoistDiagnostic(group, reason, maxDepth) {
|
|
1978
|
+
return {
|
|
1979
|
+
name: group[0]?.name ?? "",
|
|
1980
|
+
reason,
|
|
1981
|
+
usageCount: group.length,
|
|
1982
|
+
...maxDepth === void 0 ? {} : { maxDepth }
|
|
1983
|
+
};
|
|
1984
|
+
}
|
|
1985
|
+
function findLowestCommonAncestor(elementIds, nodeById) {
|
|
1986
|
+
const [first, ...rest] = elementIds;
|
|
1987
|
+
if (!first) {
|
|
1988
|
+
return null;
|
|
1989
|
+
}
|
|
1990
|
+
let currentAncestors = ancestorChain(first, nodeById);
|
|
1991
|
+
for (const elementId of rest) {
|
|
1992
|
+
const nextAncestors = new Set(ancestorChain(elementId, nodeById));
|
|
1993
|
+
currentAncestors = currentAncestors.filter((id) => nextAncestors.has(id));
|
|
1994
|
+
if (currentAncestors.length === 0) {
|
|
1995
|
+
return null;
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
return currentAncestors[0] ?? null;
|
|
1999
|
+
}
|
|
2000
|
+
function ancestorChain(elementId, nodeById) {
|
|
2001
|
+
const chain = [];
|
|
2002
|
+
let current = elementId;
|
|
2003
|
+
while (current) {
|
|
2004
|
+
const node = nodeById.get(current);
|
|
2005
|
+
if (!node) {
|
|
2006
|
+
break;
|
|
2007
|
+
}
|
|
2008
|
+
chain.push(current);
|
|
2009
|
+
current = node.parentId;
|
|
2010
|
+
}
|
|
2011
|
+
return chain;
|
|
2012
|
+
}
|
|
2013
|
+
function distanceToAncestor(elementId, ancestorId, nodeById) {
|
|
2014
|
+
let distance = 0;
|
|
2015
|
+
let current = elementId;
|
|
2016
|
+
while (current) {
|
|
2017
|
+
if (current === ancestorId) {
|
|
2018
|
+
return distance;
|
|
2019
|
+
}
|
|
2020
|
+
const node = nodeById.get(current);
|
|
2021
|
+
if (!node) {
|
|
2022
|
+
break;
|
|
2023
|
+
}
|
|
2024
|
+
current = node.parentId;
|
|
2025
|
+
distance++;
|
|
2026
|
+
}
|
|
2027
|
+
return Number.POSITIVE_INFINITY;
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
function planCSSVariableNames(usages, options = {}) {
|
|
2031
|
+
const componentNames = /* @__PURE__ */ new Map();
|
|
2032
|
+
const scopedNamesByElement = /* @__PURE__ */ new Map();
|
|
2033
|
+
const reservedNames = options.reservedNames ?? /* @__PURE__ */ new Set();
|
|
2034
|
+
return usages.map((usage) => {
|
|
2035
|
+
if (usage.tier === "component") {
|
|
2036
|
+
const key2 = canonicalUsageKey(usage);
|
|
2037
|
+
let name2 = componentNames.get(key2);
|
|
2038
|
+
if (!name2) {
|
|
2039
|
+
name2 = allocateVariableName("--c", componentNames.size, reservedNames);
|
|
2040
|
+
componentNames.set(key2, name2);
|
|
2041
|
+
}
|
|
2042
|
+
return { ...usage, name: name2 };
|
|
2043
|
+
}
|
|
2044
|
+
const elementId = usage.elementId ?? "";
|
|
2045
|
+
const elementNames = getOrCreate(scopedNamesByElement, elementId, () => /* @__PURE__ */ new Map());
|
|
2046
|
+
const key = canonicalUsageKey(usage);
|
|
2047
|
+
let name = elementNames.get(key);
|
|
2048
|
+
if (!name) {
|
|
2049
|
+
name = allocateVariableName("--s", elementNames.size, reservedNames);
|
|
2050
|
+
elementNames.set(key, name);
|
|
2051
|
+
}
|
|
2052
|
+
return { ...usage, name };
|
|
2053
|
+
});
|
|
2054
|
+
}
|
|
2055
|
+
function allocateVariableName(prefix, startIndex, reservedNames) {
|
|
2056
|
+
let index = startIndex;
|
|
2057
|
+
while (true) {
|
|
2058
|
+
const name = `${prefix}${core.encode(index)}`;
|
|
2059
|
+
if (!reservedNames.has(name)) {
|
|
2060
|
+
return name;
|
|
2061
|
+
}
|
|
2062
|
+
index++;
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
function canonicalUsageKey(usage) {
|
|
2066
|
+
return `${usage.variantChain ?? ""}\0${usage.propertyKey}`;
|
|
2067
|
+
}
|
|
2068
|
+
function getOrCreate(map, key, create) {
|
|
2069
|
+
const existing = map.get(key);
|
|
2070
|
+
if (existing) {
|
|
2071
|
+
return existing;
|
|
2072
|
+
}
|
|
2073
|
+
const value = create();
|
|
2074
|
+
map.set(key, value);
|
|
2075
|
+
return value;
|
|
2076
|
+
}
|
|
2077
|
+
|
|
1660
2078
|
class OxcNotImplementedError extends Error {
|
|
1661
2079
|
/**
|
|
1662
2080
|
* @param slice The Phase D slice expected to implement this path.
|
|
@@ -1672,6 +2090,8 @@ function transformOxc(source, filename, options) {
|
|
|
1672
2090
|
const rawClassNames = /* @__PURE__ */ new Set();
|
|
1673
2091
|
const diagnostics = [];
|
|
1674
2092
|
const recoveryTokens = /* @__PURE__ */ new Map();
|
|
2093
|
+
const cssVariableMap = /* @__PURE__ */ new Map();
|
|
2094
|
+
const globalVarAliases = normalizeGlobalVarAliases$1(options?.globalVarAliases);
|
|
1675
2095
|
if (!source.includes("sz")) {
|
|
1676
2096
|
return {
|
|
1677
2097
|
code: source,
|
|
@@ -1682,7 +2102,8 @@ function transformOxc(source, filename, options) {
|
|
|
1682
2102
|
classes,
|
|
1683
2103
|
rawClassNames,
|
|
1684
2104
|
diagnostics,
|
|
1685
|
-
recoveryTokens
|
|
2105
|
+
recoveryTokens,
|
|
2106
|
+
cssVariableMap
|
|
1686
2107
|
};
|
|
1687
2108
|
}
|
|
1688
2109
|
const effectiveFilename = filename ?? "file.tsx";
|
|
@@ -1697,6 +2118,18 @@ function transformOxc(source, filename, options) {
|
|
|
1697
2118
|
const edits = new MagicString__default(source);
|
|
1698
2119
|
const objectBindings = collectObjectBindings(parsed.program);
|
|
1699
2120
|
const conditionalBindings = collectConditionalBindings(parsed.program);
|
|
2121
|
+
const reservedCSSVariableNames = options?.mangleVars ? collectStaticStyleCustomPropertyNames(parsed.program) : void 0;
|
|
2122
|
+
const componentHoists = options?.mangleVars ? planOxcComponentVariableHoists(
|
|
2123
|
+
parsed.program,
|
|
2124
|
+
effectiveFilename,
|
|
2125
|
+
objectBindings,
|
|
2126
|
+
source,
|
|
2127
|
+
options.mangleVarHoistMaxDepth,
|
|
2128
|
+
reservedCSSVariableNames
|
|
2129
|
+
) : null;
|
|
2130
|
+
if (componentHoists) {
|
|
2131
|
+
diagnostics.push(...componentHoists.diagnostics);
|
|
2132
|
+
}
|
|
1700
2133
|
let transformed = false;
|
|
1701
2134
|
let usesRuntime = false;
|
|
1702
2135
|
let usesMerge = false;
|
|
@@ -1722,6 +2155,24 @@ function transformOxc(source, filename, options) {
|
|
|
1722
2155
|
let szRecoverAttr = null;
|
|
1723
2156
|
let alreadyTagged = false;
|
|
1724
2157
|
let lastAttr = null;
|
|
2158
|
+
let appliedHoistedStyleProps = false;
|
|
2159
|
+
const elementId = elementIdForOpening(openingNode);
|
|
2160
|
+
const hoistedStyleProps = componentHoists?.stylePropsByTarget.get(elementId) ?? [];
|
|
2161
|
+
const applyHoistedStyleProps = () => {
|
|
2162
|
+
if (appliedHoistedStyleProps || hoistedStyleProps.length === 0) {
|
|
2163
|
+
return;
|
|
2164
|
+
}
|
|
2165
|
+
applyStyleProps(
|
|
2166
|
+
edits,
|
|
2167
|
+
source,
|
|
2168
|
+
styleAttr,
|
|
2169
|
+
lastAttr,
|
|
2170
|
+
hoistedStyleProps,
|
|
2171
|
+
openingNode.name.end
|
|
2172
|
+
);
|
|
2173
|
+
appliedHoistedStyleProps = true;
|
|
2174
|
+
transformed = true;
|
|
2175
|
+
};
|
|
1725
2176
|
for (const attrRaw of attrs) {
|
|
1726
2177
|
if (attrRaw.type !== "JSXAttribute") {
|
|
1727
2178
|
continue;
|
|
@@ -1782,6 +2233,7 @@ function transformOxc(source, filename, options) {
|
|
|
1782
2233
|
}
|
|
1783
2234
|
}
|
|
1784
2235
|
if (szAttrs.length === 0) {
|
|
2236
|
+
applyHoistedStyleProps();
|
|
1785
2237
|
return;
|
|
1786
2238
|
}
|
|
1787
2239
|
const szDerived = [];
|
|
@@ -1818,7 +2270,9 @@ function transformOxc(source, filename, options) {
|
|
|
1818
2270
|
effectiveFilename,
|
|
1819
2271
|
objectBindings,
|
|
1820
2272
|
source,
|
|
1821
|
-
classes
|
|
2273
|
+
classes,
|
|
2274
|
+
globalVarAliases,
|
|
2275
|
+
cssVariableMap
|
|
1822
2276
|
);
|
|
1823
2277
|
if (conditionalClassExpr) {
|
|
1824
2278
|
if (classNameAttr || szAttrs.length > 1) {
|
|
@@ -1840,7 +2294,11 @@ function transformOxc(source, filename, options) {
|
|
|
1840
2294
|
const bound = objectBindings.get(identifierName);
|
|
1841
2295
|
if (bound) {
|
|
1842
2296
|
const result2 = transformCore.transform(
|
|
1843
|
-
|
|
2297
|
+
applyGlobalVarAliasesToSzObject(
|
|
2298
|
+
astObjectToSzObject(bound, effectiveFilename, objectBindings),
|
|
2299
|
+
globalVarAliases,
|
|
2300
|
+
cssVariableMap
|
|
2301
|
+
)
|
|
1844
2302
|
);
|
|
1845
2303
|
for (const c of result2.className.split(/\s+/)) {
|
|
1846
2304
|
if (c) {
|
|
@@ -1857,7 +2315,9 @@ function transformOxc(source, filename, options) {
|
|
|
1857
2315
|
effectiveFilename,
|
|
1858
2316
|
objectBindings,
|
|
1859
2317
|
source,
|
|
1860
|
-
classes
|
|
2318
|
+
classes,
|
|
2319
|
+
globalVarAliases,
|
|
2320
|
+
cssVariableMap
|
|
1861
2321
|
);
|
|
1862
2322
|
if (conditionalClassExpr) {
|
|
1863
2323
|
if (classNameAttr || szAttrs.length > 1) {
|
|
@@ -1879,7 +2339,9 @@ function transformOxc(source, filename, options) {
|
|
|
1879
2339
|
const arrayClasses = astArrayToStaticClasses(
|
|
1880
2340
|
expression,
|
|
1881
2341
|
effectiveFilename,
|
|
1882
|
-
objectBindings
|
|
2342
|
+
objectBindings,
|
|
2343
|
+
globalVarAliases,
|
|
2344
|
+
cssVariableMap
|
|
1883
2345
|
);
|
|
1884
2346
|
if (arrayClasses === null) {
|
|
1885
2347
|
collectArrayCandidateClasses(
|
|
@@ -1917,7 +2379,9 @@ function transformOxc(source, filename, options) {
|
|
|
1917
2379
|
effectiveFilename,
|
|
1918
2380
|
objectBindings,
|
|
1919
2381
|
source,
|
|
1920
|
-
classes
|
|
2382
|
+
classes,
|
|
2383
|
+
globalVarAliases,
|
|
2384
|
+
cssVariableMap
|
|
1921
2385
|
);
|
|
1922
2386
|
if (conditionalSpreadClassExpr) {
|
|
1923
2387
|
if (classNameAttr || szAttrs.length > 1) {
|
|
@@ -1937,9 +2401,15 @@ function transformOxc(source, filename, options) {
|
|
|
1937
2401
|
expression,
|
|
1938
2402
|
effectiveFilename,
|
|
1939
2403
|
objectBindings,
|
|
1940
|
-
source
|
|
2404
|
+
source,
|
|
2405
|
+
options,
|
|
2406
|
+
componentHoists?.usageNamesByElement.get(elementId),
|
|
2407
|
+
cssVariableMap,
|
|
2408
|
+
reservedCSSVariableNames,
|
|
2409
|
+
globalVarAliases
|
|
1941
2410
|
);
|
|
1942
2411
|
if (partial && szAttrs.length === 1) {
|
|
2412
|
+
const mergedStyleProps = hoistedStyleProps.length > 0 ? [...hoistedStyleProps, ...partial.styleProps] : partial.styleProps;
|
|
1943
2413
|
if (classNameAttr?.value?.type === "JSXExpressionContainer") {
|
|
1944
2414
|
const classExpression = classNameAttr.value.expression;
|
|
1945
2415
|
const classExpressionSource = source.slice(
|
|
@@ -1952,7 +2422,15 @@ function transformOxc(source, filename, options) {
|
|
|
1952
2422
|
`className={_szMerge(${classExpressionSource}, ${JSON.stringify(partial.className)})}`
|
|
1953
2423
|
);
|
|
1954
2424
|
edits.remove(whitespaceStart(source, szAttr.start), szAttr.end);
|
|
1955
|
-
applyStyleProps(
|
|
2425
|
+
applyStyleProps(
|
|
2426
|
+
edits,
|
|
2427
|
+
source,
|
|
2428
|
+
styleAttr,
|
|
2429
|
+
lastAttr,
|
|
2430
|
+
mergedStyleProps,
|
|
2431
|
+
openingNode.name.end
|
|
2432
|
+
);
|
|
2433
|
+
appliedHoistedStyleProps = true;
|
|
1956
2434
|
for (const c of partial.className.split(/\s+/)) {
|
|
1957
2435
|
if (c) {
|
|
1958
2436
|
classes.add(c);
|
|
@@ -1976,7 +2454,15 @@ function transformOxc(source, filename, options) {
|
|
|
1976
2454
|
} else {
|
|
1977
2455
|
edits.overwrite(szAttr.start, szAttr.end, partial.classNameAttr);
|
|
1978
2456
|
}
|
|
1979
|
-
applyStyleProps(
|
|
2457
|
+
applyStyleProps(
|
|
2458
|
+
edits,
|
|
2459
|
+
source,
|
|
2460
|
+
styleAttr,
|
|
2461
|
+
lastAttr,
|
|
2462
|
+
mergedStyleProps,
|
|
2463
|
+
openingNode.name.end
|
|
2464
|
+
);
|
|
2465
|
+
appliedHoistedStyleProps = true;
|
|
1980
2466
|
for (const c of partial.className.split(/\s+/)) {
|
|
1981
2467
|
if (c) {
|
|
1982
2468
|
classes.add(c);
|
|
@@ -1992,7 +2478,9 @@ function transformOxc(source, filename, options) {
|
|
|
1992
2478
|
}
|
|
1993
2479
|
throw err;
|
|
1994
2480
|
}
|
|
1995
|
-
const result = transformCore.transform(
|
|
2481
|
+
const result = transformCore.transform(
|
|
2482
|
+
applyGlobalVarAliasesToSzObject(szObj, globalVarAliases, cssVariableMap)
|
|
2483
|
+
);
|
|
1996
2484
|
for (const c of result.className.split(/\s+/)) {
|
|
1997
2485
|
if (c) {
|
|
1998
2486
|
szDerived.push(c);
|
|
@@ -2025,6 +2513,7 @@ function transformOxc(source, filename, options) {
|
|
|
2025
2513
|
transformed = true;
|
|
2026
2514
|
return;
|
|
2027
2515
|
}
|
|
2516
|
+
applyHoistedStyleProps();
|
|
2028
2517
|
const existingRaw = classNameAttr ? stringLiteralValue(classNameAttr.value) : null;
|
|
2029
2518
|
const mergedClasses = [
|
|
2030
2519
|
...existingRaw ? existingRaw.split(/\s+/).filter(Boolean) : [],
|
|
@@ -2059,7 +2548,8 @@ function transformOxc(source, filename, options) {
|
|
|
2059
2548
|
classes,
|
|
2060
2549
|
rawClassNames,
|
|
2061
2550
|
diagnostics,
|
|
2062
|
-
recoveryTokens
|
|
2551
|
+
recoveryTokens,
|
|
2552
|
+
cssVariableMap
|
|
2063
2553
|
};
|
|
2064
2554
|
}
|
|
2065
2555
|
function stringLiteralValue(value) {
|
|
@@ -2168,7 +2658,7 @@ function astObjectToSzObject(node, filename, bindings) {
|
|
|
2168
2658
|
}
|
|
2169
2659
|
return result;
|
|
2170
2660
|
}
|
|
2171
|
-
function astArrayToStaticClasses(node, filename, bindings) {
|
|
2661
|
+
function astArrayToStaticClasses(node, filename, bindings, globalVarAliases, cssVariableMap) {
|
|
2172
2662
|
const out = [];
|
|
2173
2663
|
for (const element of node.elements) {
|
|
2174
2664
|
if (!element || isFalsyLiteral(element)) {
|
|
@@ -2185,7 +2675,13 @@ function astArrayToStaticClasses(node, filename, bindings) {
|
|
|
2185
2675
|
}
|
|
2186
2676
|
let result;
|
|
2187
2677
|
try {
|
|
2188
|
-
result = transformCore.transform(
|
|
2678
|
+
result = transformCore.transform(
|
|
2679
|
+
applyGlobalVarAliasesToSzObject(
|
|
2680
|
+
astObjectToSzObject(objectNode, filename, bindings),
|
|
2681
|
+
globalVarAliases,
|
|
2682
|
+
cssVariableMap
|
|
2683
|
+
)
|
|
2684
|
+
);
|
|
2189
2685
|
} catch (err) {
|
|
2190
2686
|
if (err instanceof OxcNotImplementedError) {
|
|
2191
2687
|
return null;
|
|
@@ -2282,7 +2778,7 @@ function resolveObjectExpression(node, bindings) {
|
|
|
2282
2778
|
}
|
|
2283
2779
|
return null;
|
|
2284
2780
|
}
|
|
2285
|
-
function buildConditionalSpreadClassExpression(node, filename, bindings, source, classes) {
|
|
2781
|
+
function buildConditionalSpreadClassExpression(node, filename, bindings, source, classes, globalVarAliases, cssVariableMap) {
|
|
2286
2782
|
let conditionalSpread = null;
|
|
2287
2783
|
const otherProps = [];
|
|
2288
2784
|
for (const prop of node.properties) {
|
|
@@ -2305,14 +2801,18 @@ function buildConditionalSpreadClassExpression(node, filename, bindings, source,
|
|
|
2305
2801
|
otherProps,
|
|
2306
2802
|
node,
|
|
2307
2803
|
filename,
|
|
2308
|
-
bindings
|
|
2804
|
+
bindings,
|
|
2805
|
+
globalVarAliases,
|
|
2806
|
+
cssVariableMap
|
|
2309
2807
|
);
|
|
2310
2808
|
const alternate = compileConditionalSpreadBranch(
|
|
2311
2809
|
conditionalSpread.alternate,
|
|
2312
2810
|
otherProps,
|
|
2313
2811
|
node,
|
|
2314
2812
|
filename,
|
|
2315
|
-
bindings
|
|
2813
|
+
bindings,
|
|
2814
|
+
globalVarAliases,
|
|
2815
|
+
cssVariableMap
|
|
2316
2816
|
);
|
|
2317
2817
|
if (consequent === null || alternate === null) {
|
|
2318
2818
|
return null;
|
|
@@ -2325,7 +2825,7 @@ function buildConditionalSpreadClassExpression(node, filename, bindings, source,
|
|
|
2325
2825
|
const testSource = source.slice(conditionalSpread.test.start, conditionalSpread.test.end);
|
|
2326
2826
|
return `${testSource} ? ${JSON.stringify(consequent)} : ${JSON.stringify(alternate)}`;
|
|
2327
2827
|
}
|
|
2328
|
-
function compileConditionalSpreadBranch(branch, otherProps, sourceNode, filename, bindings) {
|
|
2828
|
+
function compileConditionalSpreadBranch(branch, otherProps, sourceNode, filename, bindings, globalVarAliases, cssVariableMap) {
|
|
2329
2829
|
const branchObject = resolveObjectExpression(branch, bindings);
|
|
2330
2830
|
if (!branchObject) {
|
|
2331
2831
|
return null;
|
|
@@ -2337,7 +2837,13 @@ function compileConditionalSpreadBranch(branch, otherProps, sourceNode, filename
|
|
|
2337
2837
|
filename,
|
|
2338
2838
|
bindings
|
|
2339
2839
|
);
|
|
2340
|
-
return transformCore.transform(
|
|
2840
|
+
return transformCore.transform(
|
|
2841
|
+
applyGlobalVarAliasesToSzObject(
|
|
2842
|
+
{ ...branchValue, ...overrides },
|
|
2843
|
+
globalVarAliases,
|
|
2844
|
+
cssVariableMap
|
|
2845
|
+
)
|
|
2846
|
+
).className;
|
|
2341
2847
|
} catch (err) {
|
|
2342
2848
|
if (err instanceof OxcNotImplementedError) {
|
|
2343
2849
|
return null;
|
|
@@ -2345,8 +2851,15 @@ function compileConditionalSpreadBranch(branch, otherProps, sourceNode, filename
|
|
|
2345
2851
|
throw err;
|
|
2346
2852
|
}
|
|
2347
2853
|
}
|
|
2348
|
-
function buildPartialObjectTransform(node, filename, bindings, source) {
|
|
2349
|
-
const partial = evaluatePartialObject(
|
|
2854
|
+
function buildPartialObjectTransform(node, filename, bindings, source, options, hoistedNames, cssVariableMap, reservedNames, globalVarAliases = /* @__PURE__ */ new Map()) {
|
|
2855
|
+
const partial = evaluatePartialObject(
|
|
2856
|
+
node,
|
|
2857
|
+
filename,
|
|
2858
|
+
bindings,
|
|
2859
|
+
source,
|
|
2860
|
+
globalVarAliases,
|
|
2861
|
+
cssVariableMap
|
|
2862
|
+
);
|
|
2350
2863
|
if (!partial || partial.dynamicProps.size === 0 && partial.conditionalClasses.length === 0) {
|
|
2351
2864
|
return null;
|
|
2352
2865
|
}
|
|
@@ -2355,11 +2868,17 @@ function buildPartialObjectTransform(node, filename, bindings, source) {
|
|
|
2355
2868
|
}
|
|
2356
2869
|
const classParts = [];
|
|
2357
2870
|
if (Object.keys(partial.staticProps).length > 0) {
|
|
2358
|
-
const { className: className2 } = transformCore.transform(
|
|
2871
|
+
const { className: className2 } = transformCore.transform(
|
|
2872
|
+
applyGlobalVarAliasesToSzObject(partial.staticProps, globalVarAliases, cssVariableMap)
|
|
2873
|
+
);
|
|
2359
2874
|
if (className2) {
|
|
2360
2875
|
classParts.push(className2);
|
|
2361
2876
|
}
|
|
2362
2877
|
}
|
|
2878
|
+
if (options?.mangleVars) {
|
|
2879
|
+
applyHoistedVariableNames(partial, hoistedNames, cssVariableMap);
|
|
2880
|
+
applyScopedVariablePlan(partial, hoistedNames, cssVariableMap, reservedNames);
|
|
2881
|
+
}
|
|
2363
2882
|
for (const [, info] of partial.dynamicProps) {
|
|
2364
2883
|
classParts.push(buildCSSVarClassName(info));
|
|
2365
2884
|
}
|
|
@@ -2368,12 +2887,351 @@ function buildPartialObjectTransform(node, filename, bindings, source) {
|
|
|
2368
2887
|
}
|
|
2369
2888
|
const className = classParts.filter(Boolean).join(" ");
|
|
2370
2889
|
const classNameAttr = partial.conditionalClasses.length > 0 ? `className={${buildConditionalClassSource(classParts, partial.conditionalClasses, source)}}` : `className="${className}"`;
|
|
2371
|
-
const styleProps = [...partial.dynamicProps.
|
|
2372
|
-
(info) => `${JSON.stringify(info.varName)}: ${generateStyleValueSource(info, source)}`
|
|
2890
|
+
const styleProps = [...partial.dynamicProps.entries()].filter(([id]) => !hoistedNames?.has(id)).map(
|
|
2891
|
+
([, info]) => `${JSON.stringify(info.varName)}: ${generateStyleValueSource(info, source)}`
|
|
2373
2892
|
);
|
|
2374
2893
|
return { className, classNameAttr, styleProps, usesColorVar: partial.usesColorVar };
|
|
2375
2894
|
}
|
|
2376
|
-
function
|
|
2895
|
+
function applyHoistedVariableNames(partial, hoistedNames, cssVariableMap) {
|
|
2896
|
+
if (!hoistedNames) {
|
|
2897
|
+
return;
|
|
2898
|
+
}
|
|
2899
|
+
for (const [id, name] of hoistedNames) {
|
|
2900
|
+
const info = partial.dynamicProps.get(id);
|
|
2901
|
+
if (info) {
|
|
2902
|
+
addCssVariableMapping(cssVariableMap, info.varName, name);
|
|
2903
|
+
info.varName = name;
|
|
2904
|
+
}
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
function applyScopedVariablePlan(partial, hoistedNames, cssVariableMap, reservedNames) {
|
|
2908
|
+
const entries = [...partial.dynamicProps.entries()].filter(([id]) => !hoistedNames?.has(id));
|
|
2909
|
+
const plan = planCSSVariableNames(
|
|
2910
|
+
entries.map(([id]) => ({
|
|
2911
|
+
id,
|
|
2912
|
+
tier: "scoped",
|
|
2913
|
+
elementId: "self",
|
|
2914
|
+
propertyKey: id
|
|
2915
|
+
})),
|
|
2916
|
+
{ reservedNames }
|
|
2917
|
+
);
|
|
2918
|
+
for (const planned of plan) {
|
|
2919
|
+
const info = partial.dynamicProps.get(planned.id);
|
|
2920
|
+
if (info) {
|
|
2921
|
+
addCssVariableMapping(cssVariableMap, info.varName, planned.name);
|
|
2922
|
+
info.varName = planned.name;
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2925
|
+
}
|
|
2926
|
+
function addCssVariableMapping(cssVariableMap, original, mangled) {
|
|
2927
|
+
if (!cssVariableMap) {
|
|
2928
|
+
return;
|
|
2929
|
+
}
|
|
2930
|
+
const existing = cssVariableMap.get(original);
|
|
2931
|
+
if (!existing) {
|
|
2932
|
+
cssVariableMap.set(original, mangled);
|
|
2933
|
+
return;
|
|
2934
|
+
}
|
|
2935
|
+
const values = Array.isArray(existing) ? existing : [existing];
|
|
2936
|
+
if (!values.includes(mangled)) {
|
|
2937
|
+
cssVariableMap.set(original, [...values, mangled]);
|
|
2938
|
+
}
|
|
2939
|
+
}
|
|
2940
|
+
function normalizeGlobalVarAliases$1(input) {
|
|
2941
|
+
if (!input) {
|
|
2942
|
+
return /* @__PURE__ */ new Map();
|
|
2943
|
+
}
|
|
2944
|
+
const entries = input instanceof Map ? input.entries() : Array.isArray(input) ? input : Object.entries(input);
|
|
2945
|
+
const aliases = /* @__PURE__ */ new Map();
|
|
2946
|
+
for (const [original, alias] of entries) {
|
|
2947
|
+
if (original.startsWith("--") && alias.startsWith("--")) {
|
|
2948
|
+
aliases.set(original, alias);
|
|
2949
|
+
}
|
|
2950
|
+
}
|
|
2951
|
+
return aliases;
|
|
2952
|
+
}
|
|
2953
|
+
function applyGlobalVarAliasesToSzObject(object, globalVarAliases, cssVariableMap) {
|
|
2954
|
+
if (globalVarAliases.size === 0) {
|
|
2955
|
+
return object;
|
|
2956
|
+
}
|
|
2957
|
+
const rewritten = {};
|
|
2958
|
+
for (const [key, value] of Object.entries(object)) {
|
|
2959
|
+
rewritten[key] = applyGlobalVarAliasesToSzValue(value, globalVarAliases, cssVariableMap);
|
|
2960
|
+
}
|
|
2961
|
+
return rewritten;
|
|
2962
|
+
}
|
|
2963
|
+
function applyGlobalVarAliasesToSzValue(value, globalVarAliases, cssVariableMap) {
|
|
2964
|
+
if (typeof value === "string") {
|
|
2965
|
+
const alias = globalVarAliases.get(value);
|
|
2966
|
+
if (alias) {
|
|
2967
|
+
addCssVariableMapping(cssVariableMap, value, alias);
|
|
2968
|
+
return alias;
|
|
2969
|
+
}
|
|
2970
|
+
return value;
|
|
2971
|
+
}
|
|
2972
|
+
if (typeof value === "object") {
|
|
2973
|
+
return applyGlobalVarAliasesToSzObject(value, globalVarAliases, cssVariableMap);
|
|
2974
|
+
}
|
|
2975
|
+
return value;
|
|
2976
|
+
}
|
|
2977
|
+
function planOxcComponentVariableHoists(root, filename, bindings, source, maxDepth, reservedNames) {
|
|
2978
|
+
const nodes = [];
|
|
2979
|
+
const candidates = [];
|
|
2980
|
+
collectOxcHoistCandidates(root, null, nodes, candidates, filename, bindings, source);
|
|
2981
|
+
if (candidates.length < 2) {
|
|
2982
|
+
return {
|
|
2983
|
+
stylePropsByTarget: /* @__PURE__ */ new Map(),
|
|
2984
|
+
usageNamesByElement: /* @__PURE__ */ new Map(),
|
|
2985
|
+
diagnostics: []
|
|
2986
|
+
};
|
|
2987
|
+
}
|
|
2988
|
+
const plannedNames = planCSSVariableNames(
|
|
2989
|
+
candidates.map((candidate) => ({
|
|
2990
|
+
id: candidate.id,
|
|
2991
|
+
tier: "component",
|
|
2992
|
+
elementId: candidate.elementId,
|
|
2993
|
+
propertyKey: candidate.propertyKey,
|
|
2994
|
+
variantChain: candidate.variantChain || void 0
|
|
2995
|
+
})),
|
|
2996
|
+
{ reservedNames }
|
|
2997
|
+
);
|
|
2998
|
+
const nameByUsage = new Map(plannedNames.map((entry) => [entry.id, entry.name]));
|
|
2999
|
+
const candidateById = new Map(candidates.map((candidate) => [candidate.id, candidate]));
|
|
3000
|
+
const hoistUsages = candidates.map((candidate) => ({
|
|
3001
|
+
id: candidate.id,
|
|
3002
|
+
elementId: candidate.elementId,
|
|
3003
|
+
name: nameByUsage.get(candidate.id) ?? candidate.info.varName,
|
|
3004
|
+
valueKey: candidate.valueKey
|
|
3005
|
+
}));
|
|
3006
|
+
const analysis = planComponentVariableHoistsWithDiagnostics(nodes, hoistUsages, {
|
|
3007
|
+
maxDepth
|
|
3008
|
+
});
|
|
3009
|
+
const plans = analysis.plans;
|
|
3010
|
+
const stylePropsByTarget = /* @__PURE__ */ new Map();
|
|
3011
|
+
const usageNamesByElement = /* @__PURE__ */ new Map();
|
|
3012
|
+
for (const plan of plans) {
|
|
3013
|
+
const [firstUsageId] = plan.usageIds;
|
|
3014
|
+
const firstCandidate = firstUsageId ? candidateById.get(firstUsageId) : void 0;
|
|
3015
|
+
if (!firstCandidate) {
|
|
3016
|
+
continue;
|
|
3017
|
+
}
|
|
3018
|
+
appendMapArray(
|
|
3019
|
+
stylePropsByTarget,
|
|
3020
|
+
plan.targetElementId,
|
|
3021
|
+
`${JSON.stringify(plan.name)}: ${firstCandidate.valueSource}`
|
|
3022
|
+
);
|
|
3023
|
+
for (const usageId of plan.usageIds) {
|
|
3024
|
+
const candidate = candidateById.get(usageId);
|
|
3025
|
+
if (!candidate) {
|
|
3026
|
+
continue;
|
|
3027
|
+
}
|
|
3028
|
+
getOrCreateMap(usageNamesByElement, candidate.elementId).set(
|
|
3029
|
+
candidate.dynamicKey,
|
|
3030
|
+
plan.name
|
|
3031
|
+
);
|
|
3032
|
+
}
|
|
3033
|
+
}
|
|
3034
|
+
return {
|
|
3035
|
+
stylePropsByTarget,
|
|
3036
|
+
usageNamesByElement,
|
|
3037
|
+
diagnostics: analysis.diagnostics.map(formatHoistSkipDiagnostic)
|
|
3038
|
+
};
|
|
3039
|
+
}
|
|
3040
|
+
function formatHoistSkipDiagnostic(diagnostic) {
|
|
3041
|
+
const suffix = diagnostic.reason === "max-depth" && diagnostic.maxDepth !== void 0 ? ` (maxDepth ${diagnostic.maxDepth})` : "";
|
|
3042
|
+
return `[csszyx] mangleVars skipped component CSS variable hoist for ${diagnostic.name} across ${diagnostic.usageCount} usages: ${diagnostic.reason}${suffix}`;
|
|
3043
|
+
}
|
|
3044
|
+
function collectOxcHoistCandidates(node, parentElementId, nodes, candidates, filename, bindings, source) {
|
|
3045
|
+
if (node.type === "JSXElement") {
|
|
3046
|
+
const element = node;
|
|
3047
|
+
const opening = element.openingElement;
|
|
3048
|
+
const elementId = elementIdForOpening(opening);
|
|
3049
|
+
nodes.push({
|
|
3050
|
+
id: elementId,
|
|
3051
|
+
parentId: parentElementId,
|
|
3052
|
+
canHost: canHostHoistedStyleProps(opening)
|
|
3053
|
+
});
|
|
3054
|
+
collectOpeningHoistCandidates(opening, elementId, candidates, filename, bindings, source);
|
|
3055
|
+
for (const child of element.children) {
|
|
3056
|
+
collectOxcHoistCandidates(
|
|
3057
|
+
child,
|
|
3058
|
+
elementId,
|
|
3059
|
+
nodes,
|
|
3060
|
+
candidates,
|
|
3061
|
+
filename,
|
|
3062
|
+
bindings,
|
|
3063
|
+
source
|
|
3064
|
+
);
|
|
3065
|
+
}
|
|
3066
|
+
return;
|
|
3067
|
+
}
|
|
3068
|
+
if (node.type === "JSXFragment") {
|
|
3069
|
+
const fragment = node;
|
|
3070
|
+
const elementId = `f${node.start}`;
|
|
3071
|
+
nodes.push({ id: elementId, parentId: parentElementId, canHost: false });
|
|
3072
|
+
for (const child of fragment.children) {
|
|
3073
|
+
collectOxcHoistCandidates(
|
|
3074
|
+
child,
|
|
3075
|
+
elementId,
|
|
3076
|
+
nodes,
|
|
3077
|
+
candidates,
|
|
3078
|
+
filename,
|
|
3079
|
+
bindings,
|
|
3080
|
+
source
|
|
3081
|
+
);
|
|
3082
|
+
}
|
|
3083
|
+
return;
|
|
3084
|
+
}
|
|
3085
|
+
for (const key of Object.keys(node)) {
|
|
3086
|
+
if (isAstMetadataKey(key)) {
|
|
3087
|
+
continue;
|
|
3088
|
+
}
|
|
3089
|
+
const child = node[key];
|
|
3090
|
+
if (Array.isArray(child)) {
|
|
3091
|
+
for (const item of child) {
|
|
3092
|
+
if (isOxcNode(item)) {
|
|
3093
|
+
collectOxcHoistCandidates(
|
|
3094
|
+
item,
|
|
3095
|
+
parentElementId,
|
|
3096
|
+
nodes,
|
|
3097
|
+
candidates,
|
|
3098
|
+
filename,
|
|
3099
|
+
bindings,
|
|
3100
|
+
source
|
|
3101
|
+
);
|
|
3102
|
+
}
|
|
3103
|
+
}
|
|
3104
|
+
} else if (isOxcNode(child)) {
|
|
3105
|
+
collectOxcHoistCandidates(
|
|
3106
|
+
child,
|
|
3107
|
+
parentElementId,
|
|
3108
|
+
nodes,
|
|
3109
|
+
candidates,
|
|
3110
|
+
filename,
|
|
3111
|
+
bindings,
|
|
3112
|
+
source
|
|
3113
|
+
);
|
|
3114
|
+
}
|
|
3115
|
+
}
|
|
3116
|
+
}
|
|
3117
|
+
function collectOpeningHoistCandidates(opening, elementId, candidates, filename, bindings, source) {
|
|
3118
|
+
for (const attrRaw of opening.attributes ?? []) {
|
|
3119
|
+
if (attrRaw.type !== "JSXAttribute") {
|
|
3120
|
+
continue;
|
|
3121
|
+
}
|
|
3122
|
+
const attr = attrRaw;
|
|
3123
|
+
if (attr.name?.name !== "sz" || attr.value?.type !== "JSXExpressionContainer") {
|
|
3124
|
+
continue;
|
|
3125
|
+
}
|
|
3126
|
+
const expression = attr.value.expression;
|
|
3127
|
+
if (expression.type !== "ObjectExpression") {
|
|
3128
|
+
continue;
|
|
3129
|
+
}
|
|
3130
|
+
const partial = evaluatePartialObject(
|
|
3131
|
+
expression,
|
|
3132
|
+
filename,
|
|
3133
|
+
bindings,
|
|
3134
|
+
source,
|
|
3135
|
+
/* @__PURE__ */ new Map(),
|
|
3136
|
+
void 0
|
|
3137
|
+
);
|
|
3138
|
+
if (!partial || partial.conditionalClasses.length > 0) {
|
|
3139
|
+
continue;
|
|
3140
|
+
}
|
|
3141
|
+
for (const [dynamicKey, info] of partial.dynamicProps) {
|
|
3142
|
+
candidates.push({
|
|
3143
|
+
id: `${elementId}:${dynamicKey}`,
|
|
3144
|
+
elementId,
|
|
3145
|
+
dynamicKey,
|
|
3146
|
+
propertyKey: dynamicKey,
|
|
3147
|
+
variantChain: info.variantChain,
|
|
3148
|
+
valueSource: generateStyleValueSource(info, source),
|
|
3149
|
+
valueKey: buildDynamicValueKey(info, source),
|
|
3150
|
+
info
|
|
3151
|
+
});
|
|
3152
|
+
}
|
|
3153
|
+
}
|
|
3154
|
+
}
|
|
3155
|
+
function elementIdForOpening(opening) {
|
|
3156
|
+
return `e${opening.start}`;
|
|
3157
|
+
}
|
|
3158
|
+
function canHostHoistedStyleProps(opening) {
|
|
3159
|
+
if (!isDomJsxOpening(opening)) {
|
|
3160
|
+
return false;
|
|
3161
|
+
}
|
|
3162
|
+
const styleAttr = findJsxAttribute(opening, "style");
|
|
3163
|
+
return !styleAttr || styleAttr.value?.type === "JSXExpressionContainer";
|
|
3164
|
+
}
|
|
3165
|
+
function isDomJsxOpening(opening) {
|
|
3166
|
+
if (opening.name.type !== "JSXIdentifier") {
|
|
3167
|
+
return false;
|
|
3168
|
+
}
|
|
3169
|
+
const name = String(opening.name.name);
|
|
3170
|
+
return name.length > 0 && name.charAt(0) === name.charAt(0).toLowerCase();
|
|
3171
|
+
}
|
|
3172
|
+
function findJsxAttribute(opening, name) {
|
|
3173
|
+
for (const attrRaw of opening.attributes ?? []) {
|
|
3174
|
+
if (attrRaw.type === "JSXAttribute") {
|
|
3175
|
+
const attr = attrRaw;
|
|
3176
|
+
if (attr.name?.name === name) {
|
|
3177
|
+
return attr;
|
|
3178
|
+
}
|
|
3179
|
+
}
|
|
3180
|
+
}
|
|
3181
|
+
return null;
|
|
3182
|
+
}
|
|
3183
|
+
function collectStaticStyleCustomPropertyNames(node) {
|
|
3184
|
+
const names = /* @__PURE__ */ new Set();
|
|
3185
|
+
walk(node, (child) => {
|
|
3186
|
+
if (child.type !== "JSXOpeningElement") {
|
|
3187
|
+
return;
|
|
3188
|
+
}
|
|
3189
|
+
const styleAttr = findJsxAttribute(child, "style");
|
|
3190
|
+
if (styleAttr?.value?.type !== "JSXExpressionContainer") {
|
|
3191
|
+
return;
|
|
3192
|
+
}
|
|
3193
|
+
const expression = styleAttr.value.expression;
|
|
3194
|
+
if (expression.type !== "ObjectExpression") {
|
|
3195
|
+
return;
|
|
3196
|
+
}
|
|
3197
|
+
for (const propRaw of expression.properties ?? []) {
|
|
3198
|
+
if (propRaw.type !== "Property") {
|
|
3199
|
+
continue;
|
|
3200
|
+
}
|
|
3201
|
+
const key = propRaw.key;
|
|
3202
|
+
const name = literalStringValue(key);
|
|
3203
|
+
if (name?.startsWith("--")) {
|
|
3204
|
+
names.add(name);
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
});
|
|
3208
|
+
return names;
|
|
3209
|
+
}
|
|
3210
|
+
function literalStringValue(node) {
|
|
3211
|
+
if (node.type !== "Literal") {
|
|
3212
|
+
return null;
|
|
3213
|
+
}
|
|
3214
|
+
const value = node.value;
|
|
3215
|
+
return typeof value === "string" ? value : null;
|
|
3216
|
+
}
|
|
3217
|
+
function appendMapArray(map, key, value) {
|
|
3218
|
+
const existing = map.get(key);
|
|
3219
|
+
if (existing) {
|
|
3220
|
+
existing.push(value);
|
|
3221
|
+
} else {
|
|
3222
|
+
map.set(key, [value]);
|
|
3223
|
+
}
|
|
3224
|
+
}
|
|
3225
|
+
function getOrCreateMap(map, key) {
|
|
3226
|
+
const existing = map.get(key);
|
|
3227
|
+
if (existing) {
|
|
3228
|
+
return existing;
|
|
3229
|
+
}
|
|
3230
|
+
const value = /* @__PURE__ */ new Map();
|
|
3231
|
+
map.set(key, value);
|
|
3232
|
+
return value;
|
|
3233
|
+
}
|
|
3234
|
+
function evaluatePartialObject(node, filename, bindings, source, globalVarAliases, cssVariableMap, variantChain = "") {
|
|
2377
3235
|
const staticProps = {};
|
|
2378
3236
|
const dynamicProps = /* @__PURE__ */ new Map();
|
|
2379
3237
|
const conditionalClasses = [];
|
|
@@ -2430,6 +3288,8 @@ function evaluatePartialObject(node, filename, bindings, source, variantChain =
|
|
|
2430
3288
|
filename,
|
|
2431
3289
|
bindings,
|
|
2432
3290
|
source,
|
|
3291
|
+
globalVarAliases,
|
|
3292
|
+
cssVariableMap,
|
|
2433
3293
|
nestedVariant
|
|
2434
3294
|
);
|
|
2435
3295
|
if (!nested) {
|
|
@@ -2450,8 +3310,20 @@ function evaluatePartialObject(node, filename, bindings, source, variantChain =
|
|
|
2450
3310
|
const consequent = extractStaticLiteralValue(conditional.consequent);
|
|
2451
3311
|
const alternate = extractStaticLiteralValue(conditional.alternate);
|
|
2452
3312
|
if (consequent !== null && alternate !== null) {
|
|
2453
|
-
const { className: consequentClasses } = transformCore.transform(
|
|
2454
|
-
|
|
3313
|
+
const { className: consequentClasses } = transformCore.transform(
|
|
3314
|
+
applyGlobalVarAliasesToSzObject(
|
|
3315
|
+
{ [key]: consequent },
|
|
3316
|
+
globalVarAliases,
|
|
3317
|
+
cssVariableMap
|
|
3318
|
+
)
|
|
3319
|
+
);
|
|
3320
|
+
const { className: alternateClasses } = transformCore.transform(
|
|
3321
|
+
applyGlobalVarAliasesToSzObject(
|
|
3322
|
+
{ [key]: alternate },
|
|
3323
|
+
globalVarAliases,
|
|
3324
|
+
cssVariableMap
|
|
3325
|
+
)
|
|
3326
|
+
);
|
|
2455
3327
|
conditionalClasses.push({
|
|
2456
3328
|
test: conditional.test,
|
|
2457
3329
|
consequent: prefixVariantClasses(consequentClasses, variantChain),
|
|
@@ -2480,14 +3352,15 @@ function evaluatePartialObject(node, filename, bindings, source, variantChain =
|
|
|
2480
3352
|
}
|
|
2481
3353
|
return { staticProps, dynamicProps, conditionalClasses, usesColorVar };
|
|
2482
3354
|
}
|
|
2483
|
-
function applyStyleProps(edits, source, styleAttr, lastAttr, styleProps) {
|
|
3355
|
+
function applyStyleProps(edits, source, styleAttr, lastAttr, styleProps, fallbackInsertOffset) {
|
|
2484
3356
|
if (styleProps.length === 0) {
|
|
2485
3357
|
return;
|
|
2486
3358
|
}
|
|
2487
3359
|
const propsSource = styleProps.join(", ");
|
|
2488
3360
|
if (!styleAttr) {
|
|
2489
|
-
|
|
2490
|
-
|
|
3361
|
+
const insertOffset = lastAttr?.end ?? fallbackInsertOffset;
|
|
3362
|
+
if (insertOffset !== void 0) {
|
|
3363
|
+
edits.appendRight(insertOffset, ` style={{${propsSource}}}`);
|
|
2491
3364
|
}
|
|
2492
3365
|
return;
|
|
2493
3366
|
}
|
|
@@ -2513,6 +3386,67 @@ function generateStyleValueSource(info, source) {
|
|
|
2513
3386
|
return `\`\${${expressionSource}}\``;
|
|
2514
3387
|
}
|
|
2515
3388
|
}
|
|
3389
|
+
function buildDynamicValueKey(info, source) {
|
|
3390
|
+
const expressionSource = normalizeDynamicExpressionKey(
|
|
3391
|
+
source.slice(info.expression.start, info.expression.end)
|
|
3392
|
+
);
|
|
3393
|
+
switch (info.category) {
|
|
3394
|
+
case transformCore.PropertyCategory.SPACING:
|
|
3395
|
+
return `spacing:${expressionSource}`;
|
|
3396
|
+
case transformCore.PropertyCategory.COLOR:
|
|
3397
|
+
return `color:${expressionSource}`;
|
|
3398
|
+
case transformCore.PropertyCategory.ANGLE:
|
|
3399
|
+
return `angle:${expressionSource}`;
|
|
3400
|
+
case transformCore.PropertyCategory.DURATION:
|
|
3401
|
+
return `duration:${expressionSource}`;
|
|
3402
|
+
default:
|
|
3403
|
+
return `pass:${expressionSource}`;
|
|
3404
|
+
}
|
|
3405
|
+
}
|
|
3406
|
+
function normalizeDynamicExpressionKey(expressionSource) {
|
|
3407
|
+
let normalized = expressionSource.trim();
|
|
3408
|
+
while (hasRedundantOuterParens(normalized)) {
|
|
3409
|
+
normalized = normalized.slice(1, -1).trim();
|
|
3410
|
+
}
|
|
3411
|
+
return normalized;
|
|
3412
|
+
}
|
|
3413
|
+
function hasRedundantOuterParens(expressionSource) {
|
|
3414
|
+
if (!expressionSource.startsWith("(") || !expressionSource.endsWith(")")) {
|
|
3415
|
+
return false;
|
|
3416
|
+
}
|
|
3417
|
+
let depth = 0;
|
|
3418
|
+
let quote = null;
|
|
3419
|
+
let escaped = false;
|
|
3420
|
+
for (let index = 0; index < expressionSource.length; index++) {
|
|
3421
|
+
const char = expressionSource[index];
|
|
3422
|
+
if (quote) {
|
|
3423
|
+
if (escaped) {
|
|
3424
|
+
escaped = false;
|
|
3425
|
+
} else if (char === "\\") {
|
|
3426
|
+
escaped = true;
|
|
3427
|
+
} else if (char === quote) {
|
|
3428
|
+
quote = null;
|
|
3429
|
+
}
|
|
3430
|
+
continue;
|
|
3431
|
+
}
|
|
3432
|
+
if (char === '"' || char === "'" || char === "`") {
|
|
3433
|
+
quote = char;
|
|
3434
|
+
continue;
|
|
3435
|
+
}
|
|
3436
|
+
if (char === "(") {
|
|
3437
|
+
depth++;
|
|
3438
|
+
} else if (char === ")") {
|
|
3439
|
+
depth--;
|
|
3440
|
+
if (depth === 0 && index !== expressionSource.length - 1) {
|
|
3441
|
+
return false;
|
|
3442
|
+
}
|
|
3443
|
+
}
|
|
3444
|
+
if (depth < 0) {
|
|
3445
|
+
return false;
|
|
3446
|
+
}
|
|
3447
|
+
}
|
|
3448
|
+
return depth === 0;
|
|
3449
|
+
}
|
|
2516
3450
|
function buildCSSVarClassName(info) {
|
|
2517
3451
|
const variantPrefix = info.variantChain ? `${transformCore.getVariantPrefix(info.variantChain)}:` : "";
|
|
2518
3452
|
return `${variantPrefix}${info.twPrefix}-(${info.varName})`;
|
|
@@ -2545,9 +3479,21 @@ function prefixVariantClasses(className, variantChain) {
|
|
|
2545
3479
|
function isRuntimeExpression(node) {
|
|
2546
3480
|
return node.type === "Identifier" || node.type === "MemberExpression" || node.type === "CallExpression" || node.type === "ConditionalExpression" || node.type === "TemplateLiteral" || node.type === "BinaryExpression" || node.type === "LogicalExpression";
|
|
2547
3481
|
}
|
|
2548
|
-
function buildStaticConditionalClassExpression(node, filename, bindings, source, classes) {
|
|
2549
|
-
const consequent = resolveStaticClassString(
|
|
2550
|
-
|
|
3482
|
+
function buildStaticConditionalClassExpression(node, filename, bindings, source, classes, globalVarAliases, cssVariableMap) {
|
|
3483
|
+
const consequent = resolveStaticClassString(
|
|
3484
|
+
node.consequent,
|
|
3485
|
+
filename,
|
|
3486
|
+
bindings,
|
|
3487
|
+
globalVarAliases,
|
|
3488
|
+
cssVariableMap
|
|
3489
|
+
);
|
|
3490
|
+
const alternate = resolveStaticClassString(
|
|
3491
|
+
node.alternate,
|
|
3492
|
+
filename,
|
|
3493
|
+
bindings,
|
|
3494
|
+
globalVarAliases,
|
|
3495
|
+
cssVariableMap
|
|
3496
|
+
);
|
|
2551
3497
|
if (consequent === null || alternate === null) {
|
|
2552
3498
|
return null;
|
|
2553
3499
|
}
|
|
@@ -2559,7 +3505,7 @@ function buildStaticConditionalClassExpression(node, filename, bindings, source,
|
|
|
2559
3505
|
const testSource = source.slice(node.test.start, node.test.end);
|
|
2560
3506
|
return `${testSource} ? ${JSON.stringify(consequent)} : ${JSON.stringify(alternate)}`;
|
|
2561
3507
|
}
|
|
2562
|
-
function resolveStaticClassString(node, filename, bindings) {
|
|
3508
|
+
function resolveStaticClassString(node, filename, bindings, globalVarAliases, cssVariableMap) {
|
|
2563
3509
|
const unwrapped = unwrapExpression(node);
|
|
2564
3510
|
let objectNode = null;
|
|
2565
3511
|
if (unwrapped.type === "ObjectExpression") {
|
|
@@ -2571,7 +3517,13 @@ function resolveStaticClassString(node, filename, bindings) {
|
|
|
2571
3517
|
return null;
|
|
2572
3518
|
}
|
|
2573
3519
|
try {
|
|
2574
|
-
return transformCore.transform(
|
|
3520
|
+
return transformCore.transform(
|
|
3521
|
+
applyGlobalVarAliasesToSzObject(
|
|
3522
|
+
astObjectToSzObject(objectNode, filename, bindings),
|
|
3523
|
+
globalVarAliases,
|
|
3524
|
+
cssVariableMap
|
|
3525
|
+
)
|
|
3526
|
+
).className;
|
|
2575
3527
|
} catch (err) {
|
|
2576
3528
|
if (err instanceof OxcNotImplementedError) {
|
|
2577
3529
|
return null;
|
|
@@ -2686,17 +3638,22 @@ function unwrapExpression(node) {
|
|
|
2686
3638
|
}
|
|
2687
3639
|
return current;
|
|
2688
3640
|
}
|
|
3641
|
+
function isOxcNode(value) {
|
|
3642
|
+
return Boolean(
|
|
3643
|
+
value && typeof value === "object" && typeof value.type === "string"
|
|
3644
|
+
);
|
|
3645
|
+
}
|
|
3646
|
+
function isAstMetadataKey(key) {
|
|
3647
|
+
return key === "loc" || key === "range" || key === "start" || key === "end" || key === "type";
|
|
3648
|
+
}
|
|
2689
3649
|
function walk(node, visit) {
|
|
2690
|
-
if (!node
|
|
3650
|
+
if (!isOxcNode(node)) {
|
|
2691
3651
|
return;
|
|
2692
3652
|
}
|
|
2693
3653
|
const typed = node;
|
|
2694
|
-
if (typeof typed.type !== "string") {
|
|
2695
|
-
return;
|
|
2696
|
-
}
|
|
2697
3654
|
visit(typed);
|
|
2698
3655
|
for (const key of Object.keys(typed)) {
|
|
2699
|
-
if (key
|
|
3656
|
+
if (isAstMetadataKey(key)) {
|
|
2700
3657
|
continue;
|
|
2701
3658
|
}
|
|
2702
3659
|
const child = typed[key];
|
|
@@ -2720,7 +3677,7 @@ class OxcRustNotImplementedError extends Error {
|
|
|
2720
3677
|
}
|
|
2721
3678
|
}
|
|
2722
3679
|
function transformRust(source, filename, options) {
|
|
2723
|
-
const [result] = transformRustBatch([{ filename, source }]);
|
|
3680
|
+
const [result] = transformRustBatch([{ filename, source }], options);
|
|
2724
3681
|
if (!result) {
|
|
2725
3682
|
throw new OxcRustNotImplementedError("native transform returned no result");
|
|
2726
3683
|
}
|
|
@@ -2747,7 +3704,12 @@ function transformRustBatch(files, options) {
|
|
|
2747
3704
|
files.map((file, index) => ({
|
|
2748
3705
|
filename: file.filename ?? `file-${index}.tsx`,
|
|
2749
3706
|
source: file.source
|
|
2750
|
-
}))
|
|
3707
|
+
})),
|
|
3708
|
+
{
|
|
3709
|
+
mangleVars: options?.mangleVars === true,
|
|
3710
|
+
mangleVarHoistMaxDepth: options?.mangleVarHoistMaxDepth,
|
|
3711
|
+
globalVarAliases: normalizeGlobalVarAliases(options?.globalVarAliases)
|
|
3712
|
+
}
|
|
2751
3713
|
).map(fromNativeResult);
|
|
2752
3714
|
} catch (err) {
|
|
2753
3715
|
if (err instanceof OxcRustNotImplementedError) {
|
|
@@ -2761,6 +3723,13 @@ function transformRustBatch(files, options) {
|
|
|
2761
3723
|
throw err;
|
|
2762
3724
|
}
|
|
2763
3725
|
}
|
|
3726
|
+
function normalizeGlobalVarAliases(input) {
|
|
3727
|
+
if (!input) {
|
|
3728
|
+
return [];
|
|
3729
|
+
}
|
|
3730
|
+
const entries = input instanceof Map ? input.entries() : Array.isArray(input) ? input : Object.entries(input);
|
|
3731
|
+
return [...entries].filter(([original, alias]) => original.startsWith("--") && alias.startsWith("--")).map(([original, alias]) => ({ original, alias }));
|
|
3732
|
+
}
|
|
2764
3733
|
function fromNativeResult(result) {
|
|
2765
3734
|
return {
|
|
2766
3735
|
code: result.code,
|
|
@@ -2780,9 +3749,25 @@ function fromNativeResult(result) {
|
|
|
2780
3749
|
path: data.path
|
|
2781
3750
|
}
|
|
2782
3751
|
])
|
|
2783
|
-
)
|
|
3752
|
+
),
|
|
3753
|
+
cssVariableMap: aggregateCssVariableMap(result.cssVariableMap ?? [])
|
|
2784
3754
|
};
|
|
2785
3755
|
}
|
|
3756
|
+
function aggregateCssVariableMap(entries) {
|
|
3757
|
+
const map = /* @__PURE__ */ new Map();
|
|
3758
|
+
for (const entry of entries) {
|
|
3759
|
+
const existing = map.get(entry.original);
|
|
3760
|
+
if (!existing) {
|
|
3761
|
+
map.set(entry.original, entry.mangled);
|
|
3762
|
+
continue;
|
|
3763
|
+
}
|
|
3764
|
+
const values = Array.isArray(existing) ? existing : [existing];
|
|
3765
|
+
if (!values.includes(entry.mangled)) {
|
|
3766
|
+
map.set(entry.original, [...values, entry.mangled]);
|
|
3767
|
+
}
|
|
3768
|
+
}
|
|
3769
|
+
return map;
|
|
3770
|
+
}
|
|
2786
3771
|
|
|
2787
3772
|
const VERSION = "0.0.0";
|
|
2788
3773
|
const DEFAULT_COMPILER_OPTIONS = {
|
|
@@ -2803,6 +3788,7 @@ exports.KNOWN_VARIANTS = transformCore.KNOWN_VARIANTS;
|
|
|
2803
3788
|
exports.PROPERTY_CATEGORY_MAP = transformCore.PROPERTY_CATEGORY_MAP;
|
|
2804
3789
|
exports.PROPERTY_MAP = transformCore.PROPERTY_MAP;
|
|
2805
3790
|
exports.PropertyCategory = transformCore.PropertyCategory;
|
|
3791
|
+
exports.SPECIAL_VARIANTS = transformCore.SPECIAL_VARIANTS;
|
|
2806
3792
|
exports.SUGGESTION_MAP = transformCore.SUGGESTION_MAP;
|
|
2807
3793
|
exports.getCSSVariableName = transformCore.getCSSVariableName;
|
|
2808
3794
|
exports.getPropertyCategory = transformCore.getPropertyCategory;
|
|
@@ -2824,6 +3810,7 @@ exports.injectRecoveryToken = injectRecoveryToken;
|
|
|
2824
3810
|
exports.isValidRecoveryMode = isValidRecoveryMode;
|
|
2825
3811
|
exports.mergeOptions = mergeOptions;
|
|
2826
3812
|
exports.parseManifest = parseManifest;
|
|
3813
|
+
exports.scanGlobalVarUsages = scanGlobalVarUsages;
|
|
2827
3814
|
exports.serializeManifest = serializeManifest;
|
|
2828
3815
|
exports.transformOxc = transformOxc;
|
|
2829
3816
|
exports.transformRust = transformRust;
|