@@ -72,6 +72,12 @@ namespace ts.server {
72
72
export interface PluginModule {
73
73
create ( createInfo : PluginCreateInfo ) : LanguageService ;
74
74
getExternalFiles ?( proj : Project ) : string [ ] ;
75
+ onConfigurationChanged ?( config : any ) : void ;
76
+ }
77
+
78
+ export interface PluginModuleWithName {
79
+ name : string ;
80
+ module : PluginModule ;
75
81
}
76
82
77
83
export type PluginModuleFactory = ( mod : { typescript : typeof ts } ) => PluginModule ;
@@ -92,7 +98,7 @@ namespace ts.server {
92
98
private program : Program ;
93
99
private externalFiles : SortedReadonlyArray < string > ;
94
100
private missingFilesMap : Map < FileWatcher > ;
95
- private plugins : PluginModule [ ] = [ ] ;
101
+ private plugins : PluginModuleWithName [ ] = [ ] ;
96
102
97
103
/*@internal */
98
104
/**
@@ -549,9 +555,9 @@ namespace ts.server {
549
555
550
556
getExternalFiles ( ) : SortedReadonlyArray < string > {
551
557
return toSortedArray ( flatMap ( this . plugins , plugin => {
552
- if ( typeof plugin . getExternalFiles !== "function" ) return ;
558
+ if ( typeof plugin . module . getExternalFiles !== "function" ) return ;
553
559
try {
554
- return plugin . getExternalFiles ( this ) ;
560
+ return plugin . module . getExternalFiles ( this ) ;
555
561
}
556
562
catch ( e ) {
557
563
this . projectService . logger . info ( `A plugin threw an exception in getExternalFiles: ${ e } ` ) ;
@@ -1105,7 +1111,7 @@ namespace ts.server {
1105
1111
this . rootFilesMap . delete ( info . path ) ;
1106
1112
}
1107
1113
1108
- protected enableGlobalPlugins ( options : CompilerOptions ) {
1114
+ protected enableGlobalPlugins ( options : CompilerOptions , pluginConfigOverrides : Map < any > | undefined ) {
1109
1115
const host = this . projectService . host ;
1110
1116
1111
1117
if ( ! host . require ) {
@@ -1128,12 +1134,13 @@ namespace ts.server {
1128
1134
1129
1135
// Provide global: true so plugins can detect why they can't find their config
1130
1136
this . projectService . logger . info ( `Loading global plugin ${ globalPluginName } ` ) ;
1131
- this . enablePlugin ( { name : globalPluginName , global : true } as PluginImport , searchPaths ) ;
1137
+
1138
+ this . enablePlugin ( { name : globalPluginName , global : true } as PluginImport , searchPaths , pluginConfigOverrides ) ;
1132
1139
}
1133
1140
}
1134
1141
}
1135
1142
1136
- protected enablePlugin ( pluginConfigEntry : PluginImport , searchPaths : string [ ] ) {
1143
+ protected enablePlugin ( pluginConfigEntry : PluginImport , searchPaths : string [ ] , pluginConfigOverrides : Map < any > | undefined ) {
1137
1144
this . projectService . logger . info ( `Enabling plugin ${ pluginConfigEntry . name } from candidate paths: ${ searchPaths . join ( "," ) } ` ) ;
1138
1145
1139
1146
const log = ( message : string ) => {
@@ -1143,18 +1150,21 @@ namespace ts.server {
1143
1150
const resolvedModule = firstDefined ( searchPaths , searchPath =>
1144
1151
< PluginModuleFactory | undefined > Project . resolveModule ( pluginConfigEntry . name , searchPath , this . projectService . host , log ) ) ;
1145
1152
if ( resolvedModule ) {
1153
+ const configurationOverride = pluginConfigOverrides && pluginConfigOverrides . get ( pluginConfigEntry . name ) ;
1154
+ if ( configurationOverride ) {
1155
+ // Preserve the name property since it's immutable
1156
+ const pluginName = pluginConfigEntry . name ;
1157
+ pluginConfigEntry = configurationOverride ;
1158
+ pluginConfigEntry . name = pluginName ;
1159
+ }
1160
+
1146
1161
this . enableProxy ( resolvedModule , pluginConfigEntry ) ;
1147
1162
}
1148
1163
else {
1149
1164
this . projectService . logger . info ( `Couldn't find ${ pluginConfigEntry . name } ` ) ;
1150
1165
}
1151
1166
}
1152
1167
1153
- /** Starts a new check for diagnostics. Call this if some file has updated that would cause diagnostics to be changed. */
1154
- refreshDiagnostics ( ) {
1155
- this . projectService . sendProjectsUpdatedInBackgroundEvent ( ) ;
1156
- }
1157
-
1158
1168
private enableProxy ( pluginModuleFactory : PluginModuleFactory , configEntry : PluginImport ) {
1159
1169
try {
1160
1170
if ( typeof pluginModuleFactory !== "function" ) {
@@ -1180,12 +1190,25 @@ namespace ts.server {
1180
1190
}
1181
1191
this . projectService . logger . info ( `Plugin validation succeded` ) ;
1182
1192
this . languageService = newLS ;
1183
- this . plugins . push ( pluginModule ) ;
1193
+ this . plugins . push ( { name : configEntry . name , module : pluginModule } ) ;
1184
1194
}
1185
1195
catch ( e ) {
1186
1196
this . projectService . logger . info ( `Plugin activation failed: ${ e } ` ) ;
1187
1197
}
1188
1198
}
1199
+
1200
+ onPluginConfigurationChanged ( pluginName : string , configuration : any ) {
1201
+ this . plugins . filter ( plugin => plugin . name === pluginName ) . forEach ( plugin => {
1202
+ if ( plugin . module . onConfigurationChanged ) {
1203
+ plugin . module . onConfigurationChanged ( configuration ) ;
1204
+ }
1205
+ } ) ;
1206
+ }
1207
+
1208
+ /** Starts a new check for diagnostics. Call this if some file has updated that would cause diagnostics to be changed. */
1209
+ refreshDiagnostics ( ) {
1210
+ this . projectService . sendProjectsUpdatedInBackgroundEvent ( ) ;
1211
+ }
1189
1212
}
1190
1213
1191
1214
/**
@@ -1241,7 +1264,8 @@ namespace ts.server {
1241
1264
documentRegistry : DocumentRegistry ,
1242
1265
compilerOptions : CompilerOptions ,
1243
1266
projectRootPath : NormalizedPath | undefined ,
1244
- currentDirectory : string | undefined ) {
1267
+ currentDirectory : string | undefined ,
1268
+ pluginConfigOverrides : Map < any > | undefined ) {
1245
1269
super ( InferredProject . newName ( ) ,
1246
1270
ProjectKind . Inferred ,
1247
1271
projectService ,
@@ -1257,7 +1281,7 @@ namespace ts.server {
1257
1281
if ( ! projectRootPath && ! projectService . useSingleInferredProject ) {
1258
1282
this . canonicalCurrentDirectory = projectService . toCanonicalFileName ( this . currentDirectory ) ;
1259
1283
}
1260
- this . enableGlobalPlugins ( this . getCompilerOptions ( ) ) ;
1284
+ this . enableGlobalPlugins ( this . getCompilerOptions ( ) , pluginConfigOverrides ) ;
1261
1285
}
1262
1286
1263
1287
addRoot ( info : ScriptInfo ) {
@@ -1402,12 +1426,8 @@ namespace ts.server {
1402
1426
return program && program . getResolvedProjectReferences ( ) ;
1403
1427
}
1404
1428
1405
- enablePlugins ( ) {
1406
- this . enablePluginsWithOptions ( this . getCompilerOptions ( ) ) ;
1407
- }
1408
-
1409
1429
/*@internal */
1410
- enablePluginsWithOptions ( options : CompilerOptions ) {
1430
+ enablePluginsWithOptions ( options : CompilerOptions , pluginConfigOverrides : Map < any > | undefined ) {
1411
1431
const host = this . projectService . host ;
1412
1432
1413
1433
if ( ! host . require ) {
@@ -1428,11 +1448,11 @@ namespace ts.server {
1428
1448
// Enable tsconfig-specified plugins
1429
1449
if ( options . plugins ) {
1430
1450
for ( const pluginConfigEntry of options . plugins ) {
1431
- this . enablePlugin ( pluginConfigEntry , searchPaths ) ;
1451
+ this . enablePlugin ( pluginConfigEntry , searchPaths , pluginConfigOverrides ) ;
1432
1452
}
1433
1453
}
1434
1454
1435
- this . enableGlobalPlugins ( options ) ;
1455
+ this . enableGlobalPlugins ( options , pluginConfigOverrides ) ;
1436
1456
}
1437
1457
1438
1458
/**
0 commit comments