Skip to content

Commit

Permalink
Add plugin override for watchFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
sheetalkamat committed Oct 10, 2022
1 parent 67d6ee5 commit d1d7469
Show file tree
Hide file tree
Showing 38 changed files with 91 additions and 22 deletions.
17 changes: 14 additions & 3 deletions src/compiler/sys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -963,6 +963,11 @@ namespace ts {
),
};

function getWatchFactoryPlugin(options: WatchOptions) {
const plugin = isString(options.watchFactory) ? { name: options.watchFactory } : options.watchFactory!;
return options.watchFactoryWithConfigOverride?.(plugin) || plugin;
}

function createWatcherConsideringFactory(
options: WatchOptions | undefined,
createWatcher: (factory?: UserWatchModule) => FileWatcher,
Expand Down Expand Up @@ -1001,7 +1006,7 @@ namespace ts {
setImportPluginResult(
options,
resolveModule<UserWatchFactory>(
isString(options.watchFactory) ? { name: options.watchFactory } : options.watchFactory,
getWatchFactoryPlugin(options),
searchPaths,
getSystem(),
sysLog
Expand All @@ -1022,7 +1027,7 @@ namespace ts {
function importFactory(options: WatchOptions, searchPaths: readonly string[], system: System) {
return setGetResolvedWatchFactory(options, {
pending: importPlugin<UserWatchFactory>(
isString(options.watchFactory) ? { name: options.watchFactory } : options.watchFactory!,
getWatchFactoryPlugin(options),
searchPaths,
system,
sysLog
Expand All @@ -1037,7 +1042,13 @@ namespace ts {
{ resolvedModule, errorLogs, pluginConfigEntry }: ImportPluginResult<UserWatchFactory>,
) {
if (typeof resolvedModule === "function") {
return setGetResolvedWatchFactory(options, { resolved: resolvedModule({ typescript: ts }) });
return setGetResolvedWatchFactory(options, {
resolved: resolvedModule({
typescript: ts,
options,
config: pluginConfigEntry
})
});
}
else if (!resolvedModule) {
forEach(errorLogs, sysLog);
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6673,7 +6673,7 @@ namespace ts {
[option: string]: CompilerOptionsValue | TsConfigSourceFile | undefined;
}

export type UserWatchFactory = (mod: { typescript: typeof ts }) => UserWatchModule;
export type UserWatchFactory = (mod: { typescript: typeof ts, options: WatchOptions, config: any }) => UserWatchModule;
export interface UserWatchModule {
watchFile?(fileName: string, callback: FileWatcherCallback, pollingInterval: number, options: WatchOptions | undefined): FileWatcher;
watchDirectory?(fileName: string, callback: DirectoryWatcherCallback, recursive: boolean, options: WatchOptions | undefined): FileWatcher;
Expand All @@ -6696,6 +6696,7 @@ namespace ts {
/* @internal */ readonly configFile?: TsConfigSourceFile;
/* @internal */ getResolvedWatchFactory?(): ResolvedWatchFactory | undefined;
/* @internal */ watchFactorySearchPaths?(): readonly string[];
/* @internal */ watchFactoryWithConfigOverride?(plugin: PluginImport): PluginImport;

[option: string]: CompilerOptionsValue | TsConfigSourceFile | undefined;
}
Expand Down
20 changes: 18 additions & 2 deletions src/server/editorServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ namespace ts.server {
public readonly pluginProbeLocations: readonly string[];
public readonly allowLocalPluginLoads: boolean;
/*@internal*/
currentPluginConfigOverrides: ESMap<string, any> | undefined;
private currentPluginConfigOverrides: ESMap<string, any> | undefined;

public readonly typesMapLocation: string | undefined;

Expand Down Expand Up @@ -2237,7 +2237,10 @@ namespace ts.server {
configFileExistenceInfo.config.watchedDirectoriesStale = true;
configFileExistenceInfo.config.reloadLevel = undefined;
}
if (parsedCommandLine.watchOptions) parsedCommandLine.watchOptions.watchFactorySearchPaths = () => this.getProjectPluginSearchPaths(canonicalConfigFilePath);
if (parsedCommandLine.watchOptions) {
parsedCommandLine.watchOptions.watchFactorySearchPaths = () => this.getProjectPluginSearchPaths(canonicalConfigFilePath);
parsedCommandLine.watchOptions.watchFactoryWithConfigOverride = plugin => this.getPluginWithConfigOverride(plugin);
}

// If watch options different than older options when setting for the first time, update the config file watcher
if (!oldCommandLine && !isJsonEqual(
Expand Down Expand Up @@ -3053,6 +3056,7 @@ namespace ts.server {
if (this.hostConfiguration.watchOptions?.watchFactory) {
// Set the watchFactory searchPaths same as global paths
this.hostConfiguration.watchOptions.watchFactorySearchPaths = () => this.getGlobalPluginSearchPaths();
this.hostConfiguration.watchOptions.watchFactoryWithConfigOverride = plugin => this.getPluginWithConfigOverride(plugin);
}
this.projectWatchOptions.clear();
this.logger.info(`Host watch options changed to ${JSON.stringify(this.hostConfiguration.watchOptions)}, it will be take effect for next watches.`);
Expand Down Expand Up @@ -4132,6 +4136,18 @@ namespace ts.server {
return searchPaths;
}

/*@internal*/
getPluginWithConfigOverride(pluginConfigEntry: PluginImport) {
const configurationOverride = this.currentPluginConfigOverrides?.get(pluginConfigEntry.name);
if (configurationOverride) {
// Preserve the name property since it's immutable
const pluginName = pluginConfigEntry.name;
pluginConfigEntry = configurationOverride;
pluginConfigEntry.name = pluginName;
}
return pluginConfigEntry;
}

/*@internal*/
requestEnablePlugin(project: Project, pluginConfigEntry: PluginImport, searchPaths: string[]) {
if (!this.host.importPlugin && !this.host.require) {
Expand Down
11 changes: 2 additions & 9 deletions src/server/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1442,6 +1442,7 @@ namespace ts.server {
this.watchOptions = watchOptions;
if (this.watchOptions?.watchFactory) {
this.watchOptions.watchFactorySearchPaths = () => this.getProjectPluginSearchPaths();
this.watchOptions.watchFactoryWithConfigOverride = plugin => this.projectService.getPluginWithConfigOverride(plugin);
}
}

Expand Down Expand Up @@ -1612,15 +1613,7 @@ namespace ts.server {
/*@internal*/
endEnablePlugin({ pluginConfigEntry, resolvedModule, errorLogs }: BeginEnablePluginResult) {
if (resolvedModule) {
const configurationOverride = this.projectService.currentPluginConfigOverrides?.get(pluginConfigEntry.name);
if (configurationOverride) {
// Preserve the name property since it's immutable
const pluginName = pluginConfigEntry.name;
pluginConfigEntry = configurationOverride;
pluginConfigEntry.name = pluginName;
}

this.enableProxy(resolvedModule, pluginConfigEntry);
this.enableProxy(resolvedModule, this.projectService.getPluginWithConfigOverride(pluginConfigEntry));
}
else {
forEach(errorLogs, message => this.projectService.logger.info(message));
Expand Down
11 changes: 7 additions & 4 deletions src/testRunner/unittests/tscWatch/watchEnvironment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -900,10 +900,13 @@ namespace ts.tscWatch {
system.require = (initialPath, moduleName) => {
system.write(`Require:: Resolving ${moduleName} from ${initialPath}\n`);
return {
module: () => ({
watchFile: !excludeWatchFile ? system.factoryData.watchFile : undefined,
watchDirectory: system.factoryData.watchDirectory,
}),
module: (({ options, config }) => {
system.write(`Require:: Module ${moduleName} created with config: ${JSON.stringify(config)} and options: ${JSON.stringify(options)}\n`);
return {
watchFile: !excludeWatchFile ? system.factoryData.watchFile : undefined,
watchDirectory: system.factoryData.watchDirectory,
};
}) as UserWatchFactory,
error: undefined
};
};
Expand Down
9 changes: 6 additions & 3 deletions src/testRunner/unittests/tsserver/watchEnvironment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -831,9 +831,12 @@ namespace ts.projectSystem {
return (initialPath, moduleName) => {
session.logger.logs.push(`CustomRequire:: Resolving ${moduleName} from ${initialPath}`);
return {
module: (): UserWatchModule => !plugin2 || moduleName === "myplugin" ?
plugin :
plugin2,
module: (({ options, config }) => {
session.logger.logs.push(`Require:: Module ${moduleName} created with config: ${JSON.stringify(config)} and options: ${JSON.stringify(options)}`);
return !plugin2 || moduleName === "myplugin" ?
plugin :
plugin2;
}) as UserWatchFactory,
error: undefined
};
};
Expand Down
2 changes: 2 additions & 0 deletions tests/baselines/reference/api/tsserverlibrary.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3092,6 +3092,8 @@ declare namespace ts {
}
export type UserWatchFactory = (mod: {
typescript: typeof ts;
options: WatchOptions;
config: any;
}) => UserWatchModule;
export interface UserWatchModule {
watchFile?(fileName: string, callback: FileWatcherCallback, pollingInterval: number, options: WatchOptions | undefined): FileWatcher;
Expand Down
2 changes: 2 additions & 0 deletions tests/baselines/reference/api/typescript.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3092,6 +3092,8 @@ declare namespace ts {
}
export type UserWatchFactory = (mod: {
typescript: typeof ts;
options: WatchOptions;
config: any;
}) => UserWatchModule;
export interface UserWatchModule {
watchFile?(fileName: string, callback: FileWatcherCallback, pollingInterval: number, options: WatchOptions | undefined): FileWatcher;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json
Enabling watchFactory myplugin from candidate paths: /user/username/projects/myproject,/a/lib/tsc.js/../../..
Loading myplugin from /user/username/projects/myproject (resolved to /user/username/projects/myproject/node_modules)
Require:: Resolving myplugin from /user/username/projects/myproject/node_modules
Require:: Module myplugin created with config: {"name":"myplugin","myconfig":"somethingelse"} and options: {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
Custom watchFile: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
Synchronizing program
CreatingProgramWith::
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json
Enabling watchFactory myplugin from candidate paths: /user/username/projects/myproject,/a/lib/tsc.js/../../..
Loading myplugin from /user/username/projects/myproject (resolved to /user/username/projects/myproject/node_modules)
Require:: Resolving myplugin from /user/username/projects/myproject/node_modules
Require:: Module myplugin created with config: {"name":"myplugin"} and options: {"watchFactory":"myplugin"}
Custom watchFile: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":"myplugin"}
Synchronizing program
CreatingProgramWith::
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json
Enabling watchFactory myplugin from candidate paths: /user/username/projects/myproject,/a/lib/tsc.js/../../..
Loading myplugin from /user/username/projects/myproject (resolved to /user/username/projects/myproject/node_modules)
Require:: Resolving myplugin from /user/username/projects/myproject/node_modules
Require:: Module myplugin created with config: {"name":"myplugin","myconfig":"somethingelse"} and options: {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
Custom watchFile: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
Synchronizing program
CreatingProgramWith::
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json
Enabling watchFactory myplugin from candidate paths: /user/username/projects/myproject,/a/lib/tsc.js/../../..
Loading myplugin from /user/username/projects/myproject (resolved to /user/username/projects/myproject/node_modules)
Require:: Resolving myplugin from /user/username/projects/myproject/node_modules
Require:: Module myplugin created with config: {"name":"myplugin"} and options: {"watchFactory":"myplugin"}
Custom watchFile: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":"myplugin"}
Synchronizing program
CreatingProgramWith::
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json
Enabling watchFactory myplugin from candidate paths: /user/username/projects/myproject,/a/lib/tsc.js/../../..
Loading myplugin from /user/username/projects/myproject (resolved to /user/username/projects/myproject/node_modules)
Require:: Resolving myplugin from /user/username/projects/myproject/node_modules
Require:: Module myplugin created with config: {"name":"myplugin","myconfig":"somethingelse"} and options: {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
Synchronizing program
CreatingProgramWith::
roots: ["/user/username/projects/myproject/a.ts","/user/username/projects/myproject/b.ts"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json
Enabling watchFactory myplugin from candidate paths: /user/username/projects/myproject,/a/lib/tsc.js/../../..
Loading myplugin from /user/username/projects/myproject (resolved to /user/username/projects/myproject/node_modules)
Require:: Resolving myplugin from /user/username/projects/myproject/node_modules
Require:: Module myplugin created with config: {"name":"myplugin"} and options: {"watchFactory":"myplugin"}
Synchronizing program
CreatingProgramWith::
roots: ["/user/username/projects/myproject/a.ts","/user/username/projects/myproject/b.ts"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ Info 7 [00:00:30.000] For info: /user/username/projects/myproject/a.ts :: Con
Info 8 [00:00:31.000] Creating configuration project /user/username/projects/myproject/tsconfig.json
Info 9 [00:00:32.000] FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}} Project: /user/username/projects/myproject/tsconfig.json WatchType: Config file
CustomRequire:: Resolving myplugin from /a/pluginprobe1/node_modules
Require:: Module myplugin created with config: {"name":"myplugin","myconfig":"somethingelse"} and options: {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
Custom watchFile: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
Info 10 [00:00:33.000] Config: /user/username/projects/myproject/tsconfig.json : {
"rootNames": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ Info 7 [00:00:30.000] For info: /user/username/projects/myproject/a.ts :: Con
Info 8 [00:00:31.000] Creating configuration project /user/username/projects/myproject/tsconfig.json
Info 9 [00:00:32.000] FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":"myplugin"} Project: /user/username/projects/myproject/tsconfig.json WatchType: Config file
CustomRequire:: Resolving myplugin from /a/pluginprobe1/node_modules
Require:: Module myplugin created with config: {"name":"myplugin"} and options: {"watchFactory":"myplugin"}
Custom watchFile: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":"myplugin"}
Info 10 [00:00:33.000] Config: /user/username/projects/myproject/tsconfig.json : {
"rootNames": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ Info 7 [00:00:30.000] For info: /user/username/projects/myproject/a.ts :: Con
Info 8 [00:00:31.000] Creating configuration project /user/username/projects/myproject/tsconfig.json
Info 9 [00:00:32.000] FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}} Project: /user/username/projects/myproject/tsconfig.json WatchType: Config file
CustomRequire:: Resolving myplugin from /a/pluginprobe1/node_modules
Require:: Module myplugin created with config: {"name":"myplugin","myconfig":"somethingelse"} and options: {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
Custom watchFile: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
Info 10 [00:00:33.000] Config: /user/username/projects/myproject/tsconfig.json : {
"rootNames": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ Info 10 [00:00:33.000] For info: /user/username/projects/myproject/a.ts :: Con
Info 11 [00:00:34.000] Creating configuration project /user/username/projects/myproject/tsconfig.json
Info 12 [00:00:35.000] FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}} Project: /user/username/projects/myproject/tsconfig.json WatchType: Config file
CustomRequire:: Resolving myplugin from /a/pluginprobe1/node_modules
Require:: Module myplugin created with config: {"init":"initialConfig","name":"myplugin"} and options: {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
Custom watchFile: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
Info 13 [00:00:36.000] Config: /user/username/projects/myproject/tsconfig.json : {
"rootNames": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ Info 10 [00:00:33.000] For info: /user/username/projects/myproject/a.ts :: Con
Info 11 [00:00:34.000] Creating configuration project /user/username/projects/myproject/tsconfig.json
Info 12 [00:00:35.000] FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":"myplugin"} Project: /user/username/projects/myproject/tsconfig.json WatchType: Config file
CustomRequire:: Resolving myplugin from /a/pluginprobe1/node_modules
Require:: Module myplugin created with config: {"init":"initialConfig","name":"myplugin"} and options: {"watchFactory":"myplugin"}
Custom watchFile: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":"myplugin"}
Info 13 [00:00:36.000] Config: /user/username/projects/myproject/tsconfig.json : {
"rootNames": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ Info 10 [00:00:33.000] For info: /user/username/projects/myproject/a.ts :: Con
Info 11 [00:00:34.000] Creating configuration project /user/username/projects/myproject/tsconfig.json
Info 12 [00:00:35.000] FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}} Project: /user/username/projects/myproject/tsconfig.json WatchType: Config file
CustomRequire:: Resolving myplugin from /a/pluginprobe1/node_modules
Require:: Module myplugin created with config: {"init":"initialConfig","name":"myplugin"} and options: {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
Custom watchFile: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
Info 13 [00:00:36.000] Config: /user/username/projects/myproject/tsconfig.json : {
"rootNames": [
Expand Down
Loading

0 comments on commit d1d7469

Please sign in to comment.