@@ -36,7 +36,7 @@ namespace ts {
36
36
return normalizePath ( referencedFileName ) ;
37
37
}
38
38
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 {
40
40
let moduleResolution = compilerOptions . moduleResolution !== undefined
41
41
? compilerOptions . moduleResolution
42
42
: compilerOptions . module === ModuleKind . CommonJS ? ModuleResolutionKind . NodeJs : ModuleResolutionKind . Classic ;
@@ -47,7 +47,7 @@ namespace ts {
47
47
}
48
48
}
49
49
50
- export function nodeModuleNameResolver ( moduleName : string , containingFile : string , host : ModuleResolutionHost ) : ResolvedModule {
50
+ export function nodeModuleNameResolver ( moduleName : string , containingFile : string , host : ModuleResolutionHost ) : ResolvedModuleWithFailedLookupLocations {
51
51
let containingDirectory = getDirectoryPath ( containingFile ) ;
52
52
53
53
if ( getRootLength ( moduleName ) !== 0 || nameStartsWithDotSlashOrDotDotSlash ( moduleName ) ) {
@@ -56,11 +56,13 @@ namespace ts {
56
56
let resolvedFileName = loadNodeModuleFromFile ( candidate , /* loadOnlyDts */ false , failedLookupLocations , host ) ;
57
57
58
58
if ( resolvedFileName ) {
59
- return { resolvedFileName, failedLookupLocations } ;
59
+ return { resolvedModule : { resolvedFileName } , failedLookupLocations } ;
60
60
}
61
61
62
62
resolvedFileName = loadNodeModuleFromDirectory ( candidate , /* loadOnlyDts */ false , failedLookupLocations , host ) ;
63
- return { resolvedFileName, failedLookupLocations } ;
63
+ return resolvedFileName
64
+ ? { resolvedModule : { resolvedFileName } , failedLookupLocations }
65
+ : { resolvedModule : undefined , failedLookupLocations } ;
64
66
}
65
67
else {
66
68
return loadModuleFromNodeModules ( moduleName , containingDirectory , host ) ;
@@ -117,7 +119,7 @@ namespace ts {
117
119
return loadNodeModuleFromFile ( combinePaths ( candidate , "index" ) , loadOnlyDts , failedLookupLocation , host ) ;
118
120
}
119
121
120
- function loadModuleFromNodeModules ( moduleName : string , directory : string , host : ModuleResolutionHost ) : ResolvedModule {
122
+ function loadModuleFromNodeModules ( moduleName : string , directory : string , host : ModuleResolutionHost ) : ResolvedModuleWithFailedLookupLocations {
121
123
let failedLookupLocations : string [ ] = [ ] ;
122
124
directory = normalizeSlashes ( directory ) ;
123
125
while ( true ) {
@@ -127,12 +129,12 @@ namespace ts {
127
129
let candidate = normalizePath ( combinePaths ( nodeModulesFolder , moduleName ) ) ;
128
130
let result = loadNodeModuleFromFile ( candidate , /* loadOnlyDts */ true , failedLookupLocations , host ) ;
129
131
if ( result ) {
130
- return { resolvedFileName : result , failedLookupLocations } ;
132
+ return { resolvedModule : { resolvedFileName : result , shouldBeProperExternalModule : true } , failedLookupLocations } ;
131
133
}
132
134
133
135
result = loadNodeModuleFromDirectory ( candidate , /* loadOnlyDts */ true , failedLookupLocations , host ) ;
134
136
if ( result ) {
135
- return { resolvedFileName : result , failedLookupLocations } ;
137
+ return { resolvedModule : { resolvedFileName : result , shouldBeProperExternalModule : true } , failedLookupLocations } ;
136
138
}
137
139
}
138
140
@@ -144,47 +146,19 @@ namespace ts {
144
146
directory = parentPath ;
145
147
}
146
148
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 } ;
170
150
}
171
151
172
152
function nameStartsWithDotSlashOrDotDotSlash ( name : string ) {
173
153
let i = name . lastIndexOf ( "./" , 1 ) ;
174
154
return i === 0 || ( i === 1 && name . charCodeAt ( 0 ) === CharacterCodes . dot ) ;
175
155
}
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
- }
182
156
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 {
184
158
185
159
// module names that contain '!' are used to reference resources and are not resolved to actual files on disk
186
160
if ( moduleName . indexOf ( '!' ) != - 1 ) {
187
- return { resolvedFileName : undefined , failedLookupLocations : [ ] } ;
161
+ return { resolvedModule : undefined , failedLookupLocations : [ ] } ;
188
162
}
189
163
190
164
let searchPath = getDirectoryPath ( containingFile ) ;
@@ -222,7 +196,9 @@ namespace ts {
222
196
searchPath = parentPath ;
223
197
}
224
198
225
- return { resolvedFileName : referencedSourceFile , failedLookupLocations } ;
199
+ return referencedSourceFile
200
+ ? { resolvedModule : { resolvedFileName : referencedSourceFile } , failedLookupLocations }
201
+ : { resolvedModule : undefined , failedLookupLocations } ;
226
202
}
227
203
228
204
/* @internal */
@@ -371,9 +347,9 @@ namespace ts {
371
347
372
348
host = host || createCompilerHost ( options ) ;
373
349
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 ) ) ;
377
353
378
354
let filesByName = createFileMap < SourceFile > ( fileName => host . getCanonicalFileName ( fileName ) ) ;
379
355
@@ -491,10 +467,17 @@ namespace ts {
491
467
let resolutions = resolveModuleNamesWorker ( moduleNames , newSourceFile . fileName ) ;
492
468
// ensure that module resolution results are still correct
493
469
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 ) {
496
479
return false ;
497
- }
480
+ }
498
481
}
499
482
}
500
483
// pass the cache of module resolutions from the old source file
@@ -864,9 +847,23 @@ namespace ts {
864
847
let resolutions = resolveModuleNamesWorker ( moduleNames , file . fileName ) ;
865
848
for ( let i = 0 ; i < file . imports . length ; ++ i ) {
866
849
let resolution = resolutions [ i ] ;
867
- setResolvedModuleName ( file , moduleNames [ i ] , resolution ) ;
850
+ setResolvedModule ( file , moduleNames [ i ] , resolution ) ;
868
851
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 , fil
10000
e . 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
+ }
870
867
}
871
868
}
872
869
}
0 commit comments