Skip to content

Commit e087a3e

Browse files
authored
Reimplement rootDirs (#1540)
1 parent 0d5197c commit e087a3e

18 files changed

+219
-167
lines changed

internal/module/resolver.go

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1081,7 +1081,16 @@ func (r *resolutionState) getOriginalAndResolvedFileName(fileName string) (strin
10811081
}
10821082

10831083
func (r *resolutionState) tryLoadModuleUsingOptionalResolutionSettings() *resolved {
1084-
return r.tryLoadModuleUsingPathsIfEligible()
1084+
if resolved := r.tryLoadModuleUsingPathsIfEligible(); !resolved.shouldContinueSearching() {
1085+
return resolved
1086+
}
1087+
1088+
if !tspath.IsExternalModuleNameRelative(r.name) {
1089+
// No more tryLoadModuleUsingBaseUrl.
1090+
return continueSearching()
1091+
} else {
1092+
return r.tryLoadModuleUsingRootDirs()
1093+
}
10851094
}
10861095

10871096
func (r *resolutionState) tryLoadModuleUsingPathsIfEligible() *resolved {
@@ -1136,6 +1145,82 @@ func (r *resolutionState) tryLoadModuleUsingPaths(extensions extensions, moduleN
11361145
return continueSearching()
11371146
}
11381147

1148+
func (r *resolutionState) tryLoadModuleUsingRootDirs() *resolved {
1149+
if len(r.compilerOptions.RootDirs) == 0 {
1150+
return continueSearching()
1151+
}
1152+
1153+
if r.resolver.traceEnabled() {
1154+
r.resolver.host.Trace(diagnostics.X_rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0.Format(r.name))
1155+
}
1156+
1157+
candidate := tspath.NormalizePath(tspath.CombinePaths(r.containingDirectory, r.name))
1158+
1159+
var matchedRootDir string
1160+
var matchedNormalizedPrefix string
1161+
for _, rootDir := range r.compilerOptions.RootDirs {
1162+
// rootDirs are expected to be absolute
1163+
// in case of tsconfig.json this will happen automatically - compiler will expand relative names
1164+
// using location of tsconfig.json as base location
1165+
normalizedRoot := tspath.NormalizePath(rootDir)
1166+
if !strings.HasSuffix(normalizedRoot, "/") {
1167+
normalizedRoot += "/"
1168+
}
1169+
isLongestMatchingPrefix := strings.HasPrefix(candidate, normalizedRoot) &&
1170+
(matchedNormalizedPrefix == "" || len(matchedNormalizedPrefix) < len(normalizedRoot))
1171+
1172+
if r.resolver.traceEnabled() {
1173+
r.resolver.host.Trace(diagnostics.Checking_if_0_is_the_longest_matching_prefix_for_1_2.Format(normalizedRoot, candidate, isLongestMatchingPrefix))
1174+
}
1175+
1176+
if isLongestMatchingPrefix {
1177+
matchedNormalizedPrefix = normalizedRoot
1178+
matchedRootDir = rootDir
1179+
}
1180+
}
1181+
1182+
if matchedNormalizedPrefix != "" {
1183+
if r.resolver.traceEnabled() {
1184+
r.resolver.host.Trace(diagnostics.Longest_matching_prefix_for_0_is_1.Format(candidate, matchedNormalizedPrefix))
1185+
}
1186+
suffix := candidate[len(matchedNormalizedPrefix):]
1187+
1188+
// first - try to load from a initial location
1189+
if r.resolver.traceEnabled() {
1190+
r.resolver.host.Trace(diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2.Format(suffix, matchedNormalizedPrefix, candidate))
1191+
}
1192+
loader := func(extensions extensions, candidate string, onlyRecordFailures bool) *resolved {
1193+
return r.nodeLoadModuleByRelativeName(extensions, candidate, onlyRecordFailures, true /*considerPackageJson*/)
1194+
}
1195+
if resolvedFileName := loader(r.extensions, candidate, !r.resolver.host.FS().DirectoryExists(r.containingDirectory)); !resolvedFileName.shouldContinueSearching() {
1196+
return resolvedFileName
1197+
}
1198+
1199+
if r.resolver.traceEnabled() {
1200+
r.resolver.host.Trace(diagnostics.Trying_other_entries_in_rootDirs.Format())
1201+
}
1202+
// then try to resolve using remaining entries in rootDirs
1203+
for _, rootDir := range r.compilerOptions.RootDirs {
1204+
if rootDir == matchedRootDir {
1205+
// skip the initially matched entry
1206+
continue
1207+
}
1208+
candidate := tspath.CombinePaths(tspath.NormalizePath(rootDir), suffix)
1209+
if r.resolver.traceEnabled() {
1210+
r.resolver.host.Trace(diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2.Format(suffix, rootDir, candidate))
1211+
}
1212+
baseDirectory := tspath.GetDirectoryPath(candidate)
1213+
if resolvedFileName := loader(r.extensions, candidate, !r.resolver.host.FS().DirectoryExists(baseDirectory)); !resolvedFileName.shouldContinueSearching() {
1214+
return resolvedFileName
1215+
}
1216+
}
1217+
if r.resolver.traceEnabled() {
1218+
r.resolver.host.Trace(diagnostics.Module_resolution_using_rootDirs_has_failed.Format())
1219+
}
1220+
}
1221+
return continueSearching()
1222+
}
1223+
11391224
func (r *resolutionState) nodeLoadModuleByRelativeName(extensions extensions, candidate string, onlyRecordFailures bool, considerPackageJson bool) *resolved {
11401225
if r.resolver.traceEnabled() {
11411226
r.resolver.host.Trace(diagnostics.Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_types_Colon_1.Format(candidate, extensions.String()))

internal/testrunner/compiler_runner.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -582,9 +582,6 @@ func (c *compilerTest) containsUnsupportedOptionsForDiagnostics() bool {
582582
if c.options.BaseUrl != "" {
583583
return true
584584
}
585-
if c.options.RootDirs != nil {
586-
return true
587-
}
588585
if c.options.OutFile != "" {
589586
return true
590587
}

testdata/baselines/reference/submodule/compiler/pathMappingBasedModuleResolution6_node.errors.txt

Lines changed: 0 additions & 25 deletions
This file was deleted.

testdata/baselines/reference/submodule/compiler/pathMappingBasedModuleResolution6_node.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ use(x.toFixed());
1111
export let x: number;
1212

1313

14+
//// [file3.js]
15+
"use strict";
16+
Object.defineProperty(exports, "__esModule", { value: true });
17+
exports.x = void 0;
18+
const file2_1 = require("../file2");
19+
Object.defineProperty(exports, "x", { enumerable: true, get: function () { return file2_1.x; } });
1420
//// [file1.js]
1521
"use strict";
1622
Object.defineProperty(exports, "__esModule", { value: true });

testdata/baselines/reference/submodule/compiler/pathMappingBasedModuleResolution6_node.js.diff

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
--- old.pathMappingBasedModuleResolution6_node.js
22
+++ new.pathMappingBasedModuleResolution6_node.js
3-
@@= skipped -10, +10 lines =@@
4-
export let x: number;
5-
6-
7-
-//// [file3.js]
8-
-"use strict";
9-
-Object.defineProperty(exports, "__esModule", { value: true });
10-
-exports.x = void 0;
3+
@@= skipped -14, +14 lines =@@
4+
"use strict";
5+
Object.defineProperty(exports, "__esModule", { value: true });
6+
exports.x = void 0;
117
-var file2_1 = require("../file2");
12-
-Object.defineProperty(exports, "x", { enumerable: true, get: function () { return file2_1.x; } });
8+
+const file2_1 = require("../file2");
9+
Object.defineProperty(exports, "x", { enumerable: true, get: function () { return file2_1.x; } });
1310
//// [file1.js]
1411
"use strict";
1512
Object.defineProperty(exports, "__esModule", { value: true });

testdata/baselines/reference/submodule/compiler/pathMappingBasedModuleResolution6_node.symbols

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,15 @@ declare function use(x: string);
1010

1111
use(x.toFixed());
1212
>use : Symbol(use, Decl(file1.ts, 0, 34))
13+
>x.toFixed : Symbol(toFixed, Decl(lib.es5.d.ts, --, --))
1314
>x : Symbol(x, Decl(file1.ts, 0, 8))
15+
>toFixed : Symbol(toFixed, Decl(lib.es5.d.ts, --, --))
1416

1517
=== c:/root/src/file2/index.d.ts ===
1618
export let x: number;
1719
>x : Symbol(x, Decl(index.d.ts, 0, 10))
1820

21+
=== c:/root/generated/src/project/file3.ts ===
22+
export {x} from "../file2";
23+
>x : Symbol(x, Decl(file3.ts, 0, 8))
24+

testdata/baselines/reference/submodule/compiler/pathMappingBasedModuleResolution6_node.symbols.diff

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,10 @@
55
use(x.toFixed());
66
>use : Symbol(use, Decl(file1.ts, 0, 34))
77
->x.toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --))
8+
+>x.toFixed : Symbol(toFixed, Decl(lib.es5.d.ts, --, --))
89
>x : Symbol(x, Decl(file1.ts, 0, 8))
910
->toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --))
11+
+>toFixed : Symbol(toFixed, Decl(lib.es5.d.ts, --, --))
1012

1113
=== c:/root/src/file2/index.d.ts ===
12-
export let x: number;
13-
>x : Symbol(x, Decl(index.d.ts, 0, 10))
14-
-
15-
-=== c:/root/generated/src/project/file3.ts ===
16-
-export {x} from "../file2";
17-
->x : Symbol(x, Decl(file3.ts, 0, 8))
14+
export let x: number;

testdata/baselines/reference/submodule/compiler/pathMappingBasedModuleResolution6_node.types

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
=== c:/root/src/file1.ts ===
44
import {x} from "./project/file3";
5-
>x : any
5+
>x : number
66

77
declare function use(x: string);
88
>use : (x: string) => any
@@ -11,12 +11,16 @@ declare function use(x: string);
1111
use(x.toFixed());
1212
>use(x.toFixed()) : any
1313
>use : (x: string) => any
14-
>x.toFixed() : any
15-
>x.toFixed : any
16-
>x : any
17-
>toFixed : any
14+
>x.toFixed() : string
15+
>x.toFixed : (fractionDigits?: number) => string
16+
>x : number
17+
>toFixed : (fractionDigits?: number) => string
1818

1919
=== c:/root/src/file2/index.d.ts ===
2020
export let x: number;
2121
>x : number
2222

23+
=== c:/root/generated/src/project/file3.ts ===
24+
export {x} from "../file2";
25+
>x : number
26+

testdata/baselines/reference/submodule/compiler/pathMappingBasedModuleResolution6_node.types.diff

Lines changed: 0 additions & 31 deletions
This file was deleted.

testdata/baselines/reference/submodule/compiler/pathMappingBasedModuleResolution7_node.errors.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
c:/root/src/file1.ts(1,17): error TS2307: Cannot find module './project/file2' or its corresponding type declarations.
1+
c:/root/generated/src/project/file2.ts(2,17): error TS2307: Cannot find module 'templates/module2' or its corresponding type declarations.
22
c:/root/src/tsconfig.json(3,9): error TS5102: Option 'baseUrl' has been removed. Please remove it from your configuration.
33
Use '"paths": {"*": ["./../*"]}' instead.
44
c:/root/src/tsconfig.json(6,17): error TS5090: Non-relative paths are not allowed. Did you forget a leading './'?
@@ -32,10 +32,8 @@ c:/root/src/tsconfig.json(10,17): error TS5090: Non-relative paths are not allow
3232
}
3333
}
3434

35-
==== c:/root/src/file1.ts (1 errors) ====
35+
==== c:/root/src/file1.ts (0 errors) ====
3636
import {x} from "./project/file2";
37-
~~~~~~~~~~~~~~~~~
38-
!!! error TS2307: Cannot find module './project/file2' or its corresponding type declarations.
3937
import {y} from "module3";
4038

4139
declare function use(x: string);
@@ -45,9 +43,11 @@ c:/root/src/tsconfig.json(10,17): error TS5090: Non-relative paths are not allow
4543
==== c:/root/src/file3/index.d.ts (0 errors) ====
4644
export let x: number;
4745

48-
==== c:/root/generated/src/project/file2.ts (0 errors) ====
46+
==== c:/root/generated/src/project/file2.ts (1 errors) ====
4947
import {a} from "module1";
5048
import {b} from "templates/module2";
49+
~~~~~~~~~~~~~~~~~~~
50+
!!! error TS2307: Cannot find module 'templates/module2' or its corresponding type declarations.
5151
import {x as c} from "../file3";
5252
export let x = a + b + c;
5353

0 commit comments

Comments
 (0)