styled-components-to-stylex-codemod 0.0.55 → 0.0.57
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/README.md +20 -0
- package/dist/{ast-walk-C226poBl.mjs → ast-walk-DVmYZ2mK.mjs} +376 -36
- package/dist/{bridge-consumer-patcher-DDcYZM_G.mjs → bridge-consumer-patcher-jeeDUlId.mjs} +1 -1
- package/dist/index.d.mts +92 -14
- package/dist/index.mjs +622 -35
- package/dist/{transform-types-BGGNjb8R.d.mts → logger-ByYsVkrB.d.mts} +1 -198
- package/dist/{prop-usage-Bs2F3Wke.mjs → prop-usage-D1dECkkb.mjs} +93 -354
- package/dist/{run-prepass-D3Ti1ryc.mjs → run-prepass-CGL_ugPB.mjs} +29 -109
- package/dist/{sx-surface-Cth8EesU.mjs → sx-surface-Kv8zK8L4.mjs} +31 -1
- package/dist/transform.d.mts +180 -2
- package/dist/transform.mjs +600 -861
- package/package.json +1 -1
- package/dist/compute-leaf-set-Cu4lMMQ9.mjs +0 -239
- /package/dist/{forwarded-as-consumer-patcher-Bva_36Gy.mjs → forwarded-as-consumer-patcher-Do4PI4Qs.mjs} +0 -0
- /package/dist/{selector-context-heuristic-LVizWWOR.mjs → selector-context-heuristic-Dptd93Xe.mjs} +0 -0
- /package/dist/{transient-prop-consumer-patcher-DSd7uVA6.mjs → transient-prop-consumer-patcher-D-iqO8-T.mjs} +0 -0
- /package/dist/{typescript-analysis-BLyx4wAJ.mjs → typescript-analysis-eRPqsZ2z.mjs} +0 -0
|
@@ -1,290 +1,120 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import { resolve } from "node:path";
|
|
4
|
-
import "node:fs";
|
|
5
|
-
//#region src/internal/utilities/collection-utils.ts
|
|
6
|
-
/** Add a value to a Set stored in a Map, creating the Set if it doesn't exist. */
|
|
7
|
-
function addToSetMap(map, key, value) {
|
|
8
|
-
let set = map.get(key);
|
|
9
|
-
if (!set) {
|
|
10
|
-
set = /* @__PURE__ */ new Set();
|
|
11
|
-
map.set(key, set);
|
|
12
|
-
}
|
|
13
|
-
set.add(value);
|
|
14
|
-
}
|
|
15
|
-
//#endregion
|
|
16
|
-
//#region src/internal/prepass/scan-cross-file-selectors.ts
|
|
1
|
+
import { m as createPrepassParser } from "./ast-walk-DVmYZ2mK.mjs";
|
|
2
|
+
//#region src/internal/prepass/prepass-ast-utils.ts
|
|
17
3
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* in template literals (e.g. `${props => ...}`, `${theme.color}`).
|
|
21
|
-
*/
|
|
22
|
-
const BARE_TEMPLATE_IDENTIFIER_RE = /\$\{\s*[a-zA-Z_$][\w$]*\s*\}/;
|
|
23
|
-
/**
|
|
24
|
-
* Categorize cross-file selector usages into marker sidecar and global selector bridge maps.
|
|
4
|
+
* Shared structural AST helpers for prepass modules that walk raw babel ASTs
|
|
5
|
+
* to relate exports, local bindings, and named references.
|
|
25
6
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
7
|
+
* These were duplicated verbatim across `component-styled-dependencies` and
|
|
8
|
+
* `stylex-component-exports`; centralizing keeps the traversal semantics
|
|
9
|
+
* (which keys to skip, how to read a node name) consistent.
|
|
28
10
|
*/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
11
|
+
/** Parse a module `source` into its Program node, trying `tsx` then `babel`. */
|
|
12
|
+
function parseProgram(source) {
|
|
13
|
+
for (const parserName of ["tsx", "babel"]) try {
|
|
14
|
+
const ast = createPrepassParser(parserName).parse(source);
|
|
15
|
+
return ast.program ?? ast;
|
|
16
|
+
} catch {}
|
|
17
|
+
return null;
|
|
35
18
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
* Matches both:
|
|
39
|
-
* - Old format: `export const XGlobalSelector = ".sc2sx-..."`
|
|
40
|
-
* - New format: `` export const XGlobalSelector = `.${xBridgeClass}` ``
|
|
41
|
-
*/
|
|
42
|
-
const BRIDGE_EXPORT_RE = /export\s+const\s+(\w+GlobalSelector)\s*=\s*(?:["']\.sc2sx-|`\.\$\{)/g;
|
|
43
|
-
/**
|
|
44
|
-
* Detect whether an imported name is a bridge GlobalSelector from an
|
|
45
|
-
* already-converted StyleX file.
|
|
46
|
-
*
|
|
47
|
-
* Detection criteria (hybrid fast + safe):
|
|
48
|
-
* 1. Variable name ends with "GlobalSelector" AND the stripped name starts uppercase
|
|
49
|
-
* 2. Target file contains "@stylexjs/stylex" (string check, no parse)
|
|
50
|
-
* 3. Target file has a matching `export const XGlobalSelector = ".sc2sx-"` pattern
|
|
51
|
-
*
|
|
52
|
-
* @returns The stripped component name (e.g., "CollapseArrowIcon" for
|
|
53
|
-
* "CollapseArrowIconGlobalSelector"), or null if not a bridge.
|
|
54
|
-
*/
|
|
55
|
-
function detectBridgeGlobalSelector(importedName, resolvedPath, readFile) {
|
|
56
|
-
if (!importedName.endsWith("GlobalSelector")) return null;
|
|
57
|
-
const stripped = importedName.slice(0, -14);
|
|
58
|
-
if (!stripped || !/^[A-Z]/.test(stripped)) return null;
|
|
59
|
-
const content = readFile(resolvedPath);
|
|
60
|
-
if (!content || !content.includes("@stylexjs/stylex")) return null;
|
|
61
|
-
let found = false;
|
|
62
|
-
for (const m of content.matchAll(BRIDGE_EXPORT_RE)) if (m[1] === importedName) {
|
|
63
|
-
found = true;
|
|
64
|
-
break;
|
|
65
|
-
}
|
|
66
|
-
if (!found) return null;
|
|
67
|
-
return stripped;
|
|
19
|
+
function programBody(program) {
|
|
20
|
+
return astArray(program.body);
|
|
68
21
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if (!bridgeName) return;
|
|
76
|
-
usage.bridgeComponentName = bridgeName;
|
|
77
|
-
const imp = importMap.get(localName);
|
|
78
|
-
if (!imp) return;
|
|
79
|
-
let defaultImportLocal;
|
|
80
|
-
for (const [otherLocal, otherImp] of importMap) {
|
|
81
|
-
if (otherImp.source !== imp.source || otherLocal === localName) continue;
|
|
82
|
-
if (otherImp.importedName === bridgeName) {
|
|
83
|
-
usage.bridgeComponentLocalName = otherLocal;
|
|
84
|
-
defaultImportLocal = void 0;
|
|
85
|
-
break;
|
|
86
|
-
}
|
|
87
|
-
if (otherImp.importedName === "default" && defaultImportLocal === void 0) defaultImportLocal = otherLocal;
|
|
88
|
-
}
|
|
89
|
-
if (defaultImportLocal !== void 0) usage.bridgeComponentLocalName = defaultImportLocal;
|
|
22
|
+
function astArray(value) {
|
|
23
|
+
return Array.isArray(value) ? value.filter(isAstNode) : [];
|
|
24
|
+
}
|
|
25
|
+
function nodeName(node) {
|
|
26
|
+
if (!node) return;
|
|
27
|
+
if (node.type === "Identifier" || node.type === "JSXIdentifier" || node.type === "StringLiteral") return typeof node.name === "string" ? node.name : typeof node.value === "string" ? node.value : void 0;
|
|
90
28
|
}
|
|
91
|
-
/** Global version for matchAll/replace operations */
|
|
92
|
-
const PLACEHOLDER_RE_G = new RegExp(PLACEHOLDER_RE.source, "g");
|
|
93
29
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
* Uses a targeted recursive walk — only descends into node types that can
|
|
97
|
-
* contain these targets (skips type annotations, comments, etc.).
|
|
30
|
+
* Top-level binding name → initializer/body node for function, class, and
|
|
31
|
+
* variable declarations (including those behind a named export).
|
|
98
32
|
*/
|
|
99
|
-
function
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if (Array.isArray(val)) for (const child of val) walkForImportsAndTemplates(child, imports, templates);
|
|
111
|
-
else if (val && typeof val === "object" && val.type) walkForImportsAndTemplates(val, imports, templates);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
/** Build a map of localName → import info from raw ImportDeclaration nodes. */
|
|
115
|
-
function buildImportMapFromNodes(importNodes) {
|
|
116
|
-
const map = /* @__PURE__ */ new Map();
|
|
117
|
-
for (const node of importNodes) {
|
|
118
|
-
const sourceValue = node.source?.value;
|
|
119
|
-
if (typeof sourceValue !== "string") continue;
|
|
120
|
-
const specifiers = node.specifiers;
|
|
121
|
-
if (!specifiers) continue;
|
|
122
|
-
for (const spec of specifiers) {
|
|
123
|
-
const localName = getNodeName(spec.local);
|
|
124
|
-
if (!localName) continue;
|
|
125
|
-
if (spec.type === "ImportDefaultSpecifier") map.set(localName, {
|
|
126
|
-
source: sourceValue,
|
|
127
|
-
importedName: "default"
|
|
33
|
+
function localBindings(program) {
|
|
34
|
+
const bindings = [];
|
|
35
|
+
for (const stmt of programBody(program)) {
|
|
36
|
+
const declaration = stmt.type === "ExportNamedDeclaration" ? stmt.declaration : stmt;
|
|
37
|
+
if (!declaration) continue;
|
|
38
|
+
if (declaration.type === "FunctionDeclaration" || declaration.type === "ClassDeclaration") {
|
|
39
|
+
const name = nodeName(declaration.id);
|
|
40
|
+
const body = declaration.body;
|
|
41
|
+
if (name && body) bindings.push({
|
|
42
|
+
name,
|
|
43
|
+
node: body
|
|
128
44
|
});
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (declaration.type === "VariableDeclaration") for (const declarator of astArray(declaration.declarations)) {
|
|
48
|
+
const name = nodeName(declarator.id);
|
|
49
|
+
const init = declarator.init;
|
|
50
|
+
if (name && init) bindings.push({
|
|
51
|
+
name,
|
|
52
|
+
node: init
|
|
132
53
|
});
|
|
133
|
-
else if (spec.type === "ImportSpecifier") {
|
|
134
|
-
const importedName = getNodeName(spec.imported) ?? localName;
|
|
135
|
-
map.set(localName, {
|
|
136
|
-
source: sourceValue,
|
|
137
|
-
importedName
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
54
|
}
|
|
141
55
|
}
|
|
142
|
-
return
|
|
56
|
+
return bindings;
|
|
143
57
|
}
|
|
144
58
|
/**
|
|
145
|
-
*
|
|
146
|
-
*
|
|
59
|
+
* Depth-first walk that skips metadata (`loc`/comments), type annotations, and
|
|
60
|
+
* the non-computed `key`/`property` of object members and member expressions,
|
|
61
|
+
* so visitors only see value-position nodes.
|
|
147
62
|
*/
|
|
148
|
-
function
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
if (node
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
for (const spec of specifiers) if (spec.type === "ImportDefaultSpecifier") {
|
|
155
|
-
const name = getNodeName(spec.local);
|
|
156
|
-
if (name) names.add(name);
|
|
157
|
-
} else if (spec.type === "ImportSpecifier") {
|
|
158
|
-
if (getNodeName(spec.imported) === "styled") {
|
|
159
|
-
const localName = getNodeName(spec.local);
|
|
160
|
-
if (localName) names.add(localName);
|
|
161
|
-
}
|
|
63
|
+
function walkValueAst(root, visitor) {
|
|
64
|
+
const visit = (node) => {
|
|
65
|
+
if (!node || typeof node !== "object") return;
|
|
66
|
+
if (Array.isArray(node)) {
|
|
67
|
+
for (const child of node) visit(child);
|
|
68
|
+
return;
|
|
162
69
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
for (const node of importNodes) {
|
|
170
|
-
if (node.source?.value !== "styled-components") continue;
|
|
171
|
-
const specifiers = node.specifiers;
|
|
172
|
-
if (!specifiers) continue;
|
|
173
|
-
for (const spec of specifiers) if (spec.type === "ImportDefaultSpecifier") {
|
|
174
|
-
const name = getNodeName(spec.local);
|
|
175
|
-
if (name) return name;
|
|
176
|
-
} else if (spec.type === "ImportSpecifier") {
|
|
177
|
-
if (getNodeName(spec.imported) === "styled") {
|
|
178
|
-
const localName = getNodeName(spec.local);
|
|
179
|
-
if (localName) namedStyledLocal = localName;
|
|
180
|
-
}
|
|
70
|
+
const astNode = node;
|
|
71
|
+
visitor(astNode);
|
|
72
|
+
for (const key of Object.keys(astNode)) {
|
|
73
|
+
if (shouldSkipChild(astNode, key)) continue;
|
|
74
|
+
const child = astNode[key];
|
|
75
|
+
if (child && typeof child === "object") visit(child);
|
|
181
76
|
}
|
|
182
|
-
}
|
|
183
|
-
|
|
77
|
+
};
|
|
78
|
+
visit(root);
|
|
184
79
|
}
|
|
185
80
|
/**
|
|
186
|
-
*
|
|
187
|
-
*
|
|
81
|
+
* Whether `node` references any of `localNames`. `whenUndefined` is the
|
|
82
|
+
* conservative answer when `node` is absent — dependency checks treat a missing
|
|
83
|
+
* node as dependent (`true`), surface checks as not referencing (`false`).
|
|
188
84
|
*/
|
|
189
|
-
function
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
if (getNodeName(spec.imported) === "css") {
|
|
197
|
-
const localName = getNodeName(spec.local);
|
|
198
|
-
if (localName) names.add(localName);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
return names;
|
|
85
|
+
function nodeReferencesLocalNames$1(node, localNames, whenUndefined) {
|
|
86
|
+
if (!node) return whenUndefined;
|
|
87
|
+
let found = false;
|
|
88
|
+
walkValueAst(node, (candidate) => {
|
|
89
|
+
if (!found && isNamedReference(candidate, localNames)) found = true;
|
|
90
|
+
});
|
|
91
|
+
return found;
|
|
203
92
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
* styled-components template literals (both `styled` and `css` tagged templates).
|
|
207
|
-
*/
|
|
208
|
-
function findComponentSelectorLocalsFromNodes(templateNodes, styledImportName, cssImportNames) {
|
|
209
|
-
const selectorLocals = /* @__PURE__ */ new Set();
|
|
210
|
-
for (const node of templateNodes) {
|
|
211
|
-
if (!isStyledTag(node.tag, styledImportName) && !isCssTag(node.tag, cssImportNames)) continue;
|
|
212
|
-
const quasi = node.quasi;
|
|
213
|
-
if (!quasi) continue;
|
|
214
|
-
const quasis = quasi.quasis;
|
|
215
|
-
const expressions = quasi.expressions;
|
|
216
|
-
if (!quasis || !expressions) continue;
|
|
217
|
-
const rawParts = [];
|
|
218
|
-
for (let i = 0; i < quasis.length; i++) {
|
|
219
|
-
const value = quasis[i]?.value;
|
|
220
|
-
rawParts.push(value?.raw ?? "");
|
|
221
|
-
if (i < expressions.length) rawParts.push(`__SC_EXPR_${i}__`);
|
|
222
|
-
}
|
|
223
|
-
const rawCss = rawParts.join("");
|
|
224
|
-
for (const match of rawCss.matchAll(PLACEHOLDER_RE_G)) {
|
|
225
|
-
const exprIndex = Number(match[1]);
|
|
226
|
-
const pos = match.index;
|
|
227
|
-
if (isTemplatePlaceholderInSelectorContext(rawCss, pos, match[0].length)) {
|
|
228
|
-
const expr = expressions[exprIndex];
|
|
229
|
-
if (expr?.type === "Identifier" && typeof expr.name === "string") selectorLocals.add(expr.name);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
return selectorLocals;
|
|
93
|
+
function isAstNode(value) {
|
|
94
|
+
return Boolean(value && typeof value === "object");
|
|
234
95
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
* Matches: styled.div, styled(X), styled.div.attrs(...), styled(X).withConfig(...), etc.
|
|
238
|
-
*/
|
|
239
|
-
function isStyledTag(tag, styledName) {
|
|
240
|
-
if (!tag || typeof tag !== "object") return false;
|
|
241
|
-
if (tag.type === "MemberExpression") {
|
|
242
|
-
const obj = tag.object;
|
|
243
|
-
if (obj?.type === "Identifier" && obj.name === styledName) return true;
|
|
244
|
-
}
|
|
245
|
-
if (tag.type === "CallExpression") {
|
|
246
|
-
const callee = tag.callee;
|
|
247
|
-
if (callee?.type === "Identifier" && callee.name === styledName) return true;
|
|
248
|
-
if (callee?.type === "MemberExpression" && callee.object) return isStyledTag(callee.object, styledName);
|
|
249
|
-
}
|
|
96
|
+
function isNamedReference(node, localNames) {
|
|
97
|
+
if (node.type === "Identifier" || node.type === "JSXIdentifier") return typeof node.name === "string" && localNames.has(node.name);
|
|
250
98
|
return false;
|
|
251
99
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
if (
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
const abs = resolve(f);
|
|
268
|
-
if (!seen.has(abs)) {
|
|
269
|
-
seen.add(abs);
|
|
270
|
-
result.push(abs);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
for (const f of consumerPaths) {
|
|
274
|
-
const abs = resolve(f);
|
|
275
|
-
if (!seen.has(abs)) {
|
|
276
|
-
seen.add(abs);
|
|
277
|
-
result.push(abs);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
return result;
|
|
100
|
+
function shouldSkipChild(node, key) {
|
|
101
|
+
if ([
|
|
102
|
+
"loc",
|
|
103
|
+
"comments",
|
|
104
|
+
"leadingComments",
|
|
105
|
+
"trailingComments"
|
|
106
|
+
].includes(key)) return true;
|
|
107
|
+
if ([
|
|
108
|
+
"typeAnnotation",
|
|
109
|
+
"typeParameters",
|
|
110
|
+
"returnType"
|
|
111
|
+
].includes(key)) return true;
|
|
112
|
+
if (key === "key" && (node.type === "ObjectProperty" || node.type === "Property") && node.computed !== true) return true;
|
|
113
|
+
if (key === "property" && node.type === "MemberExpression" && node.computed !== true) return true;
|
|
114
|
+
return false;
|
|
281
115
|
}
|
|
282
116
|
//#endregion
|
|
283
117
|
//#region src/internal/prepass/stylex-component-exports.ts
|
|
284
|
-
/**
|
|
285
|
-
* Prepass helpers for identifying exported components that already apply StyleX.
|
|
286
|
-
* Core concepts: StyleX import bindings, export names, and local binding traces.
|
|
287
|
-
*/
|
|
288
118
|
function collectStylexExportNames(source) {
|
|
289
119
|
const parsed = parseProgram(source);
|
|
290
120
|
if (!parsed) return /* @__PURE__ */ new Set();
|
|
@@ -297,13 +127,6 @@ function collectStylexExportNames(source) {
|
|
|
297
127
|
}
|
|
298
128
|
return names;
|
|
299
129
|
}
|
|
300
|
-
function parseProgram(source) {
|
|
301
|
-
for (const parserName of ["tsx", "babel"]) try {
|
|
302
|
-
const ast = createPrepassParser(parserName).parse(source);
|
|
303
|
-
return ast.program ?? ast;
|
|
304
|
-
} catch {}
|
|
305
|
-
return null;
|
|
306
|
-
}
|
|
307
130
|
function collectStylexNamedExports(program, stmt, stylexUsage, names) {
|
|
308
131
|
if (stmt.type !== "ExportNamedDeclaration") return;
|
|
309
132
|
const declaration = stmt.declaration;
|
|
@@ -388,36 +211,6 @@ function candidateUsesStylex(candidate, stylexUsage) {
|
|
|
388
211
|
function findLocalBindingNode(program, localName) {
|
|
389
212
|
for (const binding of localBindings(program)) if (binding.name === localName) return binding.node;
|
|
390
213
|
}
|
|
391
|
-
function localBindings(program) {
|
|
392
|
-
const bindings = [];
|
|
393
|
-
for (const stmt of programBody(program)) {
|
|
394
|
-
const declaration = stmt.type === "ExportNamedDeclaration" ? stmt.declaration : stmt;
|
|
395
|
-
if (!declaration) continue;
|
|
396
|
-
const directBinding = localBindingFromDeclaration(declaration);
|
|
397
|
-
if (directBinding) {
|
|
398
|
-
bindings.push(directBinding);
|
|
399
|
-
continue;
|
|
400
|
-
}
|
|
401
|
-
if (declaration.type === "VariableDeclaration") for (const declarator of astArray(declaration.declarations)) {
|
|
402
|
-
const name = nodeName(declarator.id);
|
|
403
|
-
const init = declarator.init;
|
|
404
|
-
if (name && init) bindings.push({
|
|
405
|
-
name,
|
|
406
|
-
node: init
|
|
407
|
-
});
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
return bindings;
|
|
411
|
-
}
|
|
412
|
-
function localBindingFromDeclaration(declaration) {
|
|
413
|
-
if (declaration.type !== "FunctionDeclaration" && declaration.type !== "ClassDeclaration") return null;
|
|
414
|
-
const name = nodeName(declaration.id);
|
|
415
|
-
const body = declaration.body;
|
|
416
|
-
return name && body ? {
|
|
417
|
-
name,
|
|
418
|
-
node: body
|
|
419
|
-
} : null;
|
|
420
|
-
}
|
|
421
214
|
function referencedLocalNames(program, node) {
|
|
422
215
|
const localNameSet = new Set(localBindings(program).map((binding) => binding.name));
|
|
423
216
|
const referenced = /* @__PURE__ */ new Set();
|
|
@@ -460,63 +253,9 @@ function isStylexSxAttribute(node, styleObjectNames) {
|
|
|
460
253
|
if (!value) return false;
|
|
461
254
|
return nodeReferencesLocalNames(value.type === "JSXExpressionContainer" ? value.expression : value, styleObjectNames);
|
|
462
255
|
}
|
|
256
|
+
/** StyleX surface checks treat a missing node as not referencing the names. */
|
|
463
257
|
function nodeReferencesLocalNames(node, localNames) {
|
|
464
|
-
|
|
465
|
-
let found = false;
|
|
466
|
-
walkValueAst(node, (candidate) => {
|
|
467
|
-
if (!found && isNamedReference(candidate, localNames)) found = true;
|
|
468
|
-
});
|
|
469
|
-
return found;
|
|
470
|
-
}
|
|
471
|
-
function walkValueAst(root, visitor) {
|
|
472
|
-
const visit = (node) => {
|
|
473
|
-
if (!node || typeof node !== "object") return;
|
|
474
|
-
if (Array.isArray(node)) {
|
|
475
|
-
for (const child of node) visit(child);
|
|
476
|
-
return;
|
|
477
|
-
}
|
|
478
|
-
const astNode = node;
|
|
479
|
-
visitor(astNode);
|
|
480
|
-
for (const key of Object.keys(astNode)) {
|
|
481
|
-
if (shouldSkipChild(astNode, key)) continue;
|
|
482
|
-
const child = astNode[key];
|
|
483
|
-
if (child && typeof child === "object") visit(child);
|
|
484
|
-
}
|
|
485
|
-
};
|
|
486
|
-
visit(root);
|
|
487
|
-
}
|
|
488
|
-
function shouldSkipChild(node, key) {
|
|
489
|
-
if ([
|
|
490
|
-
"loc",
|
|
491
|
-
"comments",
|
|
492
|
-
"leadingComments",
|
|
493
|
-
"trailingComments"
|
|
494
|
-
].includes(key)) return true;
|
|
495
|
-
if ([
|
|
496
|
-
"typeAnnotation",
|
|
497
|
-
"typeParameters",
|
|
498
|
-
"returnType"
|
|
499
|
-
].includes(key)) return true;
|
|
500
|
-
if (key === "key" && (node.type === "ObjectProperty" || node.type === "Property") && node.computed !== true) return true;
|
|
501
|
-
if (key === "property" && node.type === "MemberExpression" && node.computed !== true) return true;
|
|
502
|
-
return false;
|
|
503
|
-
}
|
|
504
|
-
function isNamedReference(node, localNames) {
|
|
505
|
-
if (node.type === "Identifier" || node.type === "JSXIdentifier") return typeof node.name === "string" && localNames.has(node.name);
|
|
506
|
-
return false;
|
|
507
|
-
}
|
|
508
|
-
function programBody(program) {
|
|
509
|
-
return astArray(program.body);
|
|
510
|
-
}
|
|
511
|
-
function astArray(value) {
|
|
512
|
-
return Array.isArray(value) ? value.filter(isAstNode) : [];
|
|
513
|
-
}
|
|
514
|
-
function isAstNode(value) {
|
|
515
|
-
return Boolean(value && typeof value === "object");
|
|
516
|
-
}
|
|
517
|
-
function nodeName(node) {
|
|
518
|
-
if (!node) return;
|
|
519
|
-
if (node.type === "Identifier" || node.type === "JSXIdentifier" || node.type === "StringLiteral") return typeof node.name === "string" ? node.name : typeof node.value === "string" ? node.value : void 0;
|
|
258
|
+
return nodeReferencesLocalNames$1(node, localNames, false);
|
|
520
259
|
}
|
|
521
260
|
//#endregion
|
|
522
261
|
//#region src/internal/utilities/jsx-static-literal.ts
|
|
@@ -597,4 +336,4 @@ function getExhaustiveObservedStaticValues(info, propName) {
|
|
|
597
336
|
return values.length === propUsage.values.length ? values : null;
|
|
598
337
|
}
|
|
599
338
|
//#endregion
|
|
600
|
-
export {
|
|
339
|
+
export { mergeComponentPropUsage as a, astArray as c, nodeReferencesLocalNames$1 as d, parseProgram as f, getExhaustiveObservedStaticValues as i, localBindings as l, createComponentPropUsageInfo as n, readStaticJsxLiteral as o, programBody as p, formatObservedVariantCondition as r, collectStylexExportNames as s, KNOWN_NON_ELEMENT_PROPS as t, nodeName as u };
|