Skip to content
This repository was archived by the owner on Oct 16, 2020. It is now read-only.

Commit 3df438c

Browse files
committed
fix: Add documentation and reorder functions
1 parent 77429ce commit 3df438c

File tree

1 file changed

+72
-32
lines changed

1 file changed

+72
-32
lines changed

src/project-manager.ts

Lines changed: 72 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,24 @@ import {
2525
export type ConfigType = 'js' | 'ts';
2626

2727
// definitions from from TypeScript server/project.ts
28-
interface Project {
29-
projectService: {
30-
logger: Logger;
31-
};
32-
}
3328

34-
type ServerHost = object;
29+
/**
30+
* A plugin exports an initialization function, injected with
31+
* the current typescript instance
32+
*/
33+
type PluginModuleFactory = (mod: { typescript: typeof ts }) => PluginModule;
34+
35+
/**
36+
* A plugin presents this API when initialized
37+
*/
38+
interface PluginModule {
39+
create(createInfo: PluginCreateInfo): ts.LanguageService;
40+
getExternalFiles?(proj: Project): string[];
41+
}
3542

43+
/**
44+
* All of tsserver's environment exposed to plugins
45+
*/
3646
interface PluginCreateInfo {
3747
project: Project;
3848
languageService: ts.LanguageService;
@@ -41,14 +51,24 @@ interface PluginCreateInfo {
4151
config: any;
4252
}
4353

44-
type RequireResult = { module: {}, error: undefined } | { module: undefined, error: {} };
45-
46-
interface PluginModule {
47-
create(createInfo: PluginCreateInfo): ts.LanguageService;
48-
getExternalFiles?(proj: Project): string[];
54+
/**
55+
* The portion of tsserver's Project API exposed to plugins
56+
*/
57+
interface Project {
58+
projectService: {
59+
logger: Logger;
60+
};
4961
}
5062

51-
type PluginModuleFactory = (mod: { typescript: typeof ts }) => PluginModule;
63+
/**
64+
* The portion of tsserver's ServerHost API exposed to plugins
65+
*/
66+
type ServerHost = object;
67+
68+
/**
69+
* The result of a node require: a module or an error.
70+
*/
71+
type RequireResult = { module: {}, error: undefined } | { module: undefined, error: {} };
5272

5373
/**
5474
* ProjectManager translates VFS files to one or many projects denoted by [tj]config.json.
@@ -964,6 +984,27 @@ export class ProjectConfiguration {
964984
// TODO: support globalPlugins flag if desired
965985
}
966986

987+
/**
988+
* Tries to load and enable a single plugin
989+
* @param pluginConfigEntry
990+
* @param searchPaths
991+
*/
992+
private enablePlugin(pluginConfigEntry: ts.PluginImport, searchPaths: string[]) {
993+
for (const searchPath of searchPaths) {
994+
const resolvedModule = this.resolveModule(pluginConfigEntry.name, searchPath) as PluginModuleFactory;
995+
if (resolvedModule) {
996+
this.enableProxy(resolvedModule, pluginConfigEntry);
997+
return;
998+
}
999+
}
1000+
this.logger.info(`Couldn't find ${pluginConfigEntry.name} anywhere in paths: ${searchPaths.join(',')}`);
1001+
}
1002+
1003+
/**
1004+
* Load a plugin use a node require
1005+
* @param moduleName
1006+
* @param initialDir
1007+
*/
9671008
private resolveModule(moduleName: string, initialDir: string): {} | undefined {
9681009
const resolvedPath = path.resolve(initialDir, 'node_modules');
9691010
this.logger.info(`Loading ${moduleName} from ${initialDir} (resolved to ${resolvedPath})`);
@@ -975,6 +1016,20 @@ export class ProjectConfiguration {
9751016
return result.module;
9761017
}
9771018

1019+
/**
1020+
* Resolves a loads a plugin function relative to initialDir
1021+
* @param initialDir
1022+
* @param moduleName
1023+
*/
1024+
private requirePlugin(initialDir: string, moduleName: string): RequireResult {
1025+
const modulePath = this.resolveJavaScriptModule(moduleName, initialDir, this.fs);
1026+
try {
1027+
return { module: require(modulePath), error: undefined };
1028+
} catch (error) {
1029+
return { module: undefined, error };
1030+
}
1031+
}
1032+
9781033
// TODO: stolen from moduleNameResolver.ts because marked as internal
9791034
/**
9801035
* Expose resolution logic to allow us to use Node module resolution logic from arbitrary locations.
@@ -992,26 +1047,11 @@ export class ProjectConfiguration {
9921047
return resolvedModule.resolvedFileName;
9931048
}
9941049

995-
private requirePlugin(initialDir: string, moduleName: string): RequireResult {
996-
const modulePath = this.resolveJavaScriptModule(moduleName, initialDir, this.fs);
997-
try {
998-
return { module: require(modulePath), error: undefined };
999-
} catch (error) {
1000-
return { module: undefined, error };
1001-
}
1002-
}
1003-
1004-
private enablePlugin(pluginConfigEntry: ts.PluginImport, searchPaths: string[]) {
1005-
for (const searchPath of searchPaths) {
1006-
const resolvedModule = this.resolveModule(pluginConfigEntry.name, searchPath) as PluginModuleFactory;
1007-
if (resolvedModule) {
1008-
this.enableProxy(resolvedModule, pluginConfigEntry);
1009-
return;
1010-
}
1011-
}
1012-
this.logger.info(`Couldn't find ${pluginConfigEntry.name} anywhere in paths: ${searchPaths.join(',')}`);
1013-
}
1014-
1050+
/**
1051+
* Replaces the LanguageService with an instance wrapped by the plugin
1052+
* @param pluginModuleFactory function to create the module
1053+
* @param configEntry extra settings from tsconfig to pass to the plugin module
1054+
*/
10151055
private enableProxy(pluginModuleFactory: PluginModuleFactory, configEntry: ts.PluginImport) {
10161056
try {
10171057
if (typeof pluginModuleFactory !== 'function') {

0 commit comments

Comments
 (0)