UNPKG

vscode-helpers

Version:

Helper functions and classes for own VS Code (extensions)

231 lines 6.77 kB
"use strict"; /** * This file is part of the vscode-helpers distribution. * Copyright (c) Marcel Joachim Kloubert. * * vscode-helpers is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, version 3. * * vscode-helpers is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ Object.defineProperty(exports, "__esModule", { value: true }); const _ = require("lodash"); const Events = require("events"); const vscode_helpers = require("../index"); /** * Name of the event, when an object has been disposed. */ exports.EVENT_DISPOSED = 'disposed'; /** * Name of an event, when an object is going to be disposed. */ exports.EVENT_DISPOSING = 'disposing'; /** * A disposable object. */ class DisposableBase extends Events.EventEmitter { constructor() { super(...arguments); /** * Stores disposable sub objects. */ this._DISPOSABLES = []; /** * Stores intervals. */ this._INTERVALS = []; this._isDisposed = false; this._isDisposing = false; /** * Stores timeouts. */ this._TIMEOUTS = []; } /** * Cleansup all timeouts. */ cleanupIntervals() { while (this._TIMEOUTS.length > 0) { vscode_helpers.tryClearInterval(this._TIMEOUTS.shift()); } } /** * Cleansup all timeouts. */ cleanupTimeouts() { while (this._TIMEOUTS.length > 0) { vscode_helpers.tryClearTimeout(this._TIMEOUTS.shift()); } } /** @inheritdoc */ dispose() { if (this.isInFinalizeState) { return; } try { this._isDisposing = true; this.emit(exports.EVENT_DISPOSING); this.cleanupIntervals(); this.cleanupTimeouts(); this.removeAllListeners(); while (this._DISPOSABLES.length > 0) { tryDispose(this._DISPOSABLES.shift()); } this.onDispose(); this._isDisposed = true; this.emit(exports.EVENT_DISPOSED); } finally { this._isDisposing = false; } } /** * Gets if object has been disposed or not. */ get isDisposed() { return this._isDisposed; } /** * Gets if the 'dispose()' method is currently executed or not. */ get isDisposing() { return this._isDisposing; } /** * Gets if the object is disposed or currently disposing. */ get isInFinalizeState() { return this.isDisposed || this.isDisposing; } /** * Additional logic for the 'dispose()' method. */ onDispose() { } } exports.DisposableBase = DisposableBase; /** * Clones an object and makes it non disposable. * * @param {TObj} obj The object to clone. * @param {boolean} [throwOnDispose] Throw error when coll 'dispose()' method or not. * * @return {TObj} The cloned object. */ function makeNonDisposable(obj, throwOnDispose = true) { throwOnDispose = vscode_helpers.toBooleanSafe(throwOnDispose, true); const CLONED_OBJ = vscode_helpers.cloneObjectFlat(obj); if (CLONED_OBJ) { if (_.isFunction(CLONED_OBJ.dispose)) { CLONED_OBJ.dispose = () => { if (throwOnDispose) { throw new Error('Disposing object is not allowed!'); } }; } } return CLONED_OBJ; } exports.makeNonDisposable = makeNonDisposable; /** * Tries to dispose an object. * * @param {object} obj The object to dispose. * * @return {boolean} Operation was successful or not. */ function tryDispose(obj) { try { if (obj && obj.dispose) { obj.dispose(); } return true; } catch (_a) { return false; } } exports.tryDispose = tryDispose; /** * Tries to dispose an object inside another, parent object and deletes it there. * * @param {any} obj The "other" / parent object. * @param {PropertyKey} key The key inside 'obj', where the disposable object is stored and should be removed. * @param {boolean} [alwaysDelete] Delete even if operation failed or not. * * @return {vscode.Disposable|false} The disposed and removed object or (false) if failed. */ function tryDisposeAndDelete(obj, key, alwaysDelete = true) { alwaysDelete = vscode_helpers.toBooleanSafe(alwaysDelete, true); let result; try { if (obj) { let deleteObject = true; result = obj[key]; if (!tryDispose(result)) { deleteObject = alwaysDelete; } if (deleteObject) { delete obj[key]; } else { result = false; } } } catch (_a) { result = false; } return result; } exports.tryDisposeAndDelete = tryDisposeAndDelete; /** * Invokes a function for a disposable object and keeps sure, that this object will be disposed, * even on error. * * @param {TObj} obj The object. * @param {Function} func The function to invoke. * @param {any[]} [args] One or more additional arguments for the function. * * @return Promise<TResult> The promise with the result of the function. */ async function using(obj, func, ...args) { try { return await Promise.resolve(func.apply(null, [obj].concat(args))); } finally { if (obj) { obj.dispose(); } } } exports.using = using; /** * Invokes a function for a disposable object sync and keeps sure, that this object will be disposed, * even on error. * * @param {TObj} obj The object. * @param {Function} func The function to invoke. * @param {any[]} [args] One or more additional arguments for the function. * * @return TResult The result of the function. */ function usingSync(obj, func, ...args) { try { return func.apply(null, [obj].concat(args)); } finally { if (obj) { obj.dispose(); } } } exports.usingSync = usingSync; //# sourceMappingURL=index.js.map