Skip to content

Commit 0e3a48d

Browse files
committed
Filter out more paths that should not be watched irrespective of the root
1 parent 2ba4a12 commit 0e3a48d

File tree

506 files changed

+2157
-20820
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

506 files changed

+2157
-20820
lines changed

src/compiler/resolutionCache.ts

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,30 @@ export function removeIgnoredPath(path: Path): Path | undefined {
206206
path;
207207
}
208208

209+
function perceivedOsRootLengthForWatching(pathComponents: Readonly<PathPathComponents>) {
210+
// Ignore "/", "c:/"
211+
if (pathComponents.length <= 1) return 1;
212+
let userCheckIndex = 1;
213+
let isDosStyle = pathComponents[0].search(/[a-zA-Z]:/) === 0;
214+
if (pathComponents[0] !== directorySeparator &&
215+
!isDosStyle && // Non dos style paths
216+
pathComponents[1].search(/[a-zA-Z]\$$/) === 0) { // Dos style nextPart
217+
// ignore "//vda1cs4850/c$/folderAtRoot"
218+
if (pathComponents.length === 2) return 2;
219+
userCheckIndex = 2;
220+
isDosStyle = true;
221+
}
222+
223+
if (isDosStyle &&
224+
!pathComponents[userCheckIndex].match(/^users$/i)) {
225+
// Paths like c:/notUsers
226+
return userCheckIndex;
227+
}
228+
229+
// Paths like: c:/users/username or /home/username
230+
return userCheckIndex + 2;
231+
}
232+
209233
/**
210234
* Filter out paths like
211235
* "/", "/user", "/user/username", "/user/username/folderAtRoot",
@@ -218,29 +242,14 @@ export function canWatchDirectoryOrFile(pathComponents: Readonly<PathPathCompone
218242
// Ignore "/", "c:/"
219243
// ignore "/user", "c:/users" or "c:/folderAtRoot"
220244
if (pathComponents.length <= 2) return false;
221-
let userCheckIndex = 1;
222-
const isNonDirectorySeparatorRoot = pathComponents[0] !== "/";
223-
if (isNonDirectorySeparatorRoot &&
224-
pathComponents[0].search(/[a-zA-Z]:/) !== 0 && // Non dos style paths
225-
pathComponents[1].search(/[a-zA-Z]\$$/) === 0) { // Dos style nextPart
226-
// ignore "//vda1cs4850/c$/folderAtRoot"
227-
if (pathComponents.length === 3) return false;
228-
userCheckIndex = 2;
229-
}
230-
231-
if (isNonDirectorySeparatorRoot &&
232-
!pathComponents[userCheckIndex].match(/^users$/i)) {
233-
// Paths like c:/folderAtRoot/subFolder are allowed
234-
return true;
235-
}
236-
237-
return pathComponents.length > userCheckIndex + 3;
245+
const perceivedOsRootLength = perceivedOsRootLengthForWatching(pathComponents);
246+
return pathComponents.length > perceivedOsRootLength + 1;
238247
}
239248

240249
/** @internal */
241-
export function canWatchAtTypes(atTypes: Path, rootPathComponents: Readonly<PathPathComponents>) {
250+
export function canWatchAtTypes(atTypes: Path) {
242251
// Otherwise can watch directory only if we can watch the parent directory of node_modules/@types
243-
return isInRootPathOrCanWatchDirectoryOrFile(getDirectoryPath(atTypes), rootPathComponents);
252+
return canWatchAffectedPackageJsonOrNodeModulesOfAtTypes(getDirectoryPath(atTypes));
244253
}
245254

246255
function isInDirectoryPath(dirComponents: Readonly<PathPathComponents>, fileOrDirComponents: Readonly<PathPathComponents>) {
@@ -251,15 +260,14 @@ function isInDirectoryPath(dirComponents: Readonly<PathPathComponents>, fileOrDi
251260
return true;
252261
}
253262

254-
function isInRootPathOrCanWatchDirectoryOrFile(fileOrDirPath: Path, rootPathComponents: Readonly<PathPathComponents>) {
263+
function canWatchAffectedPackageJsonOrNodeModulesOfAtTypes(fileOrDirPath: Path) {
255264
const fileOrDirPathComponents = getPathComponents(fileOrDirPath);
256-
return isInDirectoryPath(rootPathComponents, fileOrDirPathComponents) ||
257-
canWatchDirectoryOrFile(fileOrDirPathComponents);
265+
return fileOrDirPathComponents.length > perceivedOsRootLengthForWatching(fileOrDirPathComponents) + 1;
258266
}
259267

260268
/** @internal */
261-
export function canWatchAffectingLocation(filePath: Path, rootPathComponents: Readonly<PathPathComponents>) {
262-
return isInRootPathOrCanWatchDirectoryOrFile(filePath, rootPathComponents);
269+
export function canWatchAffectingLocation(filePath: Path) {
270+
return canWatchAffectedPackageJsonOrNodeModulesOfAtTypes(filePath);
263271
}
264272

265273
/** @internal */
@@ -351,6 +359,7 @@ export function getDirectoryToWatchFailedLookupLocationFromTypeRoot(
351359
): Path | undefined {
352360
const typeRootPathComponents = getPathComponents(typeRootPath);
353361
if (isInDirectoryPath(rootPathComponents, typeRootPathComponents)) {
362+
// Because this is called when we are watching typeRoot, we dont need additional check whether typeRoot is not say c:/users/node_modules/@types when root is c:/
354363
return rootPath;
355364
}
356365
typeRoot = isRootedDiskPath(typeRoot) ? normalizePath(typeRoot) : getNormalizedAbsolutePath(typeRoot, getCurrentDirectory());
@@ -903,7 +912,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
903912
}
904913
const paths = new Set<string>();
905914
paths.add(locationToWatch);
906-
let actualWatcher = canWatchAffectingLocation(resolutionHost.toPath(locationToWatch), rootPathComponents) ?
915+
let actualWatcher = canWatchAffectingLocation(resolutionHost.toPath(locationToWatch)) ?
907916
resolutionHost.watchAffectingFileLocation(locationToWatch, (fileName, eventKind) => {
908917
cachedDirectoryStructureHost?.addOrDeleteFile(fileName, resolutionHost.toPath(locationToWatch), eventKind);
909918
const packageJsonMap = moduleResolutionCache.getPackageJsonInfoCache().getInternalMap();
@@ -1258,7 +1267,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
12581267
if (resolutionHost.getCompilationSettings().typeRoots) return true;
12591268

12601269
// Otherwise can watch directory only if we can watch the parent directory of node_modules/@types
1261-
return canWatchAtTypes(resolutionHost.toPath(typeRoot), rootPathComponents);
1270+
return canWatchAtTypes(resolutionHost.toPath(typeRoot));
12621271
}
12631272
}
12641273

src/testRunner/unittests/canWatch.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,12 @@ describe("unittests:: canWatch::", () => {
2525
(paths, longestPathLength, baseline) => {
2626
const testType = "canWatchAtTypes";
2727
const maxLengths = [longestPathLength + "/node_modules/@types".length, testType.length] as const;
28-
baselineCanWatchForRoot(paths, baseline, rootPathCompoments => {
29-
pushHeader(baseline, ["Directory", testType], maxLengths);
30-
paths.forEach(path => {
31-
path = combinePaths(path, "node_modules/@types");
32-
pushRow(baseline, [path, `${ts.canWatchAtTypes(path, rootPathCompoments)}`], maxLengths);
33-
});
28+
pushHeader(baseline, ["Directory", testType], maxLengths);
29+
paths.forEach(path => {
30+
path = combinePaths(path, "node_modules/@types");
31+
pushRow(baseline, [path, `${ts.canWatchAtTypes(path)}`], maxLengths);
3432
});
33+
baseline.push("", "");
3534
},
3635
);
3736

@@ -41,13 +40,12 @@ describe("unittests:: canWatch::", () => {
4140
(paths, longestPathLength, baseline) => {
4241
const testType = "canWatchAffectingLocation";
4342
const maxLengths = [longestPathLength + "/package.json".length, testType.length] as const;
44-
baselineCanWatchForRoot(paths, baseline, rootPathCompoments => {
45-
pushHeader(baseline, ["File", testType], maxLengths);
46-
paths.forEach(path => {
47-
path = combinePaths(path, "package.json");
48-
pushRow(baseline, [path, `${ts.canWatchAffectingLocation(path, rootPathCompoments)}`], maxLengths);
49-
});
43+
pushHeader(baseline, ["File", testType], maxLengths);
44+
paths.forEach(path => {
45+
path = combinePaths(path, "package.json");
46+
pushRow(baseline, [path, `${ts.canWatchAffectingLocation(path)}`], maxLengths);
5047
});
48+
baseline.push("", "");
5149
},
5250
);
5351

@@ -99,7 +97,7 @@ describe("unittests:: canWatch::", () => {
9997
paths.forEach(path => {
10098
path = combinePaths(path, "node_modules/@types");
10199
// This is invoked only on paths that are watched
102-
if (!ts.canWatchAtTypes(path, rootPathCompoments)) return;
100+
if (!ts.canWatchAtTypes(path)) return;
103101
const result = ts.getDirectoryToWatchFailedLookupLocationFromTypeRoot(
104102
path,
105103
path,

src/testRunner/unittests/tscWatch/resolutionCache.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -227,25 +227,25 @@ describe("unittests:: tsc-watch:: resolutionCache:: tsc-watch module resolution
227227
verifyTscWatch({
228228
scenario,
229229
subScenario: "works when module resolution changes to ambient module",
230-
commandLineArgs: ["-w", "/a/b/foo.ts"],
230+
commandLineArgs: ["-w", "/users/username/projects/project/foo.ts"],
231231
sys: () => createWatchedSystem([{
232-
path: "/a/b/foo.ts",
232+
path: "/users/username/projects/project/foo.ts",
233233
content: `import * as fs from "fs";`
234-
}, libFile], { currentDirectory: "/a/b" }),
234+
}, libFile], { currentDirectory: "/users/username/projects/project" }),
235235
edits: [
236236
{
237237
caption: "npm install node types",
238238
edit: sys => {
239239
sys.ensureFileOrFolder({
240-
path: "/a/b/node_modules/@types/node/package.json",
240+
path: "/users/username/projects/project/node_modules/@types/node/package.json",
241241
content: `
242242
{
243243
"main": ""
244244
}
245245
`
246246
});
247247
sys.ensureFileOrFolder({
248-
path: "/a/b/node_modules/@types/node/index.d.ts",
248+
path: "/users/username/projects/project/node_modules/@types/node/index.d.ts",
249249
content: `
250250
declare module "fs" {
251251
export interface Stats {

src/testRunner/unittests/tsserver/resolutionCache.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,19 @@ describe("unittests:: tsserver:: resolutionCache:: tsserverProjectSystem extra r
4848
describe("unittests:: tsserver:: resolutionCache:: tsserverProjectSystem watching @types", () => {
4949
it("works correctly when typings are added or removed", () => {
5050
const f1 = {
51-
path: "/a/b/app.ts",
51+
path: "/users/username/projects/project/app.ts",
5252
content: "let x = 1;"
5353
};
5454
const t1 = {
55-
path: "/a/b/node_modules/@types/lib1/index.d.ts",
55+
path: "/users/username/projects/project/node_modules/@types/lib1/index.d.ts",
5656
content: "export let a: number"
5757
};
5858
const t2 = {
59-
path: "/a/b/node_modules/@types/lib2/index.d.ts",
59+
path: "/users/username/projects/project/node_modules/@types/lib2/index.d.ts",
6060
content: "export let b: number"
6161
};
6262
const tsconfig = {
63-
path: "/a/b/tsconfig.json",
63+
path: "/users/username/projects/project/tsconfig.json",
6464
content: JSON.stringify({
6565
compilerOptions: {},
6666
exclude: ["node_modules"]

0 commit comments

Comments
 (0)