@reckona/mreact-compiler 0.0.96 → 0.0.98
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/diagnostics.d.ts +1 -0
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js +8 -0
- package/dist/diagnostics.js.map +1 -1
- package/dist/emit-client.js +14 -9
- package/dist/emit-client.js.map +1 -1
- package/dist/emit-compat.js +5 -1
- package/dist/emit-compat.js.map +1 -1
- package/dist/emit-server-stream.d.ts.map +1 -1
- package/dist/emit-server-stream.js +70 -6
- package/dist/emit-server-stream.js.map +1 -1
- package/dist/emit-server.d.ts.map +1 -1
- package/dist/emit-server.js +69 -13
- package/dist/emit-server.js.map +1 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +7 -4
- package/dist/internal.js.map +1 -1
- package/dist/ir.d.ts +1 -0
- package/dist/ir.d.ts.map +1 -1
- package/dist/ir.js.map +1 -1
- package/dist/oxc-child-analysis.d.ts.map +1 -1
- package/dist/oxc-child-analysis.js +44 -10
- package/dist/oxc-child-analysis.js.map +1 -1
- package/dist/oxc-component-detection.d.ts +5 -2
- package/dist/oxc-component-detection.d.ts.map +1 -1
- package/dist/oxc-component-detection.js +80 -3
- package/dist/oxc-component-detection.js.map +1 -1
- package/dist/oxc-component-props.d.ts +1 -1
- package/dist/oxc-component-props.d.ts.map +1 -1
- package/dist/oxc-component-props.js +1 -1
- package/dist/oxc-component-props.js.map +1 -1
- package/dist/oxc-component-references.d.ts.map +1 -1
- package/dist/oxc-component-references.js +247 -12
- package/dist/oxc-component-references.js.map +1 -1
- package/dist/oxc-runtime-emit.d.ts.map +1 -1
- package/dist/oxc-runtime-emit.js +10 -2
- package/dist/oxc-runtime-emit.js.map +1 -1
- package/dist/oxc.d.ts.map +1 -1
- package/dist/oxc.js +109 -20
- package/dist/oxc.js.map +1 -1
- package/dist/transform.js +29 -11
- package/dist/transform.js.map +1 -1
- package/package.json +2 -2
- package/src/diagnostics.ts +10 -0
- package/src/emit-client.ts +20 -10
- package/src/emit-compat.ts +6 -1
- package/src/emit-server-stream.ts +96 -6
- package/src/emit-server.ts +93 -29
- package/src/internal.ts +9 -4
- package/src/ir.ts +1 -0
- package/src/oxc-child-analysis.ts +66 -21
- package/src/oxc-component-detection.ts +145 -2
- package/src/oxc-component-props.ts +2 -1
- package/src/oxc-component-references.ts +366 -11
- package/src/oxc-runtime-emit.ts +12 -2
- package/src/oxc.ts +167 -5
- package/src/transform.ts +42 -10
|
@@ -34,6 +34,44 @@ export function collectOxcPlainComponentNames(program: unknown): string[] {
|
|
|
34
34
|
});
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
export function collectOxcLocalJsxReturnFunctionNames(program: unknown): Set<string> {
|
|
38
|
+
const names = new Set<string>();
|
|
39
|
+
|
|
40
|
+
for (const statement of readArray(readObject(program).body)) {
|
|
41
|
+
const object = readObject(statement);
|
|
42
|
+
|
|
43
|
+
if (object.type === "FunctionDeclaration" && hasOxcFunctionLikeJsxReturn(object)) {
|
|
44
|
+
const id = readObject(object.id);
|
|
45
|
+
if (typeof id.name === "string") {
|
|
46
|
+
names.add(id.name);
|
|
47
|
+
}
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (object.type !== "VariableDeclaration") {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
for (const declarator of readArray(object.declarations)) {
|
|
56
|
+
const declaratorObject = readObject(declarator);
|
|
57
|
+
const id = readObject(declaratorObject.id);
|
|
58
|
+
const initializer = unwrapOxcComponentFunctionLikeInitializer(
|
|
59
|
+
readObject(declaratorObject.init),
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
if (
|
|
63
|
+
typeof id.name === "string" &&
|
|
64
|
+
initializer !== undefined &&
|
|
65
|
+
hasOxcFunctionLikeJsxReturn(initializer)
|
|
66
|
+
) {
|
|
67
|
+
names.add(id.name);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return names;
|
|
73
|
+
}
|
|
74
|
+
|
|
37
75
|
export function collectOxcExportedComponents(program: unknown): string[] {
|
|
38
76
|
const body = readArray(readObject(program).body);
|
|
39
77
|
const components: string[] = [];
|
|
@@ -133,8 +171,15 @@ export function isOxcExportedJsxComponent(statement: unknown): boolean {
|
|
|
133
171
|
);
|
|
134
172
|
}
|
|
135
173
|
|
|
136
|
-
export function isOxcJsxComponentStatement(
|
|
137
|
-
|
|
174
|
+
export function isOxcJsxComponentStatement(
|
|
175
|
+
statement: unknown,
|
|
176
|
+
localJsxReturnFunctionNames: ReadonlySet<string> = new Set(),
|
|
177
|
+
): boolean {
|
|
178
|
+
return (
|
|
179
|
+
isOxcExportedJsxComponent(statement) ||
|
|
180
|
+
isOxcExportedFunctionReturningLocalJsxHelper(statement, localJsxReturnFunctionNames) ||
|
|
181
|
+
readOxcPlainComponent(statement) !== undefined
|
|
182
|
+
);
|
|
138
183
|
}
|
|
139
184
|
|
|
140
185
|
export function isOxcExportedFunctionLike(statement: unknown): boolean {
|
|
@@ -159,6 +204,7 @@ export function isOxcExportedFunctionLike(statement: unknown): boolean {
|
|
|
159
204
|
export function isOxcUnsupportedExportedFunction(
|
|
160
205
|
statement: unknown,
|
|
161
206
|
options?: AnalyzeModuleOptions,
|
|
207
|
+
localJsxReturnFunctionNames: ReadonlySet<string> = new Set(),
|
|
162
208
|
): boolean {
|
|
163
209
|
if (options?.compatReactNodeReturn === true) {
|
|
164
210
|
return false;
|
|
@@ -178,10 +224,29 @@ export function isOxcUnsupportedExportedFunction(
|
|
|
178
224
|
typeof id.name === "string" &&
|
|
179
225
|
/^[A-Z]/.test(id.name) &&
|
|
180
226
|
!hasComponentReturn(declaration.body) &&
|
|
227
|
+
!hasLocalJsxHelperCallReturn(declaration.body, localJsxReturnFunctionNames) &&
|
|
181
228
|
!hasOnlyNullReturns(declaration.body)
|
|
182
229
|
);
|
|
183
230
|
}
|
|
184
231
|
|
|
232
|
+
function isOxcExportedFunctionReturningLocalJsxHelper(
|
|
233
|
+
statement: unknown,
|
|
234
|
+
localJsxReturnFunctionNames: ReadonlySet<string>,
|
|
235
|
+
): boolean {
|
|
236
|
+
const object = readObject(statement);
|
|
237
|
+
|
|
238
|
+
if (object.type !== "ExportNamedDeclaration") {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const declaration = readObject(object.declaration);
|
|
243
|
+
|
|
244
|
+
return (
|
|
245
|
+
declaration.type === "FunctionDeclaration" &&
|
|
246
|
+
hasLocalJsxHelperCallReturn(declaration.body, localJsxReturnFunctionNames)
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
|
|
185
250
|
export function readOxcVariableComponentDeclaration(
|
|
186
251
|
declaration: Record<string, unknown>,
|
|
187
252
|
): { name: string; initializer: Record<string, unknown> } | undefined {
|
|
@@ -305,6 +370,45 @@ export function hasComponentCallReturn(body: unknown): boolean {
|
|
|
305
370
|
});
|
|
306
371
|
}
|
|
307
372
|
|
|
373
|
+
export function hasLocalJsxHelperCallReturn(
|
|
374
|
+
body: unknown,
|
|
375
|
+
localJsxReturnFunctionNames: ReadonlySet<string>,
|
|
376
|
+
): boolean {
|
|
377
|
+
if (localJsxReturnFunctionNames.size === 0) {
|
|
378
|
+
return false;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
return readArray(readObject(body).body).some((statement) => {
|
|
382
|
+
const object = readObject(statement);
|
|
383
|
+
|
|
384
|
+
if (object.type === "ReturnStatement") {
|
|
385
|
+
return isOxcLocalJsxHelperCallExpression(
|
|
386
|
+
unwrapOxcParentheses(readObject(object.argument)),
|
|
387
|
+
localJsxReturnFunctionNames,
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
return hasNestedLocalJsxHelperCallReturn(object, localJsxReturnFunctionNames);
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
export function isOxcLocalJsxHelperCallExpression(
|
|
396
|
+
expression: Record<string, unknown>,
|
|
397
|
+
localJsxReturnFunctionNames: ReadonlySet<string>,
|
|
398
|
+
): boolean {
|
|
399
|
+
if (expression.type !== "CallExpression") {
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
const callee = unwrapOxcParentheses(readObject(expression.callee));
|
|
404
|
+
|
|
405
|
+
return (
|
|
406
|
+
callee.type === "Identifier" &&
|
|
407
|
+
typeof callee.name === "string" &&
|
|
408
|
+
localJsxReturnFunctionNames.has(callee.name)
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
|
|
308
412
|
function hasNestedJsxReturn(statement: Record<string, unknown>): boolean {
|
|
309
413
|
if (statement.type === "SwitchStatement") {
|
|
310
414
|
return readArray(statement.cases).some((switchCase) =>
|
|
@@ -359,6 +463,45 @@ function hasNestedComponentCallReturn(statement: Record<string, unknown>): boole
|
|
|
359
463
|
return false;
|
|
360
464
|
}
|
|
361
465
|
|
|
466
|
+
function hasNestedLocalJsxHelperCallReturn(
|
|
467
|
+
statement: Record<string, unknown>,
|
|
468
|
+
localJsxReturnFunctionNames: ReadonlySet<string>,
|
|
469
|
+
): boolean {
|
|
470
|
+
if (statement.type === "SwitchStatement") {
|
|
471
|
+
return readArray(statement.cases).some((switchCase) =>
|
|
472
|
+
readArray(readObject(switchCase).consequent).some((child) => {
|
|
473
|
+
const object = readObject(child);
|
|
474
|
+
return (
|
|
475
|
+
object.type === "ReturnStatement" &&
|
|
476
|
+
isOxcLocalJsxHelperCallExpression(
|
|
477
|
+
unwrapOxcParentheses(readObject(object.argument)),
|
|
478
|
+
localJsxReturnFunctionNames,
|
|
479
|
+
)
|
|
480
|
+
);
|
|
481
|
+
}),
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
if (statement.type === "IfStatement") {
|
|
486
|
+
return (
|
|
487
|
+
hasLocalJsxHelperCallReturn(
|
|
488
|
+
{ body: [statement.consequent] },
|
|
489
|
+
localJsxReturnFunctionNames,
|
|
490
|
+
) ||
|
|
491
|
+
hasLocalJsxHelperCallReturn(
|
|
492
|
+
{ body: [statement.alternate] },
|
|
493
|
+
localJsxReturnFunctionNames,
|
|
494
|
+
)
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
if (statement.type === "BlockStatement") {
|
|
499
|
+
return hasLocalJsxHelperCallReturn(statement, localJsxReturnFunctionNames);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
return false;
|
|
503
|
+
}
|
|
504
|
+
|
|
362
505
|
function collectReturnArguments(statement: Record<string, unknown>): Record<string, unknown>[] {
|
|
363
506
|
if (statement.type === "ReturnStatement") {
|
|
364
507
|
return [readObject(statement.argument)];
|
|
@@ -16,6 +16,7 @@ import type { Diagnostic } from "./types.js";
|
|
|
16
16
|
export type AnalyzeOxcJsxNodeCallback = (
|
|
17
17
|
node: Record<string, unknown>,
|
|
18
18
|
bodyStatementJsx?: OxcBodyStatementJsxMode,
|
|
19
|
+
shadowNames?: readonly string[],
|
|
19
20
|
) => JsxNodeIr;
|
|
20
21
|
|
|
21
22
|
export function analyzeOxcComponentProp(
|
|
@@ -159,7 +160,7 @@ export function analyzeOxcArrowJsxRenderer(
|
|
|
159
160
|
if (body.type === "JSXElement" || body.type === "JSXFragment") {
|
|
160
161
|
return {
|
|
161
162
|
valueName,
|
|
162
|
-
children: [analyzeJsxNode(body, bodyStatementJsx)],
|
|
163
|
+
children: [analyzeJsxNode(body, bodyStatementJsx, [valueName])],
|
|
163
164
|
};
|
|
164
165
|
}
|
|
165
166
|
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
import type { ClientReferenceIr, JsxNodeIr } from "./ir.js";
|
|
2
2
|
import { readArray, readObject } from "./oxc-node-utils.js";
|
|
3
3
|
|
|
4
|
-
const routerEntryCompatRuntimeExports = new Set(
|
|
5
|
-
const routerLinkCompatRuntimeExports = new Set(
|
|
4
|
+
const routerEntryCompatRuntimeExports = new Set<string>();
|
|
5
|
+
const routerLinkCompatRuntimeExports = new Set<string>();
|
|
6
|
+
const unknownCompatReference: ClientReferenceIr = { moduleId: "", exportName: "default" };
|
|
6
7
|
|
|
7
8
|
interface ClientReferenceAliasState {
|
|
9
|
+
allowAmbiguousAliases: boolean;
|
|
8
10
|
references: Map<string, ClientReferenceIr>;
|
|
9
11
|
stringConstants: Map<string, string>;
|
|
10
12
|
objectMembers: Map<string, Map<string, ClientReferenceIr>>;
|
|
13
|
+
objectMemberKeys: Map<string, Set<string>>;
|
|
14
|
+
dynamicObjectMembers: Map<string, ClientReferenceIr[]>;
|
|
15
|
+
dynamicObjectNestedMembers: Map<string, Map<string, ClientReferenceIr[]>>;
|
|
16
|
+
globModuleMaps: Set<string>;
|
|
17
|
+
objectEntryValueBindings: Map<string, string>;
|
|
11
18
|
}
|
|
12
19
|
|
|
13
20
|
export function collectOxcClientBoundaryImportComponents(
|
|
@@ -117,6 +124,7 @@ export function collectOxcCompatRuntimeImportComponents(
|
|
|
117
124
|
}
|
|
118
125
|
}
|
|
119
126
|
|
|
127
|
+
collectOxcClientReferenceAliases(program, names, { allowAmbiguousAliases: true });
|
|
120
128
|
return names;
|
|
121
129
|
}
|
|
122
130
|
|
|
@@ -321,11 +329,18 @@ function readOxcClassComponentName(
|
|
|
321
329
|
function collectOxcClientReferenceAliases(
|
|
322
330
|
node: unknown,
|
|
323
331
|
references: Map<string, ClientReferenceIr>,
|
|
332
|
+
options: { allowAmbiguousAliases?: boolean } = {},
|
|
324
333
|
): void {
|
|
325
334
|
const state: ClientReferenceAliasState = {
|
|
335
|
+
allowAmbiguousAliases: options.allowAmbiguousAliases === true,
|
|
326
336
|
references,
|
|
327
337
|
stringConstants: new Map(),
|
|
328
338
|
objectMembers: new Map(),
|
|
339
|
+
objectMemberKeys: new Map(),
|
|
340
|
+
dynamicObjectMembers: new Map(),
|
|
341
|
+
dynamicObjectNestedMembers: new Map(),
|
|
342
|
+
globModuleMaps: new Set(),
|
|
343
|
+
objectEntryValueBindings: new Map(),
|
|
329
344
|
};
|
|
330
345
|
|
|
331
346
|
collectOxcClientReferenceAliasesFromNode(node, state);
|
|
@@ -371,6 +386,11 @@ function collectOxcClientReferenceAliasesFromNode(
|
|
|
371
386
|
collectOxcObjectAssignClientReferenceAliases(object, state);
|
|
372
387
|
}
|
|
373
388
|
|
|
389
|
+
if (object.type === "ForOfStatement") {
|
|
390
|
+
collectOxcForOfClientReferenceAliases(object, state);
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
|
|
374
394
|
for (const [key, value] of Object.entries(object)) {
|
|
375
395
|
if (key === "type" || key === "start" || key === "end" || key === "loc") {
|
|
376
396
|
continue;
|
|
@@ -404,6 +424,10 @@ function collectOxcVariableClientReferenceAlias(
|
|
|
404
424
|
}
|
|
405
425
|
}
|
|
406
426
|
|
|
427
|
+
if (isImportMetaGlobEagerCall(init)) {
|
|
428
|
+
state.globModuleMaps.add(aliasName);
|
|
429
|
+
}
|
|
430
|
+
|
|
407
431
|
collectOxcObjectLiteralClientReferenceAliases(aliasName, init, state);
|
|
408
432
|
|
|
409
433
|
const reference = expressionClientReference(init, state);
|
|
@@ -428,7 +452,16 @@ function collectOxcObjectLiteralClientReferenceAliases(
|
|
|
428
452
|
}
|
|
429
453
|
|
|
430
454
|
const keyName = propertyName(readOptionalObject(property.key), property.computed === true, state);
|
|
431
|
-
const
|
|
455
|
+
const value = readOptionalObject(property.value);
|
|
456
|
+
if (keyName !== undefined) {
|
|
457
|
+
addObjectMemberKey(state, objectName, keyName);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
if (keyName !== undefined && value?.type === "ObjectExpression") {
|
|
461
|
+
collectOxcObjectLiteralClientReferenceAliases(`${objectName}.${keyName}`, value, state);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
const reference = expressionClientReference(value, state);
|
|
432
465
|
if (keyName !== undefined && reference !== undefined) {
|
|
433
466
|
setObjectMemberReference(state, objectName, keyName, reference);
|
|
434
467
|
}
|
|
@@ -448,11 +481,50 @@ function collectOxcAssignmentClientReferenceAlias(
|
|
|
448
481
|
return;
|
|
449
482
|
}
|
|
450
483
|
|
|
451
|
-
const objectName = expressionObjectName(readOptionalObject(left.object));
|
|
484
|
+
const objectName = expressionObjectName(readOptionalObject(left.object), state);
|
|
452
485
|
const memberName = propertyName(readOptionalObject(left.property), left.computed === true, state);
|
|
453
486
|
const reference = expressionClientReference(readOptionalObject(node.right), state);
|
|
454
|
-
if (objectName !== undefined && memberName !== undefined
|
|
455
|
-
|
|
487
|
+
if (objectName !== undefined && memberName !== undefined) {
|
|
488
|
+
addObjectMemberKey(state, objectName, memberName);
|
|
489
|
+
if (reference !== undefined) {
|
|
490
|
+
setObjectMemberReference(state, objectName, memberName, reference);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
if (objectName !== undefined && memberName === undefined) {
|
|
495
|
+
if (reference !== undefined) {
|
|
496
|
+
addDynamicObjectMemberReference(state, objectName, reference);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
collectDynamicObjectNestedMemberReferences(objectName, readOptionalObject(node.right), state);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
function collectOxcForOfClientReferenceAliases(
|
|
504
|
+
node: Record<string, unknown>,
|
|
505
|
+
state: ClientReferenceAliasState,
|
|
506
|
+
): void {
|
|
507
|
+
const sourceName = objectEntriesSourceName(readOptionalObject(node.right), state);
|
|
508
|
+
const valueName = forOfObjectEntriesValueBindingName(readOptionalObject(node.left));
|
|
509
|
+
|
|
510
|
+
if (sourceName === undefined || valueName === undefined) {
|
|
511
|
+
for (const [key, value] of Object.entries(node)) {
|
|
512
|
+
if (key === "type" || key === "start" || key === "end" || key === "loc") {
|
|
513
|
+
continue;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
collectOxcClientReferenceAliasesFromNode(value, state);
|
|
517
|
+
}
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
const previous = state.objectEntryValueBindings.get(valueName);
|
|
522
|
+
state.objectEntryValueBindings.set(valueName, sourceName);
|
|
523
|
+
collectOxcClientReferenceAliasesFromNode(node.body, state);
|
|
524
|
+
if (previous === undefined) {
|
|
525
|
+
state.objectEntryValueBindings.delete(valueName);
|
|
526
|
+
} else {
|
|
527
|
+
state.objectEntryValueBindings.set(valueName, previous);
|
|
456
528
|
}
|
|
457
529
|
}
|
|
458
530
|
|
|
@@ -465,7 +537,7 @@ function collectOxcObjectAssignClientReferenceAliases(
|
|
|
465
537
|
}
|
|
466
538
|
|
|
467
539
|
const args = readArray(node.arguments).map(readOptionalObject);
|
|
468
|
-
const target = expressionObjectName(args[0]);
|
|
540
|
+
const target = expressionObjectName(args[0], state);
|
|
469
541
|
if (target === undefined) {
|
|
470
542
|
return;
|
|
471
543
|
}
|
|
@@ -488,7 +560,7 @@ function expressionClientReference(
|
|
|
488
560
|
}
|
|
489
561
|
|
|
490
562
|
if (node.type === "MemberExpression") {
|
|
491
|
-
const objectName = expressionObjectName(readOptionalObject(node.object));
|
|
563
|
+
const objectName = expressionObjectName(readOptionalObject(node.object), state);
|
|
492
564
|
const memberName = propertyName(readOptionalObject(node.property), node.computed === true, state);
|
|
493
565
|
const objectReference =
|
|
494
566
|
objectName === undefined ? undefined : state.references.get(objectName);
|
|
@@ -498,10 +570,39 @@ function expressionClientReference(
|
|
|
498
570
|
if (objectMember !== undefined) {
|
|
499
571
|
return objectMember;
|
|
500
572
|
}
|
|
573
|
+
|
|
574
|
+
const dynamicObjectReference = selectClientReference(
|
|
575
|
+
dynamicObjectMemberReferences(state, objectName),
|
|
576
|
+
state.allowAmbiguousAliases,
|
|
577
|
+
);
|
|
578
|
+
if (dynamicObjectReference !== undefined) {
|
|
579
|
+
return dynamicObjectReference;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
const objectEntryReference = objectEntryMemberReference(objectName, memberName, state);
|
|
583
|
+
if (objectEntryReference !== undefined) {
|
|
584
|
+
return objectEntryReference;
|
|
585
|
+
}
|
|
501
586
|
}
|
|
502
587
|
|
|
503
588
|
if (objectName !== undefined && memberName === undefined) {
|
|
504
|
-
return
|
|
589
|
+
return selectClientReference(
|
|
590
|
+
[...objectMemberReferences(state, objectName), ...dynamicObjectMemberReferences(state, objectName)],
|
|
591
|
+
state.allowAmbiguousAliases,
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
if (objectName === undefined && memberName !== undefined) {
|
|
596
|
+
const references = [
|
|
597
|
+
...expressionObjectNameCandidates(readOptionalObject(node.object), state)
|
|
598
|
+
.map((candidate) => state.objectMembers.get(candidate)?.get(memberName)),
|
|
599
|
+
...expressionDynamicObjectNestedMemberReferences(
|
|
600
|
+
readOptionalObject(node.object),
|
|
601
|
+
memberName,
|
|
602
|
+
state,
|
|
603
|
+
),
|
|
604
|
+
];
|
|
605
|
+
return selectClientReference(references, state.allowAmbiguousAliases);
|
|
505
606
|
}
|
|
506
607
|
|
|
507
608
|
if (objectReference?.exportName === "*" && memberName !== undefined) {
|
|
@@ -532,8 +633,74 @@ function expressionClientReference(
|
|
|
532
633
|
return undefined;
|
|
533
634
|
}
|
|
534
635
|
|
|
535
|
-
function
|
|
536
|
-
|
|
636
|
+
function objectEntryMemberReference(
|
|
637
|
+
objectName: string,
|
|
638
|
+
memberName: string,
|
|
639
|
+
state: ClientReferenceAliasState,
|
|
640
|
+
): ClientReferenceIr | undefined {
|
|
641
|
+
const sourceName = state.objectEntryValueBindings.get(objectName);
|
|
642
|
+
if (sourceName === undefined) {
|
|
643
|
+
return undefined;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
if (state.allowAmbiguousAliases && state.globModuleMaps.has(sourceName) && memberName === "default") {
|
|
647
|
+
return unknownCompatReference;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
const references = Array.from(state.objectMemberKeys.get(sourceName) ?? [])
|
|
651
|
+
.map((key) => state.objectMembers.get(`${sourceName}.${key}`)?.get(memberName));
|
|
652
|
+
return selectClientReference(references, state.allowAmbiguousAliases);
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
function expressionObjectNameCandidates(
|
|
656
|
+
node: Record<string, unknown> | undefined,
|
|
657
|
+
state: ClientReferenceAliasState,
|
|
658
|
+
): string[] {
|
|
659
|
+
const exactName = expressionObjectName(node, state);
|
|
660
|
+
if (exactName !== undefined) {
|
|
661
|
+
return [exactName];
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
if (node?.type !== "MemberExpression") {
|
|
665
|
+
return [];
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
const objectName = expressionObjectName(readOptionalObject(node.object), state);
|
|
669
|
+
const memberName = propertyName(readOptionalObject(node.property), node.computed === true, state);
|
|
670
|
+
|
|
671
|
+
if (objectName !== undefined && memberName === undefined) {
|
|
672
|
+
return Array.from(state.objectMemberKeys.get(objectName) ?? []).map(
|
|
673
|
+
(key) => `${objectName}.${key}`,
|
|
674
|
+
);
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
if (memberName === undefined) {
|
|
678
|
+
return [];
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
return expressionObjectNameCandidates(readOptionalObject(node.object), state).map(
|
|
682
|
+
(candidate) => `${candidate}.${memberName}`,
|
|
683
|
+
);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
function expressionObjectName(
|
|
687
|
+
node: Record<string, unknown> | undefined,
|
|
688
|
+
state: ClientReferenceAliasState,
|
|
689
|
+
): string | undefined {
|
|
690
|
+
if (node?.type === "Identifier" && typeof node.name === "string") {
|
|
691
|
+
return node.name;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
if (node?.type === "MemberExpression") {
|
|
695
|
+
const objectName = expressionObjectName(readOptionalObject(node.object), state);
|
|
696
|
+
const memberName = propertyName(readOptionalObject(node.property), node.computed === true, state);
|
|
697
|
+
|
|
698
|
+
return objectName !== undefined && memberName !== undefined
|
|
699
|
+
? `${objectName}.${memberName}`
|
|
700
|
+
: undefined;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
return undefined;
|
|
537
704
|
}
|
|
538
705
|
|
|
539
706
|
function propertyName(
|
|
@@ -596,6 +763,63 @@ function setObjectMemberReference(
|
|
|
596
763
|
const members = state.objectMembers.get(objectName) ?? new Map<string, ClientReferenceIr>();
|
|
597
764
|
members.set(memberName, reference);
|
|
598
765
|
state.objectMembers.set(objectName, members);
|
|
766
|
+
addObjectMemberKey(state, objectName, memberName);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
function addDynamicObjectMemberReference(
|
|
770
|
+
state: ClientReferenceAliasState,
|
|
771
|
+
objectName: string,
|
|
772
|
+
reference: ClientReferenceIr,
|
|
773
|
+
): void {
|
|
774
|
+
const references = state.dynamicObjectMembers.get(objectName) ?? [];
|
|
775
|
+
references.push(reference);
|
|
776
|
+
state.dynamicObjectMembers.set(objectName, references);
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
function collectDynamicObjectNestedMemberReferences(
|
|
780
|
+
objectName: string,
|
|
781
|
+
node: Record<string, unknown> | undefined,
|
|
782
|
+
state: ClientReferenceAliasState,
|
|
783
|
+
): void {
|
|
784
|
+
if (node?.type !== "ObjectExpression") {
|
|
785
|
+
return;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
for (const propertyValue of readArray(node.properties)) {
|
|
789
|
+
const property = readOptionalObject(propertyValue);
|
|
790
|
+
if (property?.type !== "Property") {
|
|
791
|
+
continue;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
const keyName = propertyName(readOptionalObject(property.key), property.computed === true, state);
|
|
795
|
+
const reference = expressionClientReference(readOptionalObject(property.value), state);
|
|
796
|
+
if (keyName !== undefined && reference !== undefined) {
|
|
797
|
+
addDynamicObjectNestedMemberReference(state, objectName, keyName, reference);
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
function addDynamicObjectNestedMemberReference(
|
|
803
|
+
state: ClientReferenceAliasState,
|
|
804
|
+
objectName: string,
|
|
805
|
+
memberName: string,
|
|
806
|
+
reference: ClientReferenceIr,
|
|
807
|
+
): void {
|
|
808
|
+
const members = state.dynamicObjectNestedMembers.get(objectName) ?? new Map<string, ClientReferenceIr[]>();
|
|
809
|
+
const references = members.get(memberName) ?? [];
|
|
810
|
+
references.push(reference);
|
|
811
|
+
members.set(memberName, references);
|
|
812
|
+
state.dynamicObjectNestedMembers.set(objectName, members);
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
function addObjectMemberKey(
|
|
816
|
+
state: ClientReferenceAliasState,
|
|
817
|
+
objectName: string,
|
|
818
|
+
memberName: string,
|
|
819
|
+
): void {
|
|
820
|
+
const keys = state.objectMemberKeys.get(objectName) ?? new Set<string>();
|
|
821
|
+
keys.add(memberName);
|
|
822
|
+
state.objectMemberKeys.set(objectName, keys);
|
|
599
823
|
}
|
|
600
824
|
|
|
601
825
|
function isObjectAssignCall(node: Record<string, unknown>): boolean {
|
|
@@ -610,6 +834,56 @@ function isObjectAssignCall(node: Record<string, unknown>): boolean {
|
|
|
610
834
|
property?.type === "Identifier" && property.name === "assign";
|
|
611
835
|
}
|
|
612
836
|
|
|
837
|
+
function isObjectEntriesCall(node: Record<string, unknown> | undefined): boolean {
|
|
838
|
+
const callee = readOptionalObject(node?.callee);
|
|
839
|
+
if (callee?.type !== "MemberExpression" || callee.computed === true) {
|
|
840
|
+
return false;
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
const object = readOptionalObject(callee.object);
|
|
844
|
+
const property = readOptionalObject(callee.property);
|
|
845
|
+
return object?.type === "Identifier" && object.name === "Object" &&
|
|
846
|
+
property?.type === "Identifier" && property.name === "entries";
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
function isImportMetaGlobEagerCall(node: Record<string, unknown> | undefined): boolean {
|
|
850
|
+
const callee = readOptionalObject(node?.callee);
|
|
851
|
+
if (node?.type !== "CallExpression" || callee?.type !== "MemberExpression") {
|
|
852
|
+
return false;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
const property = readOptionalObject(callee.property);
|
|
856
|
+
if (callee.computed === true || property?.type !== "Identifier" || property.name !== "glob") {
|
|
857
|
+
return false;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
const metaProperty = readOptionalObject(callee.object);
|
|
861
|
+
const meta = readOptionalObject(metaProperty?.meta);
|
|
862
|
+
const metaName = meta?.type === "Identifier" ? meta.name : undefined;
|
|
863
|
+
const propertyName = readOptionalObject(metaProperty?.property);
|
|
864
|
+
const importMetaPropertyName = propertyName?.type === "Identifier" ? propertyName.name : undefined;
|
|
865
|
+
if (metaProperty?.type !== "MetaProperty" || metaName !== "import" || importMetaPropertyName !== "meta") {
|
|
866
|
+
return false;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
const options = readOptionalObject(readArray(node.arguments)[1]);
|
|
870
|
+
if (options?.type !== "ObjectExpression") {
|
|
871
|
+
return false;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
return readArray(options.properties).some((propertyValue) => {
|
|
875
|
+
const property = readOptionalObject(propertyValue);
|
|
876
|
+
const key = readOptionalObject(property?.key);
|
|
877
|
+
const value = readOptionalObject(property?.value);
|
|
878
|
+
return property?.type === "Property" &&
|
|
879
|
+
property.computed !== true &&
|
|
880
|
+
key?.type === "Identifier" &&
|
|
881
|
+
key.name === "eager" &&
|
|
882
|
+
value?.type === "Literal" &&
|
|
883
|
+
value.value === true;
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
|
|
613
887
|
function uniqueClientReference(
|
|
614
888
|
values: readonly (ClientReferenceIr | undefined)[],
|
|
615
889
|
): ClientReferenceIr | undefined {
|
|
@@ -631,6 +905,87 @@ function uniqueClientReference(
|
|
|
631
905
|
: undefined;
|
|
632
906
|
}
|
|
633
907
|
|
|
908
|
+
function selectClientReference(
|
|
909
|
+
values: readonly (ClientReferenceIr | undefined)[],
|
|
910
|
+
allowAmbiguousAliases: boolean,
|
|
911
|
+
): ClientReferenceIr | undefined {
|
|
912
|
+
if (!allowAmbiguousAliases) {
|
|
913
|
+
return uniqueClientReference(values);
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
if (values.length === 0 || values.some((value) => value === undefined)) {
|
|
917
|
+
return undefined;
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
return values[0];
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
function objectMemberReferences(
|
|
924
|
+
state: ClientReferenceAliasState,
|
|
925
|
+
objectName: string,
|
|
926
|
+
): Array<ClientReferenceIr | undefined> {
|
|
927
|
+
const keys = Array.from(state.objectMemberKeys.get(objectName) ?? []);
|
|
928
|
+
return keys.map((key) => state.objectMembers.get(objectName)?.get(key));
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
function dynamicObjectMemberReferences(
|
|
932
|
+
state: ClientReferenceAliasState,
|
|
933
|
+
objectName: string,
|
|
934
|
+
): Array<ClientReferenceIr | undefined> {
|
|
935
|
+
return state.dynamicObjectMembers.get(objectName) ?? [];
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
function expressionDynamicObjectNestedMemberReferences(
|
|
939
|
+
node: Record<string, unknown> | undefined,
|
|
940
|
+
memberName: string,
|
|
941
|
+
state: ClientReferenceAliasState,
|
|
942
|
+
): Array<ClientReferenceIr | undefined> {
|
|
943
|
+
if (node?.type !== "MemberExpression") {
|
|
944
|
+
return [];
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
const objectName = expressionObjectName(readOptionalObject(node.object), state);
|
|
948
|
+
const property = propertyName(readOptionalObject(node.property), node.computed === true, state);
|
|
949
|
+
if (objectName === undefined || property !== undefined) {
|
|
950
|
+
return [];
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
return state.dynamicObjectNestedMembers.get(objectName)?.get(memberName) ?? [];
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
function objectEntriesSourceName(
|
|
957
|
+
node: Record<string, unknown> | undefined,
|
|
958
|
+
state: ClientReferenceAliasState,
|
|
959
|
+
): string | undefined {
|
|
960
|
+
if (!isObjectEntriesCall(node)) {
|
|
961
|
+
return undefined;
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
const args = readArray(node?.arguments).map(readOptionalObject);
|
|
965
|
+
return expressionObjectName(args[0], state);
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
function forOfObjectEntriesValueBindingName(
|
|
969
|
+
node: Record<string, unknown> | undefined,
|
|
970
|
+
): string | undefined {
|
|
971
|
+
const declaration =
|
|
972
|
+
node?.type === "VariableDeclaration"
|
|
973
|
+
? readOptionalObject(readArray(node.declarations)[0])
|
|
974
|
+
: undefined;
|
|
975
|
+
const pattern = declaration?.type === "VariableDeclarator"
|
|
976
|
+
? readOptionalObject(declaration.id)
|
|
977
|
+
: node;
|
|
978
|
+
|
|
979
|
+
if (pattern?.type !== "ArrayPattern") {
|
|
980
|
+
return undefined;
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
const valueElement = readOptionalObject(readArray(pattern.elements)[1]);
|
|
984
|
+
return valueElement?.type === "Identifier" && typeof valueElement.name === "string"
|
|
985
|
+
? valueElement.name
|
|
986
|
+
: undefined;
|
|
987
|
+
}
|
|
988
|
+
|
|
634
989
|
function uniqueString(values: readonly (string | undefined)[]): string | undefined {
|
|
635
990
|
const unique = new Set(values.filter((value): value is string => value !== undefined));
|
|
636
991
|
return unique.size === 1 ? Array.from(unique)[0] : undefined;
|