diff --git a/lib/protocol.d.ts b/lib/protocol.d.ts index fc9a35893fe..2fc15c3a256 100644 --- a/lib/protocol.d.ts +++ b/lib/protocol.d.ts @@ -1790,6 +1790,7 @@ declare namespace ts.server.protocol { outDir?: string; outFile?: string; paths?: MapLike; + plugins?: PluginImport[]; preserveConstEnums?: boolean; project?: string; reactNamespace?: string; @@ -1886,7 +1887,11 @@ declare namespace ts.server.protocol { [index: string]: T; } - type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike; + interface PluginImport { + name: string; + } + + type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike | PluginImport[]; } declare namespace ts { // these types are empty stubs for types from services and should not be used directly diff --git a/lib/tsc.js b/lib/tsc.js index aeefb1ad857..66bbafecb14 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -19730,11 +19730,16 @@ var ts; } } function nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache) { + return nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, false); + } + ts.nodeModuleNameResolver = nodeModuleNameResolver; + function nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, jsOnly) { + if (jsOnly === void 0) { jsOnly = false; } var containingDirectory = ts.getDirectoryPath(containingFile); var traceEnabled = isTraceEnabled(compilerOptions, host); var failedLookupLocations = []; var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled }; - var result = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript); + var result = jsOnly ? tryResolve(Extensions.JavaScript) : (tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript)); if (result && result.value) { var _a = result.value, resolved = _a.resolved, isExternalLibraryImport = _a.isExternalLibraryImport; return createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations); @@ -19760,7 +19765,7 @@ var ts; } } } - ts.nodeModuleNameResolver = nodeModuleNameResolver; + ts.nodeModuleNameResolverWorker = nodeModuleNameResolverWorker; function realpath(path, host, traceEnabled) { if (!host.realpath) { return path; @@ -52409,6 +52414,15 @@ var ts; name: "alwaysStrict", type: "boolean", description: ts.Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file + }, + { + name: "plugins", + type: "list", + isTSConfigOnly: true, + element: { + name: "plugin", + type: "object" + } } ]; ts.typeAcquisitionDeclarations = [ diff --git a/lib/tsserver.js b/lib/tsserver.js index 53fd42a0434..43d6afe3dd5 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -3795,11 +3795,16 @@ var ts; } } function nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache) { + return nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, false); + } + ts.nodeModuleNameResolver = nodeModuleNameResolver; + function nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, jsOnly) { + if (jsOnly === void 0) { jsOnly = false; } var containingDirectory = ts.getDirectoryPath(containingFile); var traceEnabled = isTraceEnabled(compilerOptions, host); var failedLookupLocations = []; var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled }; - var result = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript); + var result = jsOnly ? tryResolve(Extensions.JavaScript) : (tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript)); if (result && result.value) { var _a = result.value, resolved = _a.resolved, isExternalLibraryImport = _a.isExternalLibraryImport; return createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations); @@ -3825,7 +3830,7 @@ var ts; } } } - ts.nodeModuleNameResolver = nodeModuleNameResolver; + ts.nodeModuleNameResolverWorker = nodeModuleNameResolverWorker; function realpath(path, host, traceEnabled) { if (!host.realpath) { return path; @@ -52419,6 +52424,15 @@ var ts; name: "alwaysStrict", type: "boolean", description: ts.Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file + }, + { + name: "plugins", + type: "list", + isTSConfigOnly: true, + element: { + name: "plugin", + type: "object" + } } ]; ts.typeAcquisitionDeclarations = [ @@ -68381,6 +68395,16 @@ var ts; Project.prototype.getCachedUnresolvedImportsPerFile_TestOnly = function () { return this.cachedUnresolvedImportsPerFile; }; + Project.resolveModule = function (moduleName, initialDir, host, log) { + var resolvedPath = ts.normalizeSlashes(host.resolvePath(ts.combinePaths(initialDir, "node_modules"))); + log("Loading " + moduleName + " from " + initialDir + " (resolved to " + resolvedPath + ")"); + var result = host.require(resolvedPath, moduleName); + if (result.error) { + log("Failed to load module: " + JSON.stringify(result.error)); + return undefined; + } + return result.module; + }; Project.prototype.setInternalCompilerOptionsForEmittingJsFiles = function () { if (this.projectKind === ProjectKind.Inferred || this.projectKind === ProjectKind.External) { this.compilerOptions.noEmitForJsFiles = true; @@ -68424,6 +68448,9 @@ var ts; Project.prototype.getProjectName = function () { return this.projectName; }; + Project.prototype.getExternalFiles = function () { + return []; + }; Project.prototype.getSourceFile = function (path) { if (!this.program) { return undefined; @@ -68891,15 +68918,63 @@ var ts; __extends(ConfiguredProject, _super); function ConfiguredProject(configFileName, projectService, documentRegistry, hasExplicitListOfFiles, compilerOptions, wildcardDirectories, languageServiceEnabled, compileOnSaveEnabled) { var _this = _super.call(this, configFileName, ProjectKind.Configured, projectService, documentRegistry, hasExplicitListOfFiles, languageServiceEnabled, compilerOptions, compileOnSaveEnabled) || this; + _this.configFileName = configFileName; _this.wildcardDirectories = wildcardDirectories; _this.compileOnSaveEnabled = compileOnSaveEnabled; + _this.plugins = []; _this.openRefCount = 0; _this.canonicalConfigFilePath = server.asNormalizedPath(projectService.toCanonicalFileName(configFileName)); + _this.enablePlugins(); return _this; } ConfiguredProject.prototype.getConfigFilePath = function () { return this.getProjectName(); }; + ConfiguredProject.prototype.enablePlugins = function () { + var _this = this; + var host = this.projectService.host; + var options = this.getCompilerOptions(); + var log = function (message) { + _this.projectService.logger.info(message); + }; + if (!(options.plugins && options.plugins.length)) { + this.projectService.logger.info("No plugins exist"); + return; + } + if (!host.require) { + this.projectService.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded"); + return; + } + for (var _i = 0, _a = options.plugins; _i < _a.length; _i++) { + var pluginConfigEntry = _a[_i]; + var searchPath = ts.getDirectoryPath(this.configFileName); + var resolvedModule = Project.resolveModule(pluginConfigEntry.name, searchPath, host, log); + if (resolvedModule) { + this.enableProxy(resolvedModule, pluginConfigEntry); + } + } + }; + ConfiguredProject.prototype.enableProxy = function (pluginModuleFactory, configEntry) { + try { + if (typeof pluginModuleFactory !== "function") { + this.projectService.logger.info("Skipped loading plugin " + configEntry.name + " because it did expose a proper factory function"); + return; + } + var info = { + config: configEntry, + project: this, + languageService: this.languageService, + languageServiceHost: this.lsHost, + serverHost: this.projectService.host + }; + var pluginModule = pluginModuleFactory({ typescript: ts }); + this.languageService = pluginModule.create(info); + this.plugins.push(pluginModule); + } + catch (e) { + this.projectService.logger.info("Plugin activation failed: " + e); + } + }; ConfiguredProject.prototype.getProjectRootPath = function () { return ts.getDirectoryPath(this.getConfigFilePath()); }; @@ -68912,6 +68987,21 @@ var ts; ConfiguredProject.prototype.getTypeAcquisition = function () { return this.typeAcquisition; }; + ConfiguredProject.prototype.getExternalFiles = function () { + var items = []; + for (var _i = 0, _a = this.plugins; _i < _a.length; _i++) { + var plugin = _a[_i]; + if (typeof plugin.getExternalFiles === "function") { + try { + items.push.apply(items, plugin.getExternalFiles(this)); + } + catch (e) { + this.projectService.logger.info("A plugin threw an exception in getExternalFiles: " + e); + } + } + } + return items; + }; ConfiguredProject.prototype.watchConfigFile = function (callback) { var _this = this; this.projectFileWatcher = this.projectService.host.watchFile(this.getConfigFilePath(), function (_) { return callback(_this); }); @@ -73011,6 +73101,15 @@ var ts; if (typeof global !== "undefined" && global.gc) { sys.gc = function () { return global.gc(); }; } + sys.require = function (initialDir, moduleName) { + var result = ts.nodeModuleNameResolverWorker(moduleName, initialDir + "/program.ts", { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, sys, undefined, true); + try { + return { module: require(result.resolvedModule.resolvedFileName), error: undefined }; + } + catch (e) { + return { module: undefined, error: e }; + } + }; var cancellationToken; try { var factory = require("./cancellationToken"); diff --git a/lib/tsserverlibrary.d.ts b/lib/tsserverlibrary.d.ts index ab8d2e141e3..95d11503c6e 100644 --- a/lib/tsserverlibrary.d.ts +++ b/lib/tsserverlibrary.d.ts @@ -1908,7 +1908,10 @@ declare namespace ts { Classic = 1, NodeJs = 2, } - type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike; + interface PluginImport { + name: string; + } + type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike | PluginImport[]; interface CompilerOptions { allowJs?: boolean; allowSyntheticDefaultImports?: boolean; @@ -2017,6 +2020,7 @@ declare namespace ts { JSX = 2, TS = 3, TSX = 4, + External = 5, } const enum ScriptTarget { ES3 = 0, @@ -3206,6 +3210,13 @@ declare namespace ts.server { compressionKind: string; data: any; } + type RequireResult = { + module: {}; + error: undefined; + } | { + module: undefined; + error: {}; + }; interface ServerHost extends System { setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): any; clearTimeout(timeoutId: any): void; @@ -3213,6 +3224,7 @@ declare namespace ts.server { clearImmediate(timeoutId: any): void; gc?(): void; trace?(s: string): void; + require?(initialPath: string, moduleName: string): RequireResult; } interface SortedReadonlyArray extends ReadonlyArray { " __sortedReadonlyArrayBrand": any; @@ -4115,6 +4127,7 @@ declare namespace ts.server.protocol { outDir?: string; outFile?: string; paths?: MapLike; + plugins?: PluginImport[]; preserveConstEnums?: boolean; project?: string; reactNamespace?: string; @@ -4598,6 +4611,22 @@ declare namespace ts.server { get(path: Path): ReadonlyArray; set(path: Path, value: ReadonlyArray): void; } + interface PluginCreateInfo { + project: Project; + languageService: LanguageService; + languageServiceHost: LanguageServiceHost; + serverHost: ServerHost; + config: any; + } + interface PluginModule { + create(createInfo: PluginCreateInfo): LanguageService; + getExternalFiles?(proj: Project): string[]; + } + interface PluginModuleFactory { + (mod: { + typescript: typeof ts; + }): PluginModule; + } abstract class Project { private readonly projectName; readonly projectKind: ProjectKind; @@ -4607,12 +4636,12 @@ declare namespace ts.server { compileOnSaveEnabled: boolean; private rootFiles; private rootFilesMap; - private lsHost; private program; private cachedUnresolvedImportsPerFile; private lastCachedUnresolvedImportsList; - private readonly languageService; + protected languageService: LanguageService; languageServiceEnabled: boolean; + protected readonly lsHost: LSHost; builder: Builder; private updatedFileNames; private lastReportedFileNames; @@ -4625,6 +4654,7 @@ declare namespace ts.server { isNonTsProject(): boolean; isJsOnlyProject(): boolean; getCachedUnresolvedImportsPerFile_TestOnly(): UnresolvedImportsMap; + static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {}; constructor(projectName: string, projectKind: ProjectKind, projectService: ProjectService, documentRegistry: ts.DocumentRegistry, hasExplicitListOfFiles: boolean, languageServiceEnabled: boolean, compilerOptions: CompilerOptions, compileOnSaveEnabled: boolean); private setInternalCompilerOptionsForEmittingJsFiles(); getProjectErrors(): Diagnostic[]; @@ -4636,6 +4666,7 @@ declare namespace ts.server { getProjectName(): string; abstract getProjectRootPath(): string | undefined; abstract getTypeAcquisition(): TypeAcquisition; + getExternalFiles(): string[]; getSourceFile(path: Path): SourceFile; updateTypes(): void; close(): void; @@ -4682,6 +4713,7 @@ declare namespace ts.server { getTypeAcquisition(): TypeAcquisition; } class ConfiguredProject extends Project { + private configFileName; private wildcardDirectories; compileOnSaveEnabled: boolean; private typeAcquisition; @@ -4690,13 +4722,17 @@ declare namespace ts.server { private directoriesWatchedForWildcards; private typeRootsWatchers; readonly canonicalConfigFilePath: NormalizedPath; + private plugins; openRefCount: number; constructor(configFileName: NormalizedPath, projectService: ProjectService, documentRegistry: ts.DocumentRegistry, hasExplicitListOfFiles: boolean, compilerOptions: CompilerOptions, wildcardDirectories: Map, languageServiceEnabled: boolean, compileOnSaveEnabled: boolean); getConfigFilePath(): string; + enablePlugins(): void; + private enableProxy(pluginModuleFactory, configEntry); getProjectRootPath(): string; setProjectErrors(projectErrors: Diagnostic[]): void; setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void; getTypeAcquisition(): TypeAcquisition; + getExternalFiles(): string[]; watchConfigFile(callback: (project: ConfiguredProject) => void): void; watchTypeRoots(callback: (project: ConfiguredProject, path: string) => void): void; watchConfigDirectory(callback: (project: ConfiguredProject, path: string) => void): void; @@ -4752,7 +4788,7 @@ declare namespace ts.server { function convertFormatOptions(protocolOptions: protocol.FormatCodeSettings): FormatCodeSettings; function convertCompilerOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): CompilerOptions & protocol.CompileOnSaveMixin; function tryConvertScriptKindName(scriptKindName: protocol.ScriptKindName | ScriptKind): ScriptKind; - function convertScriptKindName(scriptKindName: protocol.ScriptKindName): ScriptKind; + function convertScriptKindName(scriptKindName: protocol.ScriptKindName): ScriptKind.Unknown | ScriptKind.JS | ScriptKind.JSX | ScriptKind.TS | ScriptKind.TSX; function combineProjectOutput(projects: Project[], action: (project: Project) => T[], comparer?: (a: T, b: T) => number, areEqual?: (a: T, b: T) => boolean): T[]; interface HostConfiguration { formatCodeOptions: FormatCodeSettings; diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index 26499261e02..037936d6cb0 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -5351,6 +5351,15 @@ var ts; name: "alwaysStrict", type: "boolean", description: ts.Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file + }, + { + name: "plugins", + type: "list", + isTSConfigOnly: true, + element: { + name: "plugin", + type: "object" + } } ]; ts.typeAcquisitionDeclarations = [ @@ -6474,11 +6483,16 @@ var ts; } } function nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache) { + return nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, false); + } + ts.nodeModuleNameResolver = nodeModuleNameResolver; + function nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, jsOnly) { + if (jsOnly === void 0) { jsOnly = false; } var containingDirectory = ts.getDirectoryPath(containingFile); var traceEnabled = isTraceEnabled(compilerOptions, host); var failedLookupLocations = []; var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled }; - var result = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript); + var result = jsOnly ? tryResolve(Extensions.JavaScript) : (tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript)); if (result && result.value) { var _a = result.value, resolved = _a.resolved, isExternalLibraryImport = _a.isExternalLibraryImport; return createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations); @@ -6504,7 +6518,7 @@ var ts; } } } - ts.nodeModuleNameResolver = nodeModuleNameResolver; + ts.nodeModuleNameResolverWorker = nodeModuleNameResolverWorker; function realpath(path, host, traceEnabled) { if (!host.realpath) { return path; @@ -70121,6 +70135,16 @@ var ts; Project.prototype.getCachedUnresolvedImportsPerFile_TestOnly = function () { return this.cachedUnresolvedImportsPerFile; }; + Project.resolveModule = function (moduleName, initialDir, host, log) { + var resolvedPath = ts.normalizeSlashes(host.resolvePath(ts.combinePaths(initialDir, "node_modules"))); + log("Loading " + moduleName + " from " + initialDir + " (resolved to " + resolvedPath + ")"); + var result = host.require(resolvedPath, moduleName); + if (result.error) { + log("Failed to load module: " + JSON.stringify(result.error)); + return undefined; + } + return result.module; + }; Project.prototype.setInternalCompilerOptionsForEmittingJsFiles = function () { if (this.projectKind === ProjectKind.Inferred || this.projectKind === ProjectKind.External) { this.compilerOptions.noEmitForJsFiles = true; @@ -70164,6 +70188,9 @@ var ts; Project.prototype.getProjectName = function () { return this.projectName; }; + Project.prototype.getExternalFiles = function () { + return []; + }; Project.prototype.getSourceFile = function (path) { if (!this.program) { return undefined; @@ -70631,15 +70658,63 @@ var ts; __extends(ConfiguredProject, _super); function ConfiguredProject(configFileName, projectService, documentRegistry, hasExplicitListOfFiles, compilerOptions, wildcardDirectories, languageServiceEnabled, compileOnSaveEnabled) { var _this = _super.call(this, configFileName, ProjectKind.Configured, projectService, documentRegistry, hasExplicitListOfFiles, languageServiceEnabled, compilerOptions, compileOnSaveEnabled) || this; + _this.configFileName = configFileName; _this.wildcardDirectories = wildcardDirectories; _this.compileOnSaveEnabled = compileOnSaveEnabled; + _this.plugins = []; _this.openRefCount = 0; _this.canonicalConfigFilePath = server.asNormalizedPath(projectService.toCanonicalFileName(configFileName)); + _this.enablePlugins(); return _this; } ConfiguredProject.prototype.getConfigFilePath = function () { return this.getProjectName(); }; + ConfiguredProject.prototype.enablePlugins = function () { + var _this = this; + var host = this.projectService.host; + var options = this.getCompilerOptions(); + var log = function (message) { + _this.projectService.logger.info(message); + }; + if (!(options.plugins && options.plugins.length)) { + this.projectService.logger.info("No plugins exist"); + return; + } + if (!host.require) { + this.projectService.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded"); + return; + } + for (var _i = 0, _a = options.plugins; _i < _a.length; _i++) { + var pluginConfigEntry = _a[_i]; + var searchPath = ts.getDirectoryPath(this.configFileName); + var resolvedModule = Project.resolveModule(pluginConfigEntry.name, searchPath, host, log); + if (resolvedModule) { + this.enableProxy(resolvedModule, pluginConfigEntry); + } + } + }; + ConfiguredProject.prototype.enableProxy = function (pluginModuleFactory, configEntry) { + try { + if (typeof pluginModuleFactory !== "function") { + this.projectService.logger.info("Skipped loading plugin " + configEntry.name + " because it did expose a proper factory function"); + return; + } + var info = { + config: configEntry, + project: this, + languageService: this.languageService, + languageServiceHost: this.lsHost, + serverHost: this.projectService.host + }; + var pluginModule = pluginModuleFactory({ typescript: ts }); + this.languageService = pluginModule.create(info); + this.plugins.push(pluginModule); + } + catch (e) { + this.projectService.logger.info("Plugin activation failed: " + e); + } + }; ConfiguredProject.prototype.getProjectRootPath = function () { return ts.getDirectoryPath(this.getConfigFilePath()); }; @@ -70652,6 +70727,21 @@ var ts; ConfiguredProject.prototype.getTypeAcquisition = function () { return this.typeAcquisition; }; + ConfiguredProject.prototype.getExternalFiles = function () { + var items = []; + for (var _i = 0, _a = this.plugins; _i < _a.length; _i++) { + var plugin = _a[_i]; + if (typeof plugin.getExternalFiles === "function") { + try { + items.push.apply(items, plugin.getExternalFiles(this)); + } + catch (e) { + this.projectService.logger.info("A plugin threw an exception in getExternalFiles: " + e); + } + } + } + return items; + }; ConfiguredProject.prototype.watchConfigFile = function (callback) { var _this = this; this.projectFileWatcher = this.projectService.host.watchFile(this.getConfigFilePath(), function (_) { return callback(_this); }); diff --git a/lib/typescript.d.ts b/lib/typescript.d.ts index e4b99514255..2f361cffc99 100644 --- a/lib/typescript.d.ts +++ b/lib/typescript.d.ts @@ -1992,7 +1992,10 @@ declare namespace ts { Classic = 1, NodeJs = 2, } - type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike; + interface PluginImport { + name: string; + } + type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike | PluginImport[]; interface CompilerOptions { allowJs?: boolean; allowSyntheticDefaultImports?: boolean; @@ -2102,6 +2105,7 @@ declare namespace ts { JSX = 2, TS = 3, TSX = 4, + External = 5, } enum ScriptTarget { ES3 = 0, diff --git a/lib/typescript.js b/lib/typescript.js index 2637569891b..c0c6a62a410 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -823,6 +823,7 @@ var ts; ScriptKind[ScriptKind["JSX"] = 2] = "JSX"; ScriptKind[ScriptKind["TS"] = 3] = "TS"; ScriptKind[ScriptKind["TSX"] = 4] = "TSX"; + ScriptKind[ScriptKind["External"] = 5] = "External"; })(ScriptKind = ts.ScriptKind || (ts.ScriptKind = {})); var ScriptTarget; (function (ScriptTarget) { @@ -24301,11 +24302,17 @@ var ts; } } function nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache) { + return nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, /* jsOnly*/ false); + } + ts.nodeModuleNameResolver = nodeModuleNameResolver; + /* @internal */ + function nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, jsOnly) { + if (jsOnly === void 0) { jsOnly = false; } var containingDirectory = ts.getDirectoryPath(containingFile); var traceEnabled = isTraceEnabled(compilerOptions, host); var failedLookupLocations = []; var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled }; - var result = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript); + var result = jsOnly ? tryResolve(Extensions.JavaScript) : (tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript)); if (result && result.value) { var _a = result.value, resolved = _a.resolved, isExternalLibraryImport = _a.isExternalLibraryImport; return createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations); @@ -24332,7 +24339,7 @@ var ts; } } } - ts.nodeModuleNameResolver = nodeModuleNameResolver; + ts.nodeModuleNameResolverWorker = nodeModuleNameResolverWorker; function realpath(path, host, traceEnabled) { if (!host.realpath) { return path; @@ -65572,6 +65579,16 @@ var ts; name: "alwaysStrict", type: "boolean", description: ts.Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file + }, + { + // A list of plugins to load in the language service + name: "plugins", + type: "list", + isTSConfigOnly: true, + element: { + name: "plugin", + type: "object" + } } ]; /* @internal */ diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts index 6a8ffedc46a..0482926ea26 100644 --- a/lib/typescriptServices.d.ts +++ b/lib/typescriptServices.d.ts @@ -1992,7 +1992,10 @@ declare namespace ts { Classic = 1, NodeJs = 2, } - type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike; + interface PluginImport { + name: string; + } + type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike | PluginImport[]; interface CompilerOptions { allowJs?: boolean; allowSyntheticDefaultImports?: boolean; @@ -2102,6 +2105,7 @@ declare namespace ts { JSX = 2, TS = 3, TSX = 4, + External = 5, } enum ScriptTarget { ES3 = 0, diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index 2637569891b..c0c6a62a410 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -823,6 +823,7 @@ var ts; ScriptKind[ScriptKind["JSX"] = 2] = "JSX"; ScriptKind[ScriptKind["TS"] = 3] = "TS"; ScriptKind[ScriptKind["TSX"] = 4] = "TSX"; + ScriptKind[ScriptKind["External"] = 5] = "External"; })(ScriptKind = ts.ScriptKind || (ts.ScriptKind = {})); var ScriptTarget; (function (ScriptTarget) { @@ -24301,11 +24302,17 @@ var ts; } } function nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache) { + return nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, /* jsOnly*/ false); + } + ts.nodeModuleNameResolver = nodeModuleNameResolver; + /* @internal */ + function nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, jsOnly) { + if (jsOnly === void 0) { jsOnly = false; } var containingDirectory = ts.getDirectoryPath(containingFile); var traceEnabled = isTraceEnabled(compilerOptions, host); var failedLookupLocations = []; var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled }; - var result = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript); + var result = jsOnly ? tryResolve(Extensions.JavaScript) : (tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript)); if (result && result.value) { var _a = result.value, resolved = _a.resolved, isExternalLibraryImport = _a.isExternalLibraryImport; return createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations); @@ -24332,7 +24339,7 @@ var ts; } } } - ts.nodeModuleNameResolver = nodeModuleNameResolver; + ts.nodeModuleNameResolverWorker = nodeModuleNameResolverWorker; function realpath(path, host, traceEnabled) { if (!host.realpath) { return path; @@ -65572,6 +65579,16 @@ var ts; name: "alwaysStrict", type: "boolean", description: ts.Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file + }, + { + // A list of plugins to load in the language service + name: "plugins", + type: "list", + isTSConfigOnly: true, + element: { + name: "plugin", + type: "object" + } } ]; /* @internal */ diff --git a/lib/typingsInstaller.js b/lib/typingsInstaller.js index cb9d2334266..449a55c3ee9 100644 --- a/lib/typingsInstaller.js +++ b/lib/typingsInstaller.js @@ -5351,6 +5351,15 @@ var ts; name: "alwaysStrict", type: "boolean", description: ts.Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file + }, + { + name: "plugins", + type: "list", + isTSConfigOnly: true, + element: { + name: "plugin", + type: "object" + } } ]; ts.typeAcquisitionDeclarations = [ @@ -6662,11 +6671,16 @@ var ts; } } function nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache) { + return nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, false); + } + ts.nodeModuleNameResolver = nodeModuleNameResolver; + function nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, jsOnly) { + if (jsOnly === void 0) { jsOnly = false; } var containingDirectory = ts.getDirectoryPath(containingFile); var traceEnabled = isTraceEnabled(compilerOptions, host); var failedLookupLocations = []; var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled }; - var result = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript); + var result = jsOnly ? tryResolve(Extensions.JavaScript) : (tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript)); if (result && result.value) { var _a = result.value, resolved = _a.resolved, isExternalLibraryImport = _a.isExternalLibraryImport; return createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations); @@ -6692,7 +6706,7 @@ var ts; } } } - ts.nodeModuleNameResolver = nodeModuleNameResolver; + ts.nodeModuleNameResolverWorker = nodeModuleNameResolverWorker; function realpath(path, host, traceEnabled) { if (!host.realpath) { return path;