diff --git a/src/glue/js/node.d.ts b/src/glue/js/node.d.ts index 2d4fb94da6..de843ab834 100644 --- a/src/glue/js/node.d.ts +++ b/src/glue/js/node.d.ts @@ -5,3 +5,6 @@ declare const global: Record; declare function require(name: string): unknown; +declare namespace console { + function log(...args: unknown[]): void; +} diff --git a/src/program.ts b/src/program.ts index e3c183a096..8cc6ba4347 100644 --- a/src/program.ts +++ b/src/program.ts @@ -1020,50 +1020,69 @@ export class Program extends DiagnosticEmitter { } } - // queued imports should be resolvable now through traversing exports and queued exports - for (let i = 0, k = queuedImports.length; i < k; ++i) { - let queuedImport = queuedImports[i]; - let localIdentifier = queuedImport.localIdentifier; - let foreignIdentifier = queuedImport.foreignIdentifier; - if (foreignIdentifier) { // i.e. import { foo [as bar] } from "./baz" - let element = this.lookupForeign( - foreignIdentifier.text, - queuedImport.foreignPath, - queuedImport.foreignPathAlt, - queuedExports - ); - if (element) { - queuedImport.localFile.add( - localIdentifier.text, - element, - localIdentifier // isImport - ); - } else { - // FIXME: file not found is not reported if this happens? - this.error( - DiagnosticCode.Module_0_has_no_exported_member_1, - foreignIdentifier.range, queuedImport.foreignPath, foreignIdentifier.text + // queued imports should be resolvable now through traversing exports and queued exports. + // note that imports may depend upon imports, so repeat until there's no more progress. + do { + let i = 0, madeProgress = false; + while (i < queuedImports.length) { + let queuedImport = queuedImports[i]; + let localIdentifier = queuedImport.localIdentifier; + let foreignIdentifier = queuedImport.foreignIdentifier; + if (foreignIdentifier) { // i.e. import { foo [as bar] } from "./baz" + let element = this.lookupForeign( + foreignIdentifier.text, + queuedImport.foreignPath, + queuedImport.foreignPathAlt, + queuedExports ); - } - } else { // i.e. import * as bar from "./bar" - let foreignFile = this.lookupForeignFile(queuedImport.foreignPath, queuedImport.foreignPathAlt); - if (foreignFile) { - let localFile = queuedImport.localFile; - let localName = localIdentifier.text; - localFile.add( - localName, - foreignFile.asImportedNamespace( + if (element) { + queuedImport.localFile.add( + localIdentifier.text, + element, + localIdentifier // isImport + ); + queuedImports.splice(i, 1); + madeProgress = true; + } else { + ++i; + } + } else { // i.e. import * as bar from "./bar" + let foreignFile = this.lookupForeignFile(queuedImport.foreignPath, queuedImport.foreignPathAlt); + if (foreignFile) { + let localFile = queuedImport.localFile; + let localName = localIdentifier.text; + localFile.add( localName, - localFile, - localIdentifier - ), - localIdentifier // isImport - ); - } else { - assert(false); // already reported by the parser not finding the file + foreignFile.asImportedNamespace( + localName, + localFile, + localIdentifier + ), + localIdentifier // isImport + ); + queuedImports.splice(i, 1); + madeProgress = true; + } else { + ++i; + assert(false); // already reported by the parser not finding the file + } } } - } + if (!madeProgress) { + // report queued imports we were unable to resolve + for (let j = 0, l = queuedImports.length; j < l; ++j) { + let queuedImport = queuedImports[j]; + let foreignIdentifier = queuedImport.foreignIdentifier; + if (foreignIdentifier) { + this.error( + DiagnosticCode.Module_0_has_no_exported_member_1, + foreignIdentifier.range, queuedImport.foreignPath, foreignIdentifier.text + ); + } + } + break; + } + } while (true); // queued exports should be resolvable now that imports are finalized // TODO: for (let [file, exports] of queuedExports) { diff --git a/tests/compiler/wildcard-export.json b/tests/compiler/exportstar-rereexport.json similarity index 100% rename from tests/compiler/wildcard-export.json rename to tests/compiler/exportstar-rereexport.json diff --git a/tests/compiler/exportstar-rereexport.optimized.wat b/tests/compiler/exportstar-rereexport.optimized.wat new file mode 100644 index 0000000000..b66c5fd158 --- /dev/null +++ b/tests/compiler/exportstar-rereexport.optimized.wat @@ -0,0 +1,41 @@ +(module + (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) + (type $none_=>_none (func)) + (memory $0 0) + (global $export/a i32 (i32.const 1)) + (global $export/b i32 (i32.const 2)) + (global $export/c i32 (i32.const 3)) + (export "memory" (memory $0)) + (export "a" (global $export/a)) + (export "renamed_a" (global $export/a)) + (export "renamed_b" (global $export/b)) + (export "renamed_renamed_b" (global $export/b)) + (export "default" (func $export-default/theDefault)) + (export "renamed_default" (func $export-default/theDefault)) + (export "exportstar.add" (func $export/add)) + (export "exportstar.sub" (func $export/sub)) + (export "exportstar.renamed_mul" (func $export/mul)) + (export "exportstar.a" (global $export/a)) + (export "exportstar.b" (global $export/b)) + (export "exportstar.renamed_c" (global $export/c)) + (export "exportstar.ns.two" (func $export-default/theDefault)) + (export "exportstar.default.two" (func $export-default/theDefault)) + (func $export/add (param $0 i32) (param $1 i32) (result i32) + local.get $0 + local.get $1 + i32.add + ) + (func $export/mul (param $0 i32) (param $1 i32) (result i32) + local.get $0 + local.get $1 + i32.mul + ) + (func $export-default/theDefault + nop + ) + (func $export/sub (param $0 i32) (param $1 i32) (result i32) + local.get $0 + local.get $1 + i32.sub + ) +) diff --git a/tests/compiler/wildcard-export.ts b/tests/compiler/exportstar-rereexport.ts similarity index 100% rename from tests/compiler/wildcard-export.ts rename to tests/compiler/exportstar-rereexport.ts diff --git a/tests/compiler/wildcard-export.untouched.wat b/tests/compiler/exportstar-rereexport.untouched.wat similarity index 62% rename from tests/compiler/wildcard-export.untouched.wat rename to tests/compiler/exportstar-rereexport.untouched.wat index e90cbeda7f..477f4788a2 100644 --- a/tests/compiler/wildcard-export.untouched.wat +++ b/tests/compiler/exportstar-rereexport.untouched.wat @@ -13,6 +13,14 @@ (export "renamed_renamed_b" (global $export/b)) (export "default" (func $export-default/theDefault)) (export "renamed_default" (func $export-default/theDefault)) + (export "exportstar.add" (func $export/add)) + (export "exportstar.sub" (func $export/sub)) + (export "exportstar.renamed_mul" (func $export/mul)) + (export "exportstar.a" (global $export/a)) + (export "exportstar.b" (global $export/b)) + (export "exportstar.renamed_c" (global $export/c)) + (export "exportstar.ns.two" (func $export/ns.two)) + (export "exportstar.default.two" (func $export/ns.two)) (start $~start) (func $export/add (param $0 i32) (param $1 i32) (result i32) local.get $0 @@ -37,13 +45,24 @@ (func $start:rereexport call $start:reexport ) - (func $start:wildcard-export + (func $start:exportstar-rereexport call $start:rereexport ) (func $export-default/theDefault nop ) + (func $export/sub (param $0 i32) (param $1 i32) (result i32) + local.get $0 + local.get $1 + i32.sub + ) + (func $export/ns.one + nop + ) + (func $export/ns.two + nop + ) (func $~start - call $start:wildcard-export + call $start:exportstar-rereexport ) ) diff --git a/tests/compiler/rereexport.optimized.wat b/tests/compiler/rereexport.optimized.wat index ab1932c2a4..b66c5fd158 100644 --- a/tests/compiler/rereexport.optimized.wat +++ b/tests/compiler/rereexport.optimized.wat @@ -1,8 +1,10 @@ (module + (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $none_=>_none (func)) (memory $0 0) (global $export/a i32 (i32.const 1)) (global $export/b i32 (i32.const 2)) + (global $export/c i32 (i32.const 3)) (export "memory" (memory $0)) (export "a" (global $export/a)) (export "renamed_a" (global $export/a)) @@ -10,7 +12,30 @@ (export "renamed_renamed_b" (global $export/b)) (export "default" (func $export-default/theDefault)) (export "renamed_default" (func $export-default/theDefault)) + (export "exportstar.add" (func $export/add)) + (export "exportstar.sub" (func $export/sub)) + (export "exportstar.renamed_mul" (func $export/mul)) + (export "exportstar.a" (global $export/a)) + (export "exportstar.b" (global $export/b)) + (export "exportstar.renamed_c" (global $export/c)) + (export "exportstar.ns.two" (func $export-default/theDefault)) + (export "exportstar.default.two" (func $export-default/theDefault)) + (func $export/add (param $0 i32) (param $1 i32) (result i32) + local.get $0 + local.get $1 + i32.add + ) + (func $export/mul (param $0 i32) (param $1 i32) (result i32) + local.get $0 + local.get $1 + i32.mul + ) (func $export-default/theDefault nop ) + (func $export/sub (param $0 i32) (param $1 i32) (result i32) + local.get $0 + local.get $1 + i32.sub + ) ) diff --git a/tests/compiler/rereexport.ts b/tests/compiler/rereexport.ts index 63a600c265..29aeb41abe 100644 --- a/tests/compiler/rereexport.ts +++ b/tests/compiler/rereexport.ts @@ -6,3 +6,6 @@ export { default, default as renamed_default } from "./reexport"; + +import { exportstar } from "./reexport"; +export { exportstar }; diff --git a/tests/compiler/rereexport.untouched.wat b/tests/compiler/rereexport.untouched.wat index 952151602f..dd449374cc 100644 --- a/tests/compiler/rereexport.untouched.wat +++ b/tests/compiler/rereexport.untouched.wat @@ -13,6 +13,14 @@ (export "renamed_renamed_b" (global $export/b)) (export "default" (func $export-default/theDefault)) (export "renamed_default" (func $export-default/theDefault)) + (export "exportstar.add" (func $export/add)) + (export "exportstar.sub" (func $export/sub)) + (export "exportstar.renamed_mul" (func $export/mul)) + (export "exportstar.a" (global $export/a)) + (export "exportstar.b" (global $export/b)) + (export "exportstar.renamed_c" (global $export/c)) + (export "exportstar.ns.two" (func $export/ns.two)) + (export "exportstar.default.two" (func $export/ns.two)) (start $~start) (func $export/add (param $0 i32) (param $1 i32) (result i32) local.get $0 @@ -40,6 +48,17 @@ (func $export-default/theDefault nop ) + (func $export/sub (param $0 i32) (param $1 i32) (result i32) + local.get $0 + local.get $1 + i32.sub + ) + (func $export/ns.one + nop + ) + (func $export/ns.two + nop + ) (func $~start call $start:rereexport ) diff --git a/tests/compiler/wildcard-export.optimized.wat b/tests/compiler/wildcard-export.optimized.wat deleted file mode 100644 index ab1932c2a4..0000000000 --- a/tests/compiler/wildcard-export.optimized.wat +++ /dev/null @@ -1,16 +0,0 @@ -(module - (type $none_=>_none (func)) - (memory $0 0) - (global $export/a i32 (i32.const 1)) - (global $export/b i32 (i32.const 2)) - (export "memory" (memory $0)) - (export "a" (global $export/a)) - (export "renamed_a" (global $export/a)) - (export "renamed_b" (global $export/b)) - (export "renamed_renamed_b" (global $export/b)) - (export "default" (func $export-default/theDefault)) - (export "renamed_default" (func $export-default/theDefault)) - (func $export-default/theDefault - nop - ) -)