Просмотр исходного кода

Separated class for hash method.

krzysztof.sikora 4 лет назад
Родитель
Сommit
0c5bbbe912
5 измененных файлов с 140 добавлено и 61 удалено
  1. 12 49
      src/editor-finder.ts
  2. 24 5
      src/index.ts
  3. 81 0
      src/parameters-mixer.ts
  4. 12 5
      src/service.ts
  5. 11 2
      test/service.spec.ts

+ 12 - 49
src/editor-finder.ts

@@ -25,7 +25,7 @@ import { IDisposable } from '@lumino/disposable';
 
 import { Signal } from '@lumino/signaling';
 
-import { murmur2 } from 'murmurhash-js';
+import { IDebuggerParametersMixer } from './parameters-mixer';
 
 /**
  * A class to find instances of code editors across notebook, console and files widgets
@@ -41,6 +41,7 @@ export class EditorFinder implements IDisposable, IDebuggerEditorFinder {
     this._notebookTracker = options.notebookTracker;
     this._consoleTracker = options.consoleTracker;
     this._editorTracker = options.editorTracker;
+    this._parametersMixer = options.parametersMixer;
     this._readOnlyEditorTracker = new WidgetTracker<
       MainAreaWidget<CodeEditorWrapper>
     >({
@@ -64,42 +65,6 @@ export class EditorFinder implements IDisposable, IDebuggerEditorFinder {
     Signal.clearData(this);
   }
 
-  /**
-   * Computes an id based on the given code.
-   *
-   * @param code The source code.
-   */
-  public getCodeId(code: string): string {
-    return this._tmpFilePrefix + this._hashMethod(code) + this._tmpFileSuffix;
-  }
-
-  /**
-   * Set the hash parameters for the current session.
-   *
-   * @param method The hash method.
-   * @param seed The seed for the hash method.
-   */
-  public setHashParameters(method: string, seed: number): void {
-    if (method === 'Murmur2') {
-      this._hashMethod = (code: string): string => {
-        return murmur2(code, seed).toString();
-      };
-    } else {
-      throw new Error('hash method not supported ' + method);
-    }
-  }
-
-  /**
-   * Set the parameters used for the temporary files (e.g. cells).
-   *
-   * @param prefix The prefix used for the temporary files.
-   * @param suffix The suffix used for the temporary files.
-   */
-  public setTmpFileParameters(prefix: string, suffix: string): void {
-    this._tmpFilePrefix = prefix;
-    this._tmpFileSuffix = suffix;
-  }
-
   /**
    * Find the editor for a source matching the current debug session
    * by iterating through all the widgets in each of the notebook,
@@ -154,7 +119,7 @@ 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.getCodeId(code);
+        const cellId = this._parametersMixer.getCodeId(code);
         if (source !== cellId) {
           return;
         }
@@ -196,7 +161,7 @@ export class EditorFinder implements IDisposable, IDebuggerEditorFinder {
       const cells = consoleWidget.console.cells;
       each(cells, cell => {
         const code = cell.model.value.text;
-        const codeId = this.getCodeId(code);
+        const codeId = this._parametersMixer.getCodeId(code);
         if (source !== codeId) {
           return;
         }
@@ -238,7 +203,7 @@ export class EditorFinder implements IDisposable, IDebuggerEditorFinder {
       }
 
       const code = editor.model.value.text;
-      const codeId = this.getCodeId(code);
+      const codeId = this._parametersMixer.getCodeId(code);
       if (source !== codeId) {
         return;
       }
@@ -270,7 +235,7 @@ export class EditorFinder implements IDisposable, IDebuggerEditorFinder {
       }
 
       const code = editor.model.value.text;
-      const codeId = this.getCodeId(code);
+      const codeId = this._parametersMixer.getCodeId(code);
       if (widget.title.caption !== source && source !== codeId) {
         return;
       }
@@ -289,10 +254,7 @@ export class EditorFinder implements IDisposable, IDebuggerEditorFinder {
   private _notebookTracker: INotebookTracker | null;
   private _consoleTracker: IConsoleTracker | null;
   private _editorTracker: IEditorTracker | null;
-
-  private _hashMethod: (code: string) => string;
-  private _tmpFilePrefix: string;
-  private _tmpFileSuffix: string;
+  private _parametersMixer: IDebuggerParametersMixer;
 }
 /**
  * A namespace for editor finder statics.
@@ -326,6 +288,11 @@ export namespace EditorFinder {
      * The application shell.
      */
     shell: JupyterFrontEnd.IShell;
+
+    /**
+     * The instance of parameters mixer with hash method.
+     */
+    parametersMixer: IDebuggerParametersMixer;
   }
   /**
    * A token for a editor finder handler find method plugin
@@ -344,8 +311,4 @@ export interface IDebuggerEditorFinder {
     source: string,
     focus: boolean
   ): IIterator<CodeEditor.IEditor>;
-
-  setHashParameters(method: string, seed: number): void;
-  setTmpFileParameters(prefix: string, suffix: string): void;
-  getCodeId(code: string): string;
 }

+ 24 - 5
src/index.ts

@@ -54,6 +54,8 @@ import { DebuggerModel } from './model';
 
 import { VariablesBodyGrid } from './variables/grid';
 
+import { IDebuggerParametersMixer, ParametersMixer } from './parameters-mixer';
+
 /**
  * The command IDs used by the debugger plugin.
  */
@@ -272,14 +274,28 @@ const service: JupyterFrontEndPlugin<IDebugger> = {
   id: '@jupyterlab/debugger:service',
   autoStart: true,
   provides: IDebugger,
-  requires: [IDebuggerEditorFinder],
-  activate: (app: JupyterFrontEnd, editorFinder: IDebuggerEditorFinder) =>
+  requires: [IDebuggerEditorFinder, IDebuggerParametersMixer],
+  activate: (
+    app: JupyterFrontEnd,
+    editorFinder: IDebuggerEditorFinder,
+    parametersMixer: IDebuggerParametersMixer
+  ) =>
     new DebuggerService({
       specsManager: app.serviceManager.kernelspecs,
-      editorFinder
+      editorFinder,
+      parametersMixer
     })
 };
 
+/**
+ * A plugin that provides a parameters mixer with hash method.
+ */
+const mixer: JupyterFrontEndPlugin<IDebuggerParametersMixer> = {
+  id: '@jupyterlab/debugger:parameters-mixer',
+  autoStart: true,
+  activate: () => new ParametersMixer()
+};
+
 /**
  * A plugin that tracks editors, console and file editors used for debugging.
  */
@@ -287,11 +303,12 @@ const finder: JupyterFrontEndPlugin<IDebuggerEditorFinder> = {
   id: '@jupyterlab/debugger:editor-finder',
   autoStart: true,
   provides: IDebuggerEditorFinder,
-  requires: [IEditorServices],
+  requires: [IEditorServices, IDebuggerParametersMixer],
   optional: [INotebookTracker, IConsoleTracker, IEditorTracker],
   activate: (
     app: JupyterFrontEnd,
     editorServices: IEditorServices,
+    parametersMixer: IDebuggerParametersMixer,
     notebookTracker: INotebookTracker | null,
     consoleTracker: IConsoleTracker | null,
     editorTracker: IEditorTracker | null
@@ -299,6 +316,7 @@ const finder: JupyterFrontEndPlugin<IDebuggerEditorFinder> = {
     return new EditorFinder({
       shell: app.shell,
       editorServices,
+      parametersMixer,
       notebookTracker,
       consoleTracker,
       editorTracker
@@ -559,7 +577,8 @@ const plugins: JupyterFrontEndPlugin<any>[] = [
   tracker,
   variables,
   main,
-  finder
+  finder,
+  mixer
 ];
 
 export default plugins;

+ 81 - 0
src/parameters-mixer.ts

@@ -0,0 +1,81 @@
+// Copyright (c) Jupyter Development Team.
+// Distributed under the terms of the Modified BSD License.
+
+import { Token } from '@lumino/coreutils';
+
+import { Signal } from '@lumino/signaling';
+
+import { murmur2 } from 'murmurhash-js';
+
+/**
+ * A class to hash code.
+ */
+export class ParametersMixer implements IDebuggerParametersMixer {
+  /**
+   * Whether the handler is disposed.
+   */
+  isDisposed: boolean;
+
+  /**
+   * Dispose the objects.
+   */
+  dispose(): void {
+    if (this.isDisposed) {
+      return;
+    }
+    this.isDisposed = true;
+    Signal.clearData(this);
+  }
+
+  /**
+   * Computes an id based on the given code.
+   *
+   * @param code The source code.
+   */
+  public getCodeId(code: string): string {
+    return this._tmpFilePrefix + this._hashMethod(code) + this._tmpFileSuffix;
+  }
+
+  /**
+   * Set the hash parameters for the current session.
+   *
+   * @param method The hash method.
+   * @param seed The seed for the hash method.
+   */
+  public setHashParameters(method: string, seed: number): void {
+    if (method === 'Murmur2') {
+      this._hashMethod = (code: string): string => {
+        return murmur2(code, seed).toString();
+      };
+    } else {
+      throw new Error('hash method not supported ' + method);
+    }
+  }
+
+  /**
+   * Set the parameters used for the temporary files (e.g. cells).
+   *
+   * @param prefix The prefix used for the temporary files.
+   * @param suffix The suffix used for the temporary files.
+   */
+  public setTmpFileParameters(prefix: string, suffix: string): void {
+    this._tmpFilePrefix = prefix;
+    this._tmpFileSuffix = suffix;
+  }
+
+  private _hashMethod: (code: string) => string;
+  private _tmpFilePrefix: string;
+  private _tmpFileSuffix: string;
+}
+
+export const IDebuggerParametersMixer = new Token<IDebuggerParametersMixer>(
+  '@jupyterlab/debugger:parameters-mixer'
+);
+/**
+ * Interface for parameters mixer plugin
+ */
+export interface IDebuggerParametersMixer {
+  setHashParameters(method: string, seed: number): void;
+  setTmpFileParameters(prefix: string, suffix: string): void;
+  getCodeId(code: string): string;
+}

+ 12 - 5
src/service.ts

@@ -21,6 +21,8 @@ import { IDebuggerEditorFinder } from './editor-finder';
 
 import { VariablesModel } from './variables/model';
 
+import { IDebuggerParametersMixer } from './parameters-mixer';
+
 /**
  * A concrete implementation of IDebugger.
  */
@@ -40,6 +42,7 @@ export class DebuggerService implements IDebugger, IDisposable {
     this._specsManager = options.specsManager;
     this._model = new DebuggerModel();
     this._editorFinder = options.editorFinder;
+    this._parametersMixer = options.parametersMixer;
   }
 
   /**
@@ -163,7 +166,7 @@ export class DebuggerService implements IDebugger, IDisposable {
    * @param code The source code.
    */
   getCodeId(code: string): string {
-    return this._editorFinder?.getCodeId(code) ?? '';
+    return this._parametersMixer.getCodeId(code);
   }
 
   /**
@@ -225,10 +228,8 @@ export class DebuggerService implements IDebugger, IDisposable {
     const breakpoints = this._mapBreakpoints(reply.body.breakpoints);
     const stoppedThreads = new Set(reply.body.stoppedThreads);
 
-    if (this._editorFinder) {
-      this._editorFinder.setHashParameters(hashMethod, hashSeed);
-      this._editorFinder.setTmpFileParameters(tmpFilePrefix, tmpFileSuffix);
-    }
+    this._parametersMixer.setHashParameters(hashMethod, hashSeed);
+    this._parametersMixer.setTmpFileParameters(tmpFilePrefix, tmpFileSuffix);
 
     this._model.stoppedThreads = stoppedThreads;
 
@@ -675,6 +676,7 @@ export class DebuggerService implements IDebugger, IDisposable {
 
   private _specsManager: KernelSpec.IManager;
   private _editorFinder: IDebuggerEditorFinder | null;
+  private _parametersMixer: IDebuggerParametersMixer;
 }
 
 /**
@@ -694,5 +696,10 @@ export namespace DebuggerService {
      * The editor finder instance.
      */
     editorFinder?: IDebuggerEditorFinder;
+
+    /**
+     * The parameters mixer instance with hash method.
+     */
+    parametersMixer: IDebuggerParametersMixer;
   }
 }

+ 11 - 2
test/service.spec.ts

@@ -21,6 +21,11 @@ import { IDebugger } from '../src/tokens';
 
 import { KERNELSPECS, handleRequest } from './utils';
 
+import {
+  IDebuggerParametersMixer,
+  ParametersMixer
+} from '../src/parameters-mixer';
+
 /**
  * A Test class to mock a KernelSpecManager
  */
@@ -54,6 +59,7 @@ describe('Debugging support', () => {
 
   let specsManager: TestKernelSpecManager;
   let service: DebuggerService;
+  let parametersMixer: IDebuggerParametersMixer;
   let xpython: Session.ISessionConnection;
   let ipykernel: Session.ISessionConnection;
 
@@ -75,7 +81,8 @@ describe('Debugging support', () => {
     specsManager = new TestKernelSpecManager({ standby: 'never' });
     specsManager.intercept = specs;
     await specsManager.refreshSpecs();
-    service = new DebuggerService({ specsManager });
+    parametersMixer = new ParametersMixer();
+    service = new DebuggerService({ specsManager, parametersMixer });
   });
 
   afterAll(async () => {
@@ -101,6 +108,7 @@ describe('DebuggerService', () => {
   const specsManager = new KernelSpecManager();
   let connection: Session.ISessionConnection;
   let model: DebuggerModel;
+  let parametersMixer: IDebuggerParametersMixer;
   let session: IDebugger.ISession;
   let service: IDebugger;
 
@@ -113,7 +121,8 @@ describe('DebuggerService', () => {
     await connection.changeKernel({ name: 'xpython' });
     session = new DebugSession({ connection });
     model = new DebuggerModel();
-    service = new DebuggerService({ specsManager });
+    parametersMixer = new ParametersMixer();
+    service = new DebuggerService({ specsManager, parametersMixer });
   });
 
   afterEach(async () => {