@@ -10,6 +10,7 @@ import (
10
10
"github.com/microsoft/typescript-go/internal/ast"
11
11
"github.com/microsoft/typescript-go/internal/collections"
12
12
"github.com/microsoft/typescript-go/internal/core"
13
+ "github.com/microsoft/typescript-go/internal/diagnostics"
13
14
"github.com/microsoft/typescript-go/internal/module"
14
15
"github.com/microsoft/typescript-go/internal/tsoptions"
15
16
"github.com/microsoft/typescript-go/internal/tspath"
@@ -64,6 +65,10 @@ func processAllProgramFiles(
64
65
compilerOptions := opts .Config .CompilerOptions ()
65
66
rootFiles := opts .Config .FileNames ()
66
67
supportedExtensions := tsoptions .GetSupportedExtensions (compilerOptions , nil /*extraFileExtensions*/ )
68
+ var maxNodeModuleJsDepth int
69
+ if p := opts .Config .CompilerOptions ().MaxNodeModuleJsDepth ; p != nil {
70
+ maxNodeModuleJsDepth = * p
71
+ }
67
72
loader := fileLoader {
68
73
opts : opts ,
69
74
defaultLibraryPath : tspath .GetNormalizedAbsolutePath (opts .Host .DefaultLibraryPath (), opts .Host .GetCurrentDirectory ()),
@@ -72,12 +77,11 @@ func processAllProgramFiles(
72
77
CurrentDirectory : opts .Host .GetCurrentDirectory (),
73
78
},
74
79
parseTasks : & fileLoaderWorker [* parseTask ]{
75
- wg : core .NewWorkGroup (singleThreaded ),
76
- getSubTasks : getSubTasksOfParseTask ,
80
+ wg : core .NewWorkGroup (singleThreaded ),
81
+ maxDepth : maxNodeModuleJsDepth ,
77
82
},
78
83
projectReferenceParseTasks : & fileLoaderWorker [* projectReferenceParseTask ]{
79
- wg : core .NewWorkGroup (singleThreaded ),
80
- getSubTasks : getSubTasksOfProjectReferenceParseTask ,
84
+ wg : core .NewWorkGroup (singleThreaded ),
81
85
},
82
86
rootTasks : make ([]* parseTask , 0 , len (rootFiles )+ len (libs )),
83
87
supportedExtensions : core .Flatten (tsoptions .GetSupportedExtensionsWithJsonIfResolveJsonModule (compilerOptions , supportedExtensions )),
@@ -289,30 +293,36 @@ func (p *fileLoader) parseSourceFile(t *parseTask) *ast.SourceFile {
289
293
return sourceFile
290
294
}
291
295
292
- func (p * fileLoader ) resolveTripleslashPathReference (moduleName string , containingFile string ) string {
296
+ func (p * fileLoader ) resolveTripleslashPathReference (moduleName string , containingFile string ) resolvedRef {
293
297
basePath := tspath .GetDirectoryPath (containingFile )
294
298
referencedFileName := moduleName
295
299
296
300
if ! tspath .IsRootedDiskPath (moduleName ) {
297
301
referencedFileName = tspath .CombinePaths (basePath , moduleName )
298
302
}
299
- return tspath .NormalizePath (referencedFileName )
303
+ return resolvedRef {
304
+ fileName : tspath .NormalizePath (referencedFileName ),
305
+ }
300
306
}
301
307
302
308
func (p * fileLoader ) resolveTypeReferenceDirectives (file * ast.SourceFile , meta ast.SourceFileMetaData ) (
303
- toParse []string ,
309
+ toParse []resolvedRef ,
304
310
typeResolutionsInFile module.ModeAwareCache [* module.ResolvedTypeReferenceDirective ],
305
311
) {
306
312
if len (file .TypeReferenceDirectives ) != 0 {
307
- toParse = make ([]string , 0 , len (file .TypeReferenceDirectives ))
313
+ toParse = make ([]resolvedRef , 0 , len (file .TypeReferenceDirectives ))
308
314
typeResolutionsInFile = make (module.ModeAwareCache [* module.ResolvedTypeReferenceDirective ], len (file .TypeReferenceDirectives ))
309
315
for _ , ref := range file .TypeReferenceDirectives {
310
316
redirect := p .projectReferenceFileMapper .getRedirectForResolution (file )
311
317
resolutionMode := getModeForTypeReferenceDirectiveInFile (ref , file , meta , module .GetCompilerOptionsWithRedirect (p .opts .Config .CompilerOptions (), redirect ))
312
318
resolved := p .resolver .ResolveTypeReferenceDirective (ref .FileName , file .FileName (), resolutionMode , redirect )
313
319
typeResolutionsInFile [module.ModeAwareCacheKey {Name : ref .FileName , Mode : resolutionMode }] = resolved
314
320
if resolved .IsResolved () {
315
- toParse = append (toParse , resolved .ResolvedFileName )
321
+ toParse = append (toParse , resolvedRef {
322
+ fileName : resolved .ResolvedFileName ,
323
+ increaseDepth : resolved .IsExternalLibraryImport ,
324
+ elideOnDepth : false ,
325
+ })
316
326
}
317
327
}
318
328
}
@@ -322,19 +332,12 @@ func (p *fileLoader) resolveTypeReferenceDirectives(file *ast.SourceFile, meta a
322
332
const externalHelpersModuleNameText = "tslib" // TODO(jakebailey): dedupe
323
333
324
334
func (p * fileLoader ) resolveImportsAndModuleAugmentations (file * ast.SourceFile , meta ast.SourceFileMetaData ) (
325
- toParse []string ,
335
+ toParse []resolvedRef ,
326
336
resolutionsInFile module.ModeAwareCache [* module.ResolvedModule ],
327
337
importHelpersImportSpecifier * ast.Node ,
328
338
jsxRuntimeImportSpecifier_ * jsxRuntimeImportSpecifier ,
329
339
) {
330
340
moduleNames := make ([]* ast.Node , 0 , len (file .Imports ())+ len (file .ModuleAugmentations )+ 2 )
331
- moduleNames = append (moduleNames , file .Imports ()... )
332
- for _ , imp := range file .ModuleAugmentations {
333
- if imp .Kind == ast .KindStringLiteral {
334
- moduleNames = append (moduleNames , imp )
335
- }
336
- // Do nothing if it's an Identifier; we don't need to do module resolution for `declare global`.
337
- }
338
341
339
342
isJavaScriptFile := ast .IsSourceFileJS (file )
340
343
isExternalModuleFile := ast .IsExternalModule (file )
@@ -359,51 +362,118 @@ func (p *fileLoader) resolveImportsAndModuleAugmentations(file *ast.SourceFile,
359
362
}
360
363
}
361
364
365
+ importsStart := len (moduleNames )
366
+
367
+ moduleNames = append (moduleNames , file .Imports ()... )
368
+ for _ , imp := range file .ModuleAugmentations {
369
+ if imp .Kind == ast .KindStringLiteral {
370
+ moduleNames = append (moduleNames , imp )
371
+ }
372
+ // Do nothing if it's an Identifier; we don't need to do module resolution for `declare global`.
373
+ }
374
+
362
375
if len (moduleNames ) != 0 {
363
- toParse = make ([]string , 0 , len (moduleNames ))
376
+ toParse = make ([]resolvedRef , 0 , len (moduleNames ))
377
+ resolutionsInFile = make (module.ModeAwareCache [* module.ResolvedModule ], len (moduleNames ))
364
378
365
- resolutions := p .resolveModuleNames (moduleNames , file , meta , redirect )
379
+ for index , entry := range moduleNames {
380
+ moduleName := entry .Text ()
381
+ if moduleName == "" {
382
+ continue
383
+ }
366
384
367
- resolutionsInFile = make (module.ModeAwareCache [* module.ResolvedModule ], len (resolutions ))
385
+ mode := getModeForUsageLocation (file .FileName (), meta , entry , module .GetCompilerOptionsWithRedirect (p .opts .Config .CompilerOptions (), redirect ))
386
+ resolvedModule := p .resolver .ResolveModuleName (moduleName , file .FileName (), mode , redirect )
387
+ resolutionsInFile [module.ModeAwareCacheKey {Name : moduleName , Mode : mode }] = resolvedModule
368
388
369
- for _ , resolution := range resolutions {
370
- resolvedFileName := resolution . resolvedModule . ResolvedFileName
371
- // TODO(ercornel): !!!: check if from node modules
389
+ if ! resolvedModule . IsResolved () {
390
+ continue
391
+ }
372
392
373
- mode := getModeForUsageLocation (file .FileName (), meta , resolution .node , optionsForFile )
374
- resolutionsInFile [module.ModeAwareCacheKey {Name : resolution .node .Text (), Mode : mode }] = resolution .resolvedModule
393
+ resolvedFileName := resolvedModule .ResolvedFileName
394
+ isFromNodeModulesSearch := resolvedModule .IsExternalLibraryImport
395
+ // Don't treat redirected files as JS files.
396
+ isJsFile := ! tspath .FileExtensionIsOneOf (resolvedFileName , tspath .SupportedTSExtensionsWithJsonFlat ) && p .projectReferenceFileMapper .getRedirectForResolution (ast .NewHasFileName (resolvedFileName , p .toPath (resolvedFileName ))) == nil
397
+ isJsFileFromNodeModules := isFromNodeModulesSearch && isJsFile && strings .Contains (resolvedFileName , "/node_modules/" )
375
398
376
399
// add file to program only if:
377
400
// - resolution was successful
378
401
// - noResolve is falsy
379
402
// - module name comes from the list of imports
380
403
// - it's not a top level JavaScript module that exceeded the search max
381
404
382
- // const elideImport = isJSFileFromNodeModules && currentNodeModulesDepth > maxNodeModuleJsDepth;
405
+ importIndex := index - importsStart
383
406
384
- // Don't add the file if it has a bad extension (e.g. 'tsx' if we don't have '--allowJs')
385
- // This may still end up being an untyped module -- the file won't be included but imports will be allowed.
386
- hasAllowedExtension := false
387
- if optionsForFile .GetResolveJsonModule () {
388
- hasAllowedExtension = tspath .FileExtensionIsOneOf (resolvedFileName , tspath .SupportedTSExtensionsWithJsonFlat )
389
- } else if optionsForFile .AllowJs .IsTrue () {
390
- hasAllowedExtension = tspath .FileExtensionIsOneOf (resolvedFileName , tspath .SupportedJSExtensionsFlat ) || tspath .FileExtensionIsOneOf (resolvedFileName , tspath .SupportedTSExtensionsFlat )
391
- } else {
392
- hasAllowedExtension = tspath .FileExtensionIsOneOf (resolvedFileName , tspath .SupportedTSExtensionsFlat )
393
- }
394
- shouldAddFile := resolution .resolvedModule .IsResolved () && hasAllowedExtension
395
- // TODO(ercornel): !!!: other checks on whether or not to add the file
407
+ shouldAddFile := moduleName != "" &&
408
+ getResolutionDiagnostic (optionsForFile , resolvedModule , file ) == nil &&
409
+ ! optionsForFile .NoResolve .IsTrue () &&
410
+ ! (isJsFile && ! optionsForFile .GetAllowJS ()) &&
411
+ (importIndex < 0 || (importIndex < len (file .Imports ()) && (ast .IsInJSFile (file .Imports ()[importIndex ]) || file .Imports ()[importIndex ].Flags & ast .NodeFlagsJSDoc == 0 )))
396
412
397
413
if shouldAddFile {
398
- // p.findSourceFile(resolvedFileName, FileIncludeReason{Import, 0})
399
- toParse = append (toParse , resolvedFileName )
414
+ toParse = append (toParse , resolvedRef {
415
+ fileName : resolvedFileName ,
416
+ increaseDepth : resolvedModule .IsExternalLibraryImport ,
417
+ elideOnDepth : isJsFileFromNodeModules ,
418
+ })
400
419
}
401
420
}
402
421
}
403
422
404
423
return toParse , resolutionsInFile , importHelpersImportSpecifier , jsxRuntimeImportSpecifier_
405
424
}
406
425
426
+ // Returns a DiagnosticMessage if we won't include a resolved module due to its extension.
427
+ // The DiagnosticMessage's parameters are the imported module name, and the filename it resolved to.
428
+ // This returns a diagnostic even if the module will be an untyped module.
429
+ func getResolutionDiagnostic (options * core.CompilerOptions , resolvedModule * module.ResolvedModule , file * ast.SourceFile ) * diagnostics.Message {
430
+ needJsx := func () * diagnostics.Message {
431
+ if options .Jsx != core .JsxEmitNone {
432
+ return nil
433
+ }
434
+ return diagnostics .Module_0_was_resolved_to_1_but_jsx_is_not_set
435
+ }
436
+
437
+ needAllowJs := func () * diagnostics.Message {
438
+ if options .GetAllowJS () || ! options .NoImplicitAny .DefaultIfUnknown (options .Strict ).IsTrue () {
439
+ return nil
440
+ }
441
+ return diagnostics .Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used
442
+ }
443
+
444
+ needResolveJsonModule := func () * diagnostics.Message {
445
+ if options .GetResolveJsonModule () {
446
+ return nil
447
+ }
448
+ return diagnostics .Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used
449
+ }
450
+
451
+ needAllowArbitraryExtensions := func () * diagnostics.Message {
452
+ if file .IsDeclarationFile || options .AllowArbitraryExtensions .IsTrue () {
453
+ return nil
454
+ }
455
+ return diagnostics .Module_0_was_resolved_to_1_but_allowArbitraryExtensions_is_not_set
456
+ }
457
+
458
+ switch resolvedModule .Extension {
459
+ case tspath .ExtensionTs , tspath .ExtensionDts ,
460
+ tspath .ExtensionMts , tspath .ExtensionDmts ,
461
+ tspath .ExtensionCts , tspath .ExtensionDcts :
462
+ // These are always allowed.
463
+ return nil
464
+ case tspath .ExtensionTsx :
465
+ return needJsx ()
466
+ case tspath .ExtensionJsx :
467
+ return core .Coalesce (needJsx (), needAllowJs ())
468
+ case tspath .ExtensionJs , tspath .ExtensionMjs , tspath .ExtensionCjs :
469
+ return needAllowJs ()
470
+ case tspath .ExtensionJson :
471
+ return needResolveJsonModule ()
472
+ default :
473
+ return needAllowArbitraryExtensions ()
474
+ }
475
+ }
476
+
407
477
func (p * fileLoader ) resolveModuleNames (entries []* ast.Node , file * ast.SourceFile , meta ast.SourceFileMetaData , redirect * tsoptions.ParsedCommandLine ) []* resolution {
408
478
if len (entries ) == 0 {
409
479
return nil
0 commit comments