UNPKG

@jupyterlab/debugger

Version:
270 lines 8.65 kB
// Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. import { nullTranslator } from '@jupyterlab/translation'; import { PromiseDelegate } from '@lumino/coreutils'; import { Signal } from '@lumino/signaling'; /** * A concrete implementation of IDebugger.ISession. */ export class DebuggerSession { /** * Instantiate a new debug session * * @param options - The debug session instantiation options. */ constructor(options) { this._seq = 0; this._ready = new PromiseDelegate(); this._isDisposed = false; this._isStarted = false; this._exceptionPaths = []; this._exceptionBreakpointFilters = []; this._currentExceptionFilters = {}; this._disposed = new Signal(this); this._eventMessage = new Signal(this); this.connection = options.connection; this._config = options.config; this.translator = options.translator || nullTranslator; } /** * Whether the debug session is disposed. */ get isDisposed() { return this._isDisposed; } /** * Returns the initialize response . */ get capabilities() { return this._capabilities; } /** * A signal emitted when the debug session is disposed. */ get disposed() { return this._disposed; } /** * Returns the API session connection to connect to a debugger. */ get connection() { return this._connection; } /** * Sets the API session connection to connect to a debugger to * the given parameter. * * @param connection - The new API session connection. */ set connection(connection) { var _a, _b; if (this._connection) { this._connection.iopubMessage.disconnect(this._handleEvent, this); } this._connection = connection; if (!this._connection) { this._isStarted = false; return; } this._connection.iopubMessage.connect(this._handleEvent, this); this._ready = new PromiseDelegate(); const future = (_b = (_a = this.connection) === null || _a === void 0 ? void 0 : _a.kernel) === null || _b === void 0 ? void 0 : _b.requestDebug({ type: 'request', seq: 0, command: 'debugInfo' }); if (future) { future.onReply = (msg) => { this._ready.resolve(); future.dispose(); }; } } /** * Whether the debug session is started. */ get isStarted() { return this._isStarted; } /** * Exception paths defined by the debugger */ get exceptionPaths() { return this._exceptionPaths; } /** * Exception breakpoint filters defined by the debugger */ get exceptionBreakpointFilters() { return this._exceptionBreakpointFilters; } /** * Get current exception filters. */ get currentExceptionFilters() { var _a, _b, _c; const kernel = (_c = (_b = (_a = this.connection) === null || _a === void 0 ? void 0 : _a.kernel) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : ''; if (!kernel) { return []; } const tmpFileParams = this._config.getTmpFileParams(kernel); if (!tmpFileParams) { return []; } let prefix = tmpFileParams.prefix; if (Object.keys(this._currentExceptionFilters).includes(prefix)) { return this._currentExceptionFilters[prefix]; } return []; } /** * Set current exception filters. */ set currentExceptionFilters(exceptionFilters) { var _a, _b, _c; const kernel = (_c = (_b = (_a = this.connection) === null || _a === void 0 ? void 0 : _a.kernel) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : ''; if (!kernel) { return; } const tmpFileParams = this._config.getTmpFileParams(kernel); if (!tmpFileParams) { return; } let prefix = tmpFileParams.prefix; if (exceptionFilters === null) { if (Object.keys(this._currentExceptionFilters).includes(prefix)) { delete this._currentExceptionFilters[prefix]; } } else { this._currentExceptionFilters[prefix] = exceptionFilters; } } /** * Signal emitted for debug event messages. */ get eventMessage() { return this._eventMessage; } /** * Dispose the debug session. */ dispose() { if (this._isDisposed) { return; } this._isDisposed = true; this._disposed.emit(); Signal.clearData(this); } /** * Start a new debug session */ async start() { var _a, _b, _c, _d; const initializeResponse = await this.sendRequest('initialize', { clientID: 'jupyterlab', clientName: 'JupyterLab', adapterID: (_c = (_b = (_a = this.connection) === null || _a === void 0 ? void 0 : _a.kernel) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : '', pathFormat: 'path', linesStartAt1: true, columnsStartAt1: true, supportsVariableType: true, supportsVariablePaging: true, supportsRunInTerminalRequest: true, locale: document.documentElement.lang }); if (!initializeResponse.success) { throw new Error(`Could not start the debugger: ${initializeResponse.message}`); } this._capabilities = initializeResponse.body; this._isStarted = true; this._exceptionBreakpointFilters = (_d = initializeResponse.body) === null || _d === void 0 ? void 0 : _d.exceptionBreakpointFilters; await this.sendRequest('attach', {}); } /** * Stop the running debug session. */ async stop() { this._isStarted = false; await this.sendRequest('disconnect', { restart: false, terminateDebuggee: false }); } /** * Restore the state of a debug session. */ async restoreState() { var _a; const message = await this.sendRequest('debugInfo', {}); this._isStarted = message.body.isStarted; this._exceptionPaths = (_a = message.body) === null || _a === void 0 ? void 0 : _a.exceptionPaths; return message; } /** * Whether the debugger is pausing on exception. * * @param filter - Specify a filter */ isPausingOnException(filter) { var _a, _b; if (filter) { return (_b = (_a = this.currentExceptionFilters) === null || _a === void 0 ? void 0 : _a.includes(filter)) !== null && _b !== void 0 ? _b : false; } else { return this.currentExceptionFilters.length > 0; } } /** * Send a custom debug request to the kernel. * * @param command debug command. * @param args arguments for the debug command. */ async sendRequest(command, args) { await this._ready.promise; const message = await this._sendDebugMessage({ type: 'request', seq: this._seq++, command, arguments: args }); return message.content; } /** * Handle debug events sent on the 'iopub' channel. * * @param sender - the emitter of the event. * @param message - the event message. */ _handleEvent(sender, message) { const msgType = message.header.msg_type; if (msgType !== 'debug_event') { return; } const event = message.content; this._eventMessage.emit(event); } /** * Send a debug request message to the kernel. * * @param msg debug request message to send to the kernel. */ async _sendDebugMessage(msg) { var _a; const kernel = (_a = this.connection) === null || _a === void 0 ? void 0 : _a.kernel; if (!kernel) { return Promise.reject(new Error('A kernel is required to send debug messages.')); } const reply = new PromiseDelegate(); const future = kernel.requestDebug(msg); future.onReply = (msg) => { reply.resolve(msg); }; await future.done; return reply.promise; } } //# sourceMappingURL=session.js.map