Skip to content

Commit

Permalink
Fix the incorrect copy over for watchOptions and fix order of watches…
Browse files Browse the repository at this point in the history
… for referenced projects (#59871)
  • Loading branch information
sheetalkamat authored Sep 5, 2024
1 parent 87d0e77 commit d514dab
Show file tree
Hide file tree
Showing 9 changed files with 275 additions and 27 deletions.
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

0 comments on commit d514dab

Please sign in to comment.