Skip to content

Fix incorrect assert about configFileName when watch is created with explicit options, projectReferences etc #53468

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 23, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 1 addition & 2 deletions src/compiler/watchPublic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1088,7 +1088,6 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
}

function updateExtendedConfigFilesWatches(forProjectPath: Path, options: CompilerOptions | undefined, watchOptions: WatchOptions | undefined, watchType: WatchTypeRegistry["ExtendedConfigFile"] | WatchTypeRegistry["ExtendedConfigOfReferencedProject"]) {
Debug.assert(configFileName);
updateSharedExtendedConfigFileWatcher(
forProjectPath,
options,
Expand All @@ -1104,7 +1103,7 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
// If there are no referenced projects this extended config file watcher depend on ignore
if (!projects?.size) return;
projects.forEach(projectPath => {
if (toPath(configFileName) === projectPath) {
if (configFileName && toPath(configFileName) === projectPath) {
// If this is the config file of the project, reload completely
reloadLevel = ConfigFileProgramReloadLevel.Full;
}
Expand Down
104 changes: 103 additions & 1 deletion src/testRunner/unittests/tscWatch/watchApi.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as Harness from "../../_namespaces/Harness";
import * as ts from "../../_namespaces/ts";
import { commandLineCallbacks } from "../tsc/helpers";
import { dedent } from "../../_namespaces/Utils";
import { commandLineCallbacks, libContent } from "../tsc/helpers";
import {
createWatchedSystem,
File,
Expand All @@ -11,6 +12,7 @@ import {
applyEdit,
createBaseline,
createWatchCompilerHostOfConfigFileForBaseline,
createWatchCompilerHostOfFilesAndCompilerOptionsForBaseline,
runWatchBaseline,
watchBaseline,
} from "./helpers";
Expand Down Expand Up @@ -718,3 +720,103 @@ describe("unittests:: tsc-watch:: watchAPI:: when builder emit occurs with emitO
verify("when emitting with emitOnlyDtsFiles");
verify("when emitting with emitOnlyDtsFiles with outFile", "outFile.js");
});

describe("unittests:: tsc-watch:: watchAPI:: when creating program with project references but not config file", () => {
function setup(libExtends: boolean) {
const system = createWatchedSystem({
"/user/username/projects/project/tsconfig.json": JSON.stringify({
compilerOptions: { types: [] },
files: ["app.ts"],
references: [{ path: "./lib" }]
}),
"/user/username/projects/project/app.ts": dedent`
import { one } from './lib';
console.log(one);
`,
"/user/username/projects/project/lib/tsconfig.json": JSON.stringify({
extends: libExtends ? "./tsconfig.base.json" : undefined,
compilerOptions: libExtends ? undefined : { composite: true, types: [] },
files: ["index.ts"],
}),
"/user/username/projects/project/lib/tsconfig.base.json": JSON.stringify({
compilerOptions: { composite: true, types: [] },
}),
"/user/username/projects/project/lib/index.ts": "export const one = 1;",
"/user/username/projects/project/lib/index.d.ts": "export const one = 1;",
[libFile.path]: libContent,
});
const baseline = createBaseline(system);
const commandLine = ts.getParsedCommandLineOfConfigFile(
"/user/username/projects/project/tsconfig.json",
{ extendedDiagnostics: true },
{
useCaseSensitiveFileNames: true,
fileExists: path => system.fileExists(path),
readFile: path => system.readFile(path),
getCurrentDirectory: () => system.getCurrentDirectory(),
readDirectory: (path, extensions, excludes, includes, depth) => system.readDirectory(path, extensions, excludes, includes, depth),
onUnRecoverableConfigFileDiagnostic: ts.noop,
}
)!;
const compilerHost = createWatchCompilerHostOfFilesAndCompilerOptionsForBaseline({
cb: baseline.cb,
system,
rootFiles: commandLine.fileNames,
options: commandLine.options,
projectReferences: commandLine.projectReferences,
watchOptions: commandLine.watchOptions,
});
const watch = ts.createWatchProgram(compilerHost);
return { watch, baseline };
}

it("when watching referenced project when there is no config file name", () => {
const { watch, baseline } = setup(/*libExtends*/ false);
runWatchBaseline({
scenario: "watchApi",
subScenario: "when watching referenced project when there is no config file name",
commandLineArgs: ["--w", "-p", ".", "--extendedDiagnostics"],
...baseline,
edits: [
{
caption: "Modify lib tsconfig",
edit: sys => sys.writeFile(`/user/username/projects/project/lib/tsconfig.json`, JSON.stringify({
compilerOptions: { composite: true },
files: ["index.ts"],
})),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
],
watchOrSolution: watch
});
});

it("when watching referenced project with extends when there is no config file name", () => {
const { watch, baseline } = setup(/*libExtends*/ true);
runWatchBaseline({
scenario: "watchApi",
subScenario: "when watching referenced project with extends when there is no config file name",
commandLineArgs: ["--w", "-p", ".", "--extendedDiagnostics"],
...baseline,
edits: [
{
caption: "Modify lib tsconfig",
edit: sys => sys.writeFile(`/user/username/projects/project/lib/tsconfig.json`, JSON.stringify({
extends: "./tsconfig.base.json",
compilerOptions: { typeRoots: [] },
files: ["index.ts"],
})),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
{
caption: "Modify lib extends",
edit: sys => sys.writeFile(`/user/username/projects/project/lib/tsconfig.base.json`, JSON.stringify({
compilerOptions: { composite: true },
})),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
],
watchOrSolution: watch
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
Input::
//// [/user/username/projects/project/tsconfig.json]
{"compilerOptions":{"types":[]},"files":["app.ts"],"references":[{"path":"./lib"}]}

//// [/user/username/projects/project/app.ts]
import { one } from './lib';
console.log(one);


//// [/user/username/projects/project/lib/tsconfig.json]
{"compilerOptions":{"composite":true,"types":[]},"files":["index.ts"]}

//// [/user/username/projects/project/lib/tsconfig.base.json]
{"compilerOptions":{"composite":true,"types":[]}}

//// [/user/username/projects/project/lib/index.ts]
export const one = 1;

//// [/user/username/projects/project/lib/index.d.ts]
export const one = 1;

//// [/a/lib/lib.d.ts]
/// <reference no-default-lib="true"/>
interface Boolean {}
interface Function {}
interface CallableFunction {}
interface NewableFunction {}
interface IArguments {}
interface Number { toExponential: any; }
interface Object {}
interface RegExp {}
interface String { charAt: any; }
interface Array<T> { length: number; [n: number]: T; }
interface ReadonlyArray<T> {}
declare const console: { log(msg: any): void; };


/a/lib/tsc.js --w -p . --extendedDiagnostics
Output::
[12:00:31 AM] Starting compilation in watch mode...

Current directory: / CaseSensitiveFileNames: false
Synchronizing program
CreatingProgramWith::
roots: ["/user/username/projects/project/app.ts"]
options: {"types":[],"extendedDiagnostics":true,"configFilePath":"/user/username/projects/project/tsconfig.json"}
projectReferences: [{"path":"/user/username/projects/project/lib","originalPath":"./lib"}]
Loading config file: /user/username/projects/project/lib/tsconfig.json
FileWatcher:: Added:: WatchInfo: /user/username/projects/project/lib/tsconfig.json 2000 undefined Config file of referened project
FileWatcher:: Added:: WatchInfo: /user/username/projects/project/app.ts 250 undefined Source file
DirectoryWatcher:: Added:: WatchInfo: /user 1 undefined Failed Lookup Locations
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user 1 undefined Failed Lookup Locations
FileWatcher:: Added:: WatchInfo: /user/username/projects/project/lib/index.d.ts 250 undefined Source file
FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 250 undefined Source file
DirectoryWatcher:: Triggered with /user/username/projects/project/app.js :: WatchInfo: /user 1 undefined Failed Lookup Locations
Elapsed:: *ms DirectoryWatcher:: Triggered with /user/username/projects/project/app.js :: WatchInfo: /user 1 undefined Failed Lookup Locations
[12:00:34 AM] Found 0 errors. Watching for file changes.



Program root files: ["/user/username/projects/project/app.ts"]
Program options: {"types":[],"extendedDiagnostics":true,"configFilePath":"/user/username/projects/project/tsconfig.json"}
Program structureReused: Not
Program files::
/a/lib/lib.d.ts
/user/username/projects/project/lib/index.d.ts
/user/username/projects/project/app.ts

Semantic diagnostics in builder refreshed for::
/a/lib/lib.d.ts
/user/username/projects/project/lib/index.d.ts
/user/username/projects/project/app.ts

Shape signatures in builder refreshed for::
/a/lib/lib.d.ts (used version)
/user/username/projects/project/lib/index.d.ts (used version)
/user/username/projects/project/app.ts (used version)

FsWatches::
/user/username/projects/project/lib/tsconfig.json: *new*
{}
/user/username/projects/project/app.ts: *new*
{}
/user/username/projects/project/lib/index.d.ts: *new*
{}
/a/lib/lib.d.ts: *new*
{}

FsWatchesRecursive::
/user: *new*
{}

exitCode:: ExitStatus.undefined

//// [/user/username/projects/project/app.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var lib_1 = require("./lib");
console.log(lib_1.one);



Change:: Modify lib tsconfig

Input::
//// [/user/username/projects/project/lib/tsconfig.json]
{"compilerOptions":{"composite":true},"files":["index.ts"]}


Output::
FileWatcher:: Triggered with /user/username/projects/project/lib/tsconfig.json 1:: WatchInfo: /user/username/projects/project/lib/tsconfig.json 2000 undefined Config file of referened project
Scheduling update
Elapsed:: *ms FileWatcher:: Triggered with /user/username/projects/project/lib/tsconfig.json 1:: WatchInfo: /user/username/projects/project/lib/tsconfig.json 2000 undefined Config file of referened project
Synchronizing program
Loading config file: /user/username/projects/project/lib/tsconfig.json
[12:00:38 AM] File change detected. Starting incremental compilation...

CreatingProgramWith::
roots: ["/user/username/projects/project/app.ts"]
options: {"types":[],"extendedDiagnostics":true,"configFilePath":"/user/username/projects/project/tsconfig.json"}
projectReferences: [{"path":"/user/username/projects/project/lib","originalPath":"./lib"}]
[12:00:39 AM] Found 0 errors. Watching for file changes.



Program root files: ["/user/username/projects/project/app.ts"]
Program options: {"types":[],"extendedDiagnostics":true,"configFilePath":"/user/username/projects/project/tsconfig.json"}
Program structureReused: Not
Program files::
/a/lib/lib.d.ts
/user/username/projects/project/lib/index.d.ts
/user/username/projects/project/app.ts

Semantic diagnostics in builder refreshed for::

No shapes updated in the builder::

exitCode:: ExitStatus.undefined

Loading