UNPKG

@inst/vscode-bin-darwin

Version:

BINARY ONLY - VSCode binary deployment for macOS

308 lines (307 loc) 15.2 kB
/* -------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ 'use strict'; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); const cp = require("child_process"); const client_1 = require("./client"); const vscode_1 = require("vscode"); const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol"); const is = require("./utils/is"); const electron = require("./utils/electron"); const processes_1 = require("./utils/processes"); __export(require("./client")); var TransportKind; (function (TransportKind) { TransportKind[TransportKind["stdio"] = 0] = "stdio"; TransportKind[TransportKind["ipc"] = 1] = "ipc"; TransportKind[TransportKind["pipe"] = 2] = "pipe"; })(TransportKind = exports.TransportKind || (exports.TransportKind = {})); class LanguageClient extends client_1.BaseLanguageClient { constructor(arg1, arg2, arg3, arg4, arg5) { let id; let name; let serverOptions; let clientOptions; let forceDebug; if (is.string(arg2)) { id = arg1; name = arg2; serverOptions = arg3; clientOptions = arg4; forceDebug = !!arg5; } else { id = arg1.toLowerCase(); name = arg1; serverOptions = arg2; clientOptions = arg3; forceDebug = arg4; } if (forceDebug === void 0) { forceDebug = false; } super(id, name, clientOptions); this._serverOptions = serverOptions; this._forceDebug = forceDebug; } stop() { return super.stop().then(() => { if (this._childProcess) { let toCheck = this._childProcess; this._childProcess = undefined; this.checkProcessDied(toCheck); } }); } checkProcessDied(childProcess) { if (!childProcess) { return; } setTimeout(() => { // Test if the process is still alive. Throws an exception if not try { process.kill(childProcess.pid, 0); processes_1.terminate(childProcess); } catch (error) { // All is fine. } }, 2000); } handleConnectionClosed() { this._childProcess = undefined; super.handleConnectionClosed(); } createMessageTransports(encoding) { let rootPath = this.clientOptions.workspaceFolder ? this.clientOptions.workspaceFolder.uri.fsPath : vscode_1.workspace.rootPath; function getEnvironment(env) { if (!env) { return process.env; } let result = Object.create(null); Object.keys(process.env).forEach(key => result[key] = process.env[key]); Object.keys(env).forEach(key => result[key] = env[key]); return result; } function startedInDebugMode() { let args = process.execArgv; if (args) { return args.some((arg) => /^--debug=?/.test(arg) || /^--debug-brk=?/.test(arg) || /^--inspect=?/.test(arg) || /^--inspect-brk=?/.test(arg)); } ; return false; } let server = this._serverOptions; // We got a function. if (is.func(server)) { return server().then((result) => { let info = result; if (info.writer && info.reader) { return { reader: new vscode_languageserver_protocol_1.StreamMessageReader(info.reader), writer: new vscode_languageserver_protocol_1.StreamMessageWriter(info.writer) }; } else { let cp = result; cp.stderr.on('data', data => this.outputChannel.append(is.string(data) ? data : data.toString(encoding))); return { reader: new vscode_languageserver_protocol_1.StreamMessageReader(cp.stdout), writer: new vscode_languageserver_protocol_1.StreamMessageWriter(cp.stdin) }; } }); } let json; let runDebug = server; if (runDebug.run || runDebug.debug) { // We are under debugging. So use debug as well. if (typeof v8debug === 'object' || this._forceDebug || startedInDebugMode()) { json = runDebug.debug; } else { json = runDebug.run; } } else { json = server; } if (json.module) { let node = json; let transport = node.transport || TransportKind.stdio; if (node.runtime) { let args = []; let options = node.options || Object.create(null); if (options.execArgv) { options.execArgv.forEach(element => args.push(element)); } args.push(node.module); if (node.args) { node.args.forEach(element => args.push(element)); } let execOptions = Object.create(null); execOptions.cwd = options.cwd || rootPath; execOptions.env = getEnvironment(options.env); let pipeName = undefined; if (transport === TransportKind.ipc) { // exec options not correctly typed in lib execOptions.stdio = [null, null, null, 'ipc']; args.push('--node-ipc'); } else if (transport === TransportKind.stdio) { args.push('--stdio'); } else if (transport === TransportKind.pipe) { pipeName = vscode_languageserver_protocol_1.generateRandomPipeName(); args.push(`--pipe=${pipeName}`); } if (transport === TransportKind.ipc || transport === TransportKind.stdio) { let process = cp.spawn(node.runtime, args, execOptions); if (!process || !process.pid) { return Promise.reject(`Launching server using runtime ${node.runtime} failed.`); } this._childProcess = process; process.stderr.on('data', data => this.outputChannel.append(is.string(data) ? data : data.toString(encoding))); if (transport === TransportKind.ipc) { process.stdout.on('data', data => this.outputChannel.append(is.string(data) ? data : data.toString(encoding))); return Promise.resolve({ reader: new vscode_languageserver_protocol_1.IPCMessageReader(process), writer: new vscode_languageserver_protocol_1.IPCMessageWriter(process) }); } else { return Promise.resolve({ reader: new vscode_languageserver_protocol_1.StreamMessageReader(process.stdout), writer: new vscode_languageserver_protocol_1.StreamMessageWriter(process.stdin) }); } } else if (transport == TransportKind.pipe) { return vscode_languageserver_protocol_1.createClientPipeTransport(pipeName).then((transport) => { let process = cp.spawn(node.runtime, args, execOptions); if (!process || !process.pid) { return Promise.reject(`Launching server using runtime ${node.runtime} failed.`); } this._childProcess = process; process.stderr.on('data', data => this.outputChannel.append(is.string(data) ? data : data.toString(encoding))); process.stdout.on('data', data => this.outputChannel.append(is.string(data) ? data : data.toString(encoding))); return transport.onConnected().then((protocol) => { return { reader: protocol[0], writer: protocol[1] }; }); }); } } else { let pipeName = undefined; return new Promise((resolve, reject) => { let args = node.args && node.args.slice() || []; if (transport === TransportKind.ipc) { args.push('--node-ipc'); } else if (transport === TransportKind.stdio) { args.push('--stdio'); } else if (transport === TransportKind.pipe) { pipeName = vscode_languageserver_protocol_1.generateRandomPipeName(); args.push(`--pipe=${pipeName}`); } let options = node.options || Object.create(null); options.execArgv = options.execArgv || []; options.cwd = options.cwd || rootPath; if (transport === TransportKind.ipc || transport === TransportKind.stdio) { electron.fork(node.module, args || [], options, (error, cp) => { if (error || !cp) { reject(error); } else { this._childProcess = cp; cp.stderr.on('data', data => this.outputChannel.append(is.string(data) ? data : data.toString(encoding))); if (transport === TransportKind.ipc) { cp.stdout.on('data', data => this.outputChannel.append(is.string(data) ? data : data.toString(encoding))); resolve({ reader: new vscode_languageserver_protocol_1.IPCMessageReader(this._childProcess), writer: new vscode_languageserver_protocol_1.IPCMessageWriter(this._childProcess) }); } else { resolve({ reader: new vscode_languageserver_protocol_1.StreamMessageReader(cp.stdout), writer: new vscode_languageserver_protocol_1.StreamMessageWriter(cp.stdin) }); } } }); } else if (transport === TransportKind.pipe) { vscode_languageserver_protocol_1.createClientPipeTransport(pipeName).then((transport) => { electron.fork(node.module, args || [], options, (error, cp) => { if (error || !cp) { reject(error); } else { this._childProcess = cp; cp.stderr.on('data', data => this.outputChannel.append(is.string(data) ? data : data.toString(encoding))); cp.stdout.on('data', data => this.outputChannel.append(is.string(data) ? data : data.toString(encoding))); transport.onConnected().then((protocol) => { resolve({ reader: protocol[0], writer: protocol[1] }); }); } }); }); } }); } } else if (json.command) { let command = json; let args = command.args || []; let options = command.options || {}; options.cwd = options.cwd || rootPath; let process = cp.spawn(command.command, args, options); if (!process || !process.pid) { return Promise.reject(`Launching server using command ${command.command} failed.`); } process.stderr.on('data', data => this.outputChannel.append(is.string(data) ? data : data.toString(encoding))); this._childProcess = process; return Promise.resolve({ reader: new vscode_languageserver_protocol_1.StreamMessageReader(process.stdout), writer: new vscode_languageserver_protocol_1.StreamMessageWriter(process.stdin) }); } return Promise.reject(new Error(`Unsupported server configuration ` + JSON.stringify(server, null, 4))); } registerProposedFeatures() { this.registerFeatures(ProposedFeatures.createAll(this)); } } exports.LanguageClient = LanguageClient; class SettingMonitor { constructor(_client, _setting) { this._client = _client; this._setting = _setting; this._listeners = []; } start() { vscode_1.workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, this._listeners); this.onDidChangeConfiguration(); return new vscode_1.Disposable(() => { if (this._client.needsStop()) { this._client.stop(); } }); } onDidChangeConfiguration() { let index = this._setting.indexOf('.'); let primary = index >= 0 ? this._setting.substr(0, index) : this._setting; let rest = index >= 0 ? this._setting.substr(index + 1) : undefined; let enabled = rest ? vscode_1.workspace.getConfiguration(primary).get(rest, false) : vscode_1.workspace.getConfiguration(primary); if (enabled && this._client.needsStart()) { this._client.start(); } else if (!enabled && this._client.needsStop()) { this._client.stop(); } } } exports.SettingMonitor = SettingMonitor; // Exporting proposed protocol. const config = require("./configuration.proposed"); const folders = require("./workspaceFolders.proposed"); var ProposedFeatures; (function (ProposedFeatures) { ProposedFeatures.ConfigurationFeature = config.ConfigurationFeature; ProposedFeatures.WorkspaceFoldersFeature = folders.WorkspaceFoldersFeature; function createAll(client) { let result = []; result.push(new ProposedFeatures.WorkspaceFoldersFeature(client)); result.push(new ProposedFeatures.ConfigurationFeature(client)); return result; } ProposedFeatures.createAll = createAll; })(ProposedFeatures = exports.ProposedFeatures || (exports.ProposedFeatures = {}));