Преглед изворни кода

Merge pull request #157 from jtpio/stop-button

Add the stop button to the callstack toolbar
Johan Mabille пре 5 година
родитељ
комит
9015b8c882
5 измењених фајлова са 69 додато и 18 уклоњено
  1. 13 0
      src/callstack/index.ts
  2. 27 9
      src/index.ts
  3. 22 9
      src/service.ts
  4. 6 0
      src/tokens.ts
  5. 1 0
      tests/src/debugger.spec.ts

+ 13 - 0
src/callstack/index.ts

@@ -33,6 +33,14 @@ export class Callstack extends Panel {
       })
     );
 
+    header.toolbar.addItem(
+      'terminate',
+      new CommandToolbarButton({
+        commands: commands.registry,
+        id: commands.terminate
+      })
+    );
+
     header.toolbar.addItem(
       'step-over',
       new CommandToolbarButton({
@@ -128,6 +136,11 @@ export namespace Callstack {
      */
     continue: string;
 
+    /**
+     * The terminate command ID.
+     */
+    terminate: string;
+
     /**
      * The next / stepOver command ID.
      */

+ 27 - 9
src/index.ts

@@ -53,6 +53,8 @@ export namespace CommandIDs {
 
   export const debugContinue = 'debugger:continue';
 
+  export const terminate = 'debugger:terminate';
+
   export const next = 'debugger:next';
 
   export const stepIn = 'debugger:stepIn';
@@ -63,8 +65,6 @@ export namespace CommandIDs {
 
   export const debugFile = 'debugger:debug-file';
 
-  export const debugNotebook = 'debugger:debug-notebook';
-
   export const mount = 'debugger:mount';
 
   export const changeMode = 'debugger:change-mode';
@@ -291,6 +291,19 @@ const main: JupyterFrontEndPlugin<IDebugger> = {
       }
     });
 
+    commands.addCommand(CommandIDs.terminate, {
+      label: 'Terminate',
+      caption: 'Terminate',
+      iconClass: 'jp-MaterialIcon jp-StopIcon',
+      isEnabled: () => {
+        return service.isThreadStopped();
+      },
+      execute: async () => {
+        await service.restart();
+        commands.notifyCommandChanged();
+      }
+    });
+
     commands.addCommand(CommandIDs.next, {
       label: 'Next',
       caption: 'Next',
@@ -350,6 +363,7 @@ const main: JupyterFrontEndPlugin<IDebugger> = {
         const callstackCommands = {
           registry: commands,
           continue: CommandIDs.debugContinue,
+          terminate: CommandIDs.terminate,
           next: CommandIDs.next,
           stepIn: CommandIDs.stepIn,
           stepOut: CommandIDs.stepOut
@@ -394,13 +408,17 @@ const main: JupyterFrontEndPlugin<IDebugger> = {
 
     if (palette) {
       const category = 'Debugger';
-      palette.addItem({ command: CommandIDs.changeMode, category });
-      palette.addItem({ command: CommandIDs.create, category });
-      palette.addItem({ command: CommandIDs.debugContinue, category });
-      palette.addItem({ command: CommandIDs.next, category });
-      palette.addItem({ command: CommandIDs.stepIn, category });
-      palette.addItem({ command: CommandIDs.stepOut, category });
-      palette.addItem({ command: CommandIDs.debugNotebook, category });
+      [
+        CommandIDs.changeMode,
+        CommandIDs.create,
+        CommandIDs.debugContinue,
+        CommandIDs.terminate,
+        CommandIDs.next,
+        CommandIDs.stepIn,
+        CommandIDs.stepOut
+      ].forEach(command => {
+        palette.addItem({ command, category });
+      });
     }
 
     if (restorer) {

+ 22 - 9
src/service.ts

@@ -81,11 +81,11 @@ export class DebugService implements IDebugger {
 
     this._session.eventMessage.connect((_, event) => {
       if (event.event === 'stopped') {
-        this._threadStopped.add(event.body.threadId);
+        this._stoppedThreads.add(event.body.threadId);
         void this.getAllFrames();
       } else if (event.event === 'continued') {
-        this._threadStopped.delete(event.body.threadId);
-        this.onContinued();
+        this._stoppedThreads.delete(event.body.threadId);
+        this.clearModel();
       }
       this._eventMessage.emit(event);
     });
@@ -151,7 +151,7 @@ export class DebugService implements IDebugger {
    * Whether the current thread is stopped.
    */
   isThreadStopped(): boolean {
-    return this._threadStopped.has(this.currentThread());
+    return this._stoppedThreads.has(this.currentThread());
   }
 
   /**
@@ -170,6 +170,19 @@ export class DebugService implements IDebugger {
     await this.session.stop();
   }
 
+  /**
+   * Restarts the debugger.
+   * Precondition: isStarted() and stopped.
+   */
+  async restart(): Promise<void> {
+    const breakpoints = this.model.breakpointsModel.breakpoints;
+    await this.stop();
+    this.clearModel();
+    this._stoppedThreads.clear();
+    await this.start();
+    await this.updateBreakpoints(breakpoints);
+  }
+
   /**
    * Restore the state of a debug session.
    * @param autoStart - when true, starts the debugger
@@ -197,7 +210,7 @@ export class DebugService implements IDebugger {
       await this.session.sendRequest('continue', {
         threadId: this.currentThread()
       });
-      this._threadStopped.delete(this.currentThread());
+      this._stoppedThreads.delete(this.currentThread());
     } catch (err) {
       console.error('Error:', err.message);
     }
@@ -245,7 +258,7 @@ export class DebugService implements IDebugger {
   /**
    * Update all breakpoints at once.
    */
-  updateBreakpoints = async (breakpoints: Breakpoints.IBreakpoint[]) => {
+  async updateBreakpoints(breakpoints: Breakpoints.IBreakpoint[]) {
     if (!this.session.isStarted) {
       return;
     }
@@ -273,7 +286,7 @@ export class DebugService implements IDebugger {
     );
     this._model.breakpointsModel.breakpoints = kernelBreakpoints;
     await this.session.sendRequest('configurationDone', {});
-  };
+  }
 
   getAllFrames = async () => {
     const stackFrames = await this.getFrames(this.currentThread());
@@ -373,7 +386,7 @@ export class DebugService implements IDebugger {
     return client.ready;
   }
 
-  private onContinued() {
+  private clearModel() {
     this._model.callstackModel.frames = [];
     this._model.variablesModel.scopes = [];
   }
@@ -394,7 +407,7 @@ export class DebugService implements IDebugger {
   private frames: Frame[] = [];
 
   // TODO: move this in model
-  private _threadStopped = new Set();
+  private _stoppedThreads = new Set();
 }
 
 export type Frame = {

+ 6 - 0
src/tokens.ts

@@ -78,6 +78,12 @@ export interface IDebugger extends IDisposable {
    */
   stop(): Promise<void>;
 
+  /**
+   * Restart the debugger.
+   * Precondition: isStarted()
+   */
+  restart(): Promise<void>;
+
   /**
    * Restore the state of a debug session.
    * @param autoStart - when true, starts the debugger

+ 1 - 0
tests/src/debugger.spec.ts

@@ -24,6 +24,7 @@ describe('Debugger', () => {
       callstackCommands: {
         registry,
         continue: '',
+        terminate: '',
         next: '',
         stepIn: '',
         stepOut: ''