UNPKG

@imc-trading/svlangserver

Version:
272 lines (271 loc) 8.63 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.tmpFileManager = exports.ChildProcManager = exports.DelayedCaller = exports.childProcessStderrRedir = exports.childProcessStdoutRedir = exports.ConnectionLogger = exports.isStringListEqual = exports.getTmpDirSync = exports.resolvedPath = exports.pathToUri = exports.uriToPath = exports.fsUnlinkSync = exports.fsWriteFileSync = exports.fsWriteFile = exports.fsExists = exports.fsReadFileSync = exports.fsReadFile = void 0; const node_1 = require("vscode-languageserver/node"); const vscode_uri_1 = require("vscode-uri"); const child = require("child_process"); const fs = require('fs'); const path = require('path'); const util = require('util'); const tmp = require('tmp'); const fsMkDir = util.promisify(fs.mkdir); const _fsWriteFile = util.promisify(fs.writeFile); exports.fsReadFile = util.promisify(fs.readFile); exports.fsReadFileSync = fs.readFileSync; exports.fsExists = util.promisify(fs.exists); async function fsWriteFile(file, content) { try { return fsMkDir(path.dirname(file), { recursive: true }) .then(() => { return _fsWriteFile(file, content); }) .catch(error => { ConnectionLogger.error(error); }); } catch (error) { ConnectionLogger.error(error); } } exports.fsWriteFile = fsWriteFile; function fsWriteFileSync(file, content) { try { fs.mkdirSync(path.dirname(file), { recursive: true }); fs.writeFileSync(file, content); return true; } catch (error) { ConnectionLogger.error(error); return false; } } exports.fsWriteFileSync = fsWriteFileSync; function fsUnlinkSync(file) { try { fs.unlinkSync(file); return true; } catch (error) { ConnectionLogger.error(error); return false; } } exports.fsUnlinkSync = fsUnlinkSync; function uriToPath(uri) { try { let fsPath = vscode_uri_1.URI.parse(uri).fsPath; try { return fs.realpathSync(fsPath); } catch (error) { ConnectionLogger.error(error); return fsPath; } } catch (error) { ConnectionLogger.error(error); return undefined; } } exports.uriToPath = uriToPath; ; function pathToUri(path) { try { return (vscode_uri_1.URI.file(path).toString()); } catch (error) { ConnectionLogger.error(error); return undefined; } } exports.pathToUri = pathToUri; function resolvedPath(file) { try { return path.resolve(__dirname, file); } catch (error) { ConnectionLogger.error(error); return undefined; } } exports.resolvedPath = resolvedPath; function getTmpDirSync() { try { return tmp.dirSync({ unsafeCleanup: true }); } catch (error) { ConnectionLogger.error(error); return undefined; } } exports.getTmpDirSync = getTmpDirSync; function isStringListEqual(stringList1, stringList2) { try { if ((stringList1 == undefined) && (stringList2 == undefined)) { return true; } else if (stringList1 == undefined) { return false; } else if (stringList2 == undefined) { return false; } else if (stringList1.length != stringList2.length) { return false; } let sortedStringList1 = stringList1.sort((one, two) => (one > two ? -1 : 1)); let sortedStringList2 = stringList1.sort((one, two) => (one > two ? -1 : 1)); for (let i = 0; i < stringList1.length; i++) { if (sortedStringList1[i] != sortedStringList2[i]) { return false; } } return true; } catch (error) { ConnectionLogger.error(error); return false; } } exports.isStringListEqual = isStringListEqual; class ConnectionLogger { static sendNotification(type, message) { if (!ConnectionLogger._connection) { switch (type) { case node_1.MessageType.Error: { console.error(message); break; } default: { console.log(message); break; } } } else { try { ConnectionLogger._connection.sendNotification(node_1.LogMessageNotification.type, { type: type, message: message }); } catch (error) { console.error(error); } } } static setConnection(connection) { ConnectionLogger._connection = connection; } static log(message, prefix = true) { ConnectionLogger.sendNotification(node_1.MessageType.Log, `${prefix ? "INFO: " : ""}${message}`); } static warn(message, prefix = true) { ConnectionLogger.sendNotification(node_1.MessageType.Warning, `${prefix ? "WARNING: " : ""}${message}`); } static error(message, prefix = true) { ConnectionLogger.sendNotification(node_1.MessageType.Error, `${prefix ? "ERROR: " : ""}${message}`); } } exports.ConnectionLogger = ConnectionLogger; ConnectionLogger._connection = null; function childProcessStdoutRedir(data) { try { let message = data.toString(); if (message.startsWith("WARNING: ")) { ConnectionLogger.warn(message, false); } else { ConnectionLogger.log(message, false); } } catch (error) { ConnectionLogger.error(error, false); return; } } exports.childProcessStdoutRedir = childProcessStdoutRedir; function childProcessStderrRedir(data) { try { let message = data.toString(); ConnectionLogger.error(message, false); } catch (error) { ConnectionLogger.error(error, false); return; } } exports.childProcessStderrRedir = childProcessStderrRedir; class DelayedCaller { constructor(timeOut = 1000) { this._callWaiting = new Map(); this._timeOut = timeOut; } run(callName, successCallback, errorCallback) { if (this._callWaiting.has(callName)) { let [waitTimer, resolver] = this._callWaiting.get(callName); clearTimeout(waitTimer); resolver(false); } return new Promise(resolve => { this._callWaiting.set(callName, [setTimeout(resolve, this._timeOut, true), resolve]); }).then((success) => { if (!!success) { this._callWaiting.delete(callName); } return successCallback(!!success); }).catch(error => { return errorCallback(error); }); } } exports.DelayedCaller = DelayedCaller; class ChildProcManager { constructor() { this._alreadyRunning = new Map(); } kill(key) { if (this._alreadyRunning.has(key)) { //ConnectionLogger.log(`DEBUG: Killing already running command to start a new one`); let [proc, statusRef] = this._alreadyRunning.get(key); statusRef[0] = false; proc.kill(); } } run(key, command, callBack) { let statusRef = [true]; this._alreadyRunning.set(key, [ child.exec(command, (error, stdout, stderr) => { if (statusRef[0]) { this._alreadyRunning.delete(key); } callBack(statusRef[0], error, stdout, stderr); }), statusRef ]); } } exports.ChildProcManager = ChildProcManager; class TmpFileManager { constructor() { this._freeTmpFileNums = new Map(); this._tmpDir = getTmpDirSync(); } getTmpFilePath(...elems) { return path.join(this._tmpDir.name, ...elems); } cleanupTmpFiles() { this._tmpDir.removeCallback(); } getFreeTmpFileNum(key) { if (!this._freeTmpFileNums.has(key)) { this._freeTmpFileNums.set(key, { total: 0, nums: [] }); } if (this._freeTmpFileNums.get(key).nums.length <= 0) { this._freeTmpFileNums.get(key).nums.push(this._freeTmpFileNums.get(key).total++); } return this._freeTmpFileNums.get(key).nums.shift(); } returnFreeTmpFileNum(key, tmpFileNum) { if (this._freeTmpFileNums.has(key)) { this._freeTmpFileNums.get(key).nums.push(tmpFileNum); } else { ConnectionLogger.error(`FreeTmpFileNums doesn't have the key ${key}`); } } } exports.tmpFileManager = new TmpFileManager();