Skip to content
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

Fix the incorrect copy over for watchOptions and fix order of watches for referenced projects #59871

Merged
merged 2 commits into from
Sep 5, 2024
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
11 changes: 9 additions & 2 deletions src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3267,6 +3267,7 @@ function isSuccessfulParsedTsconfig(value: ParsedTsconfig) {
interface ExtendsResult {
options: CompilerOptions;
watchOptions?: WatchOptions;
watchOptionsCopied?: boolean;
include?: string[];
exclude?: string[];
files?: string[];
Expand Down Expand Up @@ -3325,7 +3326,7 @@ function parseConfig(

ownConfig.options = assign(result.options, ownConfig.options);
ownConfig.watchOptions = ownConfig.watchOptions && result.watchOptions ?
assign(result.watchOptions, ownConfig.watchOptions) :
assignWatchOptions(result, ownConfig.watchOptions) :
ownConfig.watchOptions || result.watchOptions;
}
return ownConfig;
Expand Down Expand Up @@ -3355,11 +3356,17 @@ function parseConfig(
}
assign(result.options, extendedConfig.options);
result.watchOptions = result.watchOptions && extendedConfig.watchOptions ?
assign({}, result.watchOptions, extendedConfig.watchOptions) :
assignWatchOptions(result, extendedConfig.watchOptions) :
result.watchOptions || extendedConfig.watchOptions;
// TODO extend type typeAcquisition
}
}

function assignWatchOptions(result: ExtendsResult, watchOptions: WatchOptions) {
if (result.watchOptionsCopied) return assign(result.watchOptions!, watchOptions);
result.watchOptionsCopied = true;
return assign({}, result.watchOptions, watchOptions);
}
}

function parseOwnConfigOfJson(
Expand Down
34 changes: 21 additions & 13 deletions src/compiler/watchPublic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,11 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
let updateLevel: ProgramUpdateLevel; // level to indicate if the program needs to be reloaded from config file/just filenames etc
let missingFilesMap: Map<Path, FileWatcher>; // Map of file watchers for the missing files
let watchedWildcardDirectories: Map<string, WildcardDirectoryWatcher>; // map of watchers for the wild card directories in the config file
/**
* undefined - own watches are stale,
* path - for referenced project which need to be watched
*/
let staleWatches: Map<Path | undefined, string | undefined> | undefined = new Map([[undefined, undefined]]);
let timerToUpdateProgram: any; // timer callback to recompile the program
let timerToInvalidateFailedLookupResolutions: any; // timer callback to invalidate resolutions for changes in failed lookup locations
let parsedConfigs: Map<Path, ParsedConfig> | undefined; // Parsed commandline and watching cached for referenced projects
Expand Down Expand Up @@ -550,12 +555,6 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
builderProgram = readBuilderProgram(compilerOptions, compilerHost) as any as T;
synchronizeProgram();

// Update the wild card directory watch
watchConfigFileWildCardDirectories();

// Update extended config file watch
if (configFileName) updateExtendedConfigFilesWatches(toPath(configFileName), compilerOptions, watchOptions, WatchType.ExtendedConfigFile);

return configFileName ?
{ getCurrentProgram: getCurrentBuilderProgram, getProgram: updateProgram, close, getResolutionCache } :
{ getCurrentProgram: getCurrentBuilderProgram, getProgram: updateProgram, updateRootFileNames, close, getResolutionCache };
Expand Down Expand Up @@ -663,6 +662,20 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
compilerHost.createDirectory = originalCreateDirectory;
compilerHost.writeFile = originalWriteFile!;

staleWatches?.forEach((configFile, configPath) => {
if (!configPath) {
// Update the wild card directory watch
watchConfigFileWildCardDirectories();

// Update extended config file watch
if (configFileName) updateExtendedConfigFilesWatches(toPath(configFileName), compilerOptions, watchOptions, WatchType.ExtendedConfigFile);
}
else {
const config = parsedConfigs?.get(configPath);
if (config) watchReferencedProject(configFile!, configPath, config);
}
});
staleWatches = undefined;
return builderProgram;
}

Expand Down Expand Up @@ -930,13 +943,8 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
}
parseConfigFile();
hasChangedCompilerOptions = true;
(staleWatches ??= new Map()).set(undefined, undefined);
synchronizeProgram();

// Update the wild card directory watch
watchConfigFileWildCardDirectories();

// Update extended config file watch
updateExtendedConfigFilesWatches(toPath(configFileName), compilerOptions, watchOptions, WatchType.ExtendedConfigFile);
}

function parseConfigFile() {
Expand Down Expand Up @@ -996,7 +1004,7 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
else {
(parsedConfigs ||= new Map()).set(configPath, config = { parsedCommandLine });
}
watchReferencedProject(configFileName, configPath, config);
(staleWatches ??= new Map()).set(configPath, configFileName);
return parsedCommandLine;
}

Expand Down
37 changes: 37 additions & 0 deletions src/testRunner/unittests/tscWatch/projectsWithReferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,4 +405,41 @@ X;`,
],
baselineDependencies: true,
});

verifyTscWatch({
scenario: "projectsWithReferences",
subScenario: "watch options differing between projects",
sys: () =>
solutionBuildWithBaseline(
TestServerHost.createWatchedSystem({
"/user/username/workspace/project/tsconfig.base.json": jsonToReadableText({
watchOptions: {
excludeDirectories: ["**/node_modules"],
},
}),
"/user/username/workspace/project/tsconfig.A.json": jsonToReadableText({
extends: "./tsconfig.base.json",
compilerOptions: { composite: true },
include: ["src/a/**/*.ts"],
watchOptions: {
excludeDirectories: ["**/excludes_by_A"],
},
}),
"/user/username/workspace/project/src/a/a.ts": "export const a = 10;",
"/user/username/workspace/project/tsconfig.B.json": jsonToReadableText({
extends: "./tsconfig.base.json",
include: ["src/b/**/*.ts"],
references: [
{ path: "./tsconfig.A.json" },
],
}),
"/user/username/workspace/project/src/b/b.ts": "export const b = 10;",
}, {
currentDirectory: "/user/username/workspace/project",
useCaseSensitiveFileNames: false,
}),
["tsconfig.A.json"],
),
commandLineArgs: ["-w", "-p", "tsconfig.B.json", "--traceResolution", "--extendedDiagnostics"],
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,6 @@ CreatingProgramWith::
options: {"module":0,"composite":true,"watch":true,"project":"/user/username/projects/myproject/projects/project2/tsconfig.json","extendedDiagnostics":true,"configFilePath":"/user/username/projects/myproject/projects/project2/tsconfig.json"}
projectReferences: [{"path":"/user/username/projects/myproject/projects/project1","originalPath":"../project1"}]
Loading config file: /user/username/projects/myproject/projects/project1/tsconfig.json
FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/projects/project1/tsconfig.json 2000 undefined Config file of referened project
DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/projects/project1 1 undefined Wild card directory of referenced project
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/projects/project1 1 undefined Wild card directory of referenced project
FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/projects/project1/class1.d.ts 250 undefined Source file
FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/projects/project2/class2.ts 250 undefined Source file
FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.d.ts 250 undefined Source file
Expand All @@ -79,6 +76,9 @@ Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/node

DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/projects/project2 1 undefined Wild card directory
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/projects/project2 1 undefined Wild card directory
FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/projects/project1/tsconfig.json 2000 undefined Config file of referened project
DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/projects/project1 1 undefined Wild card directory of referenced project
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/projects/project1 1 undefined Wild card directory of referenced project


//// [/user/username/projects/myproject/projects/project2/class2.js]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
currentDirectory:: /user/username/workspace/project useCaseSensitiveFileNames:: false
Input::
//// [/user/username/workspace/project/tsconfig.base.json]
{
"watchOptions": {
"excludeDirectories": [
"**/node_modules"
]
}
}

//// [/user/username/workspace/project/tsconfig.A.json]
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"composite": true
},
"include": [
"src/a/**/*.ts"
],
"watchOptions": {
"excludeDirectories": [
"**/excludes_by_A"
]
}
}

//// [/user/username/workspace/project/src/a/a.ts]
export const a = 10;

//// [/user/username/workspace/project/tsconfig.B.json]
{
"extends": "./tsconfig.base.json",
"include": [
"src/b/**/*.ts"
],
"references": [
{
"path": "./tsconfig.A.json"
}
]
}

//// [/user/username/workspace/project/src/b/b.ts]
export const b = 10;

//// [/home/src/tslibs/TS/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; };

//// [/user/username/workspace/project/src/a/a.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.a = void 0;
exports.a = 10;


//// [/user/username/workspace/project/src/a/a.d.ts]
export declare const a = 10;


//// [/user/username/workspace/project/tsconfig.A.tsbuildinfo]
{"fileNames":["../../../../home/src/tslibs/ts/lib/lib.d.ts","./src/a/a.ts"],"fileInfos":[{"version":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true},{"version":"-14660415448-export const a = 10;","signature":"-3497920574-export declare const a = 10;\n"}],"root":[2],"options":{"composite":true},"latestChangedDtsFile":"./src/a/a.d.ts","version":"FakeTSVersion"}

//// [/user/username/workspace/project/tsconfig.A.tsbuildinfo.readable.baseline.txt]
{
"fileNames": [
"../../../../home/src/tslibs/ts/lib/lib.d.ts",
"./src/a/a.ts"
],
"fileInfos": {
"../../../../home/src/tslibs/ts/lib/lib.d.ts": {
"original": {
"version": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
"affectsGlobalScope": true
},
"version": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
"signature": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
"affectsGlobalScope": true
},
"./src/a/a.ts": {
"original": {
"version": "-14660415448-export const a = 10;",
"signature": "-3497920574-export declare const a = 10;\n"
},
"version": "-14660415448-export const a = 10;",
"signature": "-3497920574-export declare const a = 10;\n"
}
},
"root": [
[
2,
"./src/a/a.ts"
]
],
"options": {
"composite": true
},
"latestChangedDtsFile": "./src/a/a.d.ts",
"version": "FakeTSVersion",
"size": 780
}


/home/src/tslibs/TS/Lib/tsc.js -w -p tsconfig.B.json --traceResolution --extendedDiagnostics
Output::
[HH:MM:SS AM] Starting compilation in watch mode...

Current directory: /user/username/workspace/project CaseSensitiveFileNames: false
FileWatcher:: Added:: WatchInfo: /user/username/workspace/project/tsconfig.B.json 2000 {"excludeDirectories":["/user/username/workspace/project/**/node_modules"]} Config file
Synchronizing program
CreatingProgramWith::
roots: ["/user/username/workspace/project/src/b/b.ts"]
options: {"watch":true,"project":"/user/username/workspace/project/tsconfig.B.json","traceResolution":true,"extendedDiagnostics":true,"configFilePath":"/user/username/workspace/project/tsconfig.B.json"}
projectReferences: [{"path":"/user/username/workspace/project/tsconfig.A.json","originalPath":"./tsconfig.A.json"}]
Loading config file: /user/username/workspace/project/tsconfig.A.json
FileWatcher:: Added:: WatchInfo: /user/username/workspace/project/src/b/b.ts 250 {"excludeDirectories":["/user/username/workspace/project/**/node_modules"]} Source file
FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.d.ts 250 {"excludeDirectories":["/user/username/workspace/project/**/node_modules"]} Source file
ExcludeWatcher:: Added:: WatchInfo: /user/username/workspace/project/node_modules/@types 1 {"excludeDirectories":["/user/username/workspace/project/**/node_modules"]} Type roots
DirectoryWatcher:: Added:: WatchInfo: /user/username/workspace/node_modules/@types 1 {"excludeDirectories":["/user/username/workspace/project/**/node_modules"]} Type roots
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/workspace/node_modules/@types 1 {"excludeDirectories":["/user/username/workspace/project/**/node_modules"]} Type roots
[HH:MM:SS AM] Found 0 errors. Watching for file changes.

DirectoryWatcher:: Added:: WatchInfo: /user/username/workspace/project/src/b 1 {"excludeDirectories":["/user/username/workspace/project/**/node_modules"]} Wild card directory
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/workspace/project/src/b 1 {"excludeDirectories":["/user/username/workspace/project/**/node_modules"]} Wild card directory
FileWatcher:: Added:: WatchInfo: /user/username/workspace/project/tsconfig.base.json 2000 {"excludeDirectories":["/user/username/workspace/project/**/node_modules"]} Extended config file
FileWatcher:: Added:: WatchInfo: /user/username/workspace/project/tsconfig.A.json 2000 {"excludeDirectories":["/user/username/workspace/project/**/excludes_by_A"]} Config file of referened project
DirectoryWatcher:: Added:: WatchInfo: /user/username/workspace/project/src/a 1 {"excludeDirectories":["/user/username/workspace/project/**/excludes_by_A"]} Wild card directory of referenced project
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/workspace/project/src/a 1 {"excludeDirectories":["/user/username/workspace/project/**/excludes_by_A"]} Wild card directory of referenced project


//// [/user/username/workspace/project/src/b/b.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.b = void 0;
exports.b = 10;



PolledWatches::
/user/username/workspace/node_modules/@types: *new*
{"pollingInterval":500}

FsWatches::
/home/src/tslibs/TS/Lib/lib.d.ts: *new*
{}
/user/username/workspace/project/src/b/b.ts: *new*
{}
/user/username/workspace/project/tsconfig.A.json: *new*
{}
/user/username/workspace/project/tsconfig.B.json: *new*
{}
/user/username/workspace/project/tsconfig.base.json: *new*
{}

FsWatchesRecursive::
/user/username/workspace/project/src/a: *new*
{}
/user/username/workspace/project/src/b: *new*
{}

Program root files: [
"/user/username/workspace/project/src/b/b.ts"
]
Program options: {
"watch": true,
"project": "/user/username/workspace/project/tsconfig.B.json",
"traceResolution": true,
"extendedDiagnostics": true,
"configFilePath": "/user/username/workspace/project/tsconfig.B.json"
}
Program structureReused: Not
Program files::
/home/src/tslibs/TS/Lib/lib.d.ts
/user/username/workspace/project/src/b/b.ts

Semantic diagnostics in builder refreshed for::
/home/src/tslibs/TS/Lib/lib.d.ts
/user/username/workspace/project/src/b/b.ts

Shape signatures in builder refreshed for::
/home/src/tslibs/ts/lib/lib.d.ts (used version)
/user/username/workspace/project/src/b/b.ts (used version)

exitCode:: ExitStatus.undefined
Loading