debugger.ts 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. import { CodeEditor } from '@jupyterlab/codeeditor';
  4. import { IDataConnector } from '@jupyterlab/coreutils';
  5. import { IObservableString } from '@jupyterlab/observables';
  6. import { ReadonlyJSONValue } from '@phosphor/coreutils';
  7. import { IDisposable } from '@phosphor/disposable';
  8. import { Message } from '@phosphor/messaging';
  9. import { ISignal, Signal } from '@phosphor/signaling';
  10. import { SplitPanel } from '@phosphor/widgets';
  11. import { Breakpoints } from './breakpoints';
  12. import { Callstack } from './callstack';
  13. import { DebuggerEditors } from './editors';
  14. import { DebugService } from './service';
  15. import { IDebugger } from './tokens';
  16. import { Variables } from './variables';
  17. export class Debugger extends SplitPanel {
  18. constructor(options: Debugger.IOptions) {
  19. super({ orientation: 'horizontal' });
  20. this.title.label = 'Debugger';
  21. this.title.iconClass = 'jp-BugIcon';
  22. this.model = new Debugger.Model({
  23. connector: options.connector
  24. });
  25. this.service = options.debugService;
  26. this.service.model = this.model;
  27. this.sidebar = new Debugger.Sidebar({
  28. model: this.model,
  29. service: this.service,
  30. callstackCommands: options.callstackCommands
  31. });
  32. this.editors = new DebuggerEditors({
  33. editorFactory: options.editorFactory
  34. });
  35. this.addWidget(this.editors);
  36. this.addClass('jp-Debugger');
  37. }
  38. readonly editors: DebuggerEditors;
  39. readonly model: Debugger.Model;
  40. readonly sidebar: Debugger.Sidebar;
  41. readonly service: DebugService;
  42. dispose(): void {
  43. if (this.isDisposed) {
  44. return;
  45. }
  46. this.service.model = null;
  47. this.model.dispose();
  48. super.dispose();
  49. }
  50. protected onAfterAttach(msg: Message) {
  51. this.addWidget(this.sidebar);
  52. this.sidebar.show();
  53. }
  54. }
  55. /**
  56. * A namespace for `Debugger` statics.
  57. */
  58. export namespace Debugger {
  59. export interface IOptions {
  60. debugService: DebugService;
  61. editorFactory: CodeEditor.Factory;
  62. callstackCommands: Callstack.ICommands;
  63. connector?: IDataConnector<ReadonlyJSONValue>;
  64. }
  65. export class Sidebar extends SplitPanel {
  66. constructor(options: Sidebar.IOptions) {
  67. super();
  68. this.orientation = 'vertical';
  69. this.addClass('jp-DebuggerSidebar');
  70. const { callstackCommands, service, model } = options;
  71. this.variables = new Variables({ model: model.variablesModel });
  72. this.callstack = new Callstack({
  73. commands: callstackCommands,
  74. model: model.callstackModel
  75. });
  76. this.breakpoints = new Breakpoints({
  77. service,
  78. model: model.breakpointsModel
  79. });
  80. this.addWidget(this.variables);
  81. this.addWidget(this.callstack);
  82. this.addWidget(this.breakpoints);
  83. }
  84. readonly variables: Variables;
  85. readonly callstack: Callstack;
  86. readonly breakpoints: Breakpoints;
  87. }
  88. export class Model implements IDisposable {
  89. constructor(options: Debugger.Model.IOptions) {
  90. this.breakpointsModel = new Breakpoints.Model();
  91. this.callstackModel = new Callstack.Model([]);
  92. this.variablesModel = new Variables.Model([]);
  93. this.connector = options.connector || null;
  94. void this._populate();
  95. }
  96. readonly breakpointsModel: Breakpoints.Model;
  97. readonly callstackModel: Callstack.Model;
  98. readonly variablesModel: Variables.Model;
  99. readonly connector: IDataConnector<ReadonlyJSONValue> | null;
  100. dispose(): void {
  101. this._isDisposed = true;
  102. this._disposed.emit();
  103. }
  104. /**
  105. * A signal emitted when the debugger widget is disposed.
  106. */
  107. get disposed(): ISignal<this, void> {
  108. return this._disposed;
  109. }
  110. get isDisposed(): boolean {
  111. return this._isDisposed;
  112. }
  113. get mode(): IDebugger.Mode {
  114. return this._mode;
  115. }
  116. set mode(mode: IDebugger.Mode) {
  117. if (this._mode === mode) {
  118. return;
  119. }
  120. this._mode = mode;
  121. this._modeChanged.emit(mode);
  122. }
  123. get modeChanged(): ISignal<this, IDebugger.Mode> {
  124. return this._modeChanged;
  125. }
  126. get codeValue() {
  127. return this._codeValue;
  128. }
  129. set codeValue(observableString: IObservableString) {
  130. this._codeValue = observableString;
  131. }
  132. private async _populate(): Promise<void> {
  133. const { connector } = this;
  134. if (!connector) {
  135. return;
  136. }
  137. }
  138. private _codeValue: IObservableString;
  139. private _isDisposed = false;
  140. private _mode: IDebugger.Mode;
  141. private _modeChanged = new Signal<this, IDebugger.Mode>(this);
  142. private _disposed = new Signal<this, void>(this);
  143. }
  144. export namespace Sidebar {
  145. export interface IOptions {
  146. model: Debugger.Model;
  147. service: IDebugger;
  148. callstackCommands: Callstack.ICommands;
  149. }
  150. }
  151. export namespace Model {
  152. export interface IOptions {
  153. connector?: IDataConnector<ReadonlyJSONValue>;
  154. }
  155. }
  156. }