@@ -4379,7 +4379,15 @@ namespace ts {
4379
4379
const isRelativePath = startsWith ( literalValue , "." ) ;
4380
4380
const scriptDir = getDirectoryPath ( node . getSourceFile ( ) . path ) ;
4381
4381
if ( isRelativePath || isRootedDiskPath ( literalValue ) ) {
4382
- result = getCompletionEntriesForDirectoryFragment ( literalValue , scriptDir , getSupportedExtensions ( program . getCompilerOptions ( ) ) , /*includeExtensions*/ false ) ;
4382
+ const compilerOptions = program . getCompilerOptions ( ) ;
4383
+ if ( compilerOptions . rootDirs ) {
4384
+ result = getCompletionEntriesForDirectoryFragmentWithRootDirs (
4385
+ compilerOptions . rootDirs , literalValue , scriptDir , getSupportedExtensions ( program . getCompilerOptions ( ) ) , /*includeExtensions*/ false ) ;
4386
+ }
4387
+ else {
4388
+ result = getCompletionEntriesForDirectoryFragment (
4389
+ literalValue , scriptDir , getSupportedExtensions ( program . getCompilerOptions ( ) ) , /*includeExtensions*/ false ) ;
4390
+ }
4383
4391
}
4384
4392
else {
4385
4393
// Check for node modules
@@ -4393,10 +4401,42 @@ namespace ts {
4393
4401
} ;
4394
4402
}
4395
4403
4396
- function getCompletionEntriesForDirectoryFragment ( fragment : string , scriptPath : string , extensions : string [ ] , includeExtensions : boolean ) : CompletionEntry [ ] {
4397
- // Complete the path by looking for source files and directories
4404
+ /**
4405
+ * Takes a script path and returns paths for all potential folders that could be merged with its
4406
+ * containing folder via the "rootDirs" compiler option
4407
+ */
4408
+ function getBaseDirectoriesFromRootDirs ( rootDirs : string [ ] , basePath : string , scriptPath : string , ignoreCase : boolean ) {
4409
+ // Make all paths absolute/normalized if they are not already
4410
+ rootDirs = map ( rootDirs , rootDirectory => normalizePath ( isRootedDiskPath ( rootDirectory ) ? rootDirectory : combinePaths ( basePath , rootDirectory ) ) ) ;
4411
+
4412
+ // Determine the path to the directory containing the script relative to the root directory it is contained within
4413
+ let relativeDirectory : string ;
4414
+ forEach ( rootDirs , rootDirectory => {
4415
+ if ( containsPath ( rootDirectory , scriptPath , basePath , ignoreCase ) ) {
4416
+ relativeDirectory = scriptPath . substr ( rootDirectory . length ) ;
4417
+ return true ;
4418
+ }
4419
+ } ) ;
4420
+
4421
+ // Now find a path for each potential directory that is to be merged with the one containing the script
4422
+ return deduplicate ( map ( rootDirs , rootDirectory => combinePaths ( rootDirectory , relativeDirectory ) ) ) ;
4423
+ }
4424
+
4425
+ function getCompletionEntriesForDirectoryFragmentWithRootDirs ( rootDirs : string [ ] , fragment : string , scriptPath : string , extensions : string [ ] , includeExtensions : boolean ) : CompletionEntry [ ] {
4426
+ const basePath = program . getCompilerOptions ( ) . project || host . getCurrentDirectory ( ) ;
4427
+
4428
+ const baseDirectories = getBaseDirectoriesFromRootDirs (
4429
+ rootDirs , basePath , scriptPath , host . useCaseSensitiveFileNames && ! host . useCaseSensitiveFileNames ( ) ) ;
4398
4430
const result : CompletionEntry [ ] = [ ] ;
4399
4431
4432
+ for ( const baseDirectory of baseDirectories ) {
4433
+ getCompletionEntriesForDirectoryFragment ( fragment , baseDirectory , extensions , includeExtensions , result ) ;
4434
+ }
4435
+
4436
+ return result ;
4437
+ }
4438
+
4439
+ function getCompletionEntriesForDirectoryFragment ( fragment : string , scriptPath : string , extensions : string [ ] , includeExtensions : boolean , result : CompletionEntry [ ] = [ ] ) : CompletionEntry [ ] {
4400
4440
const toComplete = getBaseFileName ( fragment ) ;
4401
4441
const absolutePath = normalizeSlashes ( host . resolvePath ( isRootedDiskPath ( fragment ) ? fragment : combinePaths ( scriptPath , fragment ) ) ) ;
4402
4442
const baseDirectory = toComplete ? getDirectoryPath ( absolutePath ) : absolutePath ;
@@ -4456,7 +4496,8 @@ namespace ts {
4456
4496
4457
4497
if ( baseUrl ) {
4458
4498
const fileExtensions = getSupportedExtensions ( options ) ;
4459
- const absolute = isRootedDiskPath ( baseUrl ) ? baseUrl : combinePaths ( host . getCurrentDirectory ( ) , baseUrl )
4499
+ const projectDir = options . project || host . getCurrentDirectory ( ) ;
4500
+ const absolute = isRootedDiskPath ( baseUrl ) ? baseUrl : combinePaths ( projectDir , baseUrl ) ;
4460
4501
result = getCompletionEntriesForDirectoryFragment ( fragment , normalizePath ( absolute ) , fileExtensions , /*includeExtensions*/ false ) ;
4461
4502
4462
4503
if ( paths ) {
0 commit comments