@litsx/babel-preset-litsx 0.3.0 → 0.5.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/index.cjs +7 -1
- package/dist/index.cjs.map +1 -1
- package/dist/internal/transform-litsx-components.cjs +564 -610
- package/dist/internal/transform-litsx-components.cjs.map +1 -1
- package/dist/internal/transform-litsx-properties.cjs +1 -1
- package/dist/internal/transform-litsx-properties.cjs.map +1 -1
- package/dist/internal/transform-litsx-renderer-props.cjs +21 -5
- package/dist/internal/transform-litsx-renderer-props.cjs.map +1 -1
- package/dist/pipeline.cjs +9 -2
- package/dist/pipeline.cjs.map +1 -1
- package/dist/shared/transform-litsx-element-candidates-JMFlPFXK.cjs +1170 -0
- package/dist/shared/transform-litsx-element-candidates-JMFlPFXK.cjs.map +1 -0
- package/package.json +4 -2
- package/src/internal/transform-litsx-components.js +46 -231
- package/src/internal/transform-litsx-element-candidates.js +1173 -0
- package/src/internal/transform-litsx-param-rewrites.js +0 -71
- package/src/internal/transform-litsx-properties.js +1 -1
- package/src/internal/transform-litsx-render-body.js +113 -0
- package/src/internal/transform-litsx-renderer-calls.js +92 -0
- package/src/internal/transform-litsx-renderer-props.js +13 -5
- package/src/internal/transform-litsx-static-hoists.js +35 -24
- package/src/pipeline.js +2 -1
|
@@ -0,0 +1,1170 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var helperPluginUtils = require('@babel/helper-plugin-utils');
|
|
4
|
+
var babelTraverse = require('@babel/traverse');
|
|
5
|
+
var jsxSyntaxPlugin = require('@babel/plugin-syntax-jsx');
|
|
6
|
+
var parser = require('@litsx/babel-parser');
|
|
7
|
+
var fs = require('node:fs');
|
|
8
|
+
var path = require('node:path');
|
|
9
|
+
var typescriptSession = require('@litsx/typescript-session');
|
|
10
|
+
var internal_transformLitsxProperties = require('../internal/transform-litsx-properties.cjs');
|
|
11
|
+
|
|
12
|
+
const { declare } = helperPluginUtils;
|
|
13
|
+
const traverse = babelTraverse.default || babelTraverse;
|
|
14
|
+
const IMPORT_RESOLUTION_EXTENSIONS = [
|
|
15
|
+
".litsx",
|
|
16
|
+
".litsx.jsx",
|
|
17
|
+
".jsx",
|
|
18
|
+
".js",
|
|
19
|
+
".tsx",
|
|
20
|
+
".ts",
|
|
21
|
+
];
|
|
22
|
+
const DEFAULT_MODULE_RESOLUTION_OPTIONS = {
|
|
23
|
+
moduleResolution: 100,
|
|
24
|
+
allowJs: true,
|
|
25
|
+
checkJs: false,
|
|
26
|
+
jsx: 1,
|
|
27
|
+
target: 99,
|
|
28
|
+
module: 99,
|
|
29
|
+
esModuleInterop: true,
|
|
30
|
+
allowSyntheticDefaultImports: true,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
let t;
|
|
34
|
+
|
|
35
|
+
function setElementCandidatesBabelTypes(nextTypes) {
|
|
36
|
+
t = nextTypes;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function isInsideFunctionOrClass(path) {
|
|
40
|
+
return path.findParent(
|
|
41
|
+
(p) =>
|
|
42
|
+
p.isFunctionDeclaration() ||
|
|
43
|
+
p.isFunctionExpression() ||
|
|
44
|
+
p.isArrowFunctionExpression() ||
|
|
45
|
+
p.isClassDeclaration()
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function isRelativeSpecifier(value) {
|
|
50
|
+
return typeof value === "string" && (
|
|
51
|
+
value.startsWith("./") ||
|
|
52
|
+
value.startsWith("../") ||
|
|
53
|
+
value.startsWith("/")
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function createEmptyCandidateResult() {
|
|
58
|
+
return {
|
|
59
|
+
localCandidates: new Set(),
|
|
60
|
+
importedCandidates: new Map(),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function cloneCandidateResult(result) {
|
|
65
|
+
return {
|
|
66
|
+
localCandidates: new Set(result?.localCandidates || []),
|
|
67
|
+
importedCandidates: new Map(result?.importedCandidates || []),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function mergeCandidateResults(target, source) {
|
|
72
|
+
source.localCandidates.forEach((candidate) => target.localCandidates.add(candidate));
|
|
73
|
+
source.importedCandidates.forEach((candidate, key) => {
|
|
74
|
+
if (!target.importedCandidates.has(key)) {
|
|
75
|
+
target.importedCandidates.set(key, candidate);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function toImportRecordKey(record) {
|
|
81
|
+
return `${record.sourceFile}:${record.importedName}:${record.tagName}`;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function hasSupportedExtension(filePath) {
|
|
85
|
+
return IMPORT_RESOLUTION_EXTENSIONS.some((extension) => filePath.endsWith(extension));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function resolveImportSource(fromFilename, sourceValue, context) {
|
|
89
|
+
const cacheKey = `${typescriptSession.normalizeFilePath(fromFilename)}::${sourceValue}`;
|
|
90
|
+
if (context.resolvedImportCache.has(cacheKey)) {
|
|
91
|
+
return context.resolvedImportCache.get(cacheKey);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const existingFile = (candidatePath) => {
|
|
95
|
+
try {
|
|
96
|
+
return fs.existsSync(candidatePath) && fs.statSync(candidatePath).isFile();
|
|
97
|
+
} catch {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const resolveWithExtensions = (basePath) => {
|
|
103
|
+
const normalizedBasePath = typescriptSession.normalizeFilePath(basePath);
|
|
104
|
+
const candidates = [];
|
|
105
|
+
|
|
106
|
+
if (hasSupportedExtension(normalizedBasePath)) {
|
|
107
|
+
candidates.push(normalizedBasePath);
|
|
108
|
+
} else {
|
|
109
|
+
IMPORT_RESOLUTION_EXTENSIONS.forEach((extension) => {
|
|
110
|
+
candidates.push(`${normalizedBasePath}${extension}`);
|
|
111
|
+
});
|
|
112
|
+
IMPORT_RESOLUTION_EXTENSIONS.forEach((extension) => {
|
|
113
|
+
candidates.push(typescriptSession.normalizeFilePath(path.join(normalizedBasePath, `index${extension}`)));
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return candidates.find(existingFile) || null;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const resolvePathAlias = () => {
|
|
121
|
+
const compilerOptions = context.getCompilerOptions?.(fromFilename) || {};
|
|
122
|
+
const baseUrl = compilerOptions.baseUrl
|
|
123
|
+
? typescriptSession.normalizeFilePath(
|
|
124
|
+
path.isAbsolute(compilerOptions.baseUrl)
|
|
125
|
+
? compilerOptions.baseUrl
|
|
126
|
+
: path.resolve(path.dirname(fromFilename), compilerOptions.baseUrl)
|
|
127
|
+
)
|
|
128
|
+
: typescriptSession.normalizeFilePath(path.dirname(fromFilename));
|
|
129
|
+
const pathMappings = compilerOptions.paths || {};
|
|
130
|
+
|
|
131
|
+
for (const [pattern, substitutions] of Object.entries(pathMappings)) {
|
|
132
|
+
const starIndex = pattern.indexOf("*");
|
|
133
|
+
const isStarPattern = starIndex !== -1;
|
|
134
|
+
const prefix = isStarPattern ? pattern.slice(0, starIndex) : pattern;
|
|
135
|
+
const suffix = isStarPattern ? pattern.slice(starIndex + 1) : "";
|
|
136
|
+
|
|
137
|
+
if (isStarPattern) {
|
|
138
|
+
if (!sourceValue.startsWith(prefix) || !sourceValue.endsWith(suffix)) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
} else if (sourceValue !== pattern) {
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const wildcardValue = isStarPattern
|
|
146
|
+
? sourceValue.slice(prefix.length, sourceValue.length - suffix.length)
|
|
147
|
+
: "";
|
|
148
|
+
|
|
149
|
+
for (const substitution of substitutions || []) {
|
|
150
|
+
const substituted = isStarPattern
|
|
151
|
+
? substitution.replace("*", wildcardValue)
|
|
152
|
+
: substitution;
|
|
153
|
+
const candidateBase = path.isAbsolute(substituted)
|
|
154
|
+
? substituted
|
|
155
|
+
: path.join(baseUrl, substituted);
|
|
156
|
+
const resolvedPath = resolveWithExtensions(candidateBase);
|
|
157
|
+
if (resolvedPath) {
|
|
158
|
+
return resolvedPath;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return null;
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
let resolved = null;
|
|
167
|
+
if (fromFilename && isRelativeSpecifier(sourceValue)) {
|
|
168
|
+
resolved = resolveWithExtensions(
|
|
169
|
+
path.resolve(path.dirname(fromFilename), sourceValue)
|
|
170
|
+
);
|
|
171
|
+
} else if (fromFilename) {
|
|
172
|
+
resolved = resolvePathAlias();
|
|
173
|
+
if (!resolved) {
|
|
174
|
+
const ts = internal_transformLitsxProperties.ensureTypescriptModule();
|
|
175
|
+
const compilerOptions = context.getCompilerOptions?.(fromFilename) || DEFAULT_MODULE_RESOLUTION_OPTIONS;
|
|
176
|
+
const moduleResolutionHost = context.getModuleResolutionHost?.(fromFilename) || ts.sys;
|
|
177
|
+
try {
|
|
178
|
+
const resolution = ts.resolveModuleName(
|
|
179
|
+
sourceValue,
|
|
180
|
+
typescriptSession.normalizeFilePath(fromFilename),
|
|
181
|
+
compilerOptions,
|
|
182
|
+
moduleResolutionHost
|
|
183
|
+
);
|
|
184
|
+
const resolvedFileName = resolution?.resolvedModule?.resolvedFileName;
|
|
185
|
+
if (resolvedFileName) {
|
|
186
|
+
resolved = resolveWithExtensions(resolvedFileName) || typescriptSession.normalizeFilePath(resolvedFileName);
|
|
187
|
+
}
|
|
188
|
+
} catch {
|
|
189
|
+
resolved = null;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
context.resolvedImportCache.set(cacheKey, resolved);
|
|
195
|
+
return resolved;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function createCompilerContextResolver(options = {}) {
|
|
199
|
+
const providedTypescriptSession =
|
|
200
|
+
options?.typescriptSession?.projectSession || options?.typescriptSession || null;
|
|
201
|
+
|
|
202
|
+
const compilerOptionsCache = new Map();
|
|
203
|
+
const moduleResolutionHostCache = new Map();
|
|
204
|
+
|
|
205
|
+
function getProgramForFile(filename) {
|
|
206
|
+
if (!providedTypescriptSession?.getProgram || !filename) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
try {
|
|
211
|
+
if (providedTypescriptSession.kind === "project") {
|
|
212
|
+
return providedTypescriptSession.getProgram();
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (providedTypescriptSession.kind === "standalone") {
|
|
216
|
+
return providedTypescriptSession.getProgram(typescriptSession.normalizeFilePath(filename));
|
|
217
|
+
}
|
|
218
|
+
} catch {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return {
|
|
226
|
+
getCompilerOptions(filename) {
|
|
227
|
+
const cacheKey = typescriptSession.normalizeFilePath(filename);
|
|
228
|
+
if (compilerOptionsCache.has(cacheKey)) {
|
|
229
|
+
return compilerOptionsCache.get(cacheKey);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const program = getProgramForFile(filename);
|
|
233
|
+
const compilerOptions = program?.getCompilerOptions?.() || DEFAULT_MODULE_RESOLUTION_OPTIONS;
|
|
234
|
+
compilerOptionsCache.set(cacheKey, compilerOptions);
|
|
235
|
+
return compilerOptions;
|
|
236
|
+
},
|
|
237
|
+
getModuleResolutionHost(filename) {
|
|
238
|
+
const cacheKey = typescriptSession.normalizeFilePath(filename);
|
|
239
|
+
if (moduleResolutionHostCache.has(cacheKey)) {
|
|
240
|
+
return moduleResolutionHostCache.get(cacheKey);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const ts = internal_transformLitsxProperties.ensureTypescriptModule();
|
|
244
|
+
getProgramForFile(filename);
|
|
245
|
+
const host = providedTypescriptSession?.host || ts.sys;
|
|
246
|
+
moduleResolutionHostCache.set(cacheKey, host);
|
|
247
|
+
return host;
|
|
248
|
+
},
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function getOrCreateAvailableNames(programPath) {
|
|
253
|
+
const cached = programPath.getData("__litsxAvailableNames");
|
|
254
|
+
if (cached) {
|
|
255
|
+
return cached;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const availableNames = new Set();
|
|
259
|
+
programPath.get("body").forEach((nodePath) => {
|
|
260
|
+
if (nodePath.isImportDeclaration()) {
|
|
261
|
+
nodePath.node.specifiers.forEach((specifier) => {
|
|
262
|
+
if (specifier.local?.name) {
|
|
263
|
+
availableNames.add(specifier.local.name);
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (nodePath.isClassDeclaration() && nodePath.node.id?.name) {
|
|
270
|
+
availableNames.add(nodePath.node.id.name);
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (
|
|
275
|
+
(nodePath.isExportNamedDeclaration() || nodePath.isExportDefaultDeclaration()) &&
|
|
276
|
+
nodePath.get("declaration")?.isClassDeclaration?.() &&
|
|
277
|
+
nodePath.node.declaration?.id?.name
|
|
278
|
+
) {
|
|
279
|
+
availableNames.add(nodePath.node.declaration.id.name);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (nodePath.isFunctionDeclaration() && nodePath.node.id?.name) {
|
|
284
|
+
availableNames.add(nodePath.node.id.name);
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (
|
|
289
|
+
(nodePath.isExportNamedDeclaration() || nodePath.isExportDefaultDeclaration()) &&
|
|
290
|
+
nodePath.get("declaration")?.isFunctionDeclaration?.() &&
|
|
291
|
+
nodePath.node.declaration?.id?.name
|
|
292
|
+
) {
|
|
293
|
+
availableNames.add(nodePath.node.declaration.id.name);
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (
|
|
298
|
+
(nodePath.isExportNamedDeclaration() || nodePath.isExportDefaultDeclaration()) &&
|
|
299
|
+
nodePath.get("declaration")?.isVariableDeclaration?.()
|
|
300
|
+
) {
|
|
301
|
+
nodePath.get("declaration.declarations").forEach((declaratorPath) => {
|
|
302
|
+
const declarator = declaratorPath.node;
|
|
303
|
+
if (t.isIdentifier(declarator.id)) {
|
|
304
|
+
availableNames.add(declarator.id.name);
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
if (!nodePath.isVariableDeclaration()) return;
|
|
311
|
+
nodePath.get("declarations").forEach((declaratorPath) => {
|
|
312
|
+
const declarator = declaratorPath.node;
|
|
313
|
+
if (t.isIdentifier(declarator.id)) {
|
|
314
|
+
availableNames.add(declarator.id.name);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
programPath.setData("__litsxAvailableNames", availableNames);
|
|
320
|
+
return availableNames;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
function getOrCreateHelperPaths(programPath) {
|
|
324
|
+
const cached = programPath.getData("__litsxHelperPaths");
|
|
325
|
+
if (cached) {
|
|
326
|
+
return cached;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const helperPaths = new Map();
|
|
330
|
+
programPath.get("body").forEach((nodePath) => {
|
|
331
|
+
if (nodePath.isFunctionDeclaration() && nodePath.node.id?.name) {
|
|
332
|
+
helperPaths.set(nodePath.node.id.name, nodePath);
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if (
|
|
337
|
+
(nodePath.isExportNamedDeclaration() || nodePath.isExportDefaultDeclaration()) &&
|
|
338
|
+
nodePath.get("declaration")?.isFunctionDeclaration?.() &&
|
|
339
|
+
nodePath.node.declaration?.id?.name
|
|
340
|
+
) {
|
|
341
|
+
helperPaths.set(nodePath.node.declaration.id.name, nodePath.get("declaration"));
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (
|
|
346
|
+
(nodePath.isExportNamedDeclaration() || nodePath.isExportDefaultDeclaration()) &&
|
|
347
|
+
nodePath.get("declaration")?.isVariableDeclaration?.()
|
|
348
|
+
) {
|
|
349
|
+
nodePath.get("declaration.declarations").forEach((declaratorPath) => {
|
|
350
|
+
const declarator = declaratorPath.node;
|
|
351
|
+
if (!t.isIdentifier(declarator.id)) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const initPath = declaratorPath.get("init");
|
|
356
|
+
if (
|
|
357
|
+
initPath?.isArrowFunctionExpression?.() ||
|
|
358
|
+
initPath?.isFunctionExpression?.()
|
|
359
|
+
) {
|
|
360
|
+
helperPaths.set(declarator.id.name, initPath);
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if (!nodePath.isVariableDeclaration()) return;
|
|
367
|
+
nodePath.get("declarations").forEach((declaratorPath) => {
|
|
368
|
+
const declarator = declaratorPath.node;
|
|
369
|
+
if (!t.isIdentifier(declarator.id)) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const initPath = declaratorPath.get("init");
|
|
374
|
+
if (
|
|
375
|
+
initPath?.isArrowFunctionExpression?.() ||
|
|
376
|
+
initPath?.isFunctionExpression?.()
|
|
377
|
+
) {
|
|
378
|
+
helperPaths.set(declarator.id.name, initPath);
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
programPath.setData("__litsxHelperPaths", helperPaths);
|
|
384
|
+
return helperPaths;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
function buildModuleAnalysis(programPath, filename, context) {
|
|
388
|
+
const availableNames = getOrCreateAvailableNames(programPath);
|
|
389
|
+
const helperPaths = getOrCreateHelperPaths(programPath);
|
|
390
|
+
const importBindings = new Map();
|
|
391
|
+
const exportBindings = new Map();
|
|
392
|
+
|
|
393
|
+
programPath.get("body").forEach((nodePath) => {
|
|
394
|
+
if (nodePath.isImportDeclaration()) {
|
|
395
|
+
const sourceValue = nodePath.node.source.value;
|
|
396
|
+
const resolvedSource = resolveImportSource(filename, sourceValue, context);
|
|
397
|
+
|
|
398
|
+
nodePath.node.specifiers.forEach((specifier) => {
|
|
399
|
+
if (!specifier.local?.name) {
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
let importedName = null;
|
|
404
|
+
if (specifier.type === "ImportDefaultSpecifier") {
|
|
405
|
+
importedName = "default";
|
|
406
|
+
} else if (specifier.type === "ImportSpecifier") {
|
|
407
|
+
importedName = specifier.imported?.name ?? specifier.imported?.value ?? null;
|
|
408
|
+
} else if (specifier.type === "ImportNamespaceSpecifier") {
|
|
409
|
+
importedName = "*";
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
importBindings.set(specifier.local.name, {
|
|
413
|
+
localName: specifier.local.name,
|
|
414
|
+
importedName,
|
|
415
|
+
sourceValue,
|
|
416
|
+
resolvedSource,
|
|
417
|
+
});
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (nodePath.isExportNamedDeclaration()) {
|
|
424
|
+
const declarationPath = nodePath.get("declaration");
|
|
425
|
+
if (declarationPath?.node) {
|
|
426
|
+
if (declarationPath.isFunctionDeclaration() || declarationPath.isClassDeclaration()) {
|
|
427
|
+
const localName = declarationPath.node.id?.name;
|
|
428
|
+
if (localName) {
|
|
429
|
+
exportBindings.set(localName, { localName });
|
|
430
|
+
}
|
|
431
|
+
} else if (declarationPath.isVariableDeclaration()) {
|
|
432
|
+
declarationPath.get("declarations").forEach((declaratorPath) => {
|
|
433
|
+
const localName = declaratorPath.node.id?.name;
|
|
434
|
+
if (localName) {
|
|
435
|
+
exportBindings.set(localName, { localName });
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
nodePath.get("specifiers").forEach((specifierPath) => {
|
|
442
|
+
const exportedName =
|
|
443
|
+
specifierPath.node.exported?.name ?? specifierPath.node.exported?.value ?? null;
|
|
444
|
+
if (!exportedName) {
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
const sourceValue = nodePath.node.source?.value ?? null;
|
|
449
|
+
if (sourceValue) {
|
|
450
|
+
const localName =
|
|
451
|
+
specifierPath.node.local?.name ?? specifierPath.node.local?.value ?? exportedName;
|
|
452
|
+
exportBindings.set(exportedName, {
|
|
453
|
+
reexportSource: resolveImportSource(filename, sourceValue, context),
|
|
454
|
+
importedName: localName === "default" ? "default" : localName,
|
|
455
|
+
});
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
const localName =
|
|
460
|
+
specifierPath.node.local?.name ?? specifierPath.node.local?.value ?? null;
|
|
461
|
+
if (localName) {
|
|
462
|
+
exportBindings.set(exportedName, { localName });
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
if (!nodePath.isExportDefaultDeclaration()) {
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
const declarationPath = nodePath.get("declaration");
|
|
474
|
+
if (declarationPath.isIdentifier()) {
|
|
475
|
+
exportBindings.set("default", { localName: declarationPath.node.name });
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
if (
|
|
480
|
+
declarationPath.isFunctionDeclaration() ||
|
|
481
|
+
declarationPath.isClassDeclaration()
|
|
482
|
+
) {
|
|
483
|
+
const localName = declarationPath.node.id?.name;
|
|
484
|
+
if (localName) {
|
|
485
|
+
exportBindings.set("default", { localName });
|
|
486
|
+
} else {
|
|
487
|
+
exportBindings.set("default", { path: declarationPath });
|
|
488
|
+
}
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
if (
|
|
493
|
+
declarationPath.isArrowFunctionExpression() ||
|
|
494
|
+
declarationPath.isFunctionExpression()
|
|
495
|
+
) {
|
|
496
|
+
exportBindings.set("default", { path: declarationPath });
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
return {
|
|
501
|
+
filename,
|
|
502
|
+
programPath,
|
|
503
|
+
availableNames,
|
|
504
|
+
helperPaths,
|
|
505
|
+
importBindings,
|
|
506
|
+
exportBindings,
|
|
507
|
+
compatPascalNames: new Set(),
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
function getOrCreateModuleAnalysis(filename, context) {
|
|
512
|
+
const normalizedFilename = typescriptSession.normalizeFilePath(filename);
|
|
513
|
+
if (!normalizedFilename) {
|
|
514
|
+
return null;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
if (context.moduleAnalysisCache.has(normalizedFilename)) {
|
|
518
|
+
return context.moduleAnalysisCache.get(normalizedFilename);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
let source;
|
|
522
|
+
try {
|
|
523
|
+
source = fs.readFileSync(normalizedFilename, "utf8");
|
|
524
|
+
} catch {
|
|
525
|
+
return null;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
let programPath = null;
|
|
529
|
+
try {
|
|
530
|
+
const ast = parser.parse(source, { sourceType: "module" });
|
|
531
|
+
traverse(ast, {
|
|
532
|
+
Program(path) {
|
|
533
|
+
if (!programPath) {
|
|
534
|
+
programPath = path;
|
|
535
|
+
path.scope.crawl();
|
|
536
|
+
}
|
|
537
|
+
},
|
|
538
|
+
});
|
|
539
|
+
} catch {
|
|
540
|
+
return null;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
if (!programPath) {
|
|
544
|
+
return null;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
const analysis = buildModuleAnalysis(programPath, normalizedFilename, context);
|
|
548
|
+
context.moduleAnalysisCache.set(normalizedFilename, analysis);
|
|
549
|
+
return analysis;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
function isCapitalizedName(name) {
|
|
553
|
+
if (typeof name !== "string" || name.length === 0) {
|
|
554
|
+
return false;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
const first = name[0];
|
|
558
|
+
return first === first.toUpperCase() && first !== first.toLowerCase();
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
function isProgramLevelBinding(binding) {
|
|
562
|
+
return binding?.scope?.path?.isProgram?.() === true;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
function validateComponentName(nameNode, pathForErrors, context) {
|
|
566
|
+
if (!nameNode || nameNode.type !== "JSXIdentifier") return null;
|
|
567
|
+
const originalName = nameNode.__scopedOriginal || nameNode.name;
|
|
568
|
+
if (!isCapitalizedName(originalName)) return null;
|
|
569
|
+
|
|
570
|
+
const binding = pathForErrors?.scope?.getBinding?.(originalName) || null;
|
|
571
|
+
if (!binding) {
|
|
572
|
+
if (context.availableNames.has(originalName)) {
|
|
573
|
+
return originalName;
|
|
574
|
+
}
|
|
575
|
+
if (context.compatPascalNames.has(originalName)) {
|
|
576
|
+
return null;
|
|
577
|
+
}
|
|
578
|
+
if (context.options?.allowUnknownPascalCase === true) {
|
|
579
|
+
return null;
|
|
580
|
+
}
|
|
581
|
+
throw (pathForErrors?.buildCodeFrameError?.(
|
|
582
|
+
`Unknown LitSX component "${originalName}". Add an import or declare it in this module before using it in JSX.`
|
|
583
|
+
) || new Error(
|
|
584
|
+
`Unknown LitSX component "${originalName}". Add an import or declare it in this module before using it in JSX.`
|
|
585
|
+
));
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
if (!isProgramLevelBinding(binding)) {
|
|
589
|
+
return null;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
return originalName;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
function resolveImportedHelper(moduleAnalysis, helperName, context, seen = new Set()) {
|
|
596
|
+
const importInfo = moduleAnalysis.importBindings.get(helperName);
|
|
597
|
+
if (!importInfo?.resolvedSource || importInfo.importedName === "*") {
|
|
598
|
+
return null;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
const visitedKey = `${moduleAnalysis.filename}:${helperName}:${importInfo.resolvedSource}:${importInfo.importedName}`;
|
|
602
|
+
if (seen.has(visitedKey)) {
|
|
603
|
+
return null;
|
|
604
|
+
}
|
|
605
|
+
const nextSeen = new Set(seen);
|
|
606
|
+
nextSeen.add(visitedKey);
|
|
607
|
+
|
|
608
|
+
const importedModule = getOrCreateModuleAnalysis(importInfo.resolvedSource, context);
|
|
609
|
+
if (!importedModule) {
|
|
610
|
+
return null;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
return resolveExportedHelper(importedModule, importInfo.importedName, context, nextSeen);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
function resolveExportedHelper(moduleAnalysis, exportedName, context, seen = new Set()) {
|
|
617
|
+
const exportInfo = moduleAnalysis.exportBindings.get(exportedName);
|
|
618
|
+
if (!exportInfo) {
|
|
619
|
+
return null;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
if (exportInfo.path?.node) {
|
|
623
|
+
return {
|
|
624
|
+
moduleAnalysis,
|
|
625
|
+
path: exportInfo.path,
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
if (exportInfo.localName) {
|
|
630
|
+
const helperPath = moduleAnalysis.helperPaths.get(exportInfo.localName);
|
|
631
|
+
if (!helperPath?.node) {
|
|
632
|
+
if (moduleAnalysis.importBindings.has(exportInfo.localName)) {
|
|
633
|
+
return resolveImportedHelper(moduleAnalysis, exportInfo.localName, context, seen);
|
|
634
|
+
}
|
|
635
|
+
return null;
|
|
636
|
+
}
|
|
637
|
+
return {
|
|
638
|
+
moduleAnalysis,
|
|
639
|
+
path: helperPath,
|
|
640
|
+
};
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
if (exportInfo.reexportSource) {
|
|
644
|
+
const reexportedModule = getOrCreateModuleAnalysis(exportInfo.reexportSource, context);
|
|
645
|
+
if (!reexportedModule) {
|
|
646
|
+
return null;
|
|
647
|
+
}
|
|
648
|
+
return resolveExportedHelper(
|
|
649
|
+
reexportedModule,
|
|
650
|
+
exportInfo.importedName,
|
|
651
|
+
context,
|
|
652
|
+
seen
|
|
653
|
+
);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
return null;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
function resolveImportedElementRequirement(candidateName, moduleAnalysis, context, rootFilename) {
|
|
660
|
+
const binding = moduleAnalysis.programPath.scope.getBinding(candidateName);
|
|
661
|
+
if (!binding || !isProgramLevelBinding(binding)) {
|
|
662
|
+
return null;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
if (
|
|
666
|
+
binding.path.isImportSpecifier?.() ||
|
|
667
|
+
binding.path.isImportDefaultSpecifier?.()
|
|
668
|
+
) {
|
|
669
|
+
const importInfo = moduleAnalysis.importBindings.get(candidateName);
|
|
670
|
+
if (!importInfo?.resolvedSource || importInfo.importedName === "*") {
|
|
671
|
+
return null;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
return {
|
|
675
|
+
sourceFile: importInfo.resolvedSource,
|
|
676
|
+
sourceSpecifier: isRelativeSpecifier(importInfo.sourceValue)
|
|
677
|
+
? null
|
|
678
|
+
: importInfo.sourceValue,
|
|
679
|
+
importedName: importInfo.importedName,
|
|
680
|
+
originalName: candidateName,
|
|
681
|
+
tagName: candidateName.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(),
|
|
682
|
+
rootFilename,
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
const exportInfo =
|
|
687
|
+
moduleAnalysis.exportBindings.get(candidateName) ||
|
|
688
|
+
moduleAnalysis.exportBindings.get("default");
|
|
689
|
+
if (!exportInfo) {
|
|
690
|
+
throw new Error(
|
|
691
|
+
`Imported renderer helper transitively renders "${candidateName}" from "${moduleAnalysis.filename}", but that symbol is not exported and cannot be added to static elements in "${rootFilename}".`
|
|
692
|
+
);
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
const importedName = exportInfo.localName === candidateName
|
|
696
|
+
? candidateName
|
|
697
|
+
: [...moduleAnalysis.exportBindings.entries()].find(
|
|
698
|
+
([, entry]) => entry.localName === candidateName
|
|
699
|
+
)?.[0] ?? null;
|
|
700
|
+
|
|
701
|
+
if (!importedName) {
|
|
702
|
+
throw new Error(
|
|
703
|
+
`Imported renderer helper transitively renders "${candidateName}" from "${moduleAnalysis.filename}", but that symbol cannot be resolved as an importable export for "${rootFilename}".`
|
|
704
|
+
);
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
return {
|
|
708
|
+
sourceFile: moduleAnalysis.filename,
|
|
709
|
+
sourceSpecifier: null,
|
|
710
|
+
importedName,
|
|
711
|
+
originalName: candidateName,
|
|
712
|
+
tagName: candidateName.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(),
|
|
713
|
+
rootFilename,
|
|
714
|
+
};
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
function collectCandidateResult(functionPath, programPath, options = {}) {
|
|
718
|
+
const result = createEmptyCandidateResult();
|
|
719
|
+
if (!programPath || !functionPath?.node) return result;
|
|
720
|
+
programPath.scope.crawl();
|
|
721
|
+
const compilationSession = options.__litsxCompilationSession || null;
|
|
722
|
+
|
|
723
|
+
const rootFilename = typescriptSession.normalizeFilePath(
|
|
724
|
+
options.filename || programPath.hub.file?.opts?.filename || ""
|
|
725
|
+
);
|
|
726
|
+
const helperCandidateCache =
|
|
727
|
+
programPath.getData("__litsxHelperCandidateCache") || new WeakMap();
|
|
728
|
+
programPath.setData("__litsxHelperCandidateCache", helperCandidateCache);
|
|
729
|
+
const moduleAnalysisCache =
|
|
730
|
+
compilationSession?.importedModuleAnalysisCache ||
|
|
731
|
+
programPath.getData("__litsxImportedModuleAnalyses") ||
|
|
732
|
+
new Map();
|
|
733
|
+
programPath.setData("__litsxImportedModuleAnalyses", moduleAnalysisCache);
|
|
734
|
+
const resolvedImportCache =
|
|
735
|
+
compilationSession?.resolvedImportCache ||
|
|
736
|
+
programPath.getData("__litsxResolvedImports") ||
|
|
737
|
+
new Map();
|
|
738
|
+
programPath.setData("__litsxResolvedImports", resolvedImportCache);
|
|
739
|
+
|
|
740
|
+
const rootModule = {
|
|
741
|
+
filename: rootFilename,
|
|
742
|
+
programPath,
|
|
743
|
+
availableNames: getOrCreateAvailableNames(programPath),
|
|
744
|
+
helperPaths: getOrCreateHelperPaths(programPath),
|
|
745
|
+
compatPascalNames: programPath.getData("__litsxCompatPascalNames") || new Set(),
|
|
746
|
+
importBindings: new Map(),
|
|
747
|
+
exportBindings: new Map(),
|
|
748
|
+
};
|
|
749
|
+
|
|
750
|
+
programPath.get("body").forEach((nodePath) => {
|
|
751
|
+
if (!nodePath.isImportDeclaration()) {
|
|
752
|
+
return;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
const sourceValue = nodePath.node.source.value;
|
|
756
|
+
const resolvedSource = resolveImportSource(rootFilename, sourceValue, {
|
|
757
|
+
moduleAnalysisCache,
|
|
758
|
+
resolvedImportCache,
|
|
759
|
+
});
|
|
760
|
+
|
|
761
|
+
nodePath.node.specifiers.forEach((specifier) => {
|
|
762
|
+
if (!specifier.local?.name) {
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
let importedName = null;
|
|
767
|
+
if (specifier.type === "ImportDefaultSpecifier") {
|
|
768
|
+
importedName = "default";
|
|
769
|
+
} else if (specifier.type === "ImportSpecifier") {
|
|
770
|
+
importedName = specifier.imported?.name ?? specifier.imported?.value ?? null;
|
|
771
|
+
} else if (specifier.type === "ImportNamespaceSpecifier") {
|
|
772
|
+
importedName = "*";
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
rootModule.importBindings.set(specifier.local.name, {
|
|
776
|
+
localName: specifier.local.name,
|
|
777
|
+
importedName,
|
|
778
|
+
sourceValue,
|
|
779
|
+
resolvedSource,
|
|
780
|
+
});
|
|
781
|
+
});
|
|
782
|
+
});
|
|
783
|
+
|
|
784
|
+
const context = {
|
|
785
|
+
rootFilename,
|
|
786
|
+
rootModule,
|
|
787
|
+
options,
|
|
788
|
+
helperCandidateCache,
|
|
789
|
+
moduleAnalysisCache,
|
|
790
|
+
resolvedImportCache,
|
|
791
|
+
...createCompilerContextResolver(options),
|
|
792
|
+
};
|
|
793
|
+
|
|
794
|
+
function scanFunction(path, moduleAnalysis, seen = new Set()) {
|
|
795
|
+
if (!path?.node) {
|
|
796
|
+
return createEmptyCandidateResult();
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
if (context.helperCandidateCache.has(path.node)) {
|
|
800
|
+
return cloneCandidateResult(context.helperCandidateCache.get(path.node));
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
if (seen.has(path.node)) {
|
|
804
|
+
return createEmptyCandidateResult();
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
const nextSeen = new Set(seen);
|
|
808
|
+
nextSeen.add(path.node);
|
|
809
|
+
const localResult = createEmptyCandidateResult();
|
|
810
|
+
const referencedHelpers = [];
|
|
811
|
+
const scanContext = {
|
|
812
|
+
availableNames: moduleAnalysis.availableNames,
|
|
813
|
+
helperPaths: moduleAnalysis.helperPaths,
|
|
814
|
+
compatPascalNames: moduleAnalysis.compatPascalNames,
|
|
815
|
+
options,
|
|
816
|
+
};
|
|
817
|
+
|
|
818
|
+
path.traverse({
|
|
819
|
+
JSXOpeningElement(jsxPath) {
|
|
820
|
+
const candidate = validateComponentName(jsxPath.node.name, jsxPath, scanContext);
|
|
821
|
+
if (candidate) {
|
|
822
|
+
if (moduleAnalysis.filename === context.rootFilename) {
|
|
823
|
+
localResult.localCandidates.add(candidate);
|
|
824
|
+
} else {
|
|
825
|
+
const requirement = resolveImportedElementRequirement(
|
|
826
|
+
candidate,
|
|
827
|
+
moduleAnalysis,
|
|
828
|
+
context,
|
|
829
|
+
context.rootFilename
|
|
830
|
+
);
|
|
831
|
+
if (requirement) {
|
|
832
|
+
localResult.importedCandidates.set(
|
|
833
|
+
toImportRecordKey(requirement),
|
|
834
|
+
requirement
|
|
835
|
+
);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
},
|
|
840
|
+
JSXClosingElement(jsxPath) {
|
|
841
|
+
validateComponentName(jsxPath.node.name, jsxPath, scanContext);
|
|
842
|
+
},
|
|
843
|
+
Identifier(identifierPath) {
|
|
844
|
+
if (!identifierPath.isReferencedIdentifier()) {
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
if (moduleAnalysis.helperPaths.has(identifierPath.node.name)) {
|
|
849
|
+
referencedHelpers.push({
|
|
850
|
+
moduleAnalysis,
|
|
851
|
+
path: moduleAnalysis.helperPaths.get(identifierPath.node.name),
|
|
852
|
+
});
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
const binding = identifierPath.scope.getBinding(identifierPath.node.name);
|
|
857
|
+
if (!binding) {
|
|
858
|
+
return;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
if (
|
|
862
|
+
!binding.path.isImportSpecifier?.() &&
|
|
863
|
+
!binding.path.isImportDefaultSpecifier?.()
|
|
864
|
+
) {
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
const resolvedHelper = resolveImportedHelper(
|
|
869
|
+
moduleAnalysis,
|
|
870
|
+
identifierPath.node.name,
|
|
871
|
+
context
|
|
872
|
+
);
|
|
873
|
+
if (!resolvedHelper?.path?.node) {
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
referencedHelpers.push(resolvedHelper);
|
|
878
|
+
},
|
|
879
|
+
});
|
|
880
|
+
|
|
881
|
+
referencedHelpers.forEach((helperEntry) => {
|
|
882
|
+
const helperCandidates = scanFunction(
|
|
883
|
+
helperEntry.path,
|
|
884
|
+
helperEntry.moduleAnalysis,
|
|
885
|
+
nextSeen
|
|
886
|
+
);
|
|
887
|
+
mergeCandidateResults(localResult, helperCandidates);
|
|
888
|
+
});
|
|
889
|
+
|
|
890
|
+
context.helperCandidateCache.set(path.node, cloneCandidateResult(localResult));
|
|
891
|
+
return localResult;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
return scanFunction(functionPath, rootModule);
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
function getAnnotatedElementCandidates(path, programPath, options = {}) {
|
|
898
|
+
if (path?.node?._litsxElementCandidates instanceof Set) {
|
|
899
|
+
return new Set(path.node._litsxElementCandidates);
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
return collectCandidateResult(path, programPath, options).localCandidates;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
function getAnnotatedImportedElementCandidates(path, programPath, options = {}) {
|
|
906
|
+
if (Array.isArray(path?.node?._litsxImportedElementCandidates)) {
|
|
907
|
+
return [...path.node._litsxImportedElementCandidates];
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
return [...collectCandidateResult(path, programPath, options).importedCandidates.values()];
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
function importedBindingNeedsRendererContext(programPath, localName, options = {}) {
|
|
914
|
+
if (!programPath?.node || !localName) {
|
|
915
|
+
return false;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
programPath.scope.crawl();
|
|
919
|
+
const compilationSession = options.__litsxCompilationSession || null;
|
|
920
|
+
const rootFilename = typescriptSession.normalizeFilePath(
|
|
921
|
+
options.filename || programPath.hub.file?.opts?.filename || ""
|
|
922
|
+
);
|
|
923
|
+
const helperCandidateCache =
|
|
924
|
+
programPath.getData("__litsxHelperCandidateCache") || new WeakMap();
|
|
925
|
+
programPath.setData("__litsxHelperCandidateCache", helperCandidateCache);
|
|
926
|
+
const moduleAnalysisCache =
|
|
927
|
+
compilationSession?.importedModuleAnalysisCache ||
|
|
928
|
+
programPath.getData("__litsxImportedModuleAnalyses") ||
|
|
929
|
+
new Map();
|
|
930
|
+
programPath.setData("__litsxImportedModuleAnalyses", moduleAnalysisCache);
|
|
931
|
+
const resolvedImportCache =
|
|
932
|
+
compilationSession?.resolvedImportCache ||
|
|
933
|
+
programPath.getData("__litsxResolvedImports") ||
|
|
934
|
+
new Map();
|
|
935
|
+
programPath.setData("__litsxResolvedImports", resolvedImportCache);
|
|
936
|
+
|
|
937
|
+
const rootModule = {
|
|
938
|
+
filename: rootFilename,
|
|
939
|
+
programPath,
|
|
940
|
+
availableNames: getOrCreateAvailableNames(programPath),
|
|
941
|
+
helperPaths: getOrCreateHelperPaths(programPath),
|
|
942
|
+
compatPascalNames: programPath.getData("__litsxCompatPascalNames") || new Set(),
|
|
943
|
+
importBindings: new Map(),
|
|
944
|
+
exportBindings: new Map(),
|
|
945
|
+
};
|
|
946
|
+
|
|
947
|
+
programPath.get("body").forEach((nodePath) => {
|
|
948
|
+
if (!nodePath.isImportDeclaration()) {
|
|
949
|
+
return;
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
const sourceValue = nodePath.node.source.value;
|
|
953
|
+
const resolvedSource = resolveImportSource(rootFilename, sourceValue, {
|
|
954
|
+
moduleAnalysisCache,
|
|
955
|
+
resolvedImportCache,
|
|
956
|
+
});
|
|
957
|
+
|
|
958
|
+
nodePath.node.specifiers.forEach((specifier) => {
|
|
959
|
+
if (!specifier.local?.name) {
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
let importedName = null;
|
|
964
|
+
if (specifier.type === "ImportDefaultSpecifier") {
|
|
965
|
+
importedName = "default";
|
|
966
|
+
} else if (specifier.type === "ImportSpecifier") {
|
|
967
|
+
importedName = specifier.imported?.name ?? specifier.imported?.value ?? null;
|
|
968
|
+
} else if (specifier.type === "ImportNamespaceSpecifier") {
|
|
969
|
+
importedName = "*";
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
rootModule.importBindings.set(specifier.local.name, {
|
|
973
|
+
localName: specifier.local.name,
|
|
974
|
+
importedName,
|
|
975
|
+
sourceValue,
|
|
976
|
+
resolvedSource,
|
|
977
|
+
});
|
|
978
|
+
});
|
|
979
|
+
});
|
|
980
|
+
|
|
981
|
+
const context = {
|
|
982
|
+
rootFilename,
|
|
983
|
+
rootModule,
|
|
984
|
+
options,
|
|
985
|
+
helperCandidateCache,
|
|
986
|
+
moduleAnalysisCache,
|
|
987
|
+
resolvedImportCache,
|
|
988
|
+
...createCompilerContextResolver(options),
|
|
989
|
+
};
|
|
990
|
+
|
|
991
|
+
const resolvedHelper = resolveImportedHelper(rootModule, localName, context);
|
|
992
|
+
if (!resolvedHelper?.path?.node) {
|
|
993
|
+
return false;
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
function scanFunction(path, moduleAnalysis, seen = new Set()) {
|
|
997
|
+
if (!path?.node) {
|
|
998
|
+
return false;
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
const cacheKey = path.node;
|
|
1002
|
+
if (context.helperCandidateCache.has(cacheKey)) {
|
|
1003
|
+
const cached = context.helperCandidateCache.get(cacheKey);
|
|
1004
|
+
return cached.localCandidates.size > 0 || cached.importedCandidates.size > 0;
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
if (seen.has(path.node)) {
|
|
1008
|
+
return false;
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
const nextSeen = new Set(seen);
|
|
1012
|
+
nextSeen.add(path.node);
|
|
1013
|
+
let needsContext = false;
|
|
1014
|
+
const referencedHelpers = [];
|
|
1015
|
+
const scanContext = {
|
|
1016
|
+
availableNames: moduleAnalysis.availableNames,
|
|
1017
|
+
helperPaths: moduleAnalysis.helperPaths,
|
|
1018
|
+
compatPascalNames: moduleAnalysis.compatPascalNames,
|
|
1019
|
+
options,
|
|
1020
|
+
};
|
|
1021
|
+
|
|
1022
|
+
path.traverse({
|
|
1023
|
+
JSXOpeningElement(jsxPath) {
|
|
1024
|
+
const candidate = validateComponentName(jsxPath.node.name, jsxPath, scanContext);
|
|
1025
|
+
if (candidate) {
|
|
1026
|
+
needsContext = true;
|
|
1027
|
+
}
|
|
1028
|
+
},
|
|
1029
|
+
JSXClosingElement(jsxPath) {
|
|
1030
|
+
validateComponentName(jsxPath.node.name, jsxPath, scanContext);
|
|
1031
|
+
},
|
|
1032
|
+
Identifier(identifierPath) {
|
|
1033
|
+
if (!identifierPath.isReferencedIdentifier()) {
|
|
1034
|
+
return;
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
if (moduleAnalysis.helperPaths.has(identifierPath.node.name)) {
|
|
1038
|
+
referencedHelpers.push({
|
|
1039
|
+
moduleAnalysis,
|
|
1040
|
+
path: moduleAnalysis.helperPaths.get(identifierPath.node.name),
|
|
1041
|
+
});
|
|
1042
|
+
return;
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
const binding = identifierPath.scope.getBinding(identifierPath.node.name);
|
|
1046
|
+
if (
|
|
1047
|
+
!binding ||
|
|
1048
|
+
(
|
|
1049
|
+
!binding.path.isImportSpecifier?.() &&
|
|
1050
|
+
!binding.path.isImportDefaultSpecifier?.()
|
|
1051
|
+
)
|
|
1052
|
+
) {
|
|
1053
|
+
return;
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
const importedHelper = resolveImportedHelper(
|
|
1057
|
+
moduleAnalysis,
|
|
1058
|
+
identifierPath.node.name,
|
|
1059
|
+
context
|
|
1060
|
+
);
|
|
1061
|
+
if (importedHelper?.path?.node) {
|
|
1062
|
+
referencedHelpers.push(importedHelper);
|
|
1063
|
+
}
|
|
1064
|
+
},
|
|
1065
|
+
});
|
|
1066
|
+
|
|
1067
|
+
if (!needsContext) {
|
|
1068
|
+
needsContext = referencedHelpers.some((helperEntry) =>
|
|
1069
|
+
scanFunction(helperEntry.path, helperEntry.moduleAnalysis, nextSeen)
|
|
1070
|
+
);
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
context.helperCandidateCache.set(cacheKey, needsContext
|
|
1074
|
+
? {
|
|
1075
|
+
localCandidates: new Set(["__context"]),
|
|
1076
|
+
importedCandidates: new Map(),
|
|
1077
|
+
}
|
|
1078
|
+
: createEmptyCandidateResult()
|
|
1079
|
+
);
|
|
1080
|
+
|
|
1081
|
+
return needsContext;
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
return scanFunction(resolvedHelper.path, resolvedHelper.moduleAnalysis);
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
declare((api) => {
|
|
1088
|
+
api.assertVersion(7);
|
|
1089
|
+
t = api.types;
|
|
1090
|
+
|
|
1091
|
+
return {
|
|
1092
|
+
name: "transform-litsx-element-candidates",
|
|
1093
|
+
inherits: jsxSyntaxPlugin.default || jsxSyntaxPlugin,
|
|
1094
|
+
visitor: {
|
|
1095
|
+
Program: {
|
|
1096
|
+
enter(path) {
|
|
1097
|
+
path.scope.crawl();
|
|
1098
|
+
path.setData("__litsxAvailableNames", null);
|
|
1099
|
+
path.setData("__litsxHelperPaths", null);
|
|
1100
|
+
path.setData("__litsxHelperCandidateCache", new WeakMap());
|
|
1101
|
+
path.setData("__litsxImportedModuleAnalyses", new Map());
|
|
1102
|
+
path.setData("__litsxResolvedImports", new Map());
|
|
1103
|
+
},
|
|
1104
|
+
},
|
|
1105
|
+
FunctionDeclaration: {
|
|
1106
|
+
exit(path, state) {
|
|
1107
|
+
if (isInsideFunctionOrClass(path)) {
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
const programPath = path.findParent((entry) => entry.isProgram());
|
|
1112
|
+
const result = collectCandidateResult(
|
|
1113
|
+
path,
|
|
1114
|
+
programPath,
|
|
1115
|
+
{
|
|
1116
|
+
...(state.opts || {}),
|
|
1117
|
+
filename: state.file?.opts?.filename || "",
|
|
1118
|
+
}
|
|
1119
|
+
);
|
|
1120
|
+
path.node._litsxElementCandidates = result.localCandidates;
|
|
1121
|
+
path.node._litsxImportedElementCandidates = [...result.importedCandidates.values()];
|
|
1122
|
+
},
|
|
1123
|
+
},
|
|
1124
|
+
ArrowFunctionExpression: {
|
|
1125
|
+
exit(path, state) {
|
|
1126
|
+
if (isInsideFunctionOrClass(path)) {
|
|
1127
|
+
return;
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
const programPath = path.findParent((entry) => entry.isProgram());
|
|
1131
|
+
const result = collectCandidateResult(
|
|
1132
|
+
path,
|
|
1133
|
+
programPath,
|
|
1134
|
+
{
|
|
1135
|
+
...(state.opts || {}),
|
|
1136
|
+
filename: state.file?.opts?.filename || "",
|
|
1137
|
+
}
|
|
1138
|
+
);
|
|
1139
|
+
path.node._litsxElementCandidates = result.localCandidates;
|
|
1140
|
+
path.node._litsxImportedElementCandidates = [...result.importedCandidates.values()];
|
|
1141
|
+
},
|
|
1142
|
+
},
|
|
1143
|
+
FunctionExpression: {
|
|
1144
|
+
exit(path, state) {
|
|
1145
|
+
if (isInsideFunctionOrClass(path)) {
|
|
1146
|
+
return;
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
const programPath = path.findParent((entry) => entry.isProgram());
|
|
1150
|
+
const result = collectCandidateResult(
|
|
1151
|
+
path,
|
|
1152
|
+
programPath,
|
|
1153
|
+
{
|
|
1154
|
+
...(state.opts || {}),
|
|
1155
|
+
filename: state.file?.opts?.filename || "",
|
|
1156
|
+
}
|
|
1157
|
+
);
|
|
1158
|
+
path.node._litsxElementCandidates = result.localCandidates;
|
|
1159
|
+
path.node._litsxImportedElementCandidates = [...result.importedCandidates.values()];
|
|
1160
|
+
},
|
|
1161
|
+
},
|
|
1162
|
+
},
|
|
1163
|
+
};
|
|
1164
|
+
});
|
|
1165
|
+
|
|
1166
|
+
exports.getAnnotatedElementCandidates = getAnnotatedElementCandidates;
|
|
1167
|
+
exports.getAnnotatedImportedElementCandidates = getAnnotatedImportedElementCandidates;
|
|
1168
|
+
exports.importedBindingNeedsRendererContext = importedBindingNeedsRendererContext;
|
|
1169
|
+
exports.setElementCandidatesBabelTypes = setElementCandidatesBabelTypes;
|
|
1170
|
+
//# sourceMappingURL=transform-litsx-element-candidates-JMFlPFXK.cjs.map
|