@@ -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 */
@@ -372,9 +348,9 @@ namespace ts {
372348
373349 host = host || createCompilerHost ( options ) ;
374350
375- const resolveModuleNamesWorker =
376- host . resolveModuleNames ||
377- ( ( moduleNames , containingFile ) => map ( moduleNames , moduleName => resolveModuleName ( moduleName , containingFile , options , host ) . resolvedFileName ) ) ;
351+ const resolveModuleNamesWorker = host . resolveModuleNames
352+ ? ( ( moduleNames : string [ ] , containingFile : string ) => host . resolveModuleNames ( moduleNames , containingFile ) )
353+ : ( ( moduleNames : string [ ] , containingFile : string ) => map ( moduleNames , moduleName => resolveModuleName ( moduleName , containingFile , options , host ) . resolvedModule ) ) ;
378354
379355 let filesByName = createFileMap < SourceFile > ( fileName => host . getCanonicalFileName ( fileName ) ) ;
380356
@@ -494,10 +470,17 @@ namespace ts {
494470 let resolutions = resolveModuleNamesWorker ( moduleNames , newSourceFile . fileName ) ;
495471 // ensure that module resolution results are still correct
496472 for ( let i = 0 ; i < moduleNames . length ; ++ i ) {
497- let oldResolution = getResolvedModuleFileName ( oldSourceFile , moduleNames [ i ] ) ;
498- if ( oldResolution !== resolutions [ i ] ) {
473+ let newResolution = resolutions [ i ] ;
474+ let oldResolution = getResolvedModule ( oldSourceFile , moduleNames [ i ] ) ;
475+ let resolutionChanged = oldResolution
476+ ? ! newResolution ||
477+ oldResolution . resolvedFileName !== newResolution . resolvedFileName ||
478+ ! ! oldResolution . shouldBeProperExternalModule !== ! ! newResolution . shouldBeProperExternalModule
479+ : newResolution ;
480+
481+ if ( resolutionChanged ) {
499482 return false ;
500- }
483+ }
501484 }
502485 }
503486 // pass the cache of module resolutions from the old source file
@@ -874,9 +857,23 @@ namespace ts {
874857 let resolutions = resolveModuleNamesWorker ( moduleNames , file . fileName ) ;
875858 for ( let i = 0 ; i < file . imports . length ; ++ i ) {
876859 let resolution = resolutions [ i ] ;
877- setResolvedModuleName ( file , moduleNames [ i ] , resolution ) ;
860+ setResolvedModule ( file , moduleNames [ i ] , resolution ) ;
878861 if ( resolution && ! options . noResolve ) {
879- findModuleSourceFile ( resolution , file . imports [ i ] ) ;
862+ const importedFile = findModuleSourceFile ( resolution . resolvedFileName , file . imports [ i ] ) ;
863+ if ( importedFile && resolution . shouldBeProperExternalModule ) {
864+ if ( ! isExternalModule ( importedFile ) ) {
865+ let start = getTokenPosOfNode ( file . imports [ i ] , file )
866+ diagnostics . add ( createFileDiagnostic ( file , start , file . imports [ i ] . end - start , Diagnostics . File_0_is_not_a_module , importedFile . fileName ) ) ;
867+ }
868+ else if ( ! fileExtensionIs ( importedFile . fileName , ".d.ts" ) ) {
869+ let start = getTokenPosOfNode ( file . imports [ i ] , file )
870+ diagnostics . add ( createFileDiagnostic ( file , start , file . imports [ i ] . end - start , Diagnostics . Proper_external_module_that_carries_external_typings_should_be_d_ts_file ) ) ;
871+ }
872+ else if ( importedFile . referencedFiles . length ) {
873+ let firstRef = importedFile . referencedFiles [ 0 ] ;
874+ diagnostics . add ( createFileDiagnostic ( importedFile , firstRef . pos , firstRef . end - firstRef . pos , Diagnostics . Proper_external_module_that_carries_external_typings_cannot_contain_tripleslash_references ) ) ;
875+ }
876+ }
880877 }
881878 }
882879 }
0 commit comments