Skip to content

Commit

Permalink
Make the typescript plugins contribution point dynamic
Browse files Browse the repository at this point in the history
Part of #67575
  • Loading branch information
mjbvz committed Feb 12, 2019
1 parent ebff3af commit a8216d4
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ export default class TypeScriptServiceClient extends Disposable implements IType
this._register(this.pluginManager.onDidUpdateConfig(update => {
this.configurePlugin(update.pluginId, update.config);
}));

this._register(this.pluginManager.onDidChangePlugins(() => {
this.restartTsServer();
}));
}

public get configuration() {
Expand Down
71 changes: 55 additions & 16 deletions extensions/typescript-language-features/src/utils/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
*--------------------------------------------------------------------------------------------*/

import * as vscode from 'vscode';
import * as arrays from './arrays';
import { Disposable } from './dispose';
import { memoize } from './memoize';

export interface TypeScriptServerPlugin {
readonly path: string;
Expand All @@ -14,28 +14,45 @@ export interface TypeScriptServerPlugin {
readonly languages: ReadonlyArray<string>;
}

namespace TypeScriptServerPlugin {
export function equals(a: TypeScriptServerPlugin, b: TypeScriptServerPlugin): boolean {
return a.path === b.path
&& a.name === b.name
&& a.enableForWorkspaceTypeScriptVersions === b.enableForWorkspaceTypeScriptVersions
&& arrays.equals(a.languages, b.languages);
}
}

export class PluginManager extends Disposable {
private readonly _pluginConfigurations = new Map<string, {}>();

@memoize
public get plugins(): ReadonlyArray<TypeScriptServerPlugin> {
const plugins: TypeScriptServerPlugin[] = [];
for (const extension of vscode.extensions.all) {
const pack = extension.packageJSON;
if (pack.contributes && Array.isArray(pack.contributes.typescriptServerPlugins)) {
for (const plugin of pack.contributes.typescriptServerPlugins) {
plugins.push({
name: plugin.name,
enableForWorkspaceTypeScriptVersions: !!plugin.enableForWorkspaceTypeScriptVersions,
path: extension.extensionPath,
languages: Array.isArray(plugin.languages) ? plugin.languages : [],
});
}
private _plugins: Map<string, ReadonlyArray<TypeScriptServerPlugin>> | undefined;

constructor() {
super();

vscode.extensions.onDidChange(() => {
if (!this._plugins) {
return;
}
const newPlugins = this.readPlugins();
if (!arrays.equals(arrays.flatten(Array.from(this._plugins.values())), arrays.flatten(Array.from(newPlugins.values())), TypeScriptServerPlugin.equals)) {
this._plugins = newPlugins;
this._onDidUpdatePlugins.fire(this);
}
}, undefined, this._disposables);
}

public get plugins(): ReadonlyArray<TypeScriptServerPlugin> {
if (!this._plugins) {
this._plugins = this.readPlugins();
}
return plugins;
return arrays.flatten(Array.from(this._plugins.values()));
}

private readonly _onDidUpdatePlugins = this._register(new vscode.EventEmitter<this>());
public readonly onDidChangePlugins = this._onDidUpdatePlugins.event;

private readonly _onDidUpdateConfig = this._register(new vscode.EventEmitter<{ pluginId: string, config: {} }>());
public readonly onDidUpdateConfig = this._onDidUpdateConfig.event;

Expand All @@ -47,4 +64,26 @@ export class PluginManager extends Disposable {
public configurations(): IterableIterator<[string, {}]> {
return this._pluginConfigurations.entries();
}

private readPlugins() {
const pluginMap = new Map<string, ReadonlyArray<TypeScriptServerPlugin>>();
for (const extension of vscode.extensions.all) {
const pack = extension.packageJSON;
if (pack.contributes && Array.isArray(pack.contributes.typescriptServerPlugins)) {
const plugins: TypeScriptServerPlugin[] = [];
for (const plugin of pack.contributes.typescriptServerPlugins) {
plugins.push({
name: plugin.name,
enableForWorkspaceTypeScriptVersions: !!plugin.enableForWorkspaceTypeScriptVersions,
path: extension.extensionPath,
languages: Array.isArray(plugin.languages) ? plugin.languages : [],
});
}
if (plugins.length) {
pluginMap.set(extension.id, plugins);
}
}
}
return pluginMap;
}
}

0 comments on commit a8216d4

Please sign in to comment.