@@ -36,7 +36,7 @@ namespace ts {
3636 return normalizePath ( referencedFileName ) ;
3737 }
3838
39- export function resolveModuleName ( moduleName : string , containingFile : string , compilerOptions : CompilerOptions , host : ModuleResolutionHost ) : ResolvedModule {
39+ export function resolveModuleName ( moduleName : string , containingFile : string , compilerOptions : CompilerOptions , host : ModuleResolutionHost ) : ResolvedModuleWithFailedLookupLocations {
4040 let moduleResolution = compilerOptions . moduleResolution !== undefined
4141 ? compilerOptions . moduleResolution
4242 : compilerOptions . module === ModuleKind . CommonJS ? ModuleResolutionKind . NodeJs : ModuleResolutionKind . Classic ;
@@ -47,7 +47,7 @@ namespace ts {
4747 }
4848 }
4949
50- export function nodeModuleNameResolver ( moduleName : string , containingFile : string , host : ModuleResolutionHost ) : ResolvedModule {
50+ export function nodeModuleNameResolver ( moduleName : string , containingFile : string , host : ModuleResolutionHost ) : ResolvedModuleWithFailedLookupLocations {
5151 let containingDirectory = getDirectoryPath ( containingFile ) ;
5252
5353 if ( getRootLength ( moduleName ) !== 0 || nameStartsWithDotSlashOrDotDotSlash ( moduleName ) ) {
@@ -56,11 +56,13 @@ namespace ts {
5656 let resolvedFileName = loadNodeModuleFromFile ( candidate , /* loadOnlyDts */ false , failedLookupLocations , host ) ;
5757
5858 if ( resolvedFileName ) {
59- return { resolvedFileName, failedLookupLocations } ;
59+ return { resolvedModule : { resolvedFileName } , failedLookupLocations } ;
6060 }
6161
6262 resolvedFileName = loadNodeModuleFromDirectory ( candidate , /* loadOnlyDts */ false , failedLookupLocations , host ) ;
63- return { resolvedFileName, failedLookupLocations } ;
63+ return resolvedFileName
64+ ? { resolvedModule : { resolvedFileName } , failedLookupLocations }
65+ : { resolvedModule : undefined , failedLookupLocations } ;
6466 }
6567 else {
6668 return loadModuleFromNodeModules ( moduleName , containingDirectory , host ) ;
@@ -117,7 +119,7 @@ namespace ts {
117119 return loadNodeModuleFromFile ( combinePaths ( candidate , "index" ) , loadOnlyDts , failedLookupLocation , host ) ;
118120 }
119121
120- function loadModuleFromNodeModules ( moduleName : string , directory : string , host : ModuleResolutionHost ) : ResolvedModule {
122+ function loadModuleFromNodeModules ( moduleName : string , directory : string , host : ModuleResolutionHost ) : ResolvedModuleWithFailedLookupLocations {
121123 let failedLookupLocations : string [ ] = [ ] ;
122124 directory = normalizeSlashes ( directory ) ;
123125 while ( true ) {
@@ -127,12 +129,12 @@ namespace ts {
127129 let candidate = normalizePath ( combinePaths ( nodeModulesFolder , moduleName ) ) ;
128130 let result = loadNodeModuleFromFile ( candidate , /* loadOnlyDts */ true , failedLookupLocations , host ) ;
129131 if ( result ) {
130- return { resolvedFileName : result , failedLookupLocations } ;
132+ return { resolvedModule : { resolvedFileName : result , shouldBeProperExternalModule : true } , failedLookupLocations } ;
131133 }
132134
133135 result = loadNodeModuleFromDirectory ( candidate , /* loadOnlyDts */ true , failedLookupLocations , host ) ;
134136 if ( result ) {
135- return { resolvedFileName : result , failedLookupLocations } ;
137+ return { resolvedModule : { resolvedFileName : result , shouldBeProperExternalModule : true } , failedLookupLocations } ;
136138 }
137139 }
138140
@@ -144,47 +146,19 @@ namespace ts {
144146 directory = parentPath ;
145147 }
146148
147- return { resolvedFileName : undefined , failedLookupLocations } ;
148- }
149-
150- export function baseUrlModuleNameResolver ( moduleName : string , containingFile : string , baseUrl : string , host : ModuleResolutionHost ) : ResolvedModule {
151- Debug . assert ( baseUrl !== undefined ) ;
152-
153- let normalizedModuleName = normalizeSlashes ( moduleName ) ;
154- let basePart = useBaseUrl ( moduleName ) ? baseUrl : getDirectoryPath ( containingFile ) ;
155- let candidate = normalizePath ( combinePaths ( basePart , moduleName ) ) ;
156-
157- let failedLookupLocations : string [ ] = [ ] ;
158-
159- return forEach ( supportedExtensions , ext => tryLoadFile ( candidate + ext ) ) || { resolvedFileName : undefined , failedLookupLocations } ;
160-
161- function tryLoadFile ( location : string ) : ResolvedModule {
162- if ( host . fileExists ( location ) ) {
163- return { resolvedFileName : location , failedLookupLocations } ;
164- }
165- else {
166- failedLookupLocations . push ( location ) ;
167- return undefined ;
168- }
169- }
149+ return { resolvedModule : undefined , failedLookupLocations } ;
170150 }
171151
172152 function nameStartsWithDotSlashOrDotDotSlash ( name : string ) {
173153 let i = name . lastIndexOf ( "./" , 1 ) ;
174154 return i === 0 || ( i === 1 && name . charCodeAt ( 0 ) === CharacterCodes . dot ) ;
175155 }
176-
177- function useBaseUrl ( moduleName : string ) : boolean {
178- // path is not rooted
179- // module name does not start with './' or '../'
180- return getRootLength ( moduleName ) === 0 && ! nameStartsWithDotSlashOrDotDotSlash ( moduleName ) ;
181- }
182156
183- export function classicNameResolver ( moduleName : string , containingFile : string , compilerOptions : CompilerOptions , host : ModuleResolutionHost ) : ResolvedModule {
157+ export function classicNameResolver ( moduleName : string , containingFile : string , compilerOptions : CompilerOptions , host : ModuleResolutionHost ) : ResolvedModuleWithFailedLookupLocations {
184158
185159 // module names that contain '!' are used to reference resources and are not resolved to actual files on disk
186160 if ( moduleName . indexOf ( '!' ) != - 1 ) {
187- return { resolvedFileName : undefined , failedLookupLocations : [ ] } ;
161+ return { resolvedModule : undefined , failedLookupLocations : [ ] } ;
188162 }
189163
190164 let searchPath = getDirectoryPath ( containingFile ) ;
@@ -222,7 +196,9 @@ namespace ts {
222196 searchPath = parentPath ;
223197 }
224198
225- return { resolvedFileName : referencedSourceFile , failedLookupLocations } ;
199+ return referencedSourceFile
200+ ? { resolvedModule : { resolvedFileName : referencedSourceFile } , failedLookupLocations }
201+ : { resolvedModule : undefined , failedLookupLocations } ;
226202 }
227203
228204 /* @internal */
@@ -371,9 +347,9 @@ namespace ts {
371347
372348 host = host || createCompilerHost ( options ) ;
373349
374- const resolveModuleNamesWorker =
375- host . resolveModuleNames ||
376- ( ( moduleNames , containingFile ) => map ( moduleNames , moduleName => resolveModuleName ( moduleName , containingFile , options , host ) . resolvedFileName ) ) ;
350+ const resolveModuleNamesWorker = host . resolveModuleNames
351+ ? ( ( moduleNames : string [ ] , containingFile : string ) => host . resolveModuleNames ( moduleNames , containingFile ) )
352+ : ( ( moduleNames : string [ ] , containingFile : string ) => map ( moduleNames , moduleName => resolveModuleName ( moduleName , containingFile , options , host ) . resolvedModule ) ) ;
377353
378354 let filesByName = createFileMap < SourceFile > ( fileName => host . getCanonicalFileName ( fileName ) ) ;
379355
@@ -491,10 +467,17 @@ namespace ts {
491467 let resolutions = resolveModuleNamesWorker ( moduleNames , newSourceFile . fileName ) ;
492468 // ensure that module resolution results are still correct
493469 for ( let i = 0 ; i < moduleNames . length ; ++ i ) {
494- let oldResolution = getResolvedModuleFileName ( oldSourceFile , moduleNames [ i ] ) ;
495- if ( oldResolution !== resolutions [ i ] ) {
470+ let newResolution = resolutions [ i ] ;
471+ let oldResolution = getResolvedModule ( oldSourceFile , moduleNames [ i ] ) ;
472+ let resolutionChanged = oldResolution
473+ ? ! newResolution ||
474+ oldResolution . resolvedFileName !== newResolution . resolvedFileName ||
475+ ! ! oldResolution . shouldBeProperExternalModule !== ! ! newResolution . shouldBeProperExternalModule
476+ : newResolution ;
477+
478+ if ( resolutionChanged ) {
496479 return false ;
497- }
480+ }
498481 }
499482 }
500483 // pass the cache of module resolutions from the old source file
@@ -864,9 +847,23 @@ namespace ts {
864847 let resolutions = resolveModuleNamesWorker ( moduleNames , file . fileName ) ;
865848 for ( let i = 0 ; i < file . imports . length ; ++ i ) {
866849 let resolution = resolutions [ i ] ;
867- setResolvedModuleName ( file , moduleNames [ i ] , resolution ) ;
850+ setResolvedModule ( file , moduleNames [ i ] , resolution ) ;
868851 if ( resolution && ! options . noResolve ) {
869- findModuleSourceFile ( resolution , file . imports [ i ] ) ;
852+ const importedFile = findModuleSourceFile ( resolution . resolvedFileName , file . imports [ i ] ) ;
853+ if ( importedFile && resolution . shouldBeProperExternalModule ) {
854+ if ( ! isExternalModule ( importedFile ) ) {
855+ let start = getTokenPosOfNode ( file . imports [ i ] , file )
856+ diagnostics . add ( createFileDiagnostic ( file , start , file . imports [ i ] . end - start , Diagnostics . File_0_is_not_a_module , importedFile . fileName ) ) ;
857+ }
858+ else if ( ! fileExtensionIs ( importedFile . fileName , ".d.ts" ) ) {
859+ let start = getTokenPosOfNode ( file . imports [ i ] , file )
860+ diagnostics . add ( createFileDiagnostic ( file , start , file . imports [ i ] . end - start , Diagnostics . Proper_external_module_that_carries_external_typings_should_be_d_ts_file ) ) ;
861+ }
862+ else if ( importedFile . referencedFiles . length ) {
863+ let firstRef = importedFile . referencedFiles [ 0 ] ;
864+ diagnostics . add ( createFileDiagnostic ( importedFile , firstRef . pos , firstRef . end - firstRef . pos , Diagnostics . Proper_external_module_that_carries_external_typings_cannot_contain_tripleslash_references ) ) ;
865+ }
866+ }
870867 }
871868 }
872869 }
0 commit comments