mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Always update LS state through Project (#56356)
Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com>
This commit is contained in:
co-authored by
Daniel Rosenwasser
parent
80ab111685
commit
ca7a3af5e6
+11
-1
@@ -1330,6 +1330,14 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
|
||||
this.hasAddedOrRemovedSymlinks = true;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
updateFromProjectInProgress = false;
|
||||
|
||||
/** @internal */
|
||||
updateFromProject() {
|
||||
updateProjectIfDirty(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates set of files that contribute to this project
|
||||
* @returns: true if set of files in the project stays the same and false - otherwise.
|
||||
@@ -1523,8 +1531,10 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
|
||||
this.hasInvalidatedResolutions = hasInvalidatedResolutions;
|
||||
this.hasInvalidatedLibResolutions = hasInvalidatedLibResolutions;
|
||||
this.resolutionCache.startCachingPerDirectoryResolution();
|
||||
this.program = this.languageService.getProgram(); // TODO: GH#18217
|
||||
this.dirty = false;
|
||||
this.updateFromProjectInProgress = true;
|
||||
this.program = this.languageService.getProgram(); // TODO: GH#18217
|
||||
this.updateFromProjectInProgress = false;
|
||||
tracing?.push(tracing.Phase.Session, "finishCachingPerDirectoryResolution");
|
||||
this.resolutionCache.finishCachingPerDirectoryResolution(this.program, oldProgram);
|
||||
tracing?.pop();
|
||||
|
||||
@@ -1620,6 +1620,15 @@ export function createLanguageService(
|
||||
}
|
||||
|
||||
function synchronizeHostData(): void {
|
||||
if (host.updateFromProject && !host.updateFromProjectInProgress) {
|
||||
host.updateFromProject();
|
||||
}
|
||||
else {
|
||||
synchronizeHostDataWorker();
|
||||
}
|
||||
}
|
||||
|
||||
function synchronizeHostDataWorker(): void {
|
||||
Debug.assert(languageServiceMode !== LanguageServiceMode.Syntactic);
|
||||
// perform fast check if host supports it
|
||||
if (host.getProjectVersion) {
|
||||
|
||||
@@ -316,6 +316,9 @@ export interface IncompleteCompletionsCache {
|
||||
export interface LanguageServiceHost extends GetEffectiveTypeRootsHost, MinimalResolutionCacheHost {
|
||||
getCompilationSettings(): CompilerOptions;
|
||||
getNewLine?(): string;
|
||||
/** @internal */ updateFromProject?(): void;
|
||||
/** @internal */ updateFromProjectInProgress?: boolean;
|
||||
|
||||
getProjectVersion?(): string;
|
||||
getScriptFileNames(): string[];
|
||||
getScriptKind?(fileName: string): ScriptKind;
|
||||
|
||||
@@ -28,6 +28,8 @@ describe("unittests:: tsserver:: plugins:: loading", () => {
|
||||
create(info: ts.server.PluginCreateInfo) {
|
||||
info.session?.addProtocolHandler(testProtocolCommand, request => {
|
||||
session.logger.log(`addProtocolHandler: ${jsonToReadableText(request)}`);
|
||||
// Assume this one needs program
|
||||
info.languageService.getProgram();
|
||||
return {
|
||||
response: testProtocolCommandResponse,
|
||||
};
|
||||
@@ -101,6 +103,41 @@ describe("unittests:: tsserver:: plugins:: loading", () => {
|
||||
baselineTsserverLogs("plugins", "With session and custom protocol message", session);
|
||||
});
|
||||
|
||||
it("when plugins use LS to get program and update is pending", () => {
|
||||
const pluginName = "some-plugin";
|
||||
const aTs: File = {
|
||||
path: "/user/username/projects/project/a.ts",
|
||||
content: `/// <reference path="./b.ts"/>`,
|
||||
};
|
||||
const tsconfig: File = {
|
||||
path: "/user/username/projects/project/tsconfig.json",
|
||||
content: jsonToReadableText({
|
||||
compilerOptions: {
|
||||
plugins: [
|
||||
{ name: pluginName },
|
||||
],
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
const { session, host } = createHostWithPlugin([aTs, tsconfig, libFile]);
|
||||
|
||||
openFilesForSession([aTs], session);
|
||||
// Write the missing file (referenced by 'a.ts') to schedule an update.
|
||||
host.writeFile("/user/username/projects/project/b.ts", "const y = 10;");
|
||||
|
||||
// This should update the language service with a new program.
|
||||
session.executeCommandSeq({
|
||||
command: testProtocolCommand,
|
||||
arguments: testProtocolCommandRequest,
|
||||
});
|
||||
|
||||
// This results in a program update.
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
baselineTsserverLogs("plugins", "when plugins use LS to get program and update is pending", session);
|
||||
});
|
||||
|
||||
it("gets external files with config file reload", () => {
|
||||
const aTs: File = { path: `/user/username/projects/myproject/a.ts`, content: `export const x = 10;` };
|
||||
const tsconfig: File = {
|
||||
|
||||
Reference in New Issue
Block a user