Skip to content

Commit

Permalink
Plugins in project were adding up after every config file reload (#51087
Browse files Browse the repository at this point in the history
)

* Add test where current plugins dont get reset when reloading config file

* Reset loaded plugins when reloading configured project and closing project
  • Loading branch information
sheetalkamat committed Oct 6, 2022
1 parent c18791c commit 2648f6a
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 2 deletions.
5 changes: 4 additions & 1 deletion src/server/project.ts
Expand Up @@ -143,7 +143,8 @@ namespace ts.server {
private missingFilesMap: ESMap<Path, FileWatcher> | undefined;
private generatedFilesMap: GeneratedFileWatcherMap | undefined;

private plugins: PluginModuleWithName[] = [];
/*@internal*/
protected readonly plugins: PluginModuleWithName[] = [];

/*@internal*/
/**
Expand Down Expand Up @@ -845,6 +846,7 @@ namespace ts.server {
this.directoryStructureHost = undefined!;
this.exportMapCache = undefined;
this.projectErrors = undefined;
this.plugins.length = 0;

// Clean up file watchers waiting for missing files
if (this.missingFilesMap) {
Expand Down Expand Up @@ -2520,6 +2522,7 @@ namespace ts.server {

/*@internal*/
enablePluginsWithOptions(options: CompilerOptions, pluginConfigOverrides: ESMap<string, any> | undefined): void {
this.plugins.length = 0;
if (!options.plugins?.length && !this.projectService.globalPlugins.length) return;
const host = this.projectService.host;
if (!host.require && !host.importPlugin) {
Expand Down
45 changes: 45 additions & 0 deletions src/testRunner/unittests/tsserver/plugins.ts
Expand Up @@ -100,5 +100,50 @@ namespace ts.projectSystem {
};
assert.deepEqual(resp, expectedResp);
});

it("gets external files with config file reload", () => {
const aTs: File = { path: `${tscWatch.projectRoot}/a.ts`, content: `export const x = 10;` };
const tsconfig: File = {
path: `${tscWatch.projectRoot}/tsconfig.json`,
content: JSON.stringify({
compilerOptions: {
plugins: [{ name: "some-plugin" }]
}
})
};

const externalFiles: MapLike<string[]> = {
"some-plugin": ["someFile.txt"],
"some-other-plugin": ["someOtherFile.txt"],
};

const host = createServerHost([aTs, tsconfig, libFile]);
host.require = (_initialPath, moduleName) => {
session.logger.logs.push(`Require:: ${moduleName}`);
return {
module: (): server.PluginModule => {
session.logger.logs.push(`PluginFactory Invoke`);
return {
create: Harness.LanguageService.makeDefaultProxy,
getExternalFiles: () => externalFiles[moduleName]
};
},
error: undefined
};
};
const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
openFilesForSession([aTs], session);
session.logger.logs.push(`ExternalFiles:: ${JSON.stringify(session.getProjectService().configuredProjects.get(tsconfig.path)!.getExternalFiles())}`);

host.writeFile(tsconfig.path, JSON.stringify({
compilerOptions: {
plugins: [{ name: "some-other-plugin" }]
}
}));
host.runQueuedTimeoutCallbacks();
session.logger.logs.push(`ExternalFiles:: ${JSON.stringify(session.getProjectService().configuredProjects.get(tsconfig.path)!.getExternalFiles())}`);

baselineTsserverLogs("plugins", "gets external files with config file reload", session);
});
});
}
1 change: 0 additions & 1 deletion tests/baselines/reference/api/tsserverlibrary.d.ts
Expand Up @@ -10084,7 +10084,6 @@ declare namespace ts.server {
private externalFiles;
private missingFilesMap;
private generatedFilesMap;
private plugins;
protected languageService: LanguageService;
languageServiceEnabled: boolean;
readonly trace?: (s: string) => void;
Expand Down
@@ -0,0 +1,195 @@
Info 0 [00:00:21.000] Provided types map file "/a/lib/typesMap.json" doesn't exist
Info 1 [00:00:22.000] request:
{
"seq": 0,
"type": "request",
"command": "open",
"arguments": {
"file": "/user/username/projects/myproject/a.ts"
}
}
Before request
//// [/user/username/projects/myproject/a.ts]
export const x = 10;
//// [/user/username/projects/myproject/tsconfig.json]
{"compilerOptions":{"plugins":[{"name":"some-plugin"}]}}
//// [/a/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; }
PolledWatches::
FsWatches::
FsWatchesRecursive::
Info 2 [00:00:23.000] Search path: /user/username/projects/myproject
Info 3 [00:00:24.000] For info: /user/username/projects/myproject/a.ts :: Config file name: /user/username/projects/myproject/tsconfig.json
Info 4 [00:00:25.000] Creating configuration project /user/username/projects/myproject/tsconfig.json
Info 5 [00:00:26.000] FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json 2000 undefined Project: /user/username/projects/myproject/tsconfig.json WatchType: Config file
Info 6 [00:00:27.000] Config: /user/username/projects/myproject/tsconfig.json : {
"rootNames": [
"/user/username/projects/myproject/a.ts"
],
"options": {
"plugins": [
{
"name": "some-plugin"
}
],
"configFilePath": "/user/username/projects/myproject/tsconfig.json"
}
}
Info 7 [00:00:28.000] DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 1 undefined Config: /user/username/projects/myproject/tsconfig.json WatchType: Wild card directory
Info 8 [00:00:29.000] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 1 undefined Config: /user/username/projects/myproject/tsconfig.json WatchType: Wild card directory
Info 9 [00:00:30.000] Enabling plugin some-plugin from candidate paths: /a/lib/tsc.js/../../..
Info 10 [00:00:31.000] Loading some-plugin from /a/lib/tsc.js/../../.. (resolved to /a/lib/tsc.js/../../../node_modules)
Require:: some-plugin
PluginFactory Invoke
Info 11 [00:00:32.000] Plugin validation succeeded
Info 12 [00:00:33.000] Starting updateGraphWorker: Project: /user/username/projects/myproject/tsconfig.json
Info 13 [00:00:34.000] FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined WatchType: Closed Script info
Info 14 [00:00:35.000] FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/somefile.txt 500 undefined Project: /user/username/projects/myproject/tsconfig.json WatchType: Missing file
Info 15 [00:00:36.000] DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/node_modules/@types 1 undefined Project: /user/username/projects/myproject/tsconfig.json WatchType: Type roots
Info 16 [00:00:37.000] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/node_modules/@types 1 undefined Project: /user/username/projects/myproject/tsconfig.json WatchType: Type roots
Info 17 [00:00:38.000] Finishing updateGraphWorker: Project: /user/username/projects/myproject/tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms
Info 18 [00:00:39.000] Project '/user/username/projects/myproject/tsconfig.json' (Configured)
Info 19 [00:00:40.000] Files (2)
/a/lib/lib.d.ts
/user/username/projects/myproject/a.ts
../../../../a/lib/lib.d.ts
Default library for target 'es3'
a.ts
Matched by default include pattern '**/*'

Info 20 [00:00:41.000] -----------------------------------------------
Info 21 [00:00:42.000] Project '/user/username/projects/myproject/tsconfig.json' (Configured)
Info 21 [00:00:43.000] Files (2)

Info 21 [00:00:44.000] -----------------------------------------------
Info 21 [00:00:45.000] Open files:
Info 21 [00:00:46.000] FileName: /user/username/projects/myproject/a.ts ProjectRootPath: undefined
Info 21 [00:00:47.000] Projects: /user/username/projects/myproject/tsconfig.json
After request

PolledWatches::
/user/username/projects/myproject/somefile.txt:
{"pollingInterval":500}
/user/username/projects/myproject/node_modules/@types:
{"pollingInterval":500}

FsWatches::
/user/username/projects/myproject/tsconfig.json:
{}
/a/lib/lib.d.ts:
{}

FsWatchesRecursive::
/user/username/projects/myproject:
{}

Info 21 [00:00:48.000] response:
{
"responseRequired": false
}
ExternalFiles:: ["someFile.txt"]
Info 22 [00:00:52.000] FileWatcher:: Triggered with /user/username/projects/myproject/tsconfig.json 1:: WatchInfo: /user/username/projects/myproject/tsconfig.json 2000 undefined Project: /user/username/projects/myproject/tsconfig.json WatchType: Config file
Info 23 [00:00:53.000] Scheduled: /user/username/projects/myproject/tsconfig.json
Info 24 [00:00:54.000] Scheduled: *ensureProjectForOpenFiles*
Info 25 [00:00:55.000] Elapsed:: *ms FileWatcher:: Triggered with /user/username/projects/myproject/tsconfig.json 1:: WatchInfo: /user/username/projects/myproject/tsconfig.json 2000 undefined Project: /user/username/projects/myproject/tsconfig.json WatchType: Config file
Before running timeout callbacks
//// [/user/username/projects/myproject/tsconfig.json]
{"compilerOptions":{"plugins":[{"name":"some-other-plugin"}]}}


PolledWatches::
/user/username/projects/myproject/somefile.txt:
{"pollingInterval":500}
/user/username/projects/myproject/node_modules/@types:
{"pollingInterval":500}

FsWatches::
/user/username/projects/myproject/tsconfig.json:
{}
/a/lib/lib.d.ts:
{}

FsWatchesRecursive::
/user/username/projects/myproject:
{}

Info 26 [00:00:56.000] Running: /user/username/projects/myproject/tsconfig.json
Info 27 [00:00:57.000] Reloading configured project /user/username/projects/myproject/tsconfig.json
Info 28 [00:00:58.000] Config: /user/username/projects/myproject/tsconfig.json : {
"rootNames": [
"/user/username/projects/myproject/a.ts"
],
"options": {
"plugins": [
{
"name": "some-other-plugin"
}
],
"configFilePath": "/user/username/projects/myproject/tsconfig.json"
}
}
Info 29 [00:00:59.000] Enabling plugin some-other-plugin from candidate paths: /a/lib/tsc.js/../../..
Info 30 [00:01:00.000] Loading some-other-plugin from /a/lib/tsc.js/../../.. (resolved to /a/lib/tsc.js/../../../node_modules)
Require:: some-other-plugin
PluginFactory Invoke
Info 31 [00:01:01.000] Plugin validation succeeded
Info 32 [00:01:02.000] Starting updateGraphWorker: Project: /user/username/projects/myproject/tsconfig.json
Info 33 [00:01:03.000] FileWatcher:: Close:: WatchInfo: /user/username/projects/myproject/somefile.txt 500 undefined Project: /user/username/projects/myproject/tsconfig.json WatchType: Missing file
Info 34 [00:01:04.000] FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/someotherfile.txt 500 undefined Project: /user/username/projects/myproject/tsconfig.json WatchType: Missing file
Info 35 [00:01:05.000] Finishing updateGraphWorker: Project: /user/username/projects/myproject/tsconfig.json Version: 2 structureChanged: true structureIsReused:: Not Elapsed:: *ms
Info 36 [00:01:06.000] Different program with same set of files
Info 37 [00:01:07.000] Running: *ensureProjectForOpenFiles*
Info 38 [00:01:08.000] Before ensureProjectForOpenFiles:
Info 39 [00:01:09.000] Project '/user/username/projects/myproject/tsconfig.json' (Configured)
Info 39 [00:01:10.000] Files (2)

Info 39 [00:01:11.000] -----------------------------------------------
Info 39 [00:01:12.000] Open files:
Info 39 [00:01:13.000] FileName: /user/username/projects/myproject/a.ts ProjectRootPath: undefined
Info 39 [00:01:14.000] Projects: /user/username/projects/myproject/tsconfig.json
Info 39 [00:01:15.000] After ensureProjectForOpenFiles:
Info 40 [00:01:16.000] Project '/user/username/projects/myproject/tsconfig.json' (Configured)
Info 40 [00:01:17.000] Files (2)

Info 40 [00:01:18.000] -----------------------------------------------
Info 40 [00:01:19.000] Open files:
Info 40 [00:01:20.000] FileName: /user/username/projects/myproject/a.ts ProjectRootPath: undefined
Info 40 [00:01:21.000] Projects: /user/username/projects/myproject/tsconfig.json
After running timeout callbacks

PolledWatches::
/user/username/projects/myproject/node_modules/@types:
{"pollingInterval":500}
/user/username/projects/myproject/someotherfile.txt:
{"pollingInterval":500}

FsWatches::
/user/username/projects/myproject/tsconfig.json:
{}
/a/lib/lib.d.ts:
{}

FsWatchesRecursive::
/user/username/projects/myproject:
{}

ExternalFiles:: ["someOtherFile.txt"]

0 comments on commit 2648f6a

Please sign in to comment.