@bamboocss/vite 1.49.0 → 1.50.0
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/fold-module.cjs +324 -330
- package/dist/fold-module.mjs +234 -240
- package/dist/index.d.mts +1 -1
- package/package.json +11 -10
package/dist/fold-module.cjs
CHANGED
|
@@ -6,7 +6,7 @@ let magic_string = require("magic-string");
|
|
|
6
6
|
magic_string = require_chunk.__toESM(magic_string);
|
|
7
7
|
let _bamboocss_config_ts_path = require("@bamboocss/config/ts-path");
|
|
8
8
|
let _bamboocss_extractor = require("@bamboocss/extractor");
|
|
9
|
-
let
|
|
9
|
+
let _bamboocss_ts_ast = require("@bamboocss/ts-ast");
|
|
10
10
|
//#region src/fold-analysis.ts
|
|
11
11
|
/**
|
|
12
12
|
* Nodes that *compose* a value out of their children rather than computing one.
|
|
@@ -21,7 +21,7 @@ let ts_morph = require("ts-morph");
|
|
|
21
21
|
* own literal argument is syntactically inside a default, so an unbounded walk calls it one.
|
|
22
22
|
* That is correct code, and rejecting it fails the build.
|
|
23
23
|
*/
|
|
24
|
-
const composesValue = (node) =>
|
|
24
|
+
const composesValue = (node) => _bamboocss_ts_ast.Node.isObjectLiteralExpression(node) || _bamboocss_ts_ast.Node.isArrayLiteralExpression(node) || _bamboocss_ts_ast.Node.isPropertyAssignment(node) || _bamboocss_ts_ast.Node.isShorthandPropertyAssignment(node) || _bamboocss_ts_ast.Node.isSpreadAssignment(node) || _bamboocss_ts_ast.Node.isSpreadElement(node) || _bamboocss_ts_ast.Node.isAsExpression(node) || _bamboocss_ts_ast.Node.isParenthesizedExpression(node) || _bamboocss_ts_ast.Node.isNonNullExpression(node) || _bamboocss_ts_ast.Node.isTypeAssertion(node) || _bamboocss_ts_ast.Node.isSatisfiesExpression(node);
|
|
25
25
|
/** Is `inner` written within `outer`? Positions rather than a walk, so it is O(1). */
|
|
26
26
|
const contains = (outer, inner) => outer.getSourceFile() === inner.getSourceFile() && outer.getStart() <= inner.getStart() && inner.getEnd() <= outer.getEnd();
|
|
27
27
|
/**
|
|
@@ -42,12 +42,12 @@ const contains = (outer, inner) => outer.getSourceFile() === inner.getSourceFile
|
|
|
42
42
|
* `{ tone = X }`'s name node is not mistaken for its default.
|
|
43
43
|
*/
|
|
44
44
|
const isBindingElementDefault = (node) => {
|
|
45
|
-
if (node &&
|
|
45
|
+
if (node && _bamboocss_ts_ast.Node.isCallExpression(node)) return false;
|
|
46
46
|
let current = node;
|
|
47
47
|
while (current) {
|
|
48
|
-
const parent = current.
|
|
48
|
+
const parent = current.parent;
|
|
49
49
|
if (!parent) return false;
|
|
50
|
-
if (
|
|
50
|
+
if (_bamboocss_ts_ast.Node.isBindingElement(parent)) return parent.initializer === current;
|
|
51
51
|
if (!composesValue(parent)) return false;
|
|
52
52
|
current = parent;
|
|
53
53
|
}
|
|
@@ -74,7 +74,7 @@ const isFromBindingDefault = (node) => {
|
|
|
74
74
|
const own = node.getNode?.();
|
|
75
75
|
if (isBindingElementDefault(own)) return true;
|
|
76
76
|
for (const entry of node.getStack?.() ?? []) {
|
|
77
|
-
if (!
|
|
77
|
+
if (!_bamboocss_ts_ast.Node.isBindingElement(entry) || !entry.initializer) continue;
|
|
78
78
|
if (own && contains(entry, own)) continue;
|
|
79
79
|
return true;
|
|
80
80
|
}
|
|
@@ -97,7 +97,7 @@ const isStaticBox = (node, seen = /* @__PURE__ */ new Set()) => {
|
|
|
97
97
|
if (isFromBindingDefault(node)) return false;
|
|
98
98
|
if (_bamboocss_extractor.box.isLiteral(node) && node.value === void 0) {
|
|
99
99
|
const source = node.getNode?.();
|
|
100
|
-
return Boolean(source &&
|
|
100
|
+
return Boolean(source && _bamboocss_ts_ast.Node.isIdentifier(source) && source.getText() === "undefined");
|
|
101
101
|
}
|
|
102
102
|
if (_bamboocss_extractor.box.isMap(node)) {
|
|
103
103
|
for (const child of node.value.values()) if (!isStaticBox(child, seen)) return false;
|
|
@@ -117,7 +117,7 @@ const isStaticBox = (node, seen = /* @__PURE__ */ new Set()) => {
|
|
|
117
117
|
* surface. Recognising fewer wrappers than it does is not a cosmetic difference: an
|
|
118
118
|
* unrecognised one leaves an object literal wrapped, and the object checks below skip it.
|
|
119
119
|
*/
|
|
120
|
-
const unwrapExpression = (node) =>
|
|
120
|
+
const unwrapExpression = (node) => _bamboocss_ts_ast.Node.isAsExpression(node) || _bamboocss_ts_ast.Node.isParenthesizedExpression(node) || _bamboocss_ts_ast.Node.isNonNullExpression(node) || _bamboocss_ts_ast.Node.isTypeAssertion(node) || _bamboocss_ts_ast.Node.isSatisfiesExpression(node) ? unwrapExpression(node.expression) : node;
|
|
121
121
|
/**
|
|
122
122
|
* Mirrors the parser's evaluator environment, so re-boxing an operand here gets the same
|
|
123
123
|
* answer the extraction did. Left to its default, ts-evaluator presets to `NODE` and
|
|
@@ -137,7 +137,7 @@ const rebox = (node) => (0, _bamboocss_extractor.maybeBoxNode)(unwrapExpression(
|
|
|
137
137
|
const resolvesExactly = (node) => {
|
|
138
138
|
const inner = unwrapExpression(node);
|
|
139
139
|
if (!rebox(inner)) return false;
|
|
140
|
-
return
|
|
140
|
+
return _bamboocss_ts_ast.Node.isConditionalExpression(inner) || isCollapsedBinary(inner) ? decidedAtBuildTime(inner) : true;
|
|
141
141
|
};
|
|
142
142
|
/**
|
|
143
143
|
* Is this operand's value written here, rather than named?
|
|
@@ -150,7 +150,7 @@ const resolvesExactly = (node) => {
|
|
|
150
150
|
*/
|
|
151
151
|
const isWrittenHere = (node) => {
|
|
152
152
|
const inner = unwrapExpression(node);
|
|
153
|
-
return
|
|
153
|
+
return _bamboocss_ts_ast.Node.isStringLiteral(inner) || _bamboocss_ts_ast.Node.isNumericLiteral(inner) || _bamboocss_ts_ast.Node.isNoSubstitutionTemplateLiteral(inner) || _bamboocss_ts_ast.Node.isObjectLiteralExpression(inner) || _bamboocss_ts_ast.Node.isArrayLiteralExpression(inner) || _bamboocss_ts_ast.Node.isTrueLiteral(inner) || _bamboocss_ts_ast.Node.isFalseLiteral(inner) || inner.kind === _bamboocss_ts_ast.SyntaxKind.NullKeyword || _bamboocss_ts_ast.Node.isPrefixUnaryExpression(inner) && _bamboocss_ts_ast.Node.isNumericLiteral(inner.operand);
|
|
154
154
|
};
|
|
155
155
|
/** An inline value's truthiness, which its box carries directly. */
|
|
156
156
|
const isTruthy = (boxNode) => _bamboocss_extractor.box.isLiteral(boxNode) ? Boolean(boxNode.value) : _bamboocss_extractor.box.isMap(boxNode) || _bamboocss_extractor.box.isArray(boxNode) || _bamboocss_extractor.box.isObject(boxNode);
|
|
@@ -168,20 +168,20 @@ const isTruthy = (boxNode) => _bamboocss_extractor.box.isLiteral(boxNode) ? Bool
|
|
|
168
168
|
* be established is that the left is the side that wins.
|
|
169
169
|
*/
|
|
170
170
|
const decidedAtBuildTime = (node) => {
|
|
171
|
-
if (
|
|
172
|
-
const operator = node.
|
|
171
|
+
if (_bamboocss_ts_ast.Node.isConditionalExpression(node)) return resolvesExactly(node.whenTrue) && resolvesExactly(node.whenFalse);
|
|
172
|
+
const operator = node.operatorToken.kind;
|
|
173
173
|
if (!SHORT_CIRCUIT.includes(operator)) return false;
|
|
174
|
-
if (!isWrittenHere(node.
|
|
175
|
-
const left = rebox(node.
|
|
174
|
+
if (!isWrittenHere(node.left)) return false;
|
|
175
|
+
const left = rebox(node.left);
|
|
176
176
|
if (!left) return false;
|
|
177
|
-
if (operator ===
|
|
178
|
-
if (operator ===
|
|
179
|
-
return isTruthy(left) ? resolvesExactly(node.
|
|
177
|
+
if (operator === _bamboocss_ts_ast.SyntaxKind.BarBarToken) return isTruthy(left);
|
|
178
|
+
if (operator === _bamboocss_ts_ast.SyntaxKind.QuestionQuestionToken) return !_bamboocss_extractor.box.isLiteral(left) || left.value != null;
|
|
179
|
+
return isTruthy(left) ? resolvesExactly(node.right) : true;
|
|
180
180
|
};
|
|
181
181
|
const SHORT_CIRCUIT = [
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
182
|
+
_bamboocss_ts_ast.SyntaxKind.AmpersandAmpersandToken,
|
|
183
|
+
_bamboocss_ts_ast.SyntaxKind.BarBarToken,
|
|
184
|
+
_bamboocss_ts_ast.SyntaxKind.QuestionQuestionToken
|
|
185
185
|
];
|
|
186
186
|
/**
|
|
187
187
|
* Every binary form the extractor collapses to one operand — the short-circuits plus the
|
|
@@ -193,18 +193,18 @@ const SHORT_CIRCUIT = [
|
|
|
193
193
|
*/
|
|
194
194
|
const COLLAPSED_BINARY = new Set([
|
|
195
195
|
...SHORT_CIRCUIT,
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
196
|
+
_bamboocss_ts_ast.SyntaxKind.EqualsEqualsToken,
|
|
197
|
+
_bamboocss_ts_ast.SyntaxKind.EqualsEqualsEqualsToken,
|
|
198
|
+
_bamboocss_ts_ast.SyntaxKind.ExclamationEqualsToken,
|
|
199
|
+
_bamboocss_ts_ast.SyntaxKind.ExclamationEqualsEqualsToken,
|
|
200
|
+
_bamboocss_ts_ast.SyntaxKind.GreaterThanToken,
|
|
201
|
+
_bamboocss_ts_ast.SyntaxKind.GreaterThanEqualsToken,
|
|
202
|
+
_bamboocss_ts_ast.SyntaxKind.LessThanToken,
|
|
203
|
+
_bamboocss_ts_ast.SyntaxKind.LessThanEqualsToken,
|
|
204
|
+
_bamboocss_ts_ast.SyntaxKind.InKeyword,
|
|
205
|
+
_bamboocss_ts_ast.SyntaxKind.InstanceOfKeyword
|
|
206
206
|
]);
|
|
207
|
-
const isCollapsedBinary = (node) =>
|
|
207
|
+
const isCollapsedBinary = (node) => _bamboocss_ts_ast.Node.isBinaryExpression(node) && COLLAPSED_BINARY.has(node.operatorToken.kind);
|
|
208
208
|
/**
|
|
209
209
|
* Does the extracted box account for every property the source declares?
|
|
210
210
|
*
|
|
@@ -231,38 +231,38 @@ const isCollapsedBinary = (node) => ts_morph.Node.isBinaryExpression(node) && CO
|
|
|
231
231
|
* expression — reading an initializer that is not there reports the property as having no
|
|
232
232
|
* source, and everything hidden behind the name goes unchecked.
|
|
233
233
|
*/
|
|
234
|
-
const valueOf = (property) =>
|
|
234
|
+
const valueOf = (property) => _bamboocss_ts_ast.Node.isPropertyAssignment(property) ? property.initializer : _bamboocss_ts_ast.Node.isShorthandPropertyAssignment(property) ? property.name : void 0;
|
|
235
235
|
const accountsForSource = (node, boxNode) => {
|
|
236
236
|
if (!node) return true;
|
|
237
237
|
const unwrapped = unwrapExpression(node);
|
|
238
|
-
if ((
|
|
239
|
-
if (
|
|
238
|
+
if ((_bamboocss_ts_ast.Node.isConditionalExpression(unwrapped) || isCollapsedBinary(unwrapped)) && !_bamboocss_extractor.box.isConditional(boxNode) && !decidedAtBuildTime(unwrapped)) return false;
|
|
239
|
+
if (_bamboocss_ts_ast.Node.isArrayLiteralExpression(unwrapped)) {
|
|
240
240
|
if (!_bamboocss_extractor.box.isArray(boxNode)) return false;
|
|
241
|
-
const elements = unwrapped.
|
|
241
|
+
const elements = unwrapped.elements;
|
|
242
242
|
if (elements.length !== boxNode.value.length) return false;
|
|
243
243
|
return elements.every((element, index) => accountsForSource(element, boxNode.value[index]));
|
|
244
244
|
}
|
|
245
|
-
if (!
|
|
245
|
+
if (!_bamboocss_ts_ast.Node.isObjectLiteralExpression(unwrapped)) {
|
|
246
246
|
const origin = _bamboocss_extractor.box.isMap(boxNode) ? boxNode.getNode() : void 0;
|
|
247
|
-
return !origin || origin === unwrapped || !
|
|
247
|
+
return !origin || origin === unwrapped || !_bamboocss_ts_ast.Node.isObjectLiteralExpression(origin) ? true : accountsForSource(origin, boxNode);
|
|
248
248
|
}
|
|
249
249
|
if (!_bamboocss_extractor.box.isMap(boxNode)) return false;
|
|
250
|
-
for (const property of unwrapped.
|
|
251
|
-
if (
|
|
252
|
-
const expression = unwrapExpression(property.
|
|
253
|
-
if (
|
|
250
|
+
for (const property of unwrapped.properties) {
|
|
251
|
+
if (_bamboocss_ts_ast.Node.isSpreadAssignment(property)) {
|
|
252
|
+
const expression = unwrapExpression(property.expression);
|
|
253
|
+
if (_bamboocss_ts_ast.Node.isObjectLiteralExpression(expression)) continue;
|
|
254
254
|
const walked = boxNode.resolvedSpreads?.find((entry) => entry.node === expression);
|
|
255
255
|
if (!walked) return false;
|
|
256
256
|
if (!accountsForSource(walked.box.getNode(), walked.box)) return false;
|
|
257
257
|
continue;
|
|
258
258
|
}
|
|
259
|
-
if (
|
|
260
|
-
if (!
|
|
261
|
-
const nameNode = property.
|
|
262
|
-
if (
|
|
263
|
-
const key =
|
|
259
|
+
if (_bamboocss_ts_ast.Node.isMethodDeclaration(property) || _bamboocss_ts_ast.Node.isGetAccessorDeclaration(property) || _bamboocss_ts_ast.Node.isSetAccessorDeclaration(property)) return false;
|
|
260
|
+
if (!_bamboocss_ts_ast.Node.isPropertyAssignment(property) && !_bamboocss_ts_ast.Node.isShorthandPropertyAssignment(property)) return false;
|
|
261
|
+
const nameNode = property.name;
|
|
262
|
+
if (_bamboocss_ts_ast.Node.isComputedPropertyName(nameNode)) return false;
|
|
263
|
+
const key = _bamboocss_ts_ast.Node.isStringLiteral(nameNode) || _bamboocss_ts_ast.Node.isNumericLiteral(nameNode) ? String((0, _bamboocss_ts_ast.literalValueOf)(nameNode)) : nameNode.getText();
|
|
264
264
|
const value = valueOf(property);
|
|
265
|
-
if (value &&
|
|
265
|
+
if (value && _bamboocss_ts_ast.Node.isIdentifier(value) && value.getText() === "undefined") continue;
|
|
266
266
|
if (!boxNode.value.has(key)) return false;
|
|
267
267
|
if (!accountsForSource(value, boxNode.value.get(key))) return false;
|
|
268
268
|
}
|
|
@@ -310,20 +310,20 @@ const collectModuleScopeNames = (sourceFile) => {
|
|
|
310
310
|
const names = /* @__PURE__ */ new Set();
|
|
311
311
|
const addBinding = (node) => {
|
|
312
312
|
if (!node) return;
|
|
313
|
-
if (
|
|
314
|
-
for (const element of node.
|
|
313
|
+
if (_bamboocss_ts_ast.Node.isObjectBindingPattern(node) || _bamboocss_ts_ast.Node.isArrayBindingPattern(node)) {
|
|
314
|
+
for (const element of node.elements) if (_bamboocss_ts_ast.Node.isBindingElement(element)) addBinding(element.name);
|
|
315
315
|
return;
|
|
316
316
|
}
|
|
317
|
-
if (
|
|
317
|
+
if (_bamboocss_ts_ast.Node.isIdentifier(node)) names.add(node.getText());
|
|
318
318
|
};
|
|
319
319
|
const addDeclarations = (list) => {
|
|
320
|
-
if (
|
|
321
|
-
for (const declaration of list.
|
|
320
|
+
if (_bamboocss_ts_ast.Node.isVariableStatement(list)) {
|
|
321
|
+
for (const declaration of list.declarationList.declarations) addBinding(declaration.name);
|
|
322
322
|
return;
|
|
323
323
|
}
|
|
324
|
-
if (
|
|
324
|
+
if (_bamboocss_ts_ast.Node.isVariableDeclarationList(list)) for (const declaration of list.declarations) addBinding(declaration.name);
|
|
325
325
|
};
|
|
326
|
-
const isVar = (node) => (
|
|
326
|
+
const isVar = (node) => (_bamboocss_ts_ast.Node.isVariableStatement(node) || _bamboocss_ts_ast.Node.isVariableDeclarationList(node)) && ((0, _bamboocss_ts_ast.childOf)(node, "declarationList")?.flags ?? 0) === 0;
|
|
327
327
|
/**
|
|
328
328
|
* `var` is scoped to the enclosing *function*, not the enclosing block, so one written
|
|
329
329
|
* inside any statement at the top level still binds at module scope. Walking only the
|
|
@@ -337,62 +337,62 @@ const collectModuleScopeNames = (sourceFile) => {
|
|
|
337
337
|
addDeclarations(node);
|
|
338
338
|
return;
|
|
339
339
|
}
|
|
340
|
-
if (
|
|
341
|
-
for (const statement of node.
|
|
340
|
+
if (_bamboocss_ts_ast.Node.isBlock(node)) {
|
|
341
|
+
for (const statement of node.statements) addHoistedVars(statement);
|
|
342
342
|
return;
|
|
343
343
|
}
|
|
344
|
-
if (
|
|
345
|
-
addHoistedVars(node.
|
|
346
|
-
const otherwise = node.
|
|
344
|
+
if (_bamboocss_ts_ast.Node.isIfStatement(node)) {
|
|
345
|
+
addHoistedVars(node.thenStatement);
|
|
346
|
+
const otherwise = node.elseStatement;
|
|
347
347
|
if (otherwise) addHoistedVars(otherwise);
|
|
348
348
|
return;
|
|
349
349
|
}
|
|
350
|
-
if (
|
|
351
|
-
const initializer = node.
|
|
350
|
+
if (_bamboocss_ts_ast.Node.isForStatement(node)) {
|
|
351
|
+
const initializer = node.initializer;
|
|
352
352
|
if (initializer) addHoistedVars(initializer);
|
|
353
|
-
addHoistedVars(node.
|
|
353
|
+
addHoistedVars(node.statement);
|
|
354
354
|
return;
|
|
355
355
|
}
|
|
356
|
-
if (
|
|
357
|
-
addHoistedVars(node.
|
|
358
|
-
addHoistedVars(node.
|
|
356
|
+
if (_bamboocss_ts_ast.Node.isForInStatement(node) || _bamboocss_ts_ast.Node.isForOfStatement(node)) {
|
|
357
|
+
addHoistedVars(node.initializer);
|
|
358
|
+
addHoistedVars(node.statement);
|
|
359
359
|
return;
|
|
360
360
|
}
|
|
361
|
-
if (
|
|
362
|
-
addHoistedVars(node.
|
|
361
|
+
if (_bamboocss_ts_ast.Node.isWhileStatement(node) || _bamboocss_ts_ast.Node.isDoStatement(node) || _bamboocss_ts_ast.Node.isWithStatement(node)) {
|
|
362
|
+
addHoistedVars(node.statement);
|
|
363
363
|
return;
|
|
364
364
|
}
|
|
365
|
-
if (
|
|
366
|
-
addHoistedVars(node.
|
|
365
|
+
if (_bamboocss_ts_ast.Node.isLabeledStatement(node)) {
|
|
366
|
+
addHoistedVars(node.statement);
|
|
367
367
|
return;
|
|
368
368
|
}
|
|
369
|
-
if (
|
|
370
|
-
addHoistedVars(node.
|
|
371
|
-
const caught =
|
|
372
|
-
if (caught) addHoistedVars(
|
|
373
|
-
const finally_ =
|
|
369
|
+
if (_bamboocss_ts_ast.Node.isTryStatement(node)) {
|
|
370
|
+
addHoistedVars(node.tryBlock);
|
|
371
|
+
const caught = (0, _bamboocss_ts_ast.childOf)(node, "catchClause");
|
|
372
|
+
if (caught) addHoistedVars((0, _bamboocss_ts_ast.childOf)(caught, "block"));
|
|
373
|
+
const finally_ = (0, _bamboocss_ts_ast.childOf)(node, "finallyBlock");
|
|
374
374
|
if (finally_) addHoistedVars(finally_);
|
|
375
375
|
return;
|
|
376
376
|
}
|
|
377
|
-
if (
|
|
377
|
+
if (_bamboocss_ts_ast.Node.isSwitchStatement(node)) for (const clause of (0, _bamboocss_ts_ast.childOf)(node, "caseBlock")?.clauses ?? []) for (const statement of (0, _bamboocss_ts_ast.childOf)(clause, "statements") ?? []) addHoistedVars(statement);
|
|
378
378
|
};
|
|
379
|
-
for (const statement of sourceFile.
|
|
380
|
-
if (
|
|
379
|
+
for (const statement of sourceFile.statements) {
|
|
380
|
+
if (_bamboocss_ts_ast.Node.isVariableStatement(statement)) {
|
|
381
381
|
addDeclarations(statement);
|
|
382
382
|
continue;
|
|
383
383
|
}
|
|
384
|
-
if (
|
|
385
|
-
addBinding(
|
|
386
|
-
addBinding(
|
|
387
|
-
for (const named of
|
|
384
|
+
if (_bamboocss_ts_ast.Node.isImportDeclaration(statement)) {
|
|
385
|
+
addBinding((0, _bamboocss_ts_ast.getDefaultImport)(statement));
|
|
386
|
+
addBinding((0, _bamboocss_ts_ast.getNamespaceImport)(statement));
|
|
387
|
+
for (const named of (0, _bamboocss_ts_ast.getNamedImports)(statement)) addBinding((0, _bamboocss_ts_ast.getAliasNode)(named) ?? (0, _bamboocss_ts_ast.nameNodeOf)(named));
|
|
388
388
|
continue;
|
|
389
389
|
}
|
|
390
|
-
if (
|
|
391
|
-
addBinding(statement.
|
|
390
|
+
if (_bamboocss_ts_ast.Node.isImportEqualsDeclaration(statement)) {
|
|
391
|
+
addBinding(statement.name);
|
|
392
392
|
continue;
|
|
393
393
|
}
|
|
394
|
-
if (
|
|
395
|
-
addBinding(statement.
|
|
394
|
+
if (_bamboocss_ts_ast.Node.isFunctionDeclaration(statement) || _bamboocss_ts_ast.Node.isClassDeclaration(statement) || _bamboocss_ts_ast.Node.isEnumDeclaration(statement) || _bamboocss_ts_ast.Node.isModuleDeclaration(statement) || _bamboocss_ts_ast.Node.isTypeAliasDeclaration(statement) || _bamboocss_ts_ast.Node.isInterfaceDeclaration(statement)) {
|
|
395
|
+
addBinding(statement.name);
|
|
396
396
|
continue;
|
|
397
397
|
}
|
|
398
398
|
addHoistedVars(statement);
|
|
@@ -410,70 +410,61 @@ const collectModuleScopeNames = (sourceFile) => {
|
|
|
410
410
|
*
|
|
411
411
|
* `SyntaxKind.Identifier` sorts *below* `SyntaxKind.FirstNode`, which is what ts-morph tests to
|
|
412
412
|
* decide whether it may search the parse tree. For a kind below that line it falls back to
|
|
413
|
-
* materialising the whole **token** tree — every brace, comma and keyword
|
|
413
|
+
* materialising the whole **token** tree — every brace, comma and keyword became a ts-morph node
|
|
414
414
|
* on the way to collecting the identifiers. On 55 KB of real tsx that measured 22ms against
|
|
415
|
-
* 0.22ms for the same collection over compiler nodes, and the node cache
|
|
415
|
+
* 0.22ms for the same collection over compiler nodes, and the node cache did not help: a second
|
|
416
416
|
* call cost the same 22ms.
|
|
417
417
|
*
|
|
418
|
-
*
|
|
419
|
-
*
|
|
420
|
-
*
|
|
421
|
-
*
|
|
422
|
-
*
|
|
418
|
+
* That cost was ts-morph's wrapper objects, and TypeScript 7 has none — the walk below yields
|
|
419
|
+
* the compiler's own nodes, which is exactly what `getDescendantsOfKind` would return. So the
|
|
420
|
+
* lazy per-bucket wrapping this used to do has nothing left to defer, and the buckets are handed
|
|
421
|
+
* back as collected. `localReferencesTo` still depends on the identity of what comes out, since
|
|
422
|
+
* it compares each reference against the declaration.
|
|
423
423
|
*
|
|
424
424
|
* JSDoc is walked explicitly. `ts.forEachChild` does not descend into it, while the token path
|
|
425
425
|
* this replaces does, so a name mentioned only in a `@type` annotation was previously found and
|
|
426
426
|
* would otherwise stop being — a silent narrowing of what counts as a surviving reference.
|
|
427
|
-
* Keyed on `
|
|
428
|
-
*
|
|
427
|
+
* Keyed on the identifier's `text` because that is the name as the compiler resolves it, so
|
|
428
|
+
* `\u0062adge` and `badge` share a bucket exactly as before.
|
|
429
429
|
*
|
|
430
430
|
* Deliberately *not* memoized across passes, unlike the module-scope names beside it. That
|
|
431
|
-
* cache holds strings, which outlive anything; this one holds nodes, and a node
|
|
432
|
-
*
|
|
433
|
-
*
|
|
434
|
-
*
|
|
435
|
-
* `Attempted to get information from a node that was removed or forgotten` on the next read.
|
|
431
|
+
* cache holds strings, which outlive anything; this one holds nodes, and a node belongs to the
|
|
432
|
+
* tree it was taken from. Keying on the source text does not help, because identical text
|
|
433
|
+
* re-parsed is a fresh tree: the cache would hit and hand back nodes from a previous snapshot,
|
|
434
|
+
* which no longer match anything the current pass compares them against.
|
|
436
435
|
*/
|
|
437
436
|
const identifierIndex = (sourceFile) => {
|
|
438
437
|
const compilerNodes = /* @__PURE__ */ new Map();
|
|
439
438
|
const collect = (node) => {
|
|
440
|
-
if (node.kind ===
|
|
441
|
-
const name = String(node.
|
|
439
|
+
if (node.kind === _bamboocss_ts_ast.ts.SyntaxKind.Identifier) {
|
|
440
|
+
const name = String(node.text);
|
|
442
441
|
const known = compilerNodes.get(name);
|
|
443
442
|
if (known) known.push(node);
|
|
444
443
|
else compilerNodes.set(name, [node]);
|
|
445
444
|
}
|
|
446
445
|
const jsDoc = node.jsDoc;
|
|
447
446
|
if (jsDoc) for (const doc of jsDoc) collect(doc);
|
|
448
|
-
|
|
447
|
+
_bamboocss_ts_ast.ts.forEachChild(node, collect);
|
|
449
448
|
};
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
const wrap = sourceFile;
|
|
453
|
-
return { get: (name) => {
|
|
454
|
-
const known = wrapped.get(name);
|
|
455
|
-
if (known) return known;
|
|
456
|
-
const nodes = (compilerNodes.get(name) ?? []).map((node) => wrap._getNodeFromCompilerNode(node));
|
|
457
|
-
wrapped.set(name, nodes);
|
|
458
|
-
return nodes;
|
|
459
|
-
} };
|
|
449
|
+
_bamboocss_ts_ast.ts.forEachChild(sourceFile, collect);
|
|
450
|
+
return { get: (name) => compilerNodes.get(name) ?? [] };
|
|
460
451
|
};
|
|
461
452
|
const localReferencesTo = (index, name, declaration) => {
|
|
462
453
|
const references = [];
|
|
463
454
|
for (const identifier of index.get(name)) {
|
|
464
455
|
if (identifier === declaration) continue;
|
|
465
|
-
const parent = identifier.
|
|
456
|
+
const parent = identifier.parent;
|
|
466
457
|
if (!parent) continue;
|
|
467
|
-
if (
|
|
468
|
-
if (
|
|
469
|
-
if (
|
|
470
|
-
if ((
|
|
471
|
-
if (
|
|
472
|
-
if ((
|
|
473
|
-
if ((
|
|
474
|
-
if (
|
|
475
|
-
if (parent.
|
|
476
|
-
if (
|
|
458
|
+
if (_bamboocss_ts_ast.Node.isPropertyAccessExpression(parent) && parent.name === identifier) continue;
|
|
459
|
+
if (_bamboocss_ts_ast.Node.isPropertyAssignment(parent) && parent.name === identifier) continue;
|
|
460
|
+
if (_bamboocss_ts_ast.Node.isBindingElement(parent) && parent.propertyName === identifier) continue;
|
|
461
|
+
if ((_bamboocss_ts_ast.Node.isJsxOpeningElement(parent) || _bamboocss_ts_ast.Node.isJsxSelfClosingElement(parent) || _bamboocss_ts_ast.Node.isJsxClosingElement(parent)) && parent.tagName === identifier) continue;
|
|
462
|
+
if (_bamboocss_ts_ast.Node.isJsxAttribute(parent) && parent.name === identifier) continue;
|
|
463
|
+
if ((_bamboocss_ts_ast.Node.isMethodDeclaration(parent) || _bamboocss_ts_ast.Node.isPropertyDeclaration(parent) || _bamboocss_ts_ast.Node.isGetAccessorDeclaration(parent) || _bamboocss_ts_ast.Node.isSetAccessorDeclaration(parent) || _bamboocss_ts_ast.Node.isMethodSignatureDeclaration(parent) || _bamboocss_ts_ast.Node.isPropertySignatureDeclaration(parent) || _bamboocss_ts_ast.Node.isEnumMember(parent)) && (0, _bamboocss_ts_ast.nameNodeOf)(parent) === identifier) continue;
|
|
464
|
+
if ((_bamboocss_ts_ast.Node.isVariableDeclaration(parent) || _bamboocss_ts_ast.Node.isParameterDeclaration(parent) || _bamboocss_ts_ast.Node.isFunctionDeclaration(parent) || _bamboocss_ts_ast.Node.isClassDeclaration(parent) || _bamboocss_ts_ast.Node.isBindingElement(parent)) && parent.name === identifier) continue;
|
|
465
|
+
if (_bamboocss_ts_ast.Node.isImportSpecifier(parent) || _bamboocss_ts_ast.Node.isExportSpecifier(parent)) {
|
|
466
|
+
if (parent.name !== identifier) continue;
|
|
467
|
+
if (_bamboocss_ts_ast.Node.isExportSpecifier(parent)) {
|
|
477
468
|
references.push(identifier);
|
|
478
469
|
continue;
|
|
479
470
|
}
|
|
@@ -500,8 +491,10 @@ const collectRecipeConfigs = (parserResult) => {
|
|
|
500
491
|
for (const definition of definitions) {
|
|
501
492
|
const node = definition.box?.getNode?.();
|
|
502
493
|
if (!node) continue;
|
|
503
|
-
const
|
|
504
|
-
|
|
494
|
+
const call = _bamboocss_ts_ast.Node.isCallExpression(node) ? node : (0, _bamboocss_ts_ast.getFirstAncestorByKind)(node, _bamboocss_ts_ast.SyntaxKind.CallExpression);
|
|
495
|
+
const declaration = call && (0, _bamboocss_ts_ast.getFirstAncestorByKind)(call, _bamboocss_ts_ast.SyntaxKind.VariableDeclaration);
|
|
496
|
+
const nameNode = declaration && (0, _bamboocss_ts_ast.nameNodeOf)(declaration);
|
|
497
|
+
if (!nameNode || !_bamboocss_ts_ast.Node.isIdentifier(nameNode)) continue;
|
|
505
498
|
if (definition.data?.length !== 1) {
|
|
506
499
|
configs.set(nameNode.getText(), AMBIGUOUS);
|
|
507
500
|
continue;
|
|
@@ -534,11 +527,11 @@ const AMBIGUOUS = Object.freeze({
|
|
|
534
527
|
const IDENTIFIER = /^[A-Za-z_$][\w$]*$/;
|
|
535
528
|
const propertyAccess = (key) => IDENTIFIER.test(key) ? `.${key}` : `[${JSON.stringify(key)}]`;
|
|
536
529
|
const LITERAL_KINDS = new Set([
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
530
|
+
_bamboocss_ts_ast.SyntaxKind.StringLiteral,
|
|
531
|
+
_bamboocss_ts_ast.SyntaxKind.NoSubstitutionTemplateLiteral,
|
|
532
|
+
_bamboocss_ts_ast.SyntaxKind.NumericLiteral,
|
|
533
|
+
_bamboocss_ts_ast.SyntaxKind.TrueKeyword,
|
|
534
|
+
_bamboocss_ts_ast.SyntaxKind.FalseKeyword
|
|
542
535
|
]);
|
|
543
536
|
/**
|
|
544
537
|
* The value a literal node denotes, or `undefined` for anything else.
|
|
@@ -549,11 +542,11 @@ const LITERAL_KINDS = new Set([
|
|
|
549
542
|
* string missing the variant — the element renders, wrongly, with no report.
|
|
550
543
|
*/
|
|
551
544
|
const literalValue = (node) => {
|
|
552
|
-
if (!node || !LITERAL_KINDS.has(node.
|
|
553
|
-
if (
|
|
554
|
-
if (
|
|
555
|
-
if (node.
|
|
556
|
-
if (node.
|
|
545
|
+
if (!node || !LITERAL_KINDS.has(node.kind)) return void 0;
|
|
546
|
+
if (_bamboocss_ts_ast.Node.isStringLiteral(node) || _bamboocss_ts_ast.Node.isNoSubstitutionTemplateLiteral(node)) return (0, _bamboocss_ts_ast.literalValueOf)(node);
|
|
547
|
+
if (_bamboocss_ts_ast.Node.isNumericLiteral(node)) return (0, _bamboocss_ts_ast.literalValueOf)(node);
|
|
548
|
+
if (node.kind === _bamboocss_ts_ast.SyntaxKind.TrueKeyword) return true;
|
|
549
|
+
if (node.kind === _bamboocss_ts_ast.SyntaxKind.FalseKeyword) return false;
|
|
557
550
|
};
|
|
558
551
|
/**
|
|
559
552
|
* The property name a key node denotes.
|
|
@@ -564,9 +557,9 @@ const literalValue = (node) => {
|
|
|
564
557
|
* numeric key normalises the same way: `{ 0x10: 'a' }` is the key `16`.
|
|
565
558
|
*/
|
|
566
559
|
const propertyKey = (nameNode) => {
|
|
567
|
-
if (
|
|
568
|
-
if (
|
|
569
|
-
if (
|
|
560
|
+
if (_bamboocss_ts_ast.Node.isIdentifier(nameNode)) return nameNode.getText();
|
|
561
|
+
if (_bamboocss_ts_ast.Node.isStringLiteral(nameNode) || _bamboocss_ts_ast.Node.isNoSubstitutionTemplateLiteral(nameNode)) return (0, _bamboocss_ts_ast.stringLiteralValue)(nameNode);
|
|
562
|
+
if (_bamboocss_ts_ast.Node.isNumericLiteral(nameNode)) return String((0, _bamboocss_ts_ast.literalValueOf)(nameNode));
|
|
570
563
|
};
|
|
571
564
|
/**
|
|
572
565
|
* Make a generated compile helper callable at this call site, by whatever name the file gives it.
|
|
@@ -579,26 +572,26 @@ const ensureRecipeHelperImport = (imported, call, isBambooCssModule, isGenerated
|
|
|
579
572
|
const sourceFile = call.getSourceFile();
|
|
580
573
|
let host;
|
|
581
574
|
let subpathModule;
|
|
582
|
-
for (const declaration of
|
|
583
|
-
const mod =
|
|
584
|
-
if (
|
|
585
|
-
for (const named of
|
|
586
|
-
if (
|
|
587
|
-
if (
|
|
588
|
-
if (!isBambooCssModule(mod)) return void 0;
|
|
589
|
-
const local = (
|
|
575
|
+
for (const declaration of (0, _bamboocss_ts_ast.getImportDeclarations)(sourceFile)) {
|
|
576
|
+
const mod = (0, _bamboocss_ts_ast.getModuleSpecifierValue)(declaration);
|
|
577
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(declaration)) continue;
|
|
578
|
+
for (const named of (0, _bamboocss_ts_ast.getNamedImports)(declaration)) {
|
|
579
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(named)) continue;
|
|
580
|
+
if ((0, _bamboocss_ts_ast.nameNodeOf)(named)?.getText() === imported) {
|
|
581
|
+
if (!isBambooCssModule(mod ?? "")) return void 0;
|
|
582
|
+
const local = ((0, _bamboocss_ts_ast.getAliasNode)(named) ?? (0, _bamboocss_ts_ast.nameNodeOf)(named))?.getText() ?? "";
|
|
590
583
|
return isShadowed(call, local) ? void 0 : { name: local };
|
|
591
584
|
}
|
|
592
585
|
}
|
|
593
|
-
if (!host && isGeneratedCssModule(mod) &&
|
|
594
|
-
if (!subpathModule) subpathModule = helperModuleFromSubpath?.(mod);
|
|
586
|
+
if (!host && isGeneratedCssModule(mod ?? "") && (0, _bamboocss_ts_ast.getNamedImports)(declaration).length > 0) host = declaration;
|
|
587
|
+
if (!subpathModule) subpathModule = helperModuleFromSubpath?.(mod ?? "");
|
|
595
588
|
}
|
|
596
589
|
const fallbackModule = newImportModule ?? subpathModule;
|
|
597
590
|
if (!host && !fallbackModule) return void 0;
|
|
598
591
|
if (declaredAtModuleScope(sourceFile).has(imported)) return void 0;
|
|
599
592
|
if (isShadowed(call, imported)) return void 0;
|
|
600
593
|
if (!host) {
|
|
601
|
-
const anchor =
|
|
594
|
+
const anchor = (0, _bamboocss_ts_ast.getImportDeclarations)(sourceFile).at(-1);
|
|
602
595
|
if (!anchor) return void 0;
|
|
603
596
|
return {
|
|
604
597
|
name: imported,
|
|
@@ -609,7 +602,7 @@ const ensureRecipeHelperImport = (imported, call, isBambooCssModule, isGenerated
|
|
|
609
602
|
}
|
|
610
603
|
};
|
|
611
604
|
}
|
|
612
|
-
const last =
|
|
605
|
+
const last = (0, _bamboocss_ts_ast.getNamedImports)(host).at(-1);
|
|
613
606
|
if (!last) return void 0;
|
|
614
607
|
return {
|
|
615
608
|
name: imported,
|
|
@@ -645,11 +638,11 @@ const lowerRecipeCall = (call, entry, styleCompiler, isInert, resolvedSelection,
|
|
|
645
638
|
kind: "decline",
|
|
646
639
|
reason: "unknown-recipe"
|
|
647
640
|
};
|
|
648
|
-
if (!
|
|
641
|
+
if (!_bamboocss_ts_ast.Node.isCallExpression(call)) return {
|
|
649
642
|
kind: "decline",
|
|
650
643
|
reason: "unsupported-shape"
|
|
651
644
|
};
|
|
652
|
-
const args = call.
|
|
645
|
+
const args = call.arguments;
|
|
653
646
|
if (args.length > 1) return {
|
|
654
647
|
kind: "decline",
|
|
655
648
|
reason: "unsupported-shape"
|
|
@@ -684,29 +677,29 @@ const lowerRecipeCall = (call, entry, styleCompiler, isInert, resolvedSelection,
|
|
|
684
677
|
* An identifier only. Each variant reads the binding again, and re-reading anything else —
|
|
685
678
|
* a call, a property access — would evaluate it once per axis instead of once.
|
|
686
679
|
*/
|
|
687
|
-
if (
|
|
680
|
+
if (_bamboocss_ts_ast.Node.isIdentifier(arg)) {
|
|
688
681
|
const binding = arg.getText();
|
|
689
682
|
for (const key of Object.keys(config.variants ?? {})) dynamicAxes.set(key, `${binding}${propertyAccess(key)}`);
|
|
690
|
-
} else if (!
|
|
683
|
+
} else if (!_bamboocss_ts_ast.Node.isObjectLiteralExpression(arg)) return {
|
|
691
684
|
kind: "decline",
|
|
692
685
|
reason: "dynamic"
|
|
693
686
|
};
|
|
694
|
-
else for (const property of arg.
|
|
695
|
-
if (
|
|
687
|
+
else for (const property of arg.properties) {
|
|
688
|
+
if (_bamboocss_ts_ast.Node.isSpreadAssignment(property)) return {
|
|
696
689
|
kind: "decline",
|
|
697
690
|
reason: "dynamic"
|
|
698
691
|
};
|
|
699
|
-
if (
|
|
700
|
-
dynamicAxes.set(
|
|
701
|
-
delete selection[
|
|
692
|
+
if (_bamboocss_ts_ast.Node.isShorthandPropertyAssignment(property)) {
|
|
693
|
+
dynamicAxes.set((0, _bamboocss_ts_ast.getName)(property) ?? "", (0, _bamboocss_ts_ast.getName)(property) ?? "");
|
|
694
|
+
delete selection[(0, _bamboocss_ts_ast.getName)(property) ?? ""];
|
|
702
695
|
continue;
|
|
703
696
|
}
|
|
704
|
-
if (!
|
|
697
|
+
if (!_bamboocss_ts_ast.Node.isPropertyAssignment(property)) return {
|
|
705
698
|
kind: "decline",
|
|
706
699
|
reason: "dynamic"
|
|
707
700
|
};
|
|
708
|
-
const nameNode = property.
|
|
709
|
-
if (
|
|
701
|
+
const nameNode = property.name;
|
|
702
|
+
if (_bamboocss_ts_ast.Node.isComputedPropertyName(nameNode)) return {
|
|
710
703
|
kind: "decline",
|
|
711
704
|
reason: "dynamic"
|
|
712
705
|
};
|
|
@@ -715,7 +708,7 @@ const lowerRecipeCall = (call, entry, styleCompiler, isInert, resolvedSelection,
|
|
|
715
708
|
kind: "decline",
|
|
716
709
|
reason: "dynamic"
|
|
717
710
|
};
|
|
718
|
-
const initializer = property.
|
|
711
|
+
const initializer = property.initializer;
|
|
719
712
|
if (initializer && !isInert(initializer)) {
|
|
720
713
|
if (!Object.hasOwn(config.variants ?? {}, key)) return {
|
|
721
714
|
kind: "decline",
|
|
@@ -1153,24 +1146,24 @@ const RECIPE_CALL_TYPE = "cva-call";
|
|
|
1153
1146
|
* A type position is excluded for a different reason: it is erased, and with it the import.
|
|
1154
1147
|
*/
|
|
1155
1148
|
const isValueReference = (identifier) => {
|
|
1156
|
-
const parent = identifier.
|
|
1149
|
+
const parent = identifier.parent;
|
|
1157
1150
|
if (!parent) return false;
|
|
1158
|
-
if (
|
|
1159
|
-
if (
|
|
1160
|
-
if (
|
|
1161
|
-
if (
|
|
1162
|
-
if (
|
|
1163
|
-
if (
|
|
1164
|
-
if (
|
|
1151
|
+
if (_bamboocss_ts_ast.Node.isImportSpecifier(parent) || _bamboocss_ts_ast.Node.isExportSpecifier(parent)) return false;
|
|
1152
|
+
if (_bamboocss_ts_ast.Node.isImportClause(parent) || _bamboocss_ts_ast.Node.isNamespaceImport(parent)) return false;
|
|
1153
|
+
if (_bamboocss_ts_ast.Node.isPropertyAccessExpression(parent) && parent.name === identifier) return false;
|
|
1154
|
+
if (_bamboocss_ts_ast.Node.isQualifiedName(parent) && parent.right === identifier) return false;
|
|
1155
|
+
if (_bamboocss_ts_ast.Node.isPropertyAssignment(parent) && parent.name === identifier) return false;
|
|
1156
|
+
if (_bamboocss_ts_ast.Node.isMethodDeclaration(parent) || _bamboocss_ts_ast.Node.isPropertyDeclaration(parent) || _bamboocss_ts_ast.Node.isGetAccessorDeclaration(parent) || _bamboocss_ts_ast.Node.isSetAccessorDeclaration(parent) || _bamboocss_ts_ast.Node.isMethodSignatureDeclaration(parent) || _bamboocss_ts_ast.Node.isPropertySignatureDeclaration(parent) || _bamboocss_ts_ast.Node.isEnumMember(parent)) {
|
|
1157
|
+
if ((0, _bamboocss_ts_ast.nameNodeOf)(parent) === identifier) return false;
|
|
1165
1158
|
}
|
|
1166
|
-
if (
|
|
1167
|
-
if (
|
|
1168
|
-
if (parent.
|
|
1159
|
+
if (_bamboocss_ts_ast.Node.isLabeledStatement(parent) || _bamboocss_ts_ast.Node.isBreakStatement(parent) || _bamboocss_ts_ast.Node.isContinueStatement(parent)) return false;
|
|
1160
|
+
if (_bamboocss_ts_ast.Node.isJsxOpeningElement(parent) || _bamboocss_ts_ast.Node.isJsxSelfClosingElement(parent) || _bamboocss_ts_ast.Node.isJsxClosingElement(parent)) {
|
|
1161
|
+
if (parent.tagName === identifier) return identifier.getText()[0] === identifier.getText()[0]?.toUpperCase();
|
|
1169
1162
|
}
|
|
1170
|
-
if (
|
|
1171
|
-
if (
|
|
1172
|
-
if ((
|
|
1173
|
-
return !
|
|
1163
|
+
if (_bamboocss_ts_ast.Node.isJsxAttribute(parent)) return false;
|
|
1164
|
+
if (_bamboocss_ts_ast.Node.isBindingElement(parent) && parent.propertyName === identifier) return false;
|
|
1165
|
+
if ((_bamboocss_ts_ast.Node.isVariableDeclaration(parent) || _bamboocss_ts_ast.Node.isParameterDeclaration(parent) || _bamboocss_ts_ast.Node.isBindingElement(parent) || _bamboocss_ts_ast.Node.isFunctionDeclaration(parent) || _bamboocss_ts_ast.Node.isClassDeclaration(parent)) && parent.name === identifier) return false;
|
|
1166
|
+
return !(0, _bamboocss_ts_ast.getFirstAncestor)(identifier, (ancestor) => _bamboocss_ts_ast.Node.isTypeNode(ancestor) || _bamboocss_ts_ast.Node.isTypeAliasDeclaration(ancestor) || _bamboocss_ts_ast.Node.isInterfaceDeclaration(ancestor));
|
|
1174
1167
|
};
|
|
1175
1168
|
/**
|
|
1176
1169
|
* Imports a surviving reference to is not a failure.
|
|
@@ -1211,7 +1204,7 @@ const TRAILING_INDEX = /\/index$/;
|
|
|
1211
1204
|
* contract is behaviour preservation regardless: a literal is the cheap way to prove it, since
|
|
1212
1205
|
* it means no call, no property read, no getter.
|
|
1213
1206
|
*/
|
|
1214
|
-
const isInertArgument = (node) =>
|
|
1207
|
+
const isInertArgument = (node) => _bamboocss_ts_ast.Node.isStringLiteral(node) || _bamboocss_ts_ast.Node.isNumericLiteral(node) || _bamboocss_ts_ast.Node.isNoSubstitutionTemplateLiteral(node) || node.kind === _bamboocss_ts_ast.SyntaxKind.TrueKeyword || node.kind === _bamboocss_ts_ast.SyntaxKind.FalseKeyword || node.kind === _bamboocss_ts_ast.SyntaxKind.NullKeyword || _bamboocss_ts_ast.Node.isIdentifier(node) && node.getText() === "undefined";
|
|
1215
1208
|
/**
|
|
1216
1209
|
* An expression whose evaluation cannot do anything observable, so deleting it preserves
|
|
1217
1210
|
* behaviour.
|
|
@@ -1223,26 +1216,26 @@ const isInertArgument = (node) => ts_morph.Node.isStringLiteral(node) || ts_morp
|
|
|
1223
1216
|
*/
|
|
1224
1217
|
const isInertExpression = (node) => {
|
|
1225
1218
|
if (isInertArgument(node)) return true;
|
|
1226
|
-
if (
|
|
1227
|
-
if (
|
|
1228
|
-
if (
|
|
1229
|
-
if (
|
|
1230
|
-
if (
|
|
1231
|
-
const operator = node.
|
|
1232
|
-
return (operator ===
|
|
1219
|
+
if (_bamboocss_ts_ast.Node.isIdentifier(node)) return true;
|
|
1220
|
+
if (_bamboocss_ts_ast.Node.isAsExpression(node) || _bamboocss_ts_ast.Node.isSatisfiesExpression(node) || _bamboocss_ts_ast.Node.isNonNullExpression(node) || _bamboocss_ts_ast.Node.isTypeAssertion(node) || _bamboocss_ts_ast.Node.isParenthesizedExpression(node)) return isInertExpression(node.expression);
|
|
1221
|
+
if (_bamboocss_ts_ast.Node.isArrowFunction(node) || _bamboocss_ts_ast.Node.isFunctionExpression(node)) return true;
|
|
1222
|
+
if (_bamboocss_ts_ast.Node.isRegularExpressionLiteral(node) || _bamboocss_ts_ast.Node.isBigIntLiteral(node)) return true;
|
|
1223
|
+
if (_bamboocss_ts_ast.Node.isPrefixUnaryExpression(node)) {
|
|
1224
|
+
const operator = node.operator;
|
|
1225
|
+
return (operator === _bamboocss_ts_ast.SyntaxKind.MinusToken || operator === _bamboocss_ts_ast.SyntaxKind.PlusToken || operator === _bamboocss_ts_ast.SyntaxKind.ExclamationToken || operator === _bamboocss_ts_ast.SyntaxKind.TildeToken) && isInertExpression(node.operand);
|
|
1233
1226
|
}
|
|
1234
|
-
if (
|
|
1235
|
-
const operator = node.
|
|
1236
|
-
return (operator ===
|
|
1227
|
+
if (_bamboocss_ts_ast.Node.isBinaryExpression(node)) {
|
|
1228
|
+
const operator = node.operatorToken.kind;
|
|
1229
|
+
return (operator === _bamboocss_ts_ast.SyntaxKind.QuestionQuestionToken || operator === _bamboocss_ts_ast.SyntaxKind.BarBarToken || operator === _bamboocss_ts_ast.SyntaxKind.AmpersandAmpersandToken) && isInertExpression(node.left) && isInertExpression(node.right);
|
|
1237
1230
|
}
|
|
1238
|
-
if (
|
|
1239
|
-
if (
|
|
1240
|
-
if (!
|
|
1241
|
-
if (
|
|
1242
|
-
const initializer = property.
|
|
1231
|
+
if (_bamboocss_ts_ast.Node.isObjectLiteralExpression(node)) return node.properties.every((property) => {
|
|
1232
|
+
if (_bamboocss_ts_ast.Node.isShorthandPropertyAssignment(property)) return true;
|
|
1233
|
+
if (!_bamboocss_ts_ast.Node.isPropertyAssignment(property)) return false;
|
|
1234
|
+
if (_bamboocss_ts_ast.Node.isComputedPropertyName(property.name)) return false;
|
|
1235
|
+
const initializer = property.initializer;
|
|
1243
1236
|
return initializer !== void 0 && isInertExpression(initializer);
|
|
1244
1237
|
});
|
|
1245
|
-
if (
|
|
1238
|
+
if (_bamboocss_ts_ast.Node.isArrayLiteralExpression(node)) return node.elements.every(isInertExpression);
|
|
1246
1239
|
return false;
|
|
1247
1240
|
};
|
|
1248
1241
|
/**
|
|
@@ -1274,7 +1267,7 @@ const createDependencyScan = (ownFile) => {
|
|
|
1274
1267
|
if (sourceFile === ownFile) return;
|
|
1275
1268
|
let path = paths.get(sourceFile);
|
|
1276
1269
|
if (path === void 0) {
|
|
1277
|
-
path =
|
|
1270
|
+
path = (0, _bamboocss_ts_ast.pathOf)(sourceFile);
|
|
1278
1271
|
paths.set(sourceFile, path);
|
|
1279
1272
|
}
|
|
1280
1273
|
if (path) results.add(path);
|
|
@@ -1291,13 +1284,13 @@ const createDependencyScan = (ownFile) => {
|
|
|
1291
1284
|
*/
|
|
1292
1285
|
const findCallExpression = (node) => {
|
|
1293
1286
|
const own = node.getNode?.();
|
|
1294
|
-
if (own &&
|
|
1287
|
+
if (own && _bamboocss_ts_ast.Node.isCallExpression(own)) return own;
|
|
1295
1288
|
const stack = node.getStack?.() ?? [];
|
|
1296
|
-
for (const entry of stack) if (
|
|
1289
|
+
for (const entry of stack) if (_bamboocss_ts_ast.Node.isCallExpression(entry)) return entry;
|
|
1297
1290
|
let current = own;
|
|
1298
1291
|
for (let depth = 0; current && depth < 3; depth++) {
|
|
1299
|
-
if (
|
|
1300
|
-
current = current.
|
|
1292
|
+
if (_bamboocss_ts_ast.Node.isCallExpression(current)) return current;
|
|
1293
|
+
current = current.parent;
|
|
1301
1294
|
}
|
|
1302
1295
|
};
|
|
1303
1296
|
/**
|
|
@@ -1306,16 +1299,16 @@ const findCallExpression = (node) => {
|
|
|
1306
1299
|
* normalizes function names, so the parser result cannot tell us; the callee text can.
|
|
1307
1300
|
*/
|
|
1308
1301
|
const isRawCall = (call) => {
|
|
1309
|
-
if (!
|
|
1310
|
-
const callee = call.
|
|
1302
|
+
if (!_bamboocss_ts_ast.Node.isCallExpression(call)) return false;
|
|
1303
|
+
const callee = call.expression.getText();
|
|
1311
1304
|
return callee === "raw" || callee.endsWith(".raw");
|
|
1312
1305
|
};
|
|
1313
1306
|
/** The identifier a callee is rooted at: `css` for `css(…)`, `panda` for `panda.css(…)`. */
|
|
1314
1307
|
const calleeRootName = (call) => {
|
|
1315
|
-
if (!
|
|
1316
|
-
let current = call.
|
|
1317
|
-
while (
|
|
1318
|
-
return
|
|
1308
|
+
if (!_bamboocss_ts_ast.Node.isCallExpression(call)) return void 0;
|
|
1309
|
+
let current = call.expression;
|
|
1310
|
+
while (_bamboocss_ts_ast.Node.isPropertyAccessExpression(current)) current = current.expression;
|
|
1311
|
+
return _bamboocss_ts_ast.Node.isIdentifier(current) ? current.getText() : void 0;
|
|
1319
1312
|
};
|
|
1320
1313
|
/**
|
|
1321
1314
|
* Local names a module binds to an import of bamboo's own generated system.
|
|
@@ -1334,26 +1327,26 @@ const calleeRootName = (call) => {
|
|
|
1334
1327
|
*/
|
|
1335
1328
|
const bambooImportedNames = (sourceFile, ctx) => {
|
|
1336
1329
|
const names = /* @__PURE__ */ new Set();
|
|
1337
|
-
for (const declaration of
|
|
1338
|
-
const mod =
|
|
1339
|
-
for (const named of
|
|
1340
|
-
const name =
|
|
1341
|
-
const alias =
|
|
1330
|
+
for (const declaration of (0, _bamboocss_ts_ast.getImportDeclarations)(sourceFile)) {
|
|
1331
|
+
const mod = (0, _bamboocss_ts_ast.getModuleSpecifierValue)(declaration);
|
|
1332
|
+
for (const named of (0, _bamboocss_ts_ast.getNamedImports)(declaration)) {
|
|
1333
|
+
const name = (0, _bamboocss_ts_ast.nameNodeOf)(named)?.getText();
|
|
1334
|
+
const alias = (0, _bamboocss_ts_ast.getAliasNode)(named)?.getText() ?? name;
|
|
1342
1335
|
if (ctx.imports.match({
|
|
1343
|
-
mod,
|
|
1344
|
-
name,
|
|
1345
|
-
alias
|
|
1346
|
-
})) names.add(alias);
|
|
1336
|
+
mod: mod ?? "",
|
|
1337
|
+
name: name ?? "",
|
|
1338
|
+
alias: alias ?? ""
|
|
1339
|
+
})) names.add(alias ?? "");
|
|
1347
1340
|
}
|
|
1348
|
-
const namespace =
|
|
1341
|
+
const namespace = (0, _bamboocss_ts_ast.getNamespaceImport)(declaration);
|
|
1349
1342
|
if (namespace) {
|
|
1350
1343
|
const alias = namespace.getText();
|
|
1351
1344
|
if (ctx.imports.match({
|
|
1352
|
-
mod,
|
|
1353
|
-
name: alias,
|
|
1354
|
-
alias,
|
|
1345
|
+
mod: mod ?? "",
|
|
1346
|
+
name: alias ?? "",
|
|
1347
|
+
alias: alias ?? "",
|
|
1355
1348
|
kind: "namespace"
|
|
1356
|
-
})) names.add(alias);
|
|
1349
|
+
})) names.add(alias ?? "");
|
|
1357
1350
|
}
|
|
1358
1351
|
}
|
|
1359
1352
|
return names;
|
|
@@ -1368,8 +1361,8 @@ const bambooImportedNames = (sourceFile, ctx) => {
|
|
|
1368
1361
|
* attributes, which match neither and cost nothing.
|
|
1369
1362
|
*/
|
|
1370
1363
|
const isShadowed = (call, name) => {
|
|
1371
|
-
for (let node = call.
|
|
1372
|
-
if (
|
|
1364
|
+
for (let node = call.parent; node; node = node.parent) {
|
|
1365
|
+
if (_bamboocss_ts_ast.Node.isSourceFile(node)) return false;
|
|
1373
1366
|
if (bindsName(node, name)) return true;
|
|
1374
1367
|
}
|
|
1375
1368
|
return false;
|
|
@@ -1384,21 +1377,21 @@ const isShadowed = (call, name) => {
|
|
|
1384
1377
|
*/
|
|
1385
1378
|
const bindingIntroduces = (nameNode, name) => {
|
|
1386
1379
|
if (!nameNode) return false;
|
|
1387
|
-
if (
|
|
1388
|
-
if (
|
|
1380
|
+
if (_bamboocss_ts_ast.Node.isIdentifier(nameNode)) return nameNode.getText() === name;
|
|
1381
|
+
if (_bamboocss_ts_ast.Node.isObjectBindingPattern(nameNode) || _bamboocss_ts_ast.Node.isArrayBindingPattern(nameNode)) return nameNode.elements.some((element) => _bamboocss_ts_ast.Node.isBindingElement(element) && bindingIntroduces(element.name, name));
|
|
1389
1382
|
return false;
|
|
1390
1383
|
};
|
|
1391
|
-
const declarationsBind = (list, name) =>
|
|
1384
|
+
const declarationsBind = (list, name) => list !== void 0 && _bamboocss_ts_ast.Node.isVariableDeclarationList(list) && list.declarations.some((declaration) => bindingIntroduces(declaration.name, name));
|
|
1392
1385
|
const bindsName = (scope, name) => {
|
|
1393
|
-
if (
|
|
1394
|
-
if (
|
|
1395
|
-
if (
|
|
1396
|
-
if (
|
|
1386
|
+
if (_bamboocss_ts_ast.Node.isBlock(scope)) return scope.statements.some((statement) => statementBinds(statement, name));
|
|
1387
|
+
if (_bamboocss_ts_ast.Node.isFunctionDeclaration(scope) || _bamboocss_ts_ast.Node.isArrowFunction(scope) || _bamboocss_ts_ast.Node.isFunctionExpression(scope) || _bamboocss_ts_ast.Node.isMethodDeclaration(scope)) return scope.parameters.some((parameter) => bindingIntroduces(parameter.name, name));
|
|
1388
|
+
if (_bamboocss_ts_ast.Node.isCatchClause(scope)) return bindingIntroduces(scope.variableDeclaration?.name, name);
|
|
1389
|
+
if (_bamboocss_ts_ast.Node.isForStatement(scope) || _bamboocss_ts_ast.Node.isForOfStatement(scope) || _bamboocss_ts_ast.Node.isForInStatement(scope)) return declarationsBind(scope.initializer, name);
|
|
1397
1390
|
return false;
|
|
1398
1391
|
};
|
|
1399
1392
|
const statementBinds = (statement, name) => {
|
|
1400
|
-
if (
|
|
1401
|
-
if (
|
|
1393
|
+
if (_bamboocss_ts_ast.Node.isVariableStatement(statement)) return statement.declarationList.declarations.some((declaration) => bindingIntroduces(declaration.name, name));
|
|
1394
|
+
if (_bamboocss_ts_ast.Node.isFunctionDeclaration(statement) || _bamboocss_ts_ast.Node.isClassDeclaration(statement)) return statement.name?.getText() === name;
|
|
1402
1395
|
return false;
|
|
1403
1396
|
};
|
|
1404
1397
|
const hasStyles = (data) => data.length > 0 && data.every((entry) => entry != null && typeof entry === "object");
|
|
@@ -1408,8 +1401,8 @@ const hasStyles = (data) => data.length > 0 && data.every((entry) => entry != nu
|
|
|
1408
1401
|
* (multi-arg calls) or just the first argument's map (single-arg calls).
|
|
1409
1402
|
*/
|
|
1410
1403
|
const argumentsAccountedFor = (call, boxNode) => {
|
|
1411
|
-
if (!
|
|
1412
|
-
const args = call.
|
|
1404
|
+
if (!_bamboocss_ts_ast.Node.isCallExpression(call)) return false;
|
|
1405
|
+
const args = call.arguments;
|
|
1413
1406
|
if (args.length === 0) return true;
|
|
1414
1407
|
if (_bamboocss_extractor.box.isArray(boxNode) && boxNode.getNode() === call) {
|
|
1415
1408
|
if (boxNode.value.length !== args.length) return false;
|
|
@@ -1515,13 +1508,13 @@ const foldSource = (options) => {
|
|
|
1515
1508
|
* its `/recipes` suffix; falling back to the configured generated entry covers bare imports.
|
|
1516
1509
|
*/
|
|
1517
1510
|
const configRecipeCssSpecifier = (call, binding) => {
|
|
1518
|
-
for (const declaration of call.getSourceFile()
|
|
1519
|
-
if (
|
|
1520
|
-
if (!
|
|
1521
|
-
if (
|
|
1522
|
-
return (
|
|
1511
|
+
for (const declaration of (0, _bamboocss_ts_ast.getImportDeclarations)(call.getSourceFile())) {
|
|
1512
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(declaration)) continue;
|
|
1513
|
+
if (!(0, _bamboocss_ts_ast.getNamedImports)(declaration).some((named) => {
|
|
1514
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(named)) return false;
|
|
1515
|
+
return ((0, _bamboocss_ts_ast.getAliasNode)(named) ?? (0, _bamboocss_ts_ast.nameNodeOf)(named))?.getText() === binding;
|
|
1523
1516
|
})) continue;
|
|
1524
|
-
const mod =
|
|
1517
|
+
const mod = ((0, _bamboocss_ts_ast.getModuleSpecifierValue)(declaration) ?? "").replaceAll("\\", "/");
|
|
1525
1518
|
const at = mod.lastIndexOf("/recipes");
|
|
1526
1519
|
if (at >= 0) return `${mod.slice(0, at)}/css`;
|
|
1527
1520
|
}
|
|
@@ -1539,10 +1532,10 @@ const foldSource = (options) => {
|
|
|
1539
1532
|
* expressed from the module being folded.
|
|
1540
1533
|
*/
|
|
1541
1534
|
const cssModuleSpecifierFrom = (declaring) => {
|
|
1542
|
-
for (const declaration of
|
|
1543
|
-
if (
|
|
1544
|
-
const mod =
|
|
1545
|
-
if (isGeneratedCssModule(mod)) return mod;
|
|
1535
|
+
for (const declaration of (0, _bamboocss_ts_ast.getImportDeclarations)(declaring)) {
|
|
1536
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(declaration)) continue;
|
|
1537
|
+
const mod = (0, _bamboocss_ts_ast.getModuleSpecifierValue)(declaration);
|
|
1538
|
+
if (isGeneratedCssModule(mod ?? "")) return mod;
|
|
1546
1539
|
}
|
|
1547
1540
|
};
|
|
1548
1541
|
/**
|
|
@@ -1593,7 +1586,7 @@ const foldSource = (options) => {
|
|
|
1593
1586
|
const resolve = () => {
|
|
1594
1587
|
if (!parseModule) return void 0;
|
|
1595
1588
|
const consuming = call.getSourceFile();
|
|
1596
|
-
if (origin.filePath ===
|
|
1589
|
+
if (origin.filePath === (0, _bamboocss_ts_ast.pathOf)(consuming)) return void 0;
|
|
1597
1590
|
let foreign = configsByModule.get(origin.filePath);
|
|
1598
1591
|
if (!foreign) {
|
|
1599
1592
|
const result = parseModule(origin.filePath);
|
|
@@ -1620,7 +1613,7 @@ const foldSource = (options) => {
|
|
|
1620
1613
|
name: origin.name,
|
|
1621
1614
|
digest: digestRecipeConfig(entry)
|
|
1622
1615
|
});
|
|
1623
|
-
helperModules.set(name, foreign.cssSpecifier ? rebaseSpecifier(foreign.cssSpecifier, origin.filePath,
|
|
1616
|
+
helperModules.set(name, foreign.cssSpecifier ? rebaseSpecifier(foreign.cssSpecifier, origin.filePath, (0, _bamboocss_ts_ast.pathOf)(consuming)) : void 0);
|
|
1624
1617
|
return entry;
|
|
1625
1618
|
};
|
|
1626
1619
|
const resolved = resolve();
|
|
@@ -1637,7 +1630,7 @@ const foldSource = (options) => {
|
|
|
1637
1630
|
if (entry === AMBIGUOUS) continue;
|
|
1638
1631
|
const definition = entry.box?.getNode?.();
|
|
1639
1632
|
if (!definition) continue;
|
|
1640
|
-
const call =
|
|
1633
|
+
const call = _bamboocss_ts_ast.Node.isCallExpression(definition) ? definition : (0, _bamboocss_ts_ast.getFirstAncestorByKind)(definition, _bamboocss_ts_ast.SyntaxKind.CallExpression);
|
|
1641
1634
|
if (!call || code.slice(call.getStart(), call.getEnd()) !== call.getText()) continue;
|
|
1642
1635
|
recipeDefinitions.push({
|
|
1643
1636
|
name,
|
|
@@ -1694,8 +1687,8 @@ const foldSource = (options) => {
|
|
|
1694
1687
|
});
|
|
1695
1688
|
continue;
|
|
1696
1689
|
}
|
|
1697
|
-
const callee =
|
|
1698
|
-
const propertyName =
|
|
1690
|
+
const callee = _bamboocss_ts_ast.Node.isCallExpression(call) ? call.expression : void 0;
|
|
1691
|
+
const propertyName = callee !== void 0 && _bamboocss_ts_ast.Node.isPropertyAccessExpression(callee) ? (0, _bamboocss_ts_ast.nameNodeOf)(callee)?.getText() ?? "" : void 0;
|
|
1699
1692
|
const wantsValue = type === "tokenValue";
|
|
1700
1693
|
if (wantsValue !== (propertyName === "value")) {
|
|
1701
1694
|
skipped.push({
|
|
@@ -1734,7 +1727,7 @@ const foldSource = (options) => {
|
|
|
1734
1727
|
});
|
|
1735
1728
|
continue;
|
|
1736
1729
|
}
|
|
1737
|
-
if (!(
|
|
1730
|
+
if (!(_bamboocss_ts_ast.Node.isCallExpression(call) ? call.arguments.slice(1) : []).every(isInertArgument)) {
|
|
1738
1731
|
skipped.push({
|
|
1739
1732
|
name,
|
|
1740
1733
|
reason: "dynamic",
|
|
@@ -1808,16 +1801,16 @@ const foldSource = (options) => {
|
|
|
1808
1801
|
let inlineSlot;
|
|
1809
1802
|
let inlineEnd = end;
|
|
1810
1803
|
if (Array.isArray(entry?.config.slots)) {
|
|
1811
|
-
const parent = call.
|
|
1812
|
-
if (
|
|
1813
|
-
const accessed =
|
|
1804
|
+
const parent = call.parent;
|
|
1805
|
+
if (_bamboocss_ts_ast.Node.isPropertyAccessExpression(parent) && parent.expression === call) {
|
|
1806
|
+
const accessed = (0, _bamboocss_ts_ast.getName)(parent);
|
|
1814
1807
|
if (entry.config.slots.includes(accessed)) {
|
|
1815
1808
|
inlineSlot = accessed;
|
|
1816
1809
|
inlineEnd = parent.getEnd();
|
|
1817
1810
|
}
|
|
1818
|
-
} else if (
|
|
1819
|
-
const argument = parent.
|
|
1820
|
-
const accessed = argument && (
|
|
1811
|
+
} else if (_bamboocss_ts_ast.Node.isElementAccessExpression(parent) && parent.expression === call) {
|
|
1812
|
+
const argument = parent.argumentExpression;
|
|
1813
|
+
const accessed = argument && (_bamboocss_ts_ast.Node.isStringLiteral(argument) || _bamboocss_ts_ast.Node.isNoSubstitutionTemplateLiteral(argument)) ? (0, _bamboocss_ts_ast.literalValueOf)(argument) : void 0;
|
|
1821
1814
|
if (typeof accessed === "string" && entry.config.slots.includes(accessed)) {
|
|
1822
1815
|
inlineSlot = accessed;
|
|
1823
1816
|
inlineEnd = parent.getEnd();
|
|
@@ -1915,9 +1908,9 @@ const foldSource = (options) => {
|
|
|
1915
1908
|
}
|
|
1916
1909
|
const start = call.getStart();
|
|
1917
1910
|
const end = call.getEnd();
|
|
1918
|
-
const memberParent = call.
|
|
1919
|
-
const accessed = type === "recipe" &&
|
|
1920
|
-
const accessedName = accessed?.
|
|
1911
|
+
const memberParent = call.parent;
|
|
1912
|
+
const accessed = type === "recipe" && _bamboocss_ts_ast.Node.isPropertyAccessExpression(memberParent) && memberParent.expression === call ? memberParent : void 0;
|
|
1913
|
+
const accessedName = accessed?.name.getText();
|
|
1921
1914
|
const declaredSlots = accessed ? ctx.recipes.getConfig(name)?.slots ?? [] : [];
|
|
1922
1915
|
const memberAccess = accessedName && declaredSlots.includes(accessedName) ? accessed : void 0;
|
|
1923
1916
|
const slot = memberAccess ? accessedName : void 0;
|
|
@@ -1953,7 +1946,7 @@ const foldSource = (options) => {
|
|
|
1953
1946
|
});
|
|
1954
1947
|
continue;
|
|
1955
1948
|
}
|
|
1956
|
-
if (!(
|
|
1949
|
+
if (!(_bamboocss_ts_ast.Node.isCallExpression(call) && call.arguments.length === 0 && item.data.length === 1) && !isStaticBox(item.box) || !hasStyles(item.data) || !argumentsAccountedFor(call, item.box)) {
|
|
1957
1950
|
skipped.push({
|
|
1958
1951
|
name,
|
|
1959
1952
|
reason: "dynamic",
|
|
@@ -2001,17 +1994,17 @@ const foldSource = (options) => {
|
|
|
2001
1994
|
const sourceFile = ownSourceFile ?? candidates[0]?.node.getSourceFile();
|
|
2002
1995
|
if (sourceFile) {
|
|
2003
1996
|
const cxBindings = /* @__PURE__ */ new Set();
|
|
2004
|
-
for (const declaration of
|
|
2005
|
-
if (
|
|
2006
|
-
for (const named of
|
|
2007
|
-
if (
|
|
2008
|
-
cxBindings.add((
|
|
1997
|
+
for (const declaration of (0, _bamboocss_ts_ast.getImportDeclarations)(sourceFile)) {
|
|
1998
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(declaration) || !isBambooCssModule((0, _bamboocss_ts_ast.getModuleSpecifierValue)(declaration) ?? "")) continue;
|
|
1999
|
+
for (const named of (0, _bamboocss_ts_ast.getNamedImports)(declaration)) {
|
|
2000
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(named) || (0, _bamboocss_ts_ast.nameNodeOf)(named)?.getText() !== "cx") continue;
|
|
2001
|
+
cxBindings.add(((0, _bamboocss_ts_ast.getAliasNode)(named) ?? (0, _bamboocss_ts_ast.nameNodeOf)(named))?.getText() ?? "");
|
|
2009
2002
|
}
|
|
2010
2003
|
}
|
|
2011
2004
|
const byRange = new Map(candidates.map((candidate) => [`${candidate.start}:${candidate.end}`, candidate]));
|
|
2012
|
-
for (const call of cxBindings.size ?
|
|
2013
|
-
const callee =
|
|
2014
|
-
if (!
|
|
2005
|
+
for (const call of cxBindings.size ? (0, _bamboocss_ts_ast.getDescendantsOfKind)(sourceFile, _bamboocss_ts_ast.SyntaxKind.CallExpression) : []) {
|
|
2006
|
+
const callee = (0, _bamboocss_ts_ast.childOf)(call, "expression");
|
|
2007
|
+
if (callee === void 0 || !_bamboocss_ts_ast.Node.isIdentifier(callee) || !cxBindings.has(callee.getText()) || isShadowed(call, callee.getText())) continue;
|
|
2015
2008
|
const matched = [];
|
|
2016
2009
|
const parts = [];
|
|
2017
2010
|
const dynamic = [];
|
|
@@ -2044,21 +2037,21 @@ const foldSource = (options) => {
|
|
|
2044
2037
|
});
|
|
2045
2038
|
return true;
|
|
2046
2039
|
}
|
|
2047
|
-
if (
|
|
2040
|
+
if (_bamboocss_ts_ast.Node.isStringLiteral(arg) || _bamboocss_ts_ast.Node.isNoSubstitutionTemplateLiteral(arg)) {
|
|
2048
2041
|
parts.push({
|
|
2049
2042
|
kind: "class",
|
|
2050
|
-
value:
|
|
2043
|
+
value: (0, _bamboocss_ts_ast.stringLiteralValue)(arg)
|
|
2051
2044
|
});
|
|
2052
2045
|
return true;
|
|
2053
2046
|
}
|
|
2054
|
-
if (
|
|
2055
|
-
for (const element of arg.
|
|
2047
|
+
if (_bamboocss_ts_ast.Node.isArrayLiteralExpression(arg)) {
|
|
2048
|
+
for (const element of arg.elements) if (_bamboocss_ts_ast.Node.isSpreadElement(element) || !take(element)) return false;
|
|
2056
2049
|
return true;
|
|
2057
2050
|
}
|
|
2058
|
-
if (arg.
|
|
2051
|
+
if (arg.kind === _bamboocss_ts_ast.SyntaxKind.FalseKeyword || arg.kind === _bamboocss_ts_ast.SyntaxKind.TrueKeyword || _bamboocss_ts_ast.Node.isNumericLiteral(arg) || arg.kind === _bamboocss_ts_ast.SyntaxKind.NullKeyword || _bamboocss_ts_ast.Node.isIdentifier(arg) && arg.getText() === "undefined") return true;
|
|
2059
2052
|
return false;
|
|
2060
2053
|
};
|
|
2061
|
-
for (const arg of
|
|
2054
|
+
for (const arg of (0, _bamboocss_ts_ast.childOf)(call, "arguments") ?? []) {
|
|
2062
2055
|
if (take(arg)) continue;
|
|
2063
2056
|
supported = false;
|
|
2064
2057
|
break;
|
|
@@ -2288,10 +2281,10 @@ const foldSource = (options) => {
|
|
|
2288
2281
|
collectSourceFiles(item.box, dependencyScan);
|
|
2289
2282
|
}
|
|
2290
2283
|
const recipeSourceFile = candidates[0]?.node.getSourceFile();
|
|
2291
|
-
if (recipeSourceFile && mayNameSplitVariantProps(recipeSourceFile.getFullText())) for (const access of
|
|
2292
|
-
if (
|
|
2293
|
-
const target =
|
|
2294
|
-
if (!
|
|
2284
|
+
if (recipeSourceFile && mayNameSplitVariantProps(recipeSourceFile.getFullText())) for (const access of (0, _bamboocss_ts_ast.getDescendantsOfKind)(recipeSourceFile, _bamboocss_ts_ast.SyntaxKind.PropertyAccessExpression)) {
|
|
2285
|
+
if ((0, _bamboocss_ts_ast.getName)(access) !== "splitVariantProps") continue;
|
|
2286
|
+
const target = (0, _bamboocss_ts_ast.childOf)(access, "expression");
|
|
2287
|
+
if (target === void 0 || !_bamboocss_ts_ast.Node.isIdentifier(target)) continue;
|
|
2295
2288
|
if (isShadowed(access, target.getText())) continue;
|
|
2296
2289
|
const local = recipeConfigs?.get(target.getText());
|
|
2297
2290
|
const importedConfig = !local && importsFor(recipeSourceFile).has(target.getText()) ? ctx.recipes.getConfig(target.getText()) : void 0;
|
|
@@ -2300,9 +2293,9 @@ const foldSource = (options) => {
|
|
|
2300
2293
|
box: void 0
|
|
2301
2294
|
} : void 0;
|
|
2302
2295
|
if (!entry) continue;
|
|
2303
|
-
const call = access.
|
|
2304
|
-
if (!
|
|
2305
|
-
const args = call.
|
|
2296
|
+
const call = access.parent;
|
|
2297
|
+
if (!_bamboocss_ts_ast.Node.isCallExpression(call) || call.expression !== access) continue;
|
|
2298
|
+
const args = call.arguments;
|
|
2306
2299
|
if (args.length !== 1) continue;
|
|
2307
2300
|
const start = call.getStart();
|
|
2308
2301
|
const end = call.getEnd();
|
|
@@ -2344,11 +2337,11 @@ const foldSource = (options) => {
|
|
|
2344
2337
|
*/
|
|
2345
2338
|
/** The specifier this module imported `binding` through, if it did. */
|
|
2346
2339
|
function importSpecifierFor(sourceFile, binding) {
|
|
2347
|
-
for (const declaration of
|
|
2348
|
-
if (
|
|
2349
|
-
for (const named of
|
|
2350
|
-
if (
|
|
2351
|
-
if ((
|
|
2340
|
+
for (const declaration of (0, _bamboocss_ts_ast.getImportDeclarations)(sourceFile)) {
|
|
2341
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(declaration)) continue;
|
|
2342
|
+
for (const named of (0, _bamboocss_ts_ast.getNamedImports)(declaration)) {
|
|
2343
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(named)) continue;
|
|
2344
|
+
if (((0, _bamboocss_ts_ast.getAliasNode)(named) ?? (0, _bamboocss_ts_ast.nameNodeOf)(named))?.getText() === binding) return (0, _bamboocss_ts_ast.getAliasNode)(named) ?? (0, _bamboocss_ts_ast.nameNodeOf)(named);
|
|
2352
2345
|
}
|
|
2353
2346
|
}
|
|
2354
2347
|
}
|
|
@@ -2376,9 +2369,9 @@ const foldSource = (options) => {
|
|
|
2376
2369
|
if (entry === AMBIGUOUS) continue;
|
|
2377
2370
|
if (!entry && !importedRecipeBindings.has(binding)) continue;
|
|
2378
2371
|
const definition = entry?.box?.getNode?.();
|
|
2379
|
-
const nameNode = definition?.getSourceFile() === sourceFile ?
|
|
2380
|
-
if (!nameNode || !
|
|
2381
|
-
const references = localReferencesTo(identifiersByName(), binding, nameNode).filter((reference) => !
|
|
2372
|
+
const nameNode = definition?.getSourceFile() === sourceFile ? (0, _bamboocss_ts_ast.nameNodeOf)((0, _bamboocss_ts_ast.getFirstAncestorByKind)(definition, _bamboocss_ts_ast.SyntaxKind.VariableDeclaration)) : importSpecifierFor(sourceFile, binding);
|
|
2373
|
+
if (!nameNode || !_bamboocss_ts_ast.Node.isIdentifier(nameNode)) continue;
|
|
2374
|
+
const references = localReferencesTo(identifiersByName(), binding, nameNode).filter((reference) => !(0, _bamboocss_ts_ast.getFirstAncestorByKind)(reference, _bamboocss_ts_ast.SyntaxKind.TypeQuery));
|
|
2382
2375
|
if (skipped.filter((item) => SURVIVES_TO_RUNTIME.has(item.reason) && item.end > item.start).some((item) => references.some((ref) => ref.getStart() >= item.start && ref.getStart() < item.end))) continue;
|
|
2383
2376
|
const survivor = references.find((ref) => !applied.some(([from, to]) => ref.getStart() >= from && ref.getStart() < to));
|
|
2384
2377
|
if (!survivor) continue;
|
|
@@ -2397,17 +2390,17 @@ const foldSource = (options) => {
|
|
|
2397
2390
|
];
|
|
2398
2391
|
const runtimeCalls = [];
|
|
2399
2392
|
const importEquals = [];
|
|
2400
|
-
|
|
2401
|
-
if (
|
|
2402
|
-
else if (
|
|
2393
|
+
(0, _bamboocss_ts_ast.forEachDescendant)(sourceFile, (node) => {
|
|
2394
|
+
if (_bamboocss_ts_ast.Node.isCallExpression(node)) runtimeCalls.push(node);
|
|
2395
|
+
else if (_bamboocss_ts_ast.Node.isImportEqualsDeclaration(node)) importEquals.push(node);
|
|
2403
2396
|
});
|
|
2404
2397
|
for (const call of runtimeCalls) {
|
|
2405
|
-
const callee = call.
|
|
2406
|
-
const argument = call.
|
|
2407
|
-
if (!argument || !
|
|
2408
|
-
if (!matchesModule(
|
|
2409
|
-
const isDynamicImport = callee.
|
|
2410
|
-
const isRequire =
|
|
2398
|
+
const callee = call.expression;
|
|
2399
|
+
const argument = call.arguments[0];
|
|
2400
|
+
if (!argument || !_bamboocss_ts_ast.Node.isStringLiteral(argument) && !_bamboocss_ts_ast.Node.isNoSubstitutionTemplateLiteral(argument)) continue;
|
|
2401
|
+
if (!matchesModule((0, _bamboocss_ts_ast.stringLiteralValue)(argument), bambooModules)) continue;
|
|
2402
|
+
const isDynamicImport = callee.kind === _bamboocss_ts_ast.SyntaxKind.ImportKeyword;
|
|
2403
|
+
const isRequire = _bamboocss_ts_ast.Node.isIdentifier(callee) && callee.getText() === "require" && !isShadowed(call, "require");
|
|
2411
2404
|
if (!isDynamicImport && !isRequire) continue;
|
|
2412
2405
|
skipped.push({
|
|
2413
2406
|
name: isDynamicImport ? "import" : "require",
|
|
@@ -2417,13 +2410,13 @@ const foldSource = (options) => {
|
|
|
2417
2410
|
});
|
|
2418
2411
|
}
|
|
2419
2412
|
for (const declaration of importEquals) {
|
|
2420
|
-
if (
|
|
2421
|
-
const reference = declaration.
|
|
2422
|
-
if (!
|
|
2423
|
-
const expression = reference.
|
|
2424
|
-
if (!expression || !
|
|
2413
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(declaration)) continue;
|
|
2414
|
+
const reference = declaration.moduleReference;
|
|
2415
|
+
if (!_bamboocss_ts_ast.Node.isExternalModuleReference(reference)) continue;
|
|
2416
|
+
const expression = reference.expression;
|
|
2417
|
+
if (!expression || !_bamboocss_ts_ast.Node.isStringLiteral(expression) || !matchesModule((0, _bamboocss_ts_ast.stringLiteralValue)(expression), bambooModules)) continue;
|
|
2425
2418
|
skipped.push({
|
|
2426
|
-
name:
|
|
2419
|
+
name: (0, _bamboocss_ts_ast.getName)(declaration) ?? "",
|
|
2427
2420
|
reason: "runtime-binding",
|
|
2428
2421
|
start: declaration.getStart(),
|
|
2429
2422
|
end: declaration.getEnd()
|
|
@@ -2431,52 +2424,53 @@ const foldSource = (options) => {
|
|
|
2431
2424
|
}
|
|
2432
2425
|
/** Local name -> what to call it in the report. */
|
|
2433
2426
|
const watched = /* @__PURE__ */ new Map();
|
|
2434
|
-
for (const declaration of
|
|
2435
|
-
if (
|
|
2436
|
-
if (!matchesModule(
|
|
2437
|
-
for (const named of
|
|
2438
|
-
if (
|
|
2439
|
-
const imported =
|
|
2440
|
-
if (PERMITTED_BINDINGS.has(imported)) continue;
|
|
2441
|
-
watched.set((
|
|
2427
|
+
for (const declaration of (0, _bamboocss_ts_ast.getImportDeclarations)(sourceFile)) {
|
|
2428
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(declaration)) continue;
|
|
2429
|
+
if (!matchesModule((0, _bamboocss_ts_ast.getModuleSpecifierValue)(declaration) ?? "", bambooModules)) continue;
|
|
2430
|
+
for (const named of (0, _bamboocss_ts_ast.getNamedImports)(declaration)) {
|
|
2431
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(named)) continue;
|
|
2432
|
+
const imported = (0, _bamboocss_ts_ast.nameNodeOf)(named)?.getText();
|
|
2433
|
+
if (PERMITTED_BINDINGS.has(imported ?? "")) continue;
|
|
2434
|
+
watched.set(((0, _bamboocss_ts_ast.getAliasNode)(named) ?? (0, _bamboocss_ts_ast.nameNodeOf)(named))?.getText() ?? "", imported ?? "");
|
|
2442
2435
|
}
|
|
2443
|
-
const namespace =
|
|
2436
|
+
const namespace = (0, _bamboocss_ts_ast.getNamespaceImport)(declaration);
|
|
2444
2437
|
if (namespace) watched.set(namespace.getText(), `${namespace.getText()}.*`);
|
|
2445
|
-
const defaultImport =
|
|
2438
|
+
const defaultImport = (0, _bamboocss_ts_ast.getDefaultImport)(declaration);
|
|
2446
2439
|
if (defaultImport) watched.set(defaultImport.getText(), defaultImport.getText());
|
|
2447
2440
|
}
|
|
2448
|
-
for (const declaration of
|
|
2449
|
-
if (
|
|
2450
|
-
if (!matchesModule(
|
|
2451
|
-
if (
|
|
2441
|
+
for (const declaration of (0, _bamboocss_ts_ast.getExportDeclarations)(sourceFile)) {
|
|
2442
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(declaration)) continue;
|
|
2443
|
+
if (!matchesModule((0, _bamboocss_ts_ast.getModuleSpecifierValue)(declaration) ?? "", bambooModules)) continue;
|
|
2444
|
+
if ((0, _bamboocss_ts_ast.isStarExport)(declaration)) {
|
|
2445
|
+
const namespace = (0, _bamboocss_ts_ast.getNamespaceExport)(declaration);
|
|
2452
2446
|
skipped.push({
|
|
2453
|
-
name:
|
|
2447
|
+
name: (namespace && (0, _bamboocss_ts_ast.getName)(namespace)) ?? "*",
|
|
2454
2448
|
reason: "runtime-binding",
|
|
2455
2449
|
start: declaration.getStart(),
|
|
2456
2450
|
end: declaration.getEnd()
|
|
2457
2451
|
});
|
|
2458
2452
|
continue;
|
|
2459
2453
|
}
|
|
2460
|
-
for (const named of
|
|
2461
|
-
if (
|
|
2462
|
-
const imported =
|
|
2463
|
-
if (PERMITTED_BINDINGS.has(imported)) continue;
|
|
2454
|
+
for (const named of (0, _bamboocss_ts_ast.getNamedExports)(declaration)) {
|
|
2455
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(named)) continue;
|
|
2456
|
+
const imported = (0, _bamboocss_ts_ast.nameNodeOf)(named)?.getText();
|
|
2457
|
+
if (PERMITTED_BINDINGS.has(imported ?? "")) continue;
|
|
2464
2458
|
skipped.push({
|
|
2465
|
-
name: imported,
|
|
2459
|
+
name: imported ?? "",
|
|
2466
2460
|
reason: "runtime-binding",
|
|
2467
2461
|
start: named.getStart(),
|
|
2468
2462
|
end: named.getEnd()
|
|
2469
2463
|
});
|
|
2470
2464
|
}
|
|
2471
2465
|
}
|
|
2472
|
-
for (const declaration of
|
|
2473
|
-
if (
|
|
2474
|
-
for (const named of
|
|
2475
|
-
if (
|
|
2476
|
-
const imported = watched.get(
|
|
2466
|
+
for (const declaration of (0, _bamboocss_ts_ast.getExportDeclarations)(sourceFile)) {
|
|
2467
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(declaration) || (0, _bamboocss_ts_ast.childOf)(declaration, "moduleSpecifier")) continue;
|
|
2468
|
+
for (const named of (0, _bamboocss_ts_ast.getNamedExports)(declaration)) {
|
|
2469
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(named)) continue;
|
|
2470
|
+
const imported = watched.get((0, _bamboocss_ts_ast.nameNodeOf)(named)?.getText() ?? "");
|
|
2477
2471
|
if (imported === void 0) continue;
|
|
2478
2472
|
skipped.push({
|
|
2479
|
-
name: imported,
|
|
2473
|
+
name: imported ?? "",
|
|
2480
2474
|
reason: "runtime-binding",
|
|
2481
2475
|
start: named.getStart(),
|
|
2482
2476
|
end: named.getEnd()
|
|
@@ -2488,7 +2482,7 @@ const foldSource = (options) => {
|
|
|
2488
2482
|
const survivors = [];
|
|
2489
2483
|
for (const [local, imported] of watched) for (const identifier of identifiersByName().get(local)) {
|
|
2490
2484
|
const start = identifier.getStart();
|
|
2491
|
-
if (
|
|
2485
|
+
if ((0, _bamboocss_ts_ast.getFirstAncestorByKind)(identifier, _bamboocss_ts_ast.SyntaxKind.ImportDeclaration)) continue;
|
|
2492
2486
|
if (applied.some(([from, to]) => start >= from && start < to)) continue;
|
|
2493
2487
|
if (declined.some(([from, to]) => start >= from && start < to)) continue;
|
|
2494
2488
|
if (!isValueReference(identifier)) continue;
|