Skip to content
Open
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
31 changes: 22 additions & 9 deletions src/compiler/resolutionCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,9 @@ export interface ResolutionCacheHost extends MinimalResolutionCacheHost {
fileIsOpen(filePath: Path): boolean;
onDiscoveredSymlink?(): void;

skipWatchingFailedLookups?(path: Path): boolean | undefined;
skipWatchingTypeRoots?(): boolean | undefined;

// For incremental testing
beforeResolveSingleModuleNameWithoutWatching?(
moduleResolutionCache: ModuleResolutionCache,
Expand Down Expand Up @@ -895,7 +898,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
resolutionHost.onDiscoveredSymlink();
}
resolutionsInFile.set(name, mode, resolution);
if (resolution !== existingResolution) {
if (resolution !== existingResolution && !resolutionHost.skipWatchingFailedLookups?.(path)) {
watchFailedLookupLocationsOfExternalModuleResolutions(name, resolution, path, getResolutionWithResolvedFileName, deferWatchingNonRelativeResolution);
if (existingResolution) {
stopWatchFailedLookupLocationOfResolution(existingResolution, path, getResolutionWithResolvedFileName);
Expand Down Expand Up @@ -947,7 +950,9 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
// Stop watching and remove the unused name
resolutionsInFile.forEach((resolution, name, mode) => {
if (!seenNamesInFile.has(name, mode)) {
stopWatchFailedLookupLocationOfResolution(resolution, path, getResolutionWithResolvedFileName);
if (!resolutionHost.skipWatchingFailedLookups?.(path)) {
stopWatchFailedLookupLocationOfResolution(resolution, path, getResolutionWithResolvedFileName);
}
resolutionsInFile.delete(name, mode);
}
});
Expand Down Expand Up @@ -1434,13 +1439,15 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
// Deleted file, stop watching failed lookups for all the resolutions in the file
const resolutions = cache.get(filePath);
if (resolutions) {
resolutions.forEach(resolution =>
stopWatchFailedLookupLocationOfResolution(
resolution,
filePath,
getResolutionWithResolvedFileName,
)
);
if (!resolutionHost.skipWatchingFailedLookups?.(filePath)) {
resolutions.forEach(resolution =>
stopWatchFailedLookupLocationOfResolution(
resolution,
filePath,
getResolutionWithResolvedFileName,
)
);
}
cache.delete(filePath);
}
}
Expand Down Expand Up @@ -1667,6 +1674,12 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
return;
}

// if this is inferred project with non watchable root or current directory that is lib location, skip watching type roots
if (!isRootWatchable || resolutionHost.skipWatchingTypeRoots?.()) {
closeTypeRootsWatch();
return;
}

// we need to assume the directories exist to ensure that we can get all the type root directories that get included
// But filter directories that are at root level to say directory doesnt exist, so that we arent watching them
const typeRoots = getEffectiveTypeRoots(options, { getCurrentDirectory });
Expand Down
16 changes: 11 additions & 5 deletions src/harness/incrementalUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ interface ResolutionInfo {
fileName: string;
name: string;
mode: ts.ResolutionMode;
watched: boolean;
}

function getResolutionCacheDetails<File, T extends ts.ResolutionWithFailedLookupLocations>(
Expand Down Expand Up @@ -254,8 +255,8 @@ export function verifyResolutionCache(
// Verify ref count
resolutionToRefs.forEach((info, resolution) => {
ts.Debug.assert(
resolution.files?.size === info.length,
`${projectName}:: Expected Resolution ref count ${info.length} but got ${resolution.files?.size}`,
(resolution.files?.size ?? 0) === info.filter(i => i.watched).length,
`${projectName}:: Expected Resolution ref count ${info.filter(i => i.watched).length} but got ${resolution.files?.size}`,
() =>
`Expected from:: ${JSON.stringify(info, undefined, " ")}` +
`Actual from: ${resolution.files?.size}`,
Expand Down Expand Up @@ -317,12 +318,13 @@ export function verifyResolutionCache(
): ExpectedResolution {
const existing = resolutionToRefs.get(resolved);
let expectedResolution: ExpectedResolution;
const watched = !resolutionHostCacheHost.skipWatchingFailedLookups?.(fileName);
if (existing) {
existing.push({ cacheType, fileName, name, mode });
existing.push({ cacheType, fileName, name, mode, watched });
expectedResolution = resolutionToExpected.get(resolved)!;
}
else {
resolutionToRefs.set(resolved, [{ cacheType, fileName, name, mode }]);
resolutionToRefs.set(resolved, [{ cacheType, fileName, name, mode, watched }]);
expectedResolution = {
resolvedModule: (resolved as any).resolvedModule,
resolvedTypeReferenceDirective: (resolved as any).resolvedTypeReferenceDirective,
Expand All @@ -333,7 +335,9 @@ export function verifyResolutionCache(
expectedToResolution.set(expectedResolution, resolved);
resolutionToExpected.set(resolved, expectedResolution);
}
expected.watchFailedLookupLocationsOfExternalModuleResolutions(name, expectedResolution, fileName, () => ({ resolvedFileName }), deferWatchingNonRelativeResolution);
if (watched) {
expected.watchFailedLookupLocationsOfExternalModuleResolutions(name, expectedResolution, fileName, () => ({ resolvedFileName }), deferWatchingNonRelativeResolution);
}
return expectedResolution;
}

Expand Down Expand Up @@ -527,6 +531,8 @@ function verifyProgram(service: ts.server.ProjectService, project: ts.server.Pro
getGlobalTypingsCacheLocation: project.getGlobalTypingsCacheLocation.bind(project),
globalCacheResolutionModuleName: project.globalCacheResolutionModuleName.bind(project),
fileIsOpen: project.fileIsOpen.bind(project),
skipWatchingFailedLookups: project.skipWatchingFailedLookups.bind(project),
skipWatchingTypeRoots: project.skipWatchingTypeRoots.bind(project),
getCurrentProgram: () => project.getCurrentProgram(),

preferNonRecursiveWatch: project.preferNonRecursiveWatch,
Expand Down
21 changes: 21 additions & 0 deletions src/server/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1530,6 +1530,15 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo

/** @internal */
watchTypingLocations(files: readonly string[] | undefined): void {
// Skip watching typing locations for inferred project whose currentDirectory is not watchable or
// is same as server's current directory
if (
this.currentDirectory === this.projectService.currentDirectory ||
!canWatchDirectoryOrFilePath(this.toPath(this.currentDirectory))
) {
return;
}

if (!files) {
this.typingWatchers!.isInvoked = false;
return;
Expand Down Expand Up @@ -1626,6 +1635,18 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
});
}

/** @internal */
skipWatchingFailedLookups(path: Path): boolean | undefined {
const info = this.projectService.getScriptInfoForPath(path);
return info?.isDynamic;
}

/** @internal */
skipWatchingTypeRoots(): boolean | undefined {
// Skip watching inferrd project where current directory is lib location
return isInferredProject(this) && this.currentDirectory === this.projectService.currentDirectory;
}

/** @internal */
getCurrentProgram(): Program | undefined {
return this.program;
Expand Down
23 changes: 23 additions & 0 deletions src/testRunner/unittests/tsserver/dynamicFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,4 +270,27 @@ describe("unittests:: tsserver:: dynamicFiles:: ", () => {
verifyPathRecognizedAsDynamic("walkThroughSnippet", "walkThroughSnippet:/usr/share/code/resources/app/out/vs/workbench/contrib/welcome/walkThrough/browser/editor/^vs_code_editor_walkthrough.md#1.ts");
verifyPathRecognizedAsDynamic("untitled", "untitled:/Users/matb/projects/san/^newFile.ts");
});

it("chat block with imports", () => {
const host = TestServerHost.createServerHost({
"/user/username/projects/myproject/a.ts": "",
"/user/username/projects/myproject/tsconfig.json": "{}",
});
const session = new TestSession({ host, useInferredProjectPerProjectRoot: true });
openFilesForSession([{ file: "/user/username/projects/myproject/a.ts", projectRootPath: "/user/username/projects/myproject" }], session);
// Without projectRoot
openFilesForSession([{
file: "^/chat-editing-snapshot-text-model/ts-nul-authority/c/temp/codeRepo/src/services/user.service.ts",
content: "",
scriptKindName: "TS",
}], session);
// with "/" as project root
openFilesForSession([{
file: '^/vscode-chat-code-block/dnnjb2rllwnoyxqtc2vzc2lvbjovl2xvy2fsl1peag1oelv6tkdvde9uvtvnuzawtxpbnuxxstrare10tvrobfpuvtbpvgmytudwaq/response_6b1244f1-9aca-4b8b-8f65-0ff7ed4e6b4e/2#{"references":[]}',
content: `import { UserService from './src/services/user.service';}`,
projectRootPath: "/",
scriptKindName: "TS",
}], session);
baselineTsserverLogs("dynamicFiles", "chat block with imports", session);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -271,12 +271,6 @@ Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Li
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/tsconfig.json 2000 undefined WatchType: Config file for the inferred project root
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/jsconfig.json 2000 undefined WatchType: Config file for the inferred project root
Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /dev/null/inferredProject1*
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/Vscode/Projects/bin/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/Vscode/Projects/bin/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/Vscode/Projects/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/Vscode/Projects/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/Vscode/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/Vscode/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots
Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /dev/null/inferredProject1* projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms
Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred)
Info seq [hh:mm:ss:mss] Files (1)
Expand All @@ -291,12 +285,6 @@ Info seq [hh:mm:ss:mss] -----------------------------------------------
TI:: Creating typing installer

PolledWatches::
/home/src/Vscode/Projects/bin/node_modules/@types: *new*
{"pollingInterval":500}
/home/src/Vscode/Projects/node_modules/@types: *new*
{"pollingInterval":500}
/home/src/Vscode/node_modules/@types: *new*
{"pollingInterval":500}
/home/src/tslibs/TS/Lib/jsconfig.json: *new*
{"pollingInterval":2000}
/home/src/tslibs/TS/Lib/tsconfig.json: *new*
Expand Down Expand Up @@ -404,10 +392,6 @@ TI:: [hh:mm:ss:mss] Sending response:
"/home/src/Vscode/Projects/bin/node_modules"
]
}
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/Vscode/Projects/bin/bower_components 1 undefined Project: /dev/null/inferredProject1* WatchType: Directory location for typing installer
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/Vscode/Projects/bin/bower_components 1 undefined Project: /dev/null/inferredProject1* WatchType: Directory location for typing installer
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/Vscode/Projects/bin/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Directory location for typing installer
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/Vscode/Projects/bin/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Directory location for typing installer
TI:: [hh:mm:ss:mss] Sending response:
{
"projectName": "/dev/null/inferredProject1*",
Expand Down Expand Up @@ -493,16 +477,6 @@ Info seq [hh:mm:ss:mss] response:
After request

PolledWatches::
/home/src/Vscode/Projects/bin/bower_components: *new*
{"pollingInterval":500}
/home/src/Vscode/Projects/bin/node_modules: *new*
{"pollingInterval":500}
/home/src/Vscode/Projects/bin/node_modules/@types:
{"pollingInterval":500}
/home/src/Vscode/Projects/node_modules/@types:
{"pollingInterval":500}
/home/src/Vscode/node_modules/@types:
{"pollingInterval":500}
/home/src/tslibs/TS/Lib/jsconfig.json:
{"pollingInterval":2000}
/home/src/tslibs/TS/Lib/tsconfig.json:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,6 @@ Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: ^/inmemory/model/6 Pro
Info seq [hh:mm:ss:mss] Creating InferredProject: /dev/null/inferredProject1*, currentDirectory: /users/user/projects/san
Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /dev/null/inferredProject1*
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.d.ts 500 undefined WatchType: Closed Script info
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /users/user/projects/san/^ 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /users/user/projects/san/^ 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /users/user/projects 0 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /users/user/projects 0 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /users/user/projects/san/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /users/user/projects/san/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /users/user/projects/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /users/user/projects/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /users/user/projects/san 0 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /users/user/projects/san 0 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /users/user/projects/san/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /users/user/projects/san/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /users/user/projects/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots
Expand Down Expand Up @@ -82,18 +72,8 @@ Info seq [hh:mm:ss:mss] response:
After request

PolledWatches::
/users/user/projects: *new*
{"pollingInterval":500}
/users/user/projects/node_modules: *new*
{"pollingInterval":500}
/users/user/projects/node_modules/@types: *new*
{"pollingInterval":500}
/users/user/projects/san: *new*
{"pollingInterval":500}
/users/user/projects/san/^: *new*
{"pollingInterval":500}
/users/user/projects/san/node_modules: *new*
{"pollingInterval":500}
/users/user/projects/san/node_modules/@types: *new*
{"pollingInterval":500}

Expand Down
Loading