@@ -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) {
0 commit comments