mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 04:49:35 +00:00
Add custom Node option to run TS Server (#191019)
* Add config for running tsserver on custom node * log when custom node install is used * create node version manager * get node path from node version manager everywhere * modify prompt * fix useIpc * use spawn for custom node and set windowsHide * detect node * link memory setting to node setting
This commit is contained in:
parent
4f6f33e491
commit
efc1b30976
|
@ -21,7 +21,8 @@
|
|||
"restrictedConfigurations": [
|
||||
"typescript.tsdk",
|
||||
"typescript.tsserver.pluginPaths",
|
||||
"typescript.npm"
|
||||
"typescript.npm",
|
||||
"typescript.tsserver.nodePath"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -1132,7 +1133,7 @@
|
|||
"typescript.tsserver.maxTsServerMemory": {
|
||||
"type": "number",
|
||||
"default": 3072,
|
||||
"description": "%configuration.tsserver.maxTsServerMemory%",
|
||||
"markdownDescription": "%configuration.tsserver.maxTsServerMemory%",
|
||||
"scope": "window"
|
||||
},
|
||||
"typescript.tsserver.experimental.enableProjectDiagnostics": {
|
||||
|
@ -1251,6 +1252,11 @@
|
|||
"description": "%configuration.tsserver.web.projectWideIntellisense.suppressSemanticErrors%",
|
||||
"scope": "window"
|
||||
},
|
||||
"typescript.tsserver.nodePath": {
|
||||
"type": "string",
|
||||
"description": "%configuration.tsserver.nodePath%",
|
||||
"scope": "window"
|
||||
},
|
||||
"typescript.experimental.tsserver.web.typeAcquisition.enabled": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
"configuration.tsserver.useSyntaxServer.always": "Use a lighter weight syntax server to handle all IntelliSense operations. This syntax server can only provide IntelliSense for opened files.",
|
||||
"configuration.tsserver.useSyntaxServer.never": "Don't use a dedicated syntax server. Use a single server to handle all IntelliSense operations.",
|
||||
"configuration.tsserver.useSyntaxServer.auto": "Spawn both a full server and a lighter weight server dedicated to syntax operations. The syntax server is used to speed up syntax operations and provide IntelliSense while projects are loading.",
|
||||
"configuration.tsserver.maxTsServerMemory": "The maximum amount of memory (in MB) to allocate to the TypeScript server process.",
|
||||
"configuration.tsserver.maxTsServerMemory": "The maximum amount of memory (in MB) to allocate to the TypeScript server process. To use a memory limit greater than 4 GB, use `#typescript.tsserver.nodePath#` to run TS Server with a custom Node installation.",
|
||||
"configuration.tsserver.experimental.enableProjectDiagnostics": "(Experimental) Enables project wide error reporting.",
|
||||
"typescript.locale": "Sets the locale used to report JavaScript and TypeScript errors. Defaults to use VS Code's locale.",
|
||||
"configuration.implicitProjectConfig.module": "Sets the module system for the program. See more: https://www.typescriptlang.org/tsconfig#module.",
|
||||
|
@ -213,6 +213,7 @@
|
|||
"configuration.suggest.objectLiteralMethodSnippets.enabled": "Enable/disable snippet completions for methods in object literals. Requires using TypeScript 4.7+ in the workspace.",
|
||||
"configuration.tsserver.web.projectWideIntellisense.enabled": "Enable/disable project-wide IntelliSense on web. Requires that VS Code is running in a trusted context.",
|
||||
"configuration.tsserver.web.projectWideIntellisense.suppressSemanticErrors": "Suppresses semantic errors. This is needed when using external packages as these can't be included analyzed on web.",
|
||||
"configuration.tsserver.nodePath": "Run TS Server on a custom Node installation. This can be a path to a Node executable, or 'node' if you want VS Code to detect a Node installation.",
|
||||
"configuration.experimental.tsserver.web.typeAcquisition.enabled": "Enable/disable package acquisition on the web.",
|
||||
"walkthroughs.nodejsWelcome.title": "Get started with JavaScript and Node.js",
|
||||
"walkthroughs.nodejsWelcome.description": "Make the most of Visual Studio Code's first-class JavaScript experience.",
|
||||
|
|
|
@ -16,4 +16,13 @@ export class BrowserServiceConfigurationProvider extends BaseServiceConfiguratio
|
|||
protected readLocalTsdk(_configuration: vscode.WorkspaceConfiguration): string | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
// On browsers, we don't run TSServer on Node
|
||||
protected readLocalNodePath(_configuration: vscode.WorkspaceConfiguration): string | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override readGlobalNodePath(_configuration: vscode.WorkspaceConfiguration): string | null {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,10 @@
|
|||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
import * as child_process from 'child_process';
|
||||
import * as fs from 'fs';
|
||||
import { BaseServiceConfigurationProvider } from './configuration';
|
||||
import { RelativeWorkspacePathResolver } from '../utils/relativePathResolver';
|
||||
|
||||
export class ElectronServiceConfigurationProvider extends BaseServiceConfigurationProvider {
|
||||
|
||||
|
@ -35,4 +38,65 @@ export class ElectronServiceConfigurationProvider extends BaseServiceConfigurati
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected readLocalNodePath(configuration: vscode.WorkspaceConfiguration): string | null {
|
||||
return this.validatePath(this.readLocalNodePathWorker(configuration));
|
||||
}
|
||||
|
||||
private readLocalNodePathWorker(configuration: vscode.WorkspaceConfiguration): string | null {
|
||||
const inspect = configuration.inspect('typescript.tsserver.nodePath');
|
||||
if (inspect?.workspaceValue && typeof inspect.workspaceValue === 'string') {
|
||||
if (inspect.workspaceValue === 'node') {
|
||||
return this.findNodePath();
|
||||
}
|
||||
const fixedPath = this.fixPathPrefixes(inspect.workspaceValue);
|
||||
if (!path.isAbsolute(fixedPath)) {
|
||||
const workspacePath = RelativeWorkspacePathResolver.asAbsoluteWorkspacePath(fixedPath);
|
||||
return workspacePath || null;
|
||||
}
|
||||
return fixedPath;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected readGlobalNodePath(configuration: vscode.WorkspaceConfiguration): string | null {
|
||||
return this.validatePath(this.readGlobalNodePathWorker(configuration));
|
||||
}
|
||||
|
||||
private readGlobalNodePathWorker(configuration: vscode.WorkspaceConfiguration): string | null {
|
||||
const inspect = configuration.inspect('typescript.tsserver.nodePath');
|
||||
if (inspect?.globalValue && typeof inspect.globalValue === 'string') {
|
||||
if (inspect.globalValue === 'node') {
|
||||
return this.findNodePath();
|
||||
}
|
||||
const fixedPath = this.fixPathPrefixes(inspect.globalValue);
|
||||
if (path.isAbsolute(fixedPath)) {
|
||||
return fixedPath;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private findNodePath(): string | null {
|
||||
try {
|
||||
const out = child_process.execFileSync('node', ['-e', 'console.log(process.execPath)'], {
|
||||
windowsHide: true,
|
||||
timeout: 2000,
|
||||
cwd: vscode.workspace.workspaceFolders?.[0].uri.fsPath,
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
return out.trim();
|
||||
} catch (error) {
|
||||
vscode.window.showWarningMessage(vscode.l10n.t("Could not detect a Node installation to run TS Server."));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private validatePath(nodePath: string | null): string | null {
|
||||
if (nodePath && (!fs.existsSync(nodePath) || fs.lstatSync(nodePath).isDirectory())) {
|
||||
vscode.window.showWarningMessage(vscode.l10n.t("The path {0} doesn\'t point to a valid Node installation to run TS Server. Falling back to bundled Node.", nodePath));
|
||||
return null;
|
||||
}
|
||||
return nodePath;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,6 +120,8 @@ export interface TypeScriptServiceConfiguration {
|
|||
readonly watchOptions: Proto.WatchOptions | undefined;
|
||||
readonly includePackageJsonAutoImports: 'auto' | 'on' | 'off' | undefined;
|
||||
readonly enableTsServerTracing: boolean;
|
||||
readonly localNodePath: string | null;
|
||||
readonly globalNodePath: string | null;
|
||||
}
|
||||
|
||||
export function areServiceConfigurationsEqual(a: TypeScriptServiceConfiguration, b: TypeScriptServiceConfiguration): boolean {
|
||||
|
@ -154,11 +156,15 @@ export abstract class BaseServiceConfigurationProvider implements ServiceConfigu
|
|||
watchOptions: this.readWatchOptions(configuration),
|
||||
includePackageJsonAutoImports: this.readIncludePackageJsonAutoImports(configuration),
|
||||
enableTsServerTracing: this.readEnableTsServerTracing(configuration),
|
||||
localNodePath: this.readLocalNodePath(configuration),
|
||||
globalNodePath: this.readGlobalNodePath(configuration),
|
||||
};
|
||||
}
|
||||
|
||||
protected abstract readGlobalTsdk(configuration: vscode.WorkspaceConfiguration): string | null;
|
||||
protected abstract readLocalTsdk(configuration: vscode.WorkspaceConfiguration): string | null;
|
||||
protected abstract readLocalNodePath(configuration: vscode.WorkspaceConfiguration): string | null;
|
||||
protected abstract readGlobalNodePath(configuration: vscode.WorkspaceConfiguration): string | null;
|
||||
|
||||
protected readTsServerLogLevel(configuration: vscode.WorkspaceConfiguration): TsServerLogLevel {
|
||||
const setting = configuration.get<string>('typescript.tsserver.log', 'off');
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { TypeScriptServiceConfiguration } from '../configuration/configuration';
|
||||
import { setImmediate } from '../utils/async';
|
||||
import { Disposable } from '../utils/dispose';
|
||||
|
||||
|
||||
const useWorkspaceNodeStorageKey = 'typescript.useWorkspaceNode';
|
||||
const lastKnownWorkspaceNodeStorageKey = 'typescript.lastKnownWorkspaceNode';
|
||||
type UseWorkspaceNodeState = undefined | boolean;
|
||||
type LastKnownWorkspaceNodeState = undefined | string;
|
||||
|
||||
export class NodeVersionManager extends Disposable {
|
||||
private _currentVersion: string | undefined;
|
||||
|
||||
public constructor(
|
||||
private configuration: TypeScriptServiceConfiguration,
|
||||
private readonly workspaceState: vscode.Memento
|
||||
) {
|
||||
super();
|
||||
|
||||
this._currentVersion = this.configuration.globalNodePath || undefined;
|
||||
if (vscode.workspace.isTrusted) {
|
||||
const workspaceVersion = this.configuration.localNodePath;
|
||||
if (workspaceVersion) {
|
||||
const useWorkspaceNode = this.canUseWorkspaceNode(workspaceVersion);
|
||||
if (useWorkspaceNode === undefined) {
|
||||
setImmediate(() => {
|
||||
this.promptAndSetWorkspaceNode();
|
||||
});
|
||||
}
|
||||
else if (useWorkspaceNode) {
|
||||
this._currentVersion = workspaceVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
this._disposables.push(vscode.workspace.onDidGrantWorkspaceTrust(() => {
|
||||
const workspaceVersion = this.configuration.localNodePath;
|
||||
if (workspaceVersion) {
|
||||
const useWorkspaceNode = this.canUseWorkspaceNode(workspaceVersion);
|
||||
if (useWorkspaceNode === undefined) {
|
||||
setImmediate(() => {
|
||||
this.promptAndSetWorkspaceNode();
|
||||
});
|
||||
}
|
||||
else if (useWorkspaceNode) {
|
||||
this.updateActiveVersion(workspaceVersion);
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private readonly _onDidPickNewVersion = this._register(new vscode.EventEmitter<void>());
|
||||
public readonly onDidPickNewVersion = this._onDidPickNewVersion.event;
|
||||
|
||||
public get currentVersion(): string | undefined {
|
||||
return this._currentVersion;
|
||||
}
|
||||
|
||||
public async updateConfiguration(nextConfiguration: TypeScriptServiceConfiguration) {
|
||||
const oldConfiguration = this.configuration;
|
||||
this.configuration = nextConfiguration;
|
||||
if (oldConfiguration.globalNodePath !== nextConfiguration.globalNodePath
|
||||
|| oldConfiguration.localNodePath !== nextConfiguration.localNodePath) {
|
||||
await this.computeNewVersion();
|
||||
}
|
||||
}
|
||||
|
||||
private async computeNewVersion() {
|
||||
let version = this.configuration.globalNodePath || undefined;
|
||||
const workspaceVersion = this.configuration.localNodePath;
|
||||
if (vscode.workspace.isTrusted && workspaceVersion) {
|
||||
const useWorkspaceNode = this.canUseWorkspaceNode(workspaceVersion);
|
||||
if (useWorkspaceNode === undefined) {
|
||||
version = await this.promptUseWorkspaceNode() || version;
|
||||
}
|
||||
else if (useWorkspaceNode) {
|
||||
version = workspaceVersion;
|
||||
}
|
||||
}
|
||||
this.updateActiveVersion(version);
|
||||
}
|
||||
|
||||
private async promptUseWorkspaceNode(): Promise<string | undefined> {
|
||||
const workspaceVersion = this.configuration.localNodePath;
|
||||
if (workspaceVersion === null) {
|
||||
throw new Error('Could not prompt to use workspace Node installation because no workspace Node installation is specified');
|
||||
}
|
||||
|
||||
const allow = vscode.l10n.t("Yes");
|
||||
const disallow = vscode.l10n.t("No");
|
||||
const dismiss = vscode.l10n.t("Not now");
|
||||
|
||||
const result = await vscode.window.showInformationMessage(vscode.l10n.t("This workspace wants to use the Node installation at '{0}' to run TS Server. Would you like to use it?", workspaceVersion),
|
||||
allow,
|
||||
disallow,
|
||||
dismiss,
|
||||
);
|
||||
|
||||
let version = undefined;
|
||||
switch (result) {
|
||||
case allow:
|
||||
await this.setUseWorkspaceNodeState(true, workspaceVersion);
|
||||
version = workspaceVersion;
|
||||
break;
|
||||
case disallow:
|
||||
await this.setUseWorkspaceNodeState(false, workspaceVersion);
|
||||
break;
|
||||
case dismiss:
|
||||
await this.setUseWorkspaceNodeState(undefined, workspaceVersion);
|
||||
break;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
private async promptAndSetWorkspaceNode(): Promise<void> {
|
||||
const version = await this.promptUseWorkspaceNode();
|
||||
if (version !== undefined) {
|
||||
this.updateActiveVersion(version);
|
||||
}
|
||||
}
|
||||
|
||||
private updateActiveVersion(pickedVersion: string | undefined): void {
|
||||
const oldVersion = this.currentVersion;
|
||||
this._currentVersion = pickedVersion;
|
||||
if (oldVersion !== pickedVersion) {
|
||||
this._onDidPickNewVersion.fire();
|
||||
}
|
||||
}
|
||||
|
||||
private canUseWorkspaceNode(nodeVersion: string): boolean | undefined {
|
||||
const lastKnownWorkspaceNode = this.workspaceState.get<LastKnownWorkspaceNodeState>(lastKnownWorkspaceNodeStorageKey);
|
||||
if (lastKnownWorkspaceNode === nodeVersion) {
|
||||
return this.workspaceState.get<UseWorkspaceNodeState>(useWorkspaceNodeStorageKey);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private async setUseWorkspaceNodeState(allow: boolean | undefined, nodeVersion: string) {
|
||||
await this.workspaceState.update(lastKnownWorkspaceNodeStorageKey, nodeVersion);
|
||||
await this.workspaceState.update(useWorkspaceNodeStorageKey, allow);
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ import type * as Proto from './protocol/protocol';
|
|||
import { EventName } from './protocol/protocol.const';
|
||||
import { TypeScriptVersionManager } from './versionManager';
|
||||
import { TypeScriptVersion } from './versionProvider';
|
||||
import { NodeVersionManager } from './nodeManager';
|
||||
|
||||
export enum ExecutionTarget {
|
||||
Semantic,
|
||||
|
@ -70,6 +71,7 @@ export interface TsServerProcessFactory {
|
|||
kind: TsServerProcessKind,
|
||||
configuration: TypeScriptServiceConfiguration,
|
||||
versionManager: TypeScriptVersionManager,
|
||||
nodeVersionManager: NodeVersionManager,
|
||||
tsServerLog: TsServerLog | undefined,
|
||||
): TsServerProcess;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import type * as Proto from './protocol/protocol';
|
|||
import { TsServerLog, TsServerProcess, TsServerProcessFactory, TsServerProcessKind } from './server';
|
||||
import { TypeScriptVersionManager } from './versionManager';
|
||||
import { TypeScriptVersion } from './versionProvider';
|
||||
import { NodeVersionManager } from './nodeManager';
|
||||
|
||||
type BrowserWatchEvent = {
|
||||
type: 'watchDirectory' | 'watchFile';
|
||||
|
@ -40,6 +41,7 @@ export class WorkerServerProcessFactory implements TsServerProcessFactory {
|
|||
kind: TsServerProcessKind,
|
||||
_configuration: TypeScriptServiceConfiguration,
|
||||
_versionManager: TypeScriptVersionManager,
|
||||
_nodeVersionManager: NodeVersionManager,
|
||||
tsServerLog: TsServerLog | undefined,
|
||||
) {
|
||||
const tsServerPath = version.tsServerPath;
|
||||
|
|
|
@ -15,6 +15,7 @@ import type * as Proto from './protocol/protocol';
|
|||
import { TsServerLog, TsServerProcess, TsServerProcessFactory, TsServerProcessKind } from './server';
|
||||
import { TypeScriptVersionManager } from './versionManager';
|
||||
import { TypeScriptVersion } from './versionProvider';
|
||||
import { NodeVersionManager } from './nodeManager';
|
||||
|
||||
|
||||
const defaultSize: number = 8192;
|
||||
|
@ -134,10 +135,12 @@ class Reader<T> extends Disposable {
|
|||
}
|
||||
}
|
||||
|
||||
function generatePatchedEnv(env: any, modulePath: string): any {
|
||||
function generatePatchedEnv(env: any, modulePath: string, hasExecPath: boolean): any {
|
||||
const newEnv = Object.assign({}, env);
|
||||
|
||||
newEnv['ELECTRON_RUN_AS_NODE'] = '1';
|
||||
if (!hasExecPath) {
|
||||
newEnv['ELECTRON_RUN_AS_NODE'] = '1';
|
||||
}
|
||||
newEnv['NODE_PATH'] = path.join(modulePath, '..', '..', '..');
|
||||
|
||||
// Ensure we always have a PATH set
|
||||
|
@ -253,6 +256,7 @@ export class ElectronServiceProcessFactory implements TsServerProcessFactory {
|
|||
kind: TsServerProcessKind,
|
||||
configuration: TypeScriptServiceConfiguration,
|
||||
versionManager: TypeScriptVersionManager,
|
||||
nodeVersionManager: NodeVersionManager,
|
||||
_tsserverLog: TsServerLog | undefined,
|
||||
): TsServerProcess {
|
||||
let tsServerPath = version.tsServerPath;
|
||||
|
@ -263,20 +267,30 @@ export class ElectronServiceProcessFactory implements TsServerProcessFactory {
|
|||
tsServerPath = versionManager.currentVersion.tsServerPath;
|
||||
}
|
||||
|
||||
const useIpc = version.apiVersion?.gte(API.v460);
|
||||
const execPath = nodeVersionManager.currentVersion;
|
||||
|
||||
const env = generatePatchedEnv(process.env, tsServerPath, !!execPath);
|
||||
const runtimeArgs = [...args];
|
||||
const execArgv = getExecArgv(kind, configuration);
|
||||
const useIpc = !execPath && version.apiVersion?.gte(API.v460);
|
||||
if (useIpc) {
|
||||
runtimeArgs.push('--useNodeIpc');
|
||||
}
|
||||
|
||||
const childProcess = child_process.fork(tsServerPath, runtimeArgs, {
|
||||
silent: true,
|
||||
cwd: undefined,
|
||||
env: generatePatchedEnv(process.env, tsServerPath),
|
||||
execArgv: getExecArgv(kind, configuration),
|
||||
stdio: useIpc ? ['pipe', 'pipe', 'pipe', 'ipc'] : undefined,
|
||||
});
|
||||
const childProcess = execPath ?
|
||||
child_process.spawn(execPath, [...execArgv, tsServerPath, ...runtimeArgs], {
|
||||
shell: true,
|
||||
windowsHide: true,
|
||||
cwd: undefined,
|
||||
env,
|
||||
}) :
|
||||
child_process.fork(tsServerPath, runtimeArgs, {
|
||||
silent: true,
|
||||
cwd: undefined,
|
||||
env,
|
||||
execArgv,
|
||||
stdio: useIpc ? ['pipe', 'pipe', 'pipe', 'ipc'] : undefined,
|
||||
});
|
||||
|
||||
return useIpc ? new IpcChildServerProcess(childProcess) : new StdioChildServerProcess(childProcess);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import { PluginManager } from './plugins';
|
|||
import { GetErrRoutingTsServer, ITypeScriptServer, SingleTsServer, SyntaxRoutingTsServer, TsServerDelegate, TsServerLog, TsServerProcessFactory, TsServerProcessKind } from './server';
|
||||
import { TypeScriptVersionManager } from './versionManager';
|
||||
import { ITypeScriptVersionProvider, TypeScriptVersion } from './versionProvider';
|
||||
import { NodeVersionManager } from './nodeManager';
|
||||
|
||||
const enum CompositeServerType {
|
||||
/** Run a single server that handles all commands */
|
||||
|
@ -44,6 +45,7 @@ export class TypeScriptServerSpawner {
|
|||
public constructor(
|
||||
private readonly _versionProvider: ITypeScriptVersionProvider,
|
||||
private readonly _versionManager: TypeScriptVersionManager,
|
||||
private readonly _nodeVersionManager: NodeVersionManager,
|
||||
private readonly _logDirectoryProvider: ILogDirectoryProvider,
|
||||
private readonly _pluginPathsProvider: TypeScriptPluginPathsProvider,
|
||||
private readonly _logger: Logger,
|
||||
|
@ -160,7 +162,7 @@ export class TypeScriptServerSpawner {
|
|||
}
|
||||
|
||||
this._logger.info(`<${kind}> Forking...`);
|
||||
const process = this._factory.fork(version, args, kind, configuration, this._versionManager, tsServerLog);
|
||||
const process = this._factory.fork(version, args, kind, configuration, this._versionManager, this._nodeVersionManager, tsServerLog);
|
||||
this._logger.info(`<${kind}> Starting...`);
|
||||
|
||||
return new SingleTsServer(
|
||||
|
|
|
@ -30,6 +30,7 @@ import { TelemetryProperties, TelemetryReporter, VSCodeTelemetryReporter } from
|
|||
import Tracer from './logging/tracer';
|
||||
import { ProjectType, inferredProjectCompilerOptions } from './tsconfig';
|
||||
import { Schemes } from './configuration/schemes';
|
||||
import { NodeVersionManager } from './tsServer/nodeManager';
|
||||
|
||||
|
||||
export interface TsDiagnostics {
|
||||
|
@ -103,6 +104,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType
|
|||
private _configuration: TypeScriptServiceConfiguration;
|
||||
private readonly pluginPathsProvider: TypeScriptPluginPathsProvider;
|
||||
private readonly _versionManager: TypeScriptVersionManager;
|
||||
private readonly _nodeVersionManager: NodeVersionManager;
|
||||
|
||||
private readonly logger: Logger;
|
||||
private readonly tracer: Tracer;
|
||||
|
@ -173,6 +175,11 @@ export default class TypeScriptServiceClient extends Disposable implements IType
|
|||
this.restartTsServer();
|
||||
}));
|
||||
|
||||
this._nodeVersionManager = this._register(new NodeVersionManager(this._configuration, context.workspaceState));
|
||||
this._register(this._nodeVersionManager.onDidPickNewVersion(() => {
|
||||
this.restartTsServer();
|
||||
}));
|
||||
|
||||
this.bufferSyncSupport = new BufferSyncSupport(this, allModeIds, onCaseInsenitiveFileSystem);
|
||||
this.onReady(() => { this.bufferSyncSupport.listen(); });
|
||||
|
||||
|
@ -192,6 +199,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType
|
|||
this.versionProvider.updateConfiguration(this._configuration);
|
||||
this._versionManager.updateConfiguration(this._configuration);
|
||||
this.pluginPathsProvider.updateConfiguration(this._configuration);
|
||||
this._nodeVersionManager.updateConfiguration(this._configuration);
|
||||
|
||||
if (this.serverState.type === ServerState.Type.Running) {
|
||||
if (!this._configuration.implicitProjectConfiguration.isEqualTo(oldConfiguration.implicitProjectConfiguration)) {
|
||||
|
@ -212,8 +220,9 @@ export default class TypeScriptServiceClient extends Disposable implements IType
|
|||
}
|
||||
return this.apiVersion.fullVersionString;
|
||||
});
|
||||
|
||||
this.diagnosticsManager = new DiagnosticsManager('typescript', this._configuration, this.telemetryReporter, onCaseInsenitiveFileSystem);
|
||||
this.typescriptServerSpawner = new TypeScriptServerSpawner(this.versionProvider, this._versionManager, this.logDirectoryProvider, this.pluginPathsProvider, this.logger, this.telemetryReporter, this.tracer, this.processFactory);
|
||||
this.typescriptServerSpawner = new TypeScriptServerSpawner(this.versionProvider, this._versionManager, this._nodeVersionManager, this.logDirectoryProvider, this.pluginPathsProvider, this.logger, this.telemetryReporter, this.tracer, this.processFactory);
|
||||
|
||||
this._register(this.pluginManager.onDidUpdateConfig(update => {
|
||||
this.configurePlugin(update.pluginId, update.config);
|
||||
|
@ -387,6 +396,10 @@ export default class TypeScriptServiceClient extends Disposable implements IType
|
|||
}
|
||||
|
||||
this.info(`Using tsserver from: ${version.path}`);
|
||||
const nodePath = this._nodeVersionManager.currentVersion;
|
||||
if (nodePath) {
|
||||
this.info(`Using Node installation from ${nodePath} to run TS Server`);
|
||||
}
|
||||
|
||||
const apiVersion = version.apiVersion || API.defaultVersion;
|
||||
const mytoken = ++this.token;
|
||||
|
|
Loading…
Reference in a new issue