44 *--------------------------------------------------------------------------------------------*/
55
66import * as vscode from 'vscode' ;
7+ import * as arrays from './arrays' ;
78import { Disposable } from './dispose' ;
8- import { memoize } from './memoize' ;
99
1010export 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+
1726export 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