diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index f462c7c1e91..249e2f30c29 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -286,7 +286,7 @@ namespace ts { name: "baseUrl", type: "string", isFilePath: true, - description: Diagnostics.Base_directory_to_resolve_relative_module_names + description: Diagnostics.Base_directory_to_resolve_non_absolute_module_names }, { // this option can only be specified in tsconfig.json diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 3fd364f0fa5..e8fd0d2a069 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2361,7 +2361,7 @@ "category": "Error", "code": 6082 }, - "Base directory to resolve relative module names.": { + "Base directory to resolve non-absolute module names.": { "category": "Message", "code": 6083 }, diff --git a/src/compiler/program.ts b/src/compiler/program.ts index b9ebef7c27f..66944354c40 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -98,7 +98,7 @@ namespace ts { return result; } - // Path mapping based module resolution strategy uses base url to resolve relative file names. This resolution strategy can be enabled + // Path mapping based module resolution strategy uses base url to resolve non-absolute file names. This resolution strategy can be enabled // by setting 'moduleResolution' option to 'baseUrl' and as it implied by the name it uses base url to resolve module names. // Base url can be specified: // - explicitly via command line option 'baseUrl'. If this value is relative it will be computed relative to current directory. @@ -161,12 +161,12 @@ namespace ts { // ] // @file: /a/b/c/src/form1.ts // import {x} from "./form.content.ts" - // @file: /a/b/c/generated/form1.content.ts + // @file: /a/b/c/generated/form.content.ts // export var x = ... // first './form.content.ts' needs to be converted to non-relative name. - // 1. convert it to absolute name '/a/b/c/src/form1.content.ts' -> + // 1. convert it to absolute name '/a/b/c/src/form.content.ts' -> // find longest prefix in rootDirs that match this path, it will be './src' (after expansion '/a/b/c/src/') -> - // suffix is form1.content.ts + // suffix is form.content.ts // 2. apply path mappings to 'form1.content.ts' -> // '*' pattern will be matched -> // '*' substitution yields '/a/b/c/form1.content.ts' - file does not exists @@ -176,6 +176,7 @@ namespace ts { Debug.assert(baseUrl !== undefined); const supportedExtensions = getSupportedExtensions(compilerOptions); + // NOTE: traceEnabled check is delibirately no inside the 'trace' at evert callside to avoid runtime impact of calling vararg function const traceEnabled = isTraceEnabled(compilerOptions, host); if (isRootedDiskPath(moduleName)) { diff --git a/tests/baselines/reference/pathMappingBasedModuleResolution11.js b/tests/baselines/reference/pathMappingBasedModuleResolution11.js new file mode 100644 index 00000000000..614357ec53f --- /dev/null +++ b/tests/baselines/reference/pathMappingBasedModuleResolution11.js @@ -0,0 +1,38 @@ +//// [tests/cases/compiler/pathMappingBasedModuleResolution11.ts] //// + +//// [file1.ts] +import {x} from "./file2" // should be resolved to 'generated/folder1/file2/file.ts' + +export var z = x.toExponential(); + +//// [file.ts] +export {x} from "folder1/file3" // should be resolved to 'folder1/file3.ts' + +//// [file3.ts] +export var x = 1; + +//// [file3.ts] +import {z as y} from "../folder1/file1" // should be resolved to 'folder1/file1.ts' +let z = y.toLowerCase(); + + +//// [file3.js] +define(["require", "exports"], function (require, exports) { + "use strict"; + exports.x = 1; +}); +//// [file.js] +define(["require", "exports", "folder1/file3"], function (require, exports, file3_1) { + "use strict"; + exports.x = file3_1.x; // should be resolved to 'folder1/file3.ts' +}); +//// [file1.js] +define(["require", "exports", "./file2"], function (require, exports, file2_1) { + "use strict"; + exports.z = file2_1.x.toExponential(); +}); +//// [file3.js] +define(["require", "exports", "../folder1/file1"], function (require, exports, file1_1) { + "use strict"; + var z = file1_1.z.toLowerCase(); +}); diff --git a/tests/baselines/reference/pathMappingBasedModuleResolution11.symbols b/tests/baselines/reference/pathMappingBasedModuleResolution11.symbols new file mode 100644 index 00000000000..f453dafe2a2 --- /dev/null +++ b/tests/baselines/reference/pathMappingBasedModuleResolution11.symbols @@ -0,0 +1,29 @@ +=== tests/cases/compiler/root/folder1/file1.ts === +import {x} from "./file2" // should be resolved to 'generated/folder1/file2/file.ts' +>x : Symbol(x, Decl(file1.ts, 0, 8)) + +export var z = x.toExponential(); +>z : Symbol(z, Decl(file1.ts, 2, 10)) +>x.toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(file1.ts, 0, 8)) +>toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --)) + +=== tests/cases/compiler/root/generated/folder1/file2/file.ts === +export {x} from "folder1/file3" // should be resolved to 'folder1/file3.ts' +>x : Symbol(x, Decl(file.ts, 0, 8)) + +=== tests/cases/compiler/root/folder1/file3.ts === +export var x = 1; +>x : Symbol(x, Decl(file3.ts, 0, 10)) + +=== tests/cases/compiler/root/generated/folder2/file3.ts === +import {z as y} from "../folder1/file1" // should be resolved to 'folder1/file1.ts' +>z : Symbol(y, Decl(file3.ts, 0, 8)) +>y : Symbol(y, Decl(file3.ts, 0, 8)) + +let z = y.toLowerCase(); +>z : Symbol(z, Decl(file3.ts, 1, 3)) +>y.toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --)) +>y : Symbol(y, Decl(file3.ts, 0, 8)) +>toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --)) + diff --git a/tests/baselines/reference/pathMappingBasedModuleResolution11.types b/tests/baselines/reference/pathMappingBasedModuleResolution11.types new file mode 100644 index 00000000000..45717088577 --- /dev/null +++ b/tests/baselines/reference/pathMappingBasedModuleResolution11.types @@ -0,0 +1,32 @@ +=== tests/cases/compiler/root/folder1/file1.ts === +import {x} from "./file2" // should be resolved to 'generated/folder1/file2/file.ts' +>x : number + +export var z = x.toExponential(); +>z : string +>x.toExponential() : string +>x.toExponential : (fractionDigits?: number) => string +>x : number +>toExponential : (fractionDigits?: number) => string + +=== tests/cases/compiler/root/generated/folder1/file2/file.ts === +export {x} from "folder1/file3" // should be resolved to 'folder1/file3.ts' +>x : number + +=== tests/cases/compiler/root/folder1/file3.ts === +export var x = 1; +>x : number +>1 : number + +=== tests/cases/compiler/root/generated/folder2/file3.ts === +import {z as y} from "../folder1/file1" // should be resolved to 'folder1/file1.ts' +>z : string +>y : string + +let z = y.toLowerCase(); +>z : string +>y.toLowerCase() : string +>y.toLowerCase : () => string +>y : string +>toLowerCase : () => string + diff --git a/tests/cases/compiler/pathMappingBasedModuleResolution11.ts b/tests/cases/compiler/pathMappingBasedModuleResolution11.ts new file mode 100644 index 00000000000..e0504126ca1 --- /dev/null +++ b/tests/cases/compiler/pathMappingBasedModuleResolution11.ts @@ -0,0 +1,34 @@ +// @module: amd + +// paths\rootDirs is defined in tsconfig.json +// baseUrl is inferred from tsconfig.json + +// @filename: root/tsconfig.json +{ + "compilerOptions": { + "paths": { + "*": [ + "*", + "generated/*/file" + ] + }, + "rootDirs": [ + ".", + "./generated" + ] + } +} +// @filename: root/folder1/file1.ts +import {x} from "./file2" // should be resolved to 'generated/folder1/file2/file.ts' + +export var z = x.toExponential(); + +// @filename: root/generated/folder1/file2/file.ts +export {x} from "folder1/file3" // should be resolved to 'folder1/file3.ts' + +// @filename: root/folder1/file3.ts +export var x = 1; + +// @filename: root/generated/folder2/file3.ts +import {z as y} from "../folder1/file1" // should be resolved to 'folder1/file1.ts' +let z = y.toLowerCase();