Skip to content

Commit 348c42b

Browse files
authored
fix: Keep resolving queued imports while there is progress (#1415)
1 parent 2bc0302 commit 348c42b

10 files changed

+171
-58
lines changed

src/glue/js/node.d.ts

+3
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@
55

66
declare const global: Record<string,unknown>;
77
declare function require(name: string): unknown;
8+
declare namespace console {
9+
function log(...args: unknown[]): void;
10+
}

src/program.ts

+59-40
Original file line numberDiff line numberDiff line change
@@ -1020,50 +1020,69 @@ export class Program extends DiagnosticEmitter {
10201020
}
10211021
}
10221022

1023-
// queued imports should be resolvable now through traversing exports and queued exports
1024-
for (let i = 0, k = queuedImports.length; i < k; ++i) {
1025-
let queuedImport = queuedImports[i];
1026-
let localIdentifier = queuedImport.localIdentifier;
1027-
let foreignIdentifier = queuedImport.foreignIdentifier;
1028-
if (foreignIdentifier) { // i.e. import { foo [as bar] } from "./baz"
1029-
let element = this.lookupForeign(
1030-
foreignIdentifier.text,
1031-
queuedImport.foreignPath,
1032-
queuedImport.foreignPathAlt,
1033-
queuedExports
1034-
);
1035-
if (element) {
1036-
queuedImport.localFile.add(
1037-
localIdentifier.text,
1038-
element,
1039-
localIdentifier // isImport
1040-
);
1041-
} else {
1042-
// FIXME: file not found is not reported if this happens?
1043-
this.error(
1044-
DiagnosticCode.Module_0_has_no_exported_member_1,
1045-
foreignIdentifier.range, queuedImport.foreignPath, foreignIdentifier.text
1023+
// queued imports should be resolvable now through traversing exports and queued exports.
1024+
// note that imports may depend upon imports, so repeat until there's no more progress.
1025+
do {
1026+
let i = 0, madeProgress = false;
1027+
while (i < queuedImports.length) {
1028+
let queuedImport = queuedImports[i];
1029+
let localIdentifier = queuedImport.localIdentifier;
1030+
let foreignIdentifier = queuedImport.foreignIdentifier;
1031+
if (foreignIdentifier) { // i.e. import { foo [as bar] } from "./baz"
1032+
let element = this.lookupForeign(
1033+
foreignIdentifier.text,
1034+
queuedImport.foreignPath,
1035+
queuedImport.foreignPathAlt,
1036+
queuedExports
10461037
);
1047-
}
1048-
} else { // i.e. import * as bar from "./bar"
1049-
let foreignFile = this.lookupForeignFile(queuedImport.foreignPath, queuedImport.foreignPathAlt);
1050-
if (foreignFile) {
1051-
let localFile = queuedImport.localFile;
1052-
let localName = localIdentifier.text;
1053-
localFile.add(
1054-
localName,
1055-
foreignFile.asImportedNamespace(
1038+
if (element) {
1039+
queuedImport.localFile.add(
1040+
localIdentifier.text,
1041+
element,
1042+
localIdentifier // isImport
1043+
);
1044+
queuedImports.splice(i, 1);
1045+
madeProgress = true;
1046+
} else {
1047+
++i;
1048+
}
1049+
} else { // i.e. import * as bar from "./bar"
1050+
let foreignFile = this.lookupForeignFile(queuedImport.foreignPath, queuedImport.foreignPathAlt);
1051+
if (foreignFile) {
1052+
let localFile = queuedImport.localFile;
1053+
let localName = localIdentifier.text;
1054+
localFile.add(
10561055
localName,
1057-
localFile,
1058-
localIdentifier
1059-
),
1060-
localIdentifier // isImport
1061-
);
1062-
} else {
1063-
assert(false); // already reported by the parser not finding the file
1056+
foreignFile.asImportedNamespace(
1057+
localName,
1058+
localFile,
1059+
localIdentifier
1060+
),
1061+
localIdentifier // isImport
1062+
);
1063+
queuedImports.splice(i, 1);
1064+
madeProgress = true;
1065+
} else {
1066+
++i;
1067+
assert(false); // already reported by the parser not finding the file
1068+
}
10641069
}
10651070
}
1066-
}
1071+
if (!madeProgress) {
1072+
// report queued imports we were unable to resolve
1073+
for (let j = 0, l = queuedImports.length; j < l; ++j) {
1074+
let queuedImport = queuedImports[j];
1075+
let foreignIdentifier = queuedImport.foreignIdentifier;
1076+
if (foreignIdentifier) {
1077+
this.error(
1078+
DiagnosticCode.Module_0_has_no_exported_member_1,
1079+
foreignIdentifier.range, queuedImport.foreignPath, foreignIdentifier.text
1080+
);
1081+
}
1082+
}
1083+
break;
1084+
}
1085+
} while (true);
10671086

10681087
// queued exports should be resolvable now that imports are finalized
10691088
// TODO: for (let [file, exports] of queuedExports) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
(module
2+
(type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))
3+
(type $none_=>_none (func))
4+
(memory $0 0)
5+
(global $export/a i32 (i32.const 1))
6+
(global $export/b i32 (i32.const 2))
7+
(global $export/c i32 (i32.const 3))
8+
(export "memory" (memory $0))
9+
(export "a" (global $export/a))
10+
(export "renamed_a" (global $export/a))
11+
(export "renamed_b" (global $export/b))
12+
(export "renamed_renamed_b" (global $export/b))
13+
(export "default" (func $export-default/theDefault))
14+
(export "renamed_default" (func $export-default/theDefault))
15+
(export "exportstar.add" (func $export/add))
16+
(export "exportstar.sub" (func $export/sub))
17+
(export "exportstar.renamed_mul" (func $export/mul))
18+
(export "exportstar.a" (global $export/a))
19+
(export "exportstar.b" (global $export/b))
20+
(export "exportstar.renamed_c" (global $export/c))
21+
(export "exportstar.ns.two" (func $export-default/theDefault))
22+
(export "exportstar.default.two" (func $export-default/theDefault))
23+
(func $export/add (param $0 i32) (param $1 i32) (result i32)
24+
local.get $0
25+
local.get $1
26+
i32.add
27+
)
28+
(func $export/mul (param $0 i32) (param $1 i32) (result i32)
29+
local.get $0
30+
local.get $1
31+
i32.mul
32+
)
33+
(func $export-default/theDefault
34+
nop
35+
)
36+
(func $export/sub (param $0 i32) (param $1 i32) (result i32)
37+
local.get $0
38+
local.get $1
39+
i32.sub
40+
)
41+
)

tests/compiler/wildcard-export.untouched.wat renamed to tests/compiler/exportstar-rereexport.untouched.wat

+21-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@
1313
(export "renamed_renamed_b" (global $export/b))
1414
(export "default" (func $export-default/theDefault))
1515
(export "renamed_default" (func $export-default/theDefault))
16+
(export "exportstar.add" (func $export/add))
17+
(export "exportstar.sub" (func $export/sub))
18+
(export "exportstar.renamed_mul" (func $export/mul))
19+
(export "exportstar.a" (global $export/a))
20+
(export "exportstar.b" (global $export/b))
21+
(export "exportstar.renamed_c" (global $export/c))
22+
(export "exportstar.ns.two" (func $export/ns.two))
23+
(export "exportstar.default.two" (func $export/ns.two))
1624
(start $~start)
1725
(func $export/add (param $0 i32) (param $1 i32) (result i32)
1826
local.get $0
@@ -37,13 +45,24 @@
3745
(func $start:rereexport
3846
call $start:reexport
3947
)
40-
(func $start:wildcard-export
48+
(func $start:exportstar-rereexport
4149
call $start:rereexport
4250
)
4351
(func $export-default/theDefault
4452
nop
4553
)
54+
(func $export/sub (param $0 i32) (param $1 i32) (result i32)
55+
local.get $0
56+
local.get $1
57+
i32.sub
58+
)
59+
(func $export/ns.one
60+
nop
61+
)
62+
(func $export/ns.two
63+
nop
64+
)
4665
(func $~start
47-
call $start:wildcard-export
66+
call $start:exportstar-rereexport
4867
)
4968
)
+25
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,41 @@
11
(module
2+
(type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))
23
(type $none_=>_none (func))
34
(memory $0 0)
45
(global $export/a i32 (i32.const 1))
56
(global $export/b i32 (i32.const 2))
7+
(global $export/c i32 (i32.const 3))
68
(export "memory" (memory $0))
79
(export "a" (global $export/a))
810
(export "renamed_a" (global $export/a))
911
(export "renamed_b" (global $export/b))
1012
(export "renamed_renamed_b" (global $export/b))
1113
(export "default" (func $export-default/theDefault))
1214
(export "renamed_default" (func $export-default/theDefault))
15+
(export "exportstar.add" (func $export/add))
16+
(export "exportstar.sub" (func $export/sub))
17+
(export "exportstar.renamed_mul" (func $export/mul))
18+
(export "exportstar.a" (global $export/a))
19+
(export "exportstar.b" (global $export/b))
20+
(export "exportstar.renamed_c" (global $export/c))
21+
(export "exportstar.ns.two" (func $export-default/theDefault))
22+
(export "exportstar.default.two" (func $export-default/theDefault))
23+
(func $export/add (param $0 i32) (param $1 i32) (result i32)
24+
local.get $0
25+
local.get $1
26+
i32.add
27+
)
28+
(func $export/mul (param $0 i32) (param $1 i32) (result i32)
29+
local.get $0
30+
local.get $1
31+
i32.mul
32+
)
1333
(func $export-default/theDefault
1434
nop
1535
)
36+
(func $export/sub (param $0 i32) (param $1 i32) (result i32)
37+
local.get $0
38+
local.get $1
39+
i32.sub
40+
)
1641
)

tests/compiler/rereexport.ts

+3
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ export {
66
default,
77
default as renamed_default
88
} from "./reexport";
9+
10+
import { exportstar } from "./reexport";
11+
export { exportstar };

tests/compiler/rereexport.untouched.wat

+19
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@
1313
(export "renamed_renamed_b" (global $export/b))
1414
(export "default" (func $export-default/theDefault))
1515
(export "renamed_default" (func $export-default/theDefault))
16+
(export "exportstar.add" (func $export/add))
17+
(export "exportstar.sub" (func $export/sub))
18+
(export "exportstar.renamed_mul" (func $export/mul))
19+
(export "exportstar.a" (global $export/a))
20+
(export "exportstar.b" (global $export/b))
21+
(export "exportstar.renamed_c" (global $export/c))
22+
(export "exportstar.ns.two" (func $export/ns.two))
23+
(export "exportstar.default.two" (func $export/ns.two))
1624
(start $~start)
1725
(func $export/add (param $0 i32) (param $1 i32) (result i32)
1826
local.get $0
@@ -40,6 +48,17 @@
4048
(func $export-default/theDefault
4149
nop
4250
)
51+
(func $export/sub (param $0 i32) (param $1 i32) (result i32)
52+
local.get $0
53+
local.get $1
54+
i32.sub
55+
)
56+
(func $export/ns.one
57+
nop
58+
)
59+
(func $export/ns.two
60+
nop
61+
)
4362
(func $~start
4463
call $start:rereexport
4564
)

tests/compiler/wildcard-export.optimized.wat

-16
This file was deleted.

0 commit comments

Comments
 (0)