212 lines
7.3 KiB
JavaScript
212 lines
7.3 KiB
JavaScript
![]() |
"use strict";
|
||
|
/* --------------------------------------------------------------------------------------------
|
||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||
|
* ------------------------------------------------------------------------------------------ */
|
||
|
/// <reference path="../../typings/thenable.d.ts" />
|
||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||
|
}
|
||
|
Object.defineProperty(o, k2, desc);
|
||
|
}) : (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
o[k2] = m[k];
|
||
|
}));
|
||
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||
|
};
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
exports.createConnection = exports.Files = void 0;
|
||
|
const Is = require("../common/utils/is");
|
||
|
const server_1 = require("../common/server");
|
||
|
const fm = require("./files");
|
||
|
const node_1 = require("vscode-languageserver-protocol/node");
|
||
|
__exportStar(require("vscode-languageserver-protocol/node"), exports);
|
||
|
__exportStar(require("../common/api"), exports);
|
||
|
var Files;
|
||
|
(function (Files) {
|
||
|
Files.uriToFilePath = fm.uriToFilePath;
|
||
|
Files.resolveGlobalNodePath = fm.resolveGlobalNodePath;
|
||
|
Files.resolveGlobalYarnPath = fm.resolveGlobalYarnPath;
|
||
|
Files.resolve = fm.resolve;
|
||
|
Files.resolveModulePath = fm.resolveModulePath;
|
||
|
})(Files = exports.Files || (exports.Files = {}));
|
||
|
let _protocolConnection;
|
||
|
function endProtocolConnection() {
|
||
|
if (_protocolConnection === undefined) {
|
||
|
return;
|
||
|
}
|
||
|
try {
|
||
|
_protocolConnection.end();
|
||
|
}
|
||
|
catch (_err) {
|
||
|
// Ignore. The client process could have already
|
||
|
// did and we can't send an end into the connection.
|
||
|
}
|
||
|
}
|
||
|
let _shutdownReceived = false;
|
||
|
let exitTimer = undefined;
|
||
|
function setupExitTimer() {
|
||
|
const argName = '--clientProcessId';
|
||
|
function runTimer(value) {
|
||
|
try {
|
||
|
let processId = parseInt(value);
|
||
|
if (!isNaN(processId)) {
|
||
|
exitTimer = setInterval(() => {
|
||
|
try {
|
||
|
process.kill(processId, 0);
|
||
|
}
|
||
|
catch (ex) {
|
||
|
// Parent process doesn't exist anymore. Exit the server.
|
||
|
endProtocolConnection();
|
||
|
process.exit(_shutdownReceived ? 0 : 1);
|
||
|
}
|
||
|
}, 3000);
|
||
|
}
|
||
|
}
|
||
|
catch (e) {
|
||
|
// Ignore errors;
|
||
|
}
|
||
|
}
|
||
|
for (let i = 2; i < process.argv.length; i++) {
|
||
|
let arg = process.argv[i];
|
||
|
if (arg === argName && i + 1 < process.argv.length) {
|
||
|
runTimer(process.argv[i + 1]);
|
||
|
return;
|
||
|
}
|
||
|
else {
|
||
|
let args = arg.split('=');
|
||
|
if (args[0] === argName) {
|
||
|
runTimer(args[1]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
setupExitTimer();
|
||
|
const watchDog = {
|
||
|
initialize: (params) => {
|
||
|
const processId = params.processId;
|
||
|
if (Is.number(processId) && exitTimer === undefined) {
|
||
|
// We received a parent process id. Set up a timer to periodically check
|
||
|
// if the parent is still alive.
|
||
|
setInterval(() => {
|
||
|
try {
|
||
|
process.kill(processId, 0);
|
||
|
}
|
||
|
catch (ex) {
|
||
|
// Parent process doesn't exist anymore. Exit the server.
|
||
|
process.exit(_shutdownReceived ? 0 : 1);
|
||
|
}
|
||
|
}, 3000);
|
||
|
}
|
||
|
},
|
||
|
get shutdownReceived() {
|
||
|
return _shutdownReceived;
|
||
|
},
|
||
|
set shutdownReceived(value) {
|
||
|
_shutdownReceived = value;
|
||
|
},
|
||
|
exit: (code) => {
|
||
|
endProtocolConnection();
|
||
|
process.exit(code);
|
||
|
}
|
||
|
};
|
||
|
function createConnection(arg1, arg2, arg3, arg4) {
|
||
|
let factories;
|
||
|
let input;
|
||
|
let output;
|
||
|
let options;
|
||
|
if (arg1 !== void 0 && arg1.__brand === 'features') {
|
||
|
factories = arg1;
|
||
|
arg1 = arg2;
|
||
|
arg2 = arg3;
|
||
|
arg3 = arg4;
|
||
|
}
|
||
|
if (node_1.ConnectionStrategy.is(arg1) || node_1.ConnectionOptions.is(arg1)) {
|
||
|
options = arg1;
|
||
|
}
|
||
|
else {
|
||
|
input = arg1;
|
||
|
output = arg2;
|
||
|
options = arg3;
|
||
|
}
|
||
|
return _createConnection(input, output, options, factories);
|
||
|
}
|
||
|
exports.createConnection = createConnection;
|
||
|
function _createConnection(input, output, options, factories) {
|
||
|
if (!input && !output && process.argv.length > 2) {
|
||
|
let port = void 0;
|
||
|
let pipeName = void 0;
|
||
|
let argv = process.argv.slice(2);
|
||
|
for (let i = 0; i < argv.length; i++) {
|
||
|
let arg = argv[i];
|
||
|
if (arg === '--node-ipc') {
|
||
|
input = new node_1.IPCMessageReader(process);
|
||
|
output = new node_1.IPCMessageWriter(process);
|
||
|
break;
|
||
|
}
|
||
|
else if (arg === '--stdio') {
|
||
|
input = process.stdin;
|
||
|
output = process.stdout;
|
||
|
break;
|
||
|
}
|
||
|
else if (arg === '--socket') {
|
||
|
port = parseInt(argv[i + 1]);
|
||
|
break;
|
||
|
}
|
||
|
else if (arg === '--pipe') {
|
||
|
pipeName = argv[i + 1];
|
||
|
break;
|
||
|
}
|
||
|
else {
|
||
|
var args = arg.split('=');
|
||
|
if (args[0] === '--socket') {
|
||
|
port = parseInt(args[1]);
|
||
|
break;
|
||
|
}
|
||
|
else if (args[0] === '--pipe') {
|
||
|
pipeName = args[1];
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (port) {
|
||
|
let transport = (0, node_1.createServerSocketTransport)(port);
|
||
|
input = transport[0];
|
||
|
output = transport[1];
|
||
|
}
|
||
|
else if (pipeName) {
|
||
|
let transport = (0, node_1.createServerPipeTransport)(pipeName);
|
||
|
input = transport[0];
|
||
|
output = transport[1];
|
||
|
}
|
||
|
}
|
||
|
var commandLineMessage = 'Use arguments of createConnection or set command line parameters: \'--node-ipc\', \'--stdio\' or \'--socket={number}\'';
|
||
|
if (!input) {
|
||
|
throw new Error('Connection input stream is not set. ' + commandLineMessage);
|
||
|
}
|
||
|
if (!output) {
|
||
|
throw new Error('Connection output stream is not set. ' + commandLineMessage);
|
||
|
}
|
||
|
// Backwards compatibility
|
||
|
if (Is.func(input.read) && Is.func(input.on)) {
|
||
|
let inputStream = input;
|
||
|
inputStream.on('end', () => {
|
||
|
endProtocolConnection();
|
||
|
process.exit(_shutdownReceived ? 0 : 1);
|
||
|
});
|
||
|
inputStream.on('close', () => {
|
||
|
endProtocolConnection();
|
||
|
process.exit(_shutdownReceived ? 0 : 1);
|
||
|
});
|
||
|
}
|
||
|
const connectionFactory = (logger) => {
|
||
|
const result = (0, node_1.createProtocolConnection)(input, output, logger, options);
|
||
|
return result;
|
||
|
};
|
||
|
return (0, server_1.createConnection)(connectionFactory, watchDog, factories);
|
||
|
}
|