Skip to content

Commit a8216d4

Browse files
committed
Make the typescript plugins contribution point dynamic
Part of microsoft#67575
1 parent ebff3af commit a8216d4

2 files changed

Lines changed: 59 additions & 16 deletions

File tree

extensions/typescript-language-features/src/typescriptServiceClient.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ export default class TypeScriptServiceClient extends Disposable implements IType
166166
this._register(this.pluginManager.onDidUpdateConfig(update => {
167167
this.configurePlugin(update.pluginId, update.config);
168168
}));
169+
170+
this._register(this.pluginManager.onDidChangePlugins(() => {
171+
this.restartTsServer();
172+
}));
169173
}
170174

171175
public get configuration() {

extensions/typescript-language-features/src/utils/plugins.ts

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import * as vscode from 'vscode';
7+
import * as arrays from './arrays';
78
import { Disposable } from './dispose';
8-
import { memoize } from './memoize';
99

1010
export interface TypeScriptServerPlugin {
1111
readonly path: string;
@@ -14,28 +14,45 @@ export interface TypeScriptServerPlugin {
1414
readonly languages: ReadonlyArray<string>;
1515
}
1616

17+
namespace TypeScriptServerPlugin {
18+
export function equals(a: TypeScriptServerPlugin, b: TypeScriptServerPlugin): boolean {
19+
return a.path === b.path
20+
&& a.name === b.name
21+
&& a.enableForWorkspaceTypeScriptVersions === b.enableForWorkspaceTypeScriptVersions
22+
&& arrays.equals(a.languages, b.languages);
23+
}
24+
}
25+
1726
export class PluginManager extends Disposable {
1827
private readonly _pluginConfigurations = new Map<string, {}>();
1928

20-
@memoize
21-
public get plugins(): ReadonlyArray<TypeScriptServerPlugin> {
22-
const plugins: TypeScriptServerPlugin[] = [];
23-
for (const extension of vscode.extensions.all) {
24-
const pack = extension.packageJSON;
25-
if (pack.contributes && Array.isArray(pack.contributes.typescriptServerPlugins)) {
26-
for (const plugin of pack.contributes.typescriptServerPlugins) {
27-
plugins.push({
28-
name: plugin.name,
29-
enableForWorkspaceTypeScriptVersions: !!plugin.enableForWorkspaceTypeScriptVersions,
30-
path: extension.extensionPath,
31-
languages: Array.isArray(plugin.languages) ? plugin.languages : [],
32-
});
33-
}
29+
private _plugins: Map<string, ReadonlyArray<TypeScriptServerPlugin>> | undefined;
30+
31+
constructor() {
32+
super();
33+
34+
vscode.extensions.onDidChange(() => {
35+
if (!this._plugins) {
36+
return;
3437
}
38+
const newPlugins = this.readPlugins();
39+
if (!arrays.equals(arrays.flatten(Array.from(this._plugins.values())), arrays.flatten(Array.from(newPlugins.values())), TypeScriptServerPlugin.equals)) {
40+
this._plugins = newPlugins;
41+
this._onDidUpdatePlugins.fire(this);
42+
}
43+
}, undefined, this._disposables);
44+
}
45+
46+
public get plugins(): ReadonlyArray<TypeScriptServerPlugin> {
47+
if (!this._plugins) {
48+
this._plugins = this.readPlugins();
3549
}
36-
return plugins;
50+
return arrays.flatten(Array.from(this._plugins.values()));
3751
}
3852

53+
private readonly _onDidUpdatePlugins = this._register(new vscode.EventEmitter<this>());
54+
public readonly onDidChangePlugins = this._onDidUpdatePlugins.event;
55+
3956
private readonly _onDidUpdateConfig = this._register(new vscode.EventEmitter<{ pluginId: string, config: {} }>());
4057
public readonly onDidUpdateConfig = this._onDidUpdateConfig.event;
4158

@@ -47,4 +64,26 @@ export class PluginManager extends Disposable {
4764
public configurations(): IterableIterator<[string, {}]> {
4865
return this._pluginConfigurations.entries();
4966
}
67+
68+
private readPlugins() {
69+
const pluginMap = new Map<string, ReadonlyArray<TypeScriptServerPlugin>>();
70+
for (const extension of vscode.extensions.all) {
71+
const pack = extension.packageJSON;
72+
if (pack.contributes && Array.isArray(pack.contributes.typescriptServerPlugins)) {
73+
const plugins: TypeScriptServerPlugin[] = [];
74+
for (const plugin of pack.contributes.typescriptServerPlugins) {
75+
plugins.push({
76+
name: plugin.name,
77+
enableForWorkspaceTypeScriptVersions: !!plugin.enableForWorkspaceTypeScriptVersions,
78+
path: extension.extensionPath,
79+
languages: Array.isArray(plugin.languages) ? plugin.languages : [],
80+
});
81+
}
82+
if (plugins.length) {
83+
pluginMap.set(extension.id, plugins);
84+
}
85+
}
86+
}
87+
return pluginMap;
88+
}
5089
}

0 commit comments

Comments
 (0)