Skip to content

Commit b66872a

Browse files
caiolimaMs2ger
authored andcommitted
Add ResolveExport tests for star exports with cyclic indirect re-exports
Star export resolution must skip cyclic paths that go through indirect named re-exports (export { foo } from "mod") and continue resolving through other star export entries. This adds two tests covering the case where the same export name cycles back via indirect re-exports while another star-export path provides the actual binding.
1 parent be10a74 commit b66872a

9 files changed

Lines changed: 126 additions & 0 deletions
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
export * from './instn-star-iee-multi-cycle-same-name-b_FIXTURE.js';
5+
export * from './instn-star-iee-multi-cycle-same-name-c_FIXTURE.js';
6+
export * from './instn-star-iee-multi-cycle-same-name-d_FIXTURE.js';
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
export { foo } from './instn-star-iee-multi-cycle-same-name-a_FIXTURE.js';
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
export let foo = 1;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
export { foo } from './instn-star-iee-multi-cycle-same-name-a_FIXTURE.js';
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
/*---
4+
description: >
5+
Star export resolution skips multiple cyclic indirect named re-exports
6+
and resolves the binding from a non-cyclic path.
7+
esid: sec-resolveexport
8+
info: |
9+
ResolveExport ( exportName [ , resolveSet ] )
10+
11+
[...]
12+
1. For each Record { [[Module]], [[ExportName]] } r of resolveSet, do
13+
a. If module and r.[[Module]] are the same Module Record and exportName is r.[[ExportName]], then
14+
i. Assert: This is a circular import request.
15+
i. Return null.
16+
1. Append the Record { [[Module]]: module, [[ExportName]]: exportName }
17+
to resolveSet.
18+
[...]
19+
1. For each ExportEntry Record e of module.[[IndirectExportEntries]], do
20+
a. If exportName is e.[[ExportName]], then
21+
[...]
22+
1. Return importedModule.ResolveExport(e.[[ImportName]],
23+
resolveSet).
24+
[...]
25+
1. Let starResolution be null.
26+
1. For each ExportEntry Record e of module.[[StarExportEntries]], do
27+
a. Let importedModule be GetImportedModule(module,
28+
e.[[ModuleRequest]]).
29+
a. Let resolution be importedModule.ResolveExport(exportName,
30+
resolveSet).
31+
a. If resolution is AMBIGUOUS, return AMBIGUOUS.
32+
a. If resolution is not null, then
33+
i. If starResolution is null, let starResolution be resolution.
34+
[...]
35+
1. Return starResolution.
36+
37+
Module "a" has three star exports:
38+
- "b" has `export { foo } from "a"` (cycles back, returns null).
39+
- "c" has `export let foo = 1` (provides the binding).
40+
- "d" has `export { foo } from "a"` (cycles back, returns null).
41+
The two cyclic paths return null (cycle detection), the star loop
42+
skips them, and the binding from "c" is used.
43+
flags: [module]
44+
---*/
45+
46+
import { foo } from './instn-star-iee-multi-cycle-same-name-a_FIXTURE.js';
47+
48+
assert.sameValue(foo, 1);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
export * from './instn-star-iee-single-cycle-same-name-b_FIXTURE.js';
5+
export * from './instn-star-iee-single-cycle-same-name-c_FIXTURE.js';
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
export { foo } from './instn-star-iee-single-cycle-same-name-a_FIXTURE.js';
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
export let foo = 42;
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
/*---
4+
description: >
5+
Star export resolution skips a single cyclic indirect named re-export
6+
and resolves the binding from the remaining non-cyclic path.
7+
esid: sec-resolveexport
8+
info: |
9+
ResolveExport ( exportName [ , resolveSet ] )
10+
11+
[...]
12+
1. For each Record { [[Module]], [[ExportName]] } r of resolveSet, do
13+
a. If module and r.[[Module]] are the same Module Record and exportName is r.[[ExportName]], then
14+
i. Assert: This is a circular import request.
15+
i. Return null.
16+
1. Append the Record { [[Module]]: module, [[ExportName]]: exportName }
17+
to resolveSet.
18+
[...]
19+
1. For each ExportEntry Record e of module.[[IndirectExportEntries]], do
20+
a. If exportName is e.[[ExportName]], then
21+
[...]
22+
1. Return importedModule.ResolveExport(e.[[ImportName]],
23+
resolveSet).
24+
[...]
25+
1. Let starResolution be null.
26+
1. For each ExportEntry Record e of module.[[StarExportEntries]], do
27+
a. Let importedModule be GetImportedModule(module,
28+
e.[[ModuleRequest]]).
29+
a. Let resolution be importedModule.ResolveExport(exportName,
30+
resolveSet).
31+
a. If resolution is AMBIGUOUS, return AMBIGUOUS.
32+
a. If resolution is not null, then
33+
i. If starResolution is null, let starResolution be resolution.
34+
[...]
35+
1. Return starResolution.
36+
37+
Module "a" has two star exports:
38+
- One to "b", which has `export { foo } from "a"` (cycles back).
39+
- One to "c", which has `export let foo = 42` (provides the binding).
40+
The cyclic path returns null (cycle detection), the star loop skips it,
41+
and the binding from "c" is used.
42+
flags: [module]
43+
---*/
44+
45+
import { foo } from './instn-star-iee-single-cycle-same-name-a_FIXTURE.js';
46+
47+
assert.sameValue(foo, 42);

0 commit comments

Comments
 (0)