Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -4469,6 +4469,10 @@
"category": "Error",
"code": 5010
},
"Inferred common source directory differs from tsconfig directory, output layout will be changed.": {
"category": "Error",
"code": 5011
},
"Cannot read file '{0}': {1}.": {
"category": "Error",
"code": 5012
Expand Down
19 changes: 18 additions & 1 deletion src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ export function getCommonSourceDirectory(
commonSourceDirectory = getNormalizedAbsolutePath(options.rootDir, currentDirectory);
checkSourceFilesBelongToPath?.(options.rootDir);
}
else if (options.composite && options.configFilePath) {
else if (options.configFilePath) {
// Project compilations never infer their root from the input source paths
commonSourceDirectory = getDirectoryPath(normalizeSlashes(options.configFilePath));
checkSourceFilesBelongToPath?.(commonSourceDirectory);
Expand All @@ -664,6 +664,23 @@ export function getCommonSourceDirectory(
return commonSourceDirectory;
}

/** @internal */
export function getComputedCommonSourceDirectory(
emittedFiles: readonly string[],
currentDirectory: string,
getCanonicalFileName: GetCanonicalFileName,
): string {
let commonSourceDirectory = computeCommonSourceDirectoryOfFilenames(emittedFiles, currentDirectory, getCanonicalFileName);

if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== directorySeparator) {
// Make sure directory path ends with directory separator so this string can directly
// used to replace with "" to get the relative path of the source file and the relative path doesn't
// start with / making it rooted path
commonSourceDirectory += directorySeparator;
}
return commonSourceDirectory;
}

/** @internal */
export function getCommonSourceDirectoryOfConfig({ options, fileNames }: ParsedCommandLine, ignoreCase: boolean): string {
return getCommonSourceDirectory(
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/moduleNameResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2886,7 +2886,7 @@ function getLoadModuleFromTargetExportOrImport(extensions: Extensions, state: Mo
const commonSourceDirGuesses: string[] = [];
// A `rootDir` compiler option strongly indicates the root location
// A `composite` project is using project references and has it's common src dir set to `.`, so it shouldn't need to check any other locations
if (state.compilerOptions.rootDir || (state.compilerOptions.composite && state.compilerOptions.configFilePath)) {
if (state.compilerOptions.rootDir || state.compilerOptions.configFilePath) {
const commonDir = toAbsolutePath(getCommonSourceDirectory(state.compilerOptions, () => [], state.host.getCurrentDirectory?.() || "", getCanonicalFileName));
commonSourceDirGuesses.push(commonDir);
}
Expand Down
27 changes: 27 additions & 0 deletions src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ import {
GetCanonicalFileName,
getCommonSourceDirectory as ts_getCommonSourceDirectory,
getCommonSourceDirectoryOfConfig,
getComputedCommonSourceDirectory,
getDeclarationDiagnostics as ts_getDeclarationDiagnostics,
getDefaultLibFileName,
getDirectoryPath,
Expand Down Expand Up @@ -4254,6 +4255,32 @@ export function createProgram(_rootNamesOrOptions: readonly string[] | CreatePro
}
}

if (
!options.noEmit &&
!options.composite &&
!options.rootDir &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you don't want to do this check if rootDir is specified, because the user should already have a working rootDir, or will otherwise get errors on individual files. Users who have a rootDir now also have to have their outputs double-checked.

options.configFilePath &&
(options.outDir || // there is --outDir specified
(getEmitDeclarations(options) && options.declarationDir)) // there is --declarationDir specified
) {
// Check if rootDir inferred changed and issue diagnostic
const dir = getCommonSourceDirectory();
const emittedFiles = mapDefined(files, file => !file.isDeclarationFile && sourceFileMayBeEmitted(file, program) ? file.fileName : undefined);
const dir59 = getComputedCommonSourceDirectory(emittedFiles, currentDirectory, getCanonicalFileName);
if (dir59 !== "" && getCanonicalFileName(dir) !== getCanonicalFileName(dir59)) {
// change in layout
createDiagnosticForOption(
/*onKey*/ true,
options.outDir ? "outDir" : "declarationDir",
options.outDir ? "declarationDir" : undefined,
chainDiagnosticMessages(
chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Visit_https_Colon_Slash_Slashaka_ms_Slashts6_for_migration_information),
Diagnostics.Inferred_common_source_directory_differs_from_tsconfig_directory_output_layout_will_be_changed,
),
);
}
}

if (options.checkJs && !getAllowJSCompilerOption(options)) {
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "checkJs", "allowJs");
}
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6622,7 +6622,7 @@ export function sourceFileMayBeEmitted(sourceFile: SourceFile, host: SourceFileM
// Json file is not emitted if outDir is not specified
if (!options.outDir) return false;
// Otherwise if rootDir or composite config file, we know common sourceDir and can check if file would be emitted in same location
if (options.rootDir || (options.composite && options.configFilePath)) {
if (options.rootDir || options.configFilePath) {
const commonDir = getNormalizedAbsolutePath(getCommonSourceDirectory(options, () => [], host.getCurrentDirectory(), host.getCanonicalFileName), host.getCurrentDirectory());
const outputPath = getSourceFilePathInNewDirWorker(sourceFile.fileName, options.outDir, host.getCurrentDirectory(), commonDir, host.getCanonicalFileName);
if (comparePaths(sourceFile.fileName, outputPath, host.getCurrentDirectory(), !host.useCaseSensitiveFileNames()) === Comparison.EqualTo) return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ function getMonorepoSymlinkedSiblingPackagesSysWithUnRelatedFolders(
compilerOptions: {
outDir: "lib",
declaration: true,
rootDir: "src",
},
include: ["src/**/*.ts"],
}),
Expand All @@ -169,6 +170,7 @@ function getMonorepoSymlinkedSiblingPackagesSysWithUnRelatedFolders(
compilerOptions: {
outDir: "lib",
declaration: true,
rootDir: "src",
},
include: ["src/**/*.ts"],
}),
Expand All @@ -183,6 +185,7 @@ function getMonorepoSymlinkedSiblingPackagesSysWithUnRelatedFolders(
"/home/src/projects/b/2/b-impl/b/tsconfig.json": jsonToReadableText({
compilerOptions: {
outDir: "lib",
rootDir: "src",
},
include: ["src/**/*.ts"],
}),
Expand Down
4 changes: 2 additions & 2 deletions src/testRunner/unittests/tsbuild/outputPaths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe("unittests:: tsbuild:: outputPaths::", () => {
...input,
});

it("verify getOutputFileNames", () => {
it("verify getOutputFileNames " + input.subScenario, () => {
const sys = input.sys();
assert.deepEqual(
ts.getOutputFileNames(
Expand Down Expand Up @@ -58,7 +58,7 @@ describe("unittests:: tsbuild:: outputPaths::", () => {
}),
}),
edits,
}, ["/home/src/workspaces/project/dist/index.js"]);
}, ["/home/src/workspaces/project/dist/src/index.js"]);

verify({
subScenario: "when rootDir is not specified and is composite",
Expand Down
33 changes: 33 additions & 0 deletions tests/baselines/reference/commonSourceDirectory.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,36 @@ foo_1.x + bar_1.y;
//// [/app/bin/index.d.ts]
/// <reference path="../../types/bar.d.ts" preserve="true" />
export {};


//// [DtsFileErrors]


/app/tsconfig.json(3,9): error TS5011: Inferred common source directory differs from tsconfig directory, output layout will be changed.
Visit https://aka.ms/ts6 for migration information.


==== /app/tsconfig.json (1 errors) ====
{
"compilerOptions": {
"outDir": "bin",
~~~~~~~~
!!! error TS5011: Inferred common source directory differs from tsconfig directory, output layout will be changed.
!!! error TS5011: Visit https://aka.ms/ts6 for migration information.
"typeRoots": ["../types"],
"sourceMap": true,
"mapRoot": "myMapRoot",
"sourceRoot": "mySourceRoot",
"declaration": true
}
}

==== /app/bin/index.d.ts (0 errors) ====
/// <reference path="../../types/bar.d.ts" preserve="true" />
export {};

==== /types/bar.d.ts (0 errors) ====
declare module "bar" {
export const y = 0;
}

25 changes: 25 additions & 0 deletions tests/baselines/reference/commonSourceDirectory_dts.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/app/tsconfig.json(3,9): error TS5011: Inferred common source directory differs from tsconfig directory, output layout will be changed.
Visit https://aka.ms/ts6 for migration information.


==== /app/tsconfig.json (1 errors) ====
{
"compilerOptions": {
"outDir": "bin",
~~~~~~~~
!!! error TS5011: Inferred common source directory differs from tsconfig directory, output layout will be changed.
!!! error TS5011: Visit https://aka.ms/ts6 for migration information.
"sourceMap": true,
"mapRoot": "myMapRoot",
"sourceRoot": "mySourceRoot",
"declaration": true
}
}

==== /app/lib/bar.d.ts (0 errors) ====
declare const y: number;

==== /app/src/index.ts (0 errors) ====
/// <reference path="../lib/bar.d.ts" preserve="true" />
export const x = y;

8 changes: 4 additions & 4 deletions tests/baselines/reference/commonSourceDirectory_dts.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ declare const y: number;
export const x = y;


//// [/app/bin/index.js]
//// [/app/bin/src/index.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.x = void 0;
/// <reference path="../lib/bar.d.ts" preserve="true" />
exports.x = y;
//# sourceMappingURL=../src/myMapRoot/index.js.map
//# sourceMappingURL=../../myMapRoot/src/index.js.map

//// [/app/bin/index.d.ts]
/// <reference path="../lib/bar.d.ts" preserve="true" />
//// [/app/bin/src/index.d.ts]
/// <reference path="../../lib/bar.d.ts" preserve="true" />
export declare const x: number;
6 changes: 3 additions & 3 deletions tests/baselines/reference/commonSourceDirectory_dts.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
===================================================================
JsFile: index.js
mapUrl: ../src/myMapRoot/index.js.map
mapUrl: ../../myMapRoot/src/index.js.map
sourceRoot: mySourceRoot/
sources: index.ts
sources: src/index.ts
===================================================================
-------------------------------------------------------------------
emittedFile:/app/bin/index.js
sourceFile:index.ts
emittedFile:/app/bin/src/index.js
sourceFile:src/index.ts
-------------------------------------------------------------------
>>>"use strict";
>>>Object.defineProperty(exports, "__esModule", { value: true });
Expand All @@ -26,7 +26,7 @@ sourceFile:index.ts
4 > ^^^
5 > ^
6 > ^
7 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^->
7 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^->
1 >
>export const
2 >
Expand All @@ -41,4 +41,4 @@ sourceFile:index.ts
5 >Emitted(5, 14) Source(2, 19) + SourceIndex(0)
6 >Emitted(5, 15) Source(2, 20) + SourceIndex(0)
---
>>>//# sourceMappingURL=../src/myMapRoot/index.js.map
>>>//# sourceMappingURL=../../myMapRoot/src/index.js.map
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
/tsconfig.json(5,5): error TS5011: Inferred common source directory differs from tsconfig directory, output layout will be changed.
Visit https://aka.ms/ts6 for migration information.
/tsconfig.json(6,5): error TS5101: Option 'baseUrl' is deprecated and will stop functioning in TypeScript 7.0. Specify compilerOption '"ignoreDeprecations": "6.0"' to silence this error.
Visit https://aka.ms/ts6 for migration information.


==== /tsconfig.json (1 errors) ====
==== /tsconfig.json (2 errors) ====
{
"compilerOptions": {
"module": "nodenext",
"declaration": true,
"outDir": "temp",
~~~~~~~~
!!! error TS5011: Inferred common source directory differs from tsconfig directory, output layout will be changed.
!!! error TS5011: Visit https://aka.ms/ts6 for migration information.
"baseUrl": "."
~~~~~~~~~
!!! error TS5101: Option 'baseUrl' is deprecated and will stop functioning in TypeScript 7.0. Specify compilerOption '"ignoreDeprecations": "6.0"' to silence this error.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
packages/b/tsconfig.json(3,9): error TS5011: Inferred common source directory differs from tsconfig directory, output layout will be changed.
Visit https://aka.ms/ts6 for migration information.
packages/b/tsconfig.json(5,9): error TS5101: Option 'baseUrl' is deprecated and will stop functioning in TypeScript 7.0. Specify compilerOption '"ignoreDeprecations": "6.0"' to silence this error.
Visit https://aka.ms/ts6 for migration information.


==== packages/b/tsconfig.json (1 errors) ====
==== packages/b/tsconfig.json (2 errors) ====
{
"compilerOptions": {
"outDir": "dist",
~~~~~~~~
!!! error TS5011: Inferred common source directory differs from tsconfig directory, output layout will be changed.
!!! error TS5011: Visit https://aka.ms/ts6 for migration information.
"declaration": true,
"baseUrl": ".",
~~~~~~~~~
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
packages/lab/tsconfig.json(3,9): error TS5011: Inferred common source directory differs from tsconfig directory, output layout will be changed.
Visit https://aka.ms/ts6 for migration information.
packages/lab/tsconfig.json(5,9): error TS5101: Option 'baseUrl' is deprecated and will stop functioning in TypeScript 7.0. Specify compilerOption '"ignoreDeprecations": "6.0"' to silence this error.
Visit https://aka.ms/ts6 for migration information.


==== packages/lab/tsconfig.json (1 errors) ====
==== packages/lab/tsconfig.json (2 errors) ====
{
"compilerOptions": {
"outDir": "dist",
~~~~~~~~
!!! error TS5011: Inferred common source directory differs from tsconfig directory, output layout will be changed.
!!! error TS5011: Visit https://aka.ms/ts6 for migration information.
"declaration": true,
"baseUrl": "../",
~~~~~~~~~
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,20 @@ interface Foo {
x: number;
}
export default Foo;


//// [DtsFileErrors]


/foo/tsconfig.json(2,47): error TS5011: Inferred common source directory differs from tsconfig directory, output layout will be changed.
Visit https://aka.ms/ts6 for migration information.


==== /foo/tsconfig.json (1 errors) ====
{
"compilerOptions": { "declaration": true, "declarationDir": "out" }
~~~~~~~~~~~~~~~~
!!! error TS5011: Inferred common source directory differs from tsconfig directory, output layout will be changed.
!!! error TS5011: Visit https://aka.ms/ts6 for migration information.
}

This file was deleted.

Loading