@inst/vscode-bin-darwin
Version:
BINARY ONLY - VSCode binary deployment for macOS
308 lines (307 loc) • 15.2 kB
JavaScript
/* --------------------------------------------------------------------------------------------
* 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 = {}));