Skip to content
This repository was archived by the owner on Jan 26, 2022. It is now read-only.

Store configuration options for multiple kernels #474

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
e940580
Editor handler for console and file debug
KrzysztofSikoraCodete Jun 17, 2020
53874c5
Refactor editor finder related with #473
KrzysztofSikoraCodete Jun 18, 2020
c2d2e16
Optional param for service (test case)
KrzysztofSikoraCodete Jun 18, 2020
903cb46
nullish and undefined editor finder instance prevent
KrzysztofSikoraCodete Jun 18, 2020
e80b425
Test
KrzysztofSikoraCodete Jun 18, 2020
0c5bbbe
Separated class for hash method.
KrzysztofSikoraCodete Jun 19, 2020
57af03b
Two line
KrzysztofSikoraCodete Jun 19, 2020
3dc3dec
Debugger test changed
KrzysztofSikoraCodete Jun 19, 2020
1f8512e
Provider error solved
KrzysztofSikoraCodete Jun 23, 2020
2af814b
Return provider
KrzysztofSikoraCodete Jun 23, 2020
946c793
Refactored name
KrzysztofSikoraCodete Jun 24, 2020
5e74dc3
Refactor _filterBreakpoints method\
KrzysztofSikoraCodete Jun 24, 2020
4f21ea1
Doc string correction
KrzysztofSikoraCodete Jun 24, 2020
7114c37
Multiple kernels hash parameters solution
KrzysztofSikoraCodete Jun 30, 2020
531ebf3
Attempt of work around test error
KrzysztofSikoraCodete Jun 30, 2020
8ba174f
Revert work around
KrzysztofSikoraCodete Jun 30, 2020
fdb4e03
Kernel name to setHashParameters
KrzysztofSikoraCodete Jul 7, 2020
96561f5
Refactor of parameters for method
KrzysztofSikoraCodete Jul 9, 2020
9ed4f17
Two line
KrzysztofSikoraCodete Jun 19, 2020
1681f75
Some clean up and refactoring
afshin Jul 10, 2020
be605a0
Update doc strings
afshin Jul 10, 2020
3106fac
Test updated
KrzysztofSikoraCodete Jul 10, 2020
d5fff95
Fix typo issue into tokens
KrzysztofSikoraCodete Jul 10, 2020
db0cffb
Refactor setHashParams()
afshin Jul 10, 2020
ea63089
More clean up and refactoring
afshin Jul 10, 2020
dcbad26
Refactor editor finder
afshin Jul 10, 2020
b618d35
Change hashing seed to `any` and make it optional to support future a…
afshin Jul 10, 2020
8937201
Remove EditorFinder#dispose
afshin Jul 10, 2020
d24e6d5
Update yarn.lock
afshin Jul 10, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions src/debugger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { bugIcon } from '@jupyterlab/ui-components';

import { Panel, SplitPanel, Widget } from '@lumino/widgets';

import { murmur2 } from 'murmurhash-js';

import { Breakpoints } from './breakpoints';

import { Callstack } from './callstack';
Expand All @@ -25,6 +27,57 @@ import { Variables } from './variables';
* A namespace for `Debugger` statics.
*/
export namespace Debugger {
/**
* A class that holds debugger configuration for a kernel.
*/
export class Config implements IDebugger.IConfig {
/**
* Returns an id based on the given code.
*
* @param code The source code.
* @param kernel The kernel name from current session.
*/
getCodeId(code: string, kernel: string): string {
const { prefix, suffix } = this._fileParams.get(kernel);
const hash = this._hashMethods.get(kernel);

if (!hash) {
throw new Error(`Kernel (${kernel}) has no hashing params.`);
}

return `${prefix}${hash(code)}${suffix}`;
}

/**
* Sets the hash parameters for a kernel.
*
* @param params - Hashing parameters for a kernel.
*/
setHashParams(params: IDebugger.IConfig.HashParams): void {
const { kernel, method, seed } = params;
switch (method) {
case 'Murmur2':
this._hashMethods.set(kernel, code => murmur2(code, seed).toString());
break;
default:
throw new Error(`Hash method (${method}) is not supported.`);
}
}

/**
* Sets the parameters used by the kernel to create temp files (e.g. cells).
*
* @param params - Temporary file prefix and suffix for a kernel.
*/
setTmpFileParams(params: IDebugger.IConfig.FileParams): void {
const { kernel, prefix, suffix } = params;
this._fileParams.set(kernel, { kernel, prefix, suffix });
}

private _fileParams = new Map<string, IDebugger.IConfig.FileParams>();
private _hashMethods = new Map<string, (code: string) => string>();
}

/**
* A debugger sidebar.
*/
Expand Down
150 changes: 48 additions & 102 deletions src/editor-finder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,94 +19,62 @@ import { INotebookTracker } from '@jupyterlab/notebook';

import { chain, each, IIterator } from '@lumino/algorithm';

import { Token } from '@lumino/coreutils';

import { IDisposable } from '@lumino/disposable';

import { Signal } from '@lumino/signaling';

import { IDebugger } from './tokens';

/**
* A class to find instances of code editors across notebook, console and files widgets
*/
export class EditorFinder implements IDisposable, IDebuggerEditorFinder {
export class EditorFinder implements IDebugger.IEditorFinder {
/**
* Instantiate a new EditorFinder.
*
* @param options The instantiation options for a EditorFinder.
*/
constructor(options: EditorFinder.IOptions) {
this._config = options.config;
this._shell = options.shell;
this._service = options.service;
this._notebookTracker = options.notebookTracker;
this._consoleTracker = options.consoleTracker;
this._editorTracker = options.editorTracker;
this._readOnlyEditorTracker = new WidgetTracker<
MainAreaWidget<CodeEditorWrapper>
>({
namespace: '@jupyterlab/debugger'
});
>({ namespace: '@jupyterlab/debugger' });
}

/**
* Whether the handler is disposed.
*/
isDisposed: boolean;

/**
* Dispose the handler.
*/
dispose(): void {
if (this.isDisposed) {
return;
}
this.isDisposed = true;
Signal.clearData(this);
}

/**
* Find the editor for a source matching the current debug session
* by iterating through all the widgets in each of the notebook,
* console, file editor, and read-only file editor trackers.
* Returns an iterator of editors for a source matching the current debug
* session by iterating through all the widgets in each of the supported
* debugger types (i.e., consoles, files, notebooks).
*
* @param debugSessionPath The path for the current debug session.
* @param source The source to find.
* @param focus - Set to true to focus on the relevant cell. Default to false.
* @param params - The editor search parameters.
*/
find(
debugSessionPath: string,
source: string,
focus: boolean
): IIterator<CodeEditor.IEditor> {
find(params: IDebugger.IEditorFinder.Params): IIterator<CodeEditor.IEditor> {
return chain(
this._findInNotebooks(debugSessionPath, source, focus),
this._findInConsoles(debugSessionPath, source, focus),
this._findInEditors(debugSessionPath, source, focus),
this._findInReadOnlyEditors(debugSessionPath, source, focus)
this._findInConsoles(params),
this._findInEditors(params),
this._findInNotebooks(params),
this._findInReadOnlyEditors(params)
);
}

/**
* Find the editor for a source matching the current debug session
* Find relevant editors matching the search params in the notebook tracker.
*
* @param debugSessionPath The path for the current debug session.
* @param source The source to find.
* @param focus - Set to true to focus on the relevant cell. Default to false.
* @param params - The editor search parameters.
*/
private _findInNotebooks(
debugSessionPath: string,
source: string,
focus: boolean
params: IDebugger.IEditorFinder.Params
): CodeEditor.IEditor[] {
if (!this._notebookTracker) {
return [];
}
const { focus, kernel, path, source } = params;

const editors: CodeEditor.IEditor[] = [];
this._notebookTracker.forEach(notebookPanel => {
const sessionContext = notebookPanel.sessionContext;

if (sessionContext.path !== debugSessionPath) {
if (path !== sessionContext.path) {
return;
}

Expand All @@ -119,13 +87,14 @@ export class EditorFinder implements IDisposable, IDebuggerEditorFinder {
cells.forEach((cell, i) => {
// check the event is for the correct cell
const code = cell.model.value.text;
const cellId = this._service.getCodeId(code);
const cellId = this._config.getCodeId(code, kernel);
if (source !== cellId) {
return;
}
if (focus) {
notebook.activeCellIndex = i;
const rect = notebook.activeCell.inputArea.node.getBoundingClientRect();
const { node } = notebook.activeCell.inputArea;
const rect = node.getBoundingClientRect();
notebook.scrollToPosition(rect.bottom, 45);
this._shell.activateById(notebookPanel.id);
}
Expand All @@ -136,32 +105,30 @@ export class EditorFinder implements IDisposable, IDebuggerEditorFinder {
}

/**
* Find the editor for a source matching the current debug session
* Find relevant editors matching the search params in the console tracker.
*
* @param debugSessionPath The path for the current debug session.
* @param source The source to find.
* @param focus - Set to true to focus on the relevant cell. Default to false.
* @param params - The editor search parameters.
*/
private _findInConsoles(
debugSessionPath: string,
source: string,
focus: boolean
params: IDebugger.IEditorFinder.Params
): CodeEditor.IEditor[] {
if (!this._consoleTracker) {
return [];
}
const { focus, kernel, path, source } = params;

const editors: CodeEditor.IEditor[] = [];
this._consoleTracker.forEach(consoleWidget => {
const sessionContext = consoleWidget.sessionContext;

if (sessionContext.path !== debugSessionPath) {
if (path !== sessionContext.path) {
return;
}

const cells = consoleWidget.console.cells;
each(cells, cell => {
const code = cell.model.value.text;
const codeId = this._service.getCodeId(code);
const codeId = this._config.getCodeId(code, kernel);
if (source !== codeId) {
return;
}
Expand All @@ -175,25 +142,22 @@ export class EditorFinder implements IDisposable, IDebuggerEditorFinder {
}

/**
* Find the editor for a source matching the current debug session
* from the editor tracker.
* Find relevant editors matching the search params in the editor tracker.
*
* @param debugSessionPath The path for the current debug session.
* @param source The source to find.
* @param focus - Set to true to focus on the relevant cell. Default to false.
* @param params - The editor search parameters.
*/
private _findInEditors(
debugSessionPath: string,
source: string,
focus: boolean
params: IDebugger.IEditorFinder.Params
): CodeEditor.IEditor[] {
if (!this._editorTracker) {
return;
}
const { focus, kernel, path, source } = params;

const editors: CodeEditor.IEditor[] = [];
this._editorTracker.forEach(doc => {
const fileEditor = doc.content;
if (debugSessionPath !== fileEditor.context.path) {
if (path !== fileEditor.context.path) {
return;
}

Expand All @@ -203,7 +167,7 @@ export class EditorFinder implements IDisposable, IDebuggerEditorFinder {
}

const code = editor.model.value.text;
const codeId = this._service.getCodeId(code);
const codeId = this._config.getCodeId(code, kernel);
if (source !== codeId) {
return;
}
Expand All @@ -216,17 +180,15 @@ export class EditorFinder implements IDisposable, IDebuggerEditorFinder {
}

/**
* Find an editor for a source from the read-only editor tracker.
* Find relevant editors matching the search params in the read-only tracker.
*
* @param debugSessionPath The path for the current debug session.
* @param source The source to find.
* @param focus Set to true to focus on the relevant cell. Default to false.
* @param params - The editor search parameters.
*/
private _findInReadOnlyEditors(
debugSessionPath: string,
source: string,
focus: boolean
params: IDebugger.IEditorFinder.Params
): CodeEditor.IEditor[] {
const { focus, kernel, source } = params;

const editors: CodeEditor.IEditor[] = [];
this._readOnlyEditorTracker.forEach(widget => {
const editor = widget.content?.editor;
Expand All @@ -235,7 +197,7 @@ export class EditorFinder implements IDisposable, IDebuggerEditorFinder {
}

const code = editor.model.value.text;
const codeId = this._service.getCodeId(code);
const codeId = this._config.getCodeId(code, kernel);
if (widget.title.caption !== source && source !== codeId) {
return;
}
Expand All @@ -246,11 +208,12 @@ export class EditorFinder implements IDisposable, IDebuggerEditorFinder {
});
return editors;
}
private _service: IDebugger;
private _shell: JupyterFrontEnd.IShell;
private _readOnlyEditorTracker: WidgetTracker<
MainAreaWidget<CodeEditorWrapper>
>;

private _config: IDebugger.IConfig;
private _notebookTracker: INotebookTracker | null;
private _consoleTracker: IConsoleTracker | null;
private _editorTracker: IEditorTracker | null;
Expand All @@ -263,6 +226,11 @@ export namespace EditorFinder {
* The options used to initialize a EditorFinder object.
*/
export interface IOptions {
/**
* The instance of configuration with hash method.
*/
config: IDebugger.IConfig;

/**
* An optional editor finder for consoles.
*/
Expand All @@ -283,31 +251,9 @@ export namespace EditorFinder {
*/
notebookTracker?: INotebookTracker;

/**
* The debugger service.
*/
service: IDebugger;

/**
* The application shell.
*/
shell: JupyterFrontEnd.IShell;
}
/**
* A token for a editor finder handler find method plugin
*
*/
}
export const IDebuggerEditorFinder = new Token<IDebuggerEditorFinder>(
'@jupyterlab/debugger:editor-finder'
);
/**
* Interface for separated find method from editor finder plugin
*/
export interface IDebuggerEditorFinder {
find(
debugSessionPath: string,
source: string,
focus: boolean
): IIterator<CodeEditor.IEditor>;
}
Loading