@theia/debug 1.70.0-next.81 → 1.71.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/lib/browser/breakpoint/breakpoint-manager.d.ts +80 -45
  2. package/lib/browser/breakpoint/breakpoint-manager.d.ts.map +1 -1
  3. package/lib/browser/breakpoint/breakpoint-manager.js +553 -170
  4. package/lib/browser/breakpoint/breakpoint-manager.js.map +1 -1
  5. package/lib/browser/breakpoint/breakpoint-manager.spec.d.ts +2 -0
  6. package/lib/browser/breakpoint/breakpoint-manager.spec.d.ts.map +1 -0
  7. package/lib/browser/breakpoint/breakpoint-manager.spec.js +861 -0
  8. package/lib/browser/breakpoint/breakpoint-manager.spec.js.map +1 -0
  9. package/lib/browser/breakpoint/breakpoint-marker.d.ts +7 -10
  10. package/lib/browser/breakpoint/breakpoint-marker.d.ts.map +1 -1
  11. package/lib/browser/breakpoint/breakpoint-marker.js +14 -11
  12. package/lib/browser/breakpoint/breakpoint-marker.js.map +1 -1
  13. package/lib/browser/breakpoint/debug-data-breakpoint-actions.js +1 -1
  14. package/lib/browser/breakpoint/debug-data-breakpoint-actions.js.map +1 -1
  15. package/lib/browser/debug-frontend-application-contribution.d.ts +1 -2
  16. package/lib/browser/debug-frontend-application-contribution.d.ts.map +1 -1
  17. package/lib/browser/debug-frontend-application-contribution.js +13 -21
  18. package/lib/browser/debug-frontend-application-contribution.js.map +1 -1
  19. package/lib/browser/debug-frontend-module.d.ts.map +1 -1
  20. package/lib/browser/debug-frontend-module.js +3 -0
  21. package/lib/browser/debug-frontend-module.js.map +1 -1
  22. package/lib/browser/debug-session-manager.d.ts +8 -27
  23. package/lib/browser/debug-session-manager.d.ts.map +1 -1
  24. package/lib/browser/debug-session-manager.js +14 -132
  25. package/lib/browser/debug-session-manager.js.map +1 -1
  26. package/lib/browser/debug-session.d.ts +1 -21
  27. package/lib/browser/debug-session.d.ts.map +1 -1
  28. package/lib/browser/debug-session.js +72 -203
  29. package/lib/browser/debug-session.js.map +1 -1
  30. package/lib/browser/disassembly-view/disassembly-view-breakpoint-renderer.js +1 -1
  31. package/lib/browser/disassembly-view/disassembly-view-breakpoint-renderer.js.map +1 -1
  32. package/lib/browser/disassembly-view/disassembly-view-widget.d.ts.map +1 -1
  33. package/lib/browser/disassembly-view/disassembly-view-widget.js +17 -24
  34. package/lib/browser/disassembly-view/disassembly-view-widget.js.map +1 -1
  35. package/lib/browser/editor/debug-editor-model.d.ts +15 -5
  36. package/lib/browser/editor/debug-editor-model.d.ts.map +1 -1
  37. package/lib/browser/editor/debug-editor-model.js +56 -32
  38. package/lib/browser/editor/debug-editor-model.js.map +1 -1
  39. package/lib/browser/model/debug-breakpoint-opener.d.ts +14 -0
  40. package/lib/browser/model/debug-breakpoint-opener.d.ts.map +1 -0
  41. package/lib/browser/model/debug-breakpoint-opener.js +67 -0
  42. package/lib/browser/model/debug-breakpoint-opener.js.map +1 -0
  43. package/lib/browser/model/debug-breakpoint.d.ts +32 -13
  44. package/lib/browser/model/debug-breakpoint.d.ts.map +1 -1
  45. package/lib/browser/model/debug-breakpoint.js +76 -16
  46. package/lib/browser/model/debug-breakpoint.js.map +1 -1
  47. package/lib/browser/model/debug-data-breakpoint.d.ts +1 -0
  48. package/lib/browser/model/debug-data-breakpoint.d.ts.map +1 -1
  49. package/lib/browser/model/debug-data-breakpoint.js +6 -5
  50. package/lib/browser/model/debug-data-breakpoint.js.map +1 -1
  51. package/lib/browser/model/debug-function-breakpoint.d.ts +4 -1
  52. package/lib/browser/model/debug-function-breakpoint.d.ts.map +1 -1
  53. package/lib/browser/model/debug-function-breakpoint.js +20 -29
  54. package/lib/browser/model/debug-function-breakpoint.js.map +1 -1
  55. package/lib/browser/model/debug-instruction-breakpoint.d.ts +2 -1
  56. package/lib/browser/model/debug-instruction-breakpoint.d.ts.map +1 -1
  57. package/lib/browser/model/debug-instruction-breakpoint.js +8 -8
  58. package/lib/browser/model/debug-instruction-breakpoint.js.map +1 -1
  59. package/lib/browser/model/debug-source-breakpoint.d.ts +6 -15
  60. package/lib/browser/model/debug-source-breakpoint.d.ts.map +1 -1
  61. package/lib/browser/model/debug-source-breakpoint.js +16 -90
  62. package/lib/browser/model/debug-source-breakpoint.js.map +1 -1
  63. package/lib/browser/view/debug-breakpoints-source.d.ts +0 -2
  64. package/lib/browser/view/debug-breakpoints-source.d.ts.map +1 -1
  65. package/lib/browser/view/debug-breakpoints-source.js +2 -10
  66. package/lib/browser/view/debug-breakpoints-source.js.map +1 -1
  67. package/lib/browser/view/debug-breakpoints-widget.d.ts +2 -0
  68. package/lib/browser/view/debug-breakpoints-widget.d.ts.map +1 -1
  69. package/lib/browser/view/debug-breakpoints-widget.js +3 -0
  70. package/lib/browser/view/debug-breakpoints-widget.js.map +1 -1
  71. package/lib/browser/view/debug-exception-breakpoint.d.ts +18 -11
  72. package/lib/browser/view/debug-exception-breakpoint.d.ts.map +1 -1
  73. package/lib/browser/view/debug-exception-breakpoint.js +58 -24
  74. package/lib/browser/view/debug-exception-breakpoint.js.map +1 -1
  75. package/lib/browser/view/debug-view-model.d.ts +8 -4
  76. package/lib/browser/view/debug-view-model.d.ts.map +1 -1
  77. package/lib/browser/view/debug-view-model.js +16 -9
  78. package/lib/browser/view/debug-view-model.js.map +1 -1
  79. package/package.json +16 -16
  80. package/src/browser/breakpoint/breakpoint-manager.spec.ts +1106 -0
  81. package/src/browser/breakpoint/breakpoint-manager.ts +583 -194
  82. package/src/browser/breakpoint/breakpoint-marker.ts +21 -15
  83. package/src/browser/breakpoint/debug-data-breakpoint-actions.ts +1 -1
  84. package/src/browser/debug-frontend-application-contribution.ts +18 -23
  85. package/src/browser/debug-frontend-module.ts +5 -1
  86. package/src/browser/debug-session-manager.ts +15 -147
  87. package/src/browser/debug-session.tsx +71 -221
  88. package/src/browser/disassembly-view/disassembly-view-breakpoint-renderer.ts +1 -1
  89. package/src/browser/disassembly-view/disassembly-view-widget.ts +17 -23
  90. package/src/browser/editor/debug-editor-model.ts +58 -35
  91. package/src/browser/model/debug-breakpoint-opener.ts +51 -0
  92. package/src/browser/model/debug-breakpoint.tsx +101 -20
  93. package/src/browser/model/debug-data-breakpoint.tsx +8 -5
  94. package/src/browser/model/debug-function-breakpoint.tsx +18 -29
  95. package/src/browser/model/debug-instruction-breakpoint.tsx +10 -8
  96. package/src/browser/model/debug-source-breakpoint.tsx +23 -101
  97. package/src/browser/view/debug-breakpoints-source.tsx +2 -9
  98. package/src/browser/view/debug-breakpoints-widget.ts +6 -0
  99. package/src/browser/view/debug-exception-breakpoint.tsx +66 -27
  100. package/src/browser/view/debug-view-model.ts +21 -13
@@ -39,25 +39,22 @@ import { DebugThread, StoppedDetails, DebugThreadData } from './model/debug-thre
39
39
  import { DebugScope, DebugVariable } from './console/debug-console-items';
40
40
  import { DebugStackFrame } from './model/debug-stack-frame';
41
41
  import { DebugSource } from './model/debug-source';
42
- import { DebugBreakpoint, DebugBreakpointOptions } from './model/debug-breakpoint';
43
- import { DebugSourceBreakpoint } from './model/debug-source-breakpoint';
42
+ import { DebugBreakpoint } from './model/debug-breakpoint';
44
43
  import debounce = require('p-debounce');
45
44
  import URI from '@theia/core/lib/common/uri';
46
45
  import { BreakpointManager } from './breakpoint/breakpoint-manager';
47
46
  import { DebugConfigurationSessionOptions, InternalDebugSessionOptions, TestRunReference } from './debug-session-options';
48
47
  import { DebugConfiguration, DebugConsoleMode } from '../common/debug-common';
49
- import { SourceBreakpoint, ExceptionBreakpoint } from './breakpoint/breakpoint-marker';
48
+ import { SourceBreakpoint } from './breakpoint/breakpoint-marker';
50
49
  import { TerminalWidgetOptions, TerminalWidget } from '@theia/terminal/lib/browser/base/terminal-widget';
51
- import { DebugFunctionBreakpoint } from './model/debug-function-breakpoint';
52
50
  import { FileService } from '@theia/filesystem/lib/browser/file-service';
53
51
  import { DebugContribution } from './debug-contribution';
54
52
  import { Deferred, waitForEvent } from '@theia/core/lib/common/promise-util';
55
53
  import { WorkspaceService } from '@theia/workspace/lib/browser';
56
- import { DebugInstructionBreakpoint } from './model/debug-instruction-breakpoint';
57
54
  import { nls } from '@theia/core';
58
55
  import { TestService, TestServices } from '@theia/test/lib/browser/test-service';
59
56
  import { DebugSessionManager } from './debug-session-manager';
60
- import { DebugDataBreakpoint } from './model/debug-data-breakpoint';
57
+
61
58
  import { DebugPreferences } from '../common/debug-preferences';
62
59
 
63
60
  export enum DebugState {
@@ -109,12 +106,6 @@ export class DebugSession implements CompositeTreeElement {
109
106
  return this.onDidFocusThreadEmitter.event;
110
107
  }
111
108
 
112
- protected readonly onDidChangeBreakpointsEmitter = new Emitter<URI>();
113
- readonly onDidChangeBreakpoints: Event<URI> = this.onDidChangeBreakpointsEmitter.event;
114
- protected fireDidChangeBreakpoints(uri: URI): void {
115
- this.onDidChangeBreakpointsEmitter.fire(uri);
116
- }
117
-
118
109
  protected readonly onDidResolveLazyVariableEmitter = new Emitter<DebugVariable>();
119
110
  readonly onDidResolveLazyVariable: Event<DebugVariable> = this.onDidResolveLazyVariableEmitter.event;
120
111
 
@@ -179,10 +170,8 @@ export class DebugSession implements CompositeTreeElement {
179
170
  this.onDidChangeEmitter,
180
171
  this.onDidFocusStackFrameEmitter,
181
172
  this.onDidFocusThreadEmitter,
182
- this.onDidChangeBreakpointsEmitter,
183
173
  this.onDidResolveLazyVariableEmitter,
184
174
  Disposable.create(() => {
185
- this.clearBreakpoints();
186
175
  this.doUpdateThreads([]);
187
176
  }),
188
177
  this.connection,
@@ -242,7 +231,7 @@ export class DebugSession implements CompositeTreeElement {
242
231
  sourceReference: Number(uri.query)
243
232
  };
244
233
  }
245
- const name = uri.displayName;
234
+ const name = this.labelProvider.getName(uri);
246
235
  let path;
247
236
  const underlying = await this.fileService.toUnderlyingResource(uri);
248
237
  if (underlying.scheme === 'file') {
@@ -410,12 +399,7 @@ export class DebugSession implements CompositeTreeElement {
410
399
  protected async configure(): Promise<void> {
411
400
  await this.didReceiveCapabilities.promise;
412
401
  if (this.capabilities.exceptionBreakpointFilters) {
413
- const exceptionBreakpoints = [];
414
- for (const filter of this.capabilities.exceptionBreakpointFilters) {
415
- const origin = this.breakpoints.getExceptionBreakpoint(filter.filter);
416
- exceptionBreakpoints.push(ExceptionBreakpoint.create(filter, origin));
417
- }
418
- this.breakpoints.setExceptionBreakpoints(exceptionBreakpoints);
402
+ this.breakpoints.addExceptionBreakpoints(this.capabilities.exceptionBreakpointFilters, this.id);
419
403
  }
420
404
  // mark as initialized, so updated breakpoints are shown in editor
421
405
  this.initialized = true;
@@ -534,7 +518,7 @@ export class DebugSession implements CompositeTreeElement {
534
518
  }
535
519
 
536
520
  if (!terminal) {
537
- terminal = await this.terminalServer.newTerminal(options);
521
+ terminal = await this.terminalServer.newTerminal({ ...options, kind: 'debug' });
538
522
  await terminal.start();
539
523
  try {
540
524
  if (terminal.commandHistoryState) {
@@ -638,71 +622,6 @@ export class DebugSession implements CompositeTreeElement {
638
622
  this.deferredOnDidConfigureCapabilities.resolve();
639
623
  }
640
624
 
641
- protected readonly _breakpoints = new Map<string, DebugBreakpoint[]>();
642
- get breakpointUris(): IterableIterator<string> {
643
- return this._breakpoints.keys();
644
- }
645
-
646
- getSourceBreakpoints(uri?: URI): DebugSourceBreakpoint[] {
647
- const breakpoints = [];
648
- for (const breakpoint of this.getBreakpoints(uri)) {
649
- if (breakpoint instanceof DebugSourceBreakpoint) {
650
- breakpoints.push(breakpoint);
651
- }
652
- }
653
- return breakpoints;
654
- }
655
-
656
- getFunctionBreakpoints(): DebugFunctionBreakpoint[] {
657
- return this.getBreakpoints(BreakpointManager.FUNCTION_URI).filter((breakpoint): breakpoint is DebugFunctionBreakpoint => breakpoint instanceof DebugFunctionBreakpoint);
658
- }
659
-
660
- getInstructionBreakpoints(): DebugInstructionBreakpoint[] {
661
- if (this.capabilities.supportsInstructionBreakpoints) {
662
- return this.getBreakpoints(BreakpointManager.INSTRUCTION_URI)
663
- .filter((breakpoint): breakpoint is DebugInstructionBreakpoint => breakpoint instanceof DebugInstructionBreakpoint);
664
- }
665
- return this.breakpoints.getInstructionBreakpoints().map(origin => new DebugInstructionBreakpoint(origin, this.asDebugBreakpointOptions()));
666
- }
667
-
668
- getDataBreakpoints(): DebugDataBreakpoint[] {
669
- if (this.capabilities.supportsDataBreakpoints) {
670
- return this.getBreakpoints(BreakpointManager.DATA_URI)
671
- .filter((breakpoint): breakpoint is DebugDataBreakpoint => breakpoint instanceof DebugDataBreakpoint);
672
- }
673
- return this.breakpoints.getDataBreakpoints().map(origin => new DebugDataBreakpoint(origin, this.asDebugBreakpointOptions()));
674
- }
675
-
676
- getBreakpoints(uri?: URI): DebugBreakpoint[] {
677
- if (uri) {
678
- return this._breakpoints.get(uri.toString()) || [];
679
- }
680
- const result = [];
681
- for (const breakpoints of this._breakpoints.values()) {
682
- result.push(...breakpoints);
683
- }
684
- return result;
685
- }
686
-
687
- getBreakpoint(id: string): DebugBreakpoint | undefined {
688
- for (const breakpoints of this._breakpoints.values()) {
689
- const breakpoint = breakpoints.find(b => b.id === id);
690
- if (breakpoint) {
691
- return breakpoint;
692
- }
693
-
694
- }
695
- return undefined;
696
- }
697
-
698
- protected clearBreakpoints(): void {
699
- const uris = [...this._breakpoints.keys()];
700
- this._breakpoints.clear();
701
- for (const uri of uris) {
702
- this.fireDidChangeBreakpoints(new URI(uri));
703
- }
704
- }
705
-
706
625
  protected updatingBreakpoints = false;
707
626
 
708
627
  protected updateBreakpoint(body: DebugProtocol.BreakpointEvent['body']): void {
@@ -713,54 +632,33 @@ export class DebugSession implements CompositeTreeElement {
713
632
  if (raw.source && typeof raw.line === 'number') {
714
633
  const uri = DebugSource.toUri(raw.source);
715
634
  const origin = SourceBreakpoint.create(uri, { line: raw.line, column: raw.column });
716
- if (this.breakpoints.addBreakpoint(origin)) {
717
- const breakpoints = this.getSourceBreakpoints(uri);
718
- const breakpoint = new DebugSourceBreakpoint(origin, this.asDebugBreakpointOptions(), this.commandService);
719
- breakpoint.update({ raw });
720
- breakpoints.push(breakpoint);
721
- this.setSourceBreakpoints(uri, breakpoints);
722
- }
635
+ const breakpoint = this.breakpoints.addBreakpoint(origin);
636
+ this.breakpoints.updateSessionData(this.id, this.capabilities, new Map<string, DebugProtocol.Breakpoint>([[breakpoint.id, raw]]));
723
637
  }
724
638
  }
725
639
  if (body.reason === 'removed' && typeof raw.id === 'number') {
726
- const toRemove = this.findBreakpoint(b => b.idFromAdapter === raw.id);
640
+ const toRemove = this.findBreakpoint(b => b.getIdForSession(this.id) === raw.id);
727
641
  if (toRemove) {
728
642
  toRemove.remove();
729
- const breakpoints = this.getBreakpoints(toRemove.uri);
730
- const index = breakpoints.indexOf(toRemove);
731
- if (index !== -1) {
732
- breakpoints.splice(index, 1);
733
- this.setBreakpoints(toRemove.uri, breakpoints);
734
- }
735
643
  }
736
644
  }
737
645
  if (body.reason === 'changed' && typeof raw.id === 'number') {
738
- const toUpdate = this.findBreakpoint(b => b.idFromAdapter === raw.id);
646
+ const toUpdate = this.findBreakpoint(b => b.getIdForSession(this.id) === raw.id);
739
647
  if (toUpdate) {
740
- toUpdate.update({ raw });
741
- if (toUpdate instanceof DebugSourceBreakpoint) {
742
- const sourceBreakpoints = this.getSourceBreakpoints(toUpdate.uri);
743
- // in order to dedup again if a debugger converted line breakpoint to inline breakpoint
744
- // i.e. assigned a column to a line breakpoint
745
- this.setSourceBreakpoints(toUpdate.uri, sourceBreakpoints);
746
- } else {
747
- this.fireDidChangeBreakpoints(toUpdate.uri);
748
- }
648
+ this.breakpoints.updateSessionData(this.id, this.capabilities, new Map([[toUpdate.id, raw]]));
749
649
  }
750
650
  }
751
651
  } finally {
752
652
  this.updatingBreakpoints = false;
753
653
  }
754
654
  }
655
+
755
656
  protected findBreakpoint(match: (breakpoint: DebugBreakpoint) => boolean): DebugBreakpoint | undefined {
756
- for (const [, breakpoints] of this._breakpoints) {
757
- for (const breakpoint of breakpoints) {
758
- if (match(breakpoint)) {
759
- return breakpoint;
760
- }
657
+ for (const bp of this.breakpoints.allBreakpoints()) {
658
+ if (match(bp)) {
659
+ return bp;
761
660
  }
762
661
  }
763
- return undefined;
764
662
  }
765
663
 
766
664
  protected async updateBreakpoints(options: {
@@ -790,71 +688,61 @@ export class DebugSession implements CompositeTreeElement {
790
688
  protected async sendExceptionBreakpoints(): Promise<void> {
791
689
  const filters: string[] = [];
792
690
  const filterOptions: DebugProtocol.ExceptionFilterOptions[] | undefined = this.capabilities.supportsExceptionFilterOptions ? [] : undefined;
793
- for (const breakpoint of this.breakpoints.getExceptionBreakpoints()) {
794
- if (breakpoint.enabled) {
795
- if (filterOptions) {
796
- filterOptions.push({
797
- filterId: breakpoint.raw.filter,
798
- condition: breakpoint.condition
799
- });
800
- } else {
801
- filters.push(breakpoint.raw.filter);
802
- }
691
+ const toSend = this.breakpoints.getExceptionBreakpoints().filter(candidate => candidate.origin.enabled);
692
+ const updates = new Map<string, DebugProtocol.Breakpoint>();
693
+ for (const breakpoint of toSend) {
694
+ if (filterOptions) {
695
+ filterOptions.push({
696
+ filterId: breakpoint.origin.raw.filter,
697
+ condition: breakpoint.origin.condition
698
+ });
699
+ } else {
700
+ filters.push(breakpoint.origin.raw.filter);
803
701
  }
804
702
  }
805
- await this.sendRequest('setExceptionBreakpoints', { filters, filterOptions });
703
+ try {
704
+ const res = await this.sendRequest('setExceptionBreakpoints', { filters, filterOptions });
705
+ res.body?.breakpoints?.forEach((bp, index) => toSend[index] && updates.set(toSend[index].id, bp));
706
+ } catch (err) {
707
+ console.error('Failed to set exception breakpoints:', err);
708
+ const message = (err as Error)?.message ? `${err.message}` : 'Failed to set exception breakpoints.';
709
+ toSend.forEach(bp => updates.set(bp.id, { verified: false, message }));
710
+ }
711
+ this.breakpoints.updateSessionData(this.id, this.capabilities, updates);
806
712
  }
807
713
 
808
714
  protected async sendFunctionBreakpoints(affectedUri: URI): Promise<void> {
809
- const all = this.breakpoints.getFunctionBreakpoints().map(origin =>
810
- new DebugFunctionBreakpoint(origin, this.asDebugBreakpointOptions())
811
- );
715
+ if (!this.capabilities.supportsFunctionBreakpoints) { return; }
716
+ const all = this.breakpoints.getFunctionBreakpoints();
812
717
  const enabled = all.filter(b => b.enabled);
813
- if (this.capabilities.supportsFunctionBreakpoints) {
814
- try {
815
- const response = await this.sendRequest('setFunctionBreakpoints', {
816
- breakpoints: enabled.map(b => b.origin.raw)
817
- });
818
- // Apparently, `body` and `breakpoints` can be missing.
819
- // https://github.com/eclipse-theia/theia/issues/11885
820
- // https://github.com/microsoft/vscode/blob/80004351ccf0884b58359f7c8c801c91bb827d83/src/vs/workbench/contrib/debug/browser/debugSession.ts#L448-L449
821
- if (response && response.body) {
822
- response.body.breakpoints.forEach((raw, index) => {
823
- // node debug adapter returns more breakpoints sometimes
824
- if (enabled[index]) {
825
- enabled[index].update({ raw });
826
- }
827
- });
828
- }
829
- } catch (error) {
830
- // could be error or promise rejection of DebugProtocol.SetFunctionBreakpoints
831
- if (error instanceof Error) {
832
- console.error(`Error setting breakpoints: ${error.message}`);
833
- } else {
834
- // handle adapters that send failed DebugProtocol.SetFunctionBreakpoints for invalid breakpoints
835
- const genericMessage: string = 'Function breakpoint not valid for current debug session';
836
- const message: string = error.message ? `${error.message}` : genericMessage;
837
- console.warn(`Could not handle function breakpoints: ${message}, disabling...`);
838
- enabled.forEach(b => b.update({
839
- raw: {
840
- verified: false,
841
- message
842
- }
843
- }));
718
+ const updates = new Map<string, DebugProtocol.Breakpoint>();
719
+ try {
720
+ const response = await this.sendRequest('setFunctionBreakpoints', {
721
+ breakpoints: enabled.map(b => b.origin.raw)
722
+ });
723
+ // Apparently, `body` and `breakpoints` can be missing.
724
+ // https://github.com/eclipse-theia/theia/issues/11885
725
+ // https://github.com/microsoft/vscode/blob/80004351ccf0884b58359f7c8c801c91bb827d83/src/vs/workbench/contrib/debug/browser/debugSession.ts#L448-L449
726
+ response?.body?.breakpoints.forEach((raw, index) => {
727
+ // node debug adapter returns more breakpoints sometimes
728
+ if (enabled[index]) {
729
+ updates.set(enabled[index].id, raw);
844
730
  }
845
- }
731
+ });
732
+ } catch (error) {
733
+ const genericMessage: string = 'Function breakpoint not valid for current debug session';
734
+ const message: string = error.message ? `${error.message}` : genericMessage;
735
+ console.warn(`Could not handle function breakpoints: ${message}, disabling...`);
736
+ enabled.forEach(b => updates.set(b.id, { verified: false, message }));
846
737
  }
847
- this.setBreakpoints(affectedUri, all);
738
+ this.breakpoints.updateSessionData(this.id, this.capabilities, updates);
848
739
  }
849
740
 
850
741
  protected async sendSourceBreakpoints(affectedUri: URI, sourceModified?: boolean): Promise<void> {
851
742
  const source = await this.toSource(affectedUri);
852
- const known = this._breakpoints.get(affectedUri.toString());
853
- const all = this.breakpoints.findMarkers({ uri: affectedUri }).map(({ data }) =>
854
- known?.find((candidate): candidate is DebugSourceBreakpoint => candidate instanceof DebugSourceBreakpoint && candidate.origin.id === data.id) ??
855
- new DebugSourceBreakpoint(data, this.asDebugBreakpointOptions(), this.commandService)
856
- );
743
+ const all = this.breakpoints.getBreakpoints(affectedUri);
857
744
  const enabled = all.filter(b => b.enabled);
745
+ const updates = new Map<string, DebugProtocol.Breakpoint>();
858
746
  try {
859
747
  const breakpoints = enabled.map(({ origin }) => origin.raw);
860
748
  const response = await this.sendRequest('setBreakpoints', {
@@ -866,7 +754,7 @@ export class DebugSession implements CompositeTreeElement {
866
754
  response.body.breakpoints.forEach((raw, index) => {
867
755
  // node debug adapter returns more breakpoints sometimes
868
756
  if (enabled[index]) {
869
- enabled[index].update({ raw });
757
+ updates.set(enabled[index].id, raw);
870
758
  }
871
759
  });
872
760
  } catch (error) {
@@ -878,77 +766,44 @@ export class DebugSession implements CompositeTreeElement {
878
766
  const genericMessage: string = 'Breakpoint not valid for current debug session';
879
767
  const message: string = error.message ? `${error.message}` : genericMessage;
880
768
  console.warn(`Could not handle breakpoints for ${affectedUri}: ${message}, disabling...`);
881
- enabled.forEach(b => b.update({
882
- raw: {
883
- verified: false,
884
- message
885
- }
886
- }));
769
+ enabled.forEach(b => updates.set(b.id, { verified: false, message }));
887
770
  }
888
771
  }
889
- this.setSourceBreakpoints(affectedUri, all);
772
+ this.breakpoints.updateSessionData(this.id, this.capabilities, updates);
890
773
  }
891
774
 
892
775
  protected async sendInstructionBreakpoints(): Promise<void> {
893
776
  if (!this.capabilities.supportsInstructionBreakpoints) {
894
777
  return;
895
778
  }
896
- const all = this.breakpoints.getInstructionBreakpoints().map(breakpoint => new DebugInstructionBreakpoint(breakpoint, this.asDebugBreakpointOptions()));
779
+ const all = this.breakpoints.getInstructionBreakpoints();
897
780
  const enabled = all.filter(breakpoint => breakpoint.enabled);
781
+ const updates = new Map<string, DebugProtocol.Breakpoint>();
898
782
  try {
899
783
  const response = await this.sendRequest('setInstructionBreakpoints', {
900
- breakpoints: enabled.map(renderable => renderable.origin),
784
+ breakpoints: enabled.map(renderable => renderable.origin.raw),
901
785
  });
902
- response.body.breakpoints.forEach((raw, index) => enabled[index]?.update({ raw }));
786
+ response.body.breakpoints.forEach((raw, index) => enabled[index] && updates.set(enabled[index].id, raw));
903
787
  } catch {
904
- enabled.forEach(breakpoint => breakpoint.update({ raw: { verified: false } }));
788
+ enabled.forEach(breakpoint => updates.set(breakpoint.id, { verified: false }));
905
789
  }
906
- this.setBreakpoints(BreakpointManager.INSTRUCTION_URI, all);
790
+ this.breakpoints.updateSessionData(this.id, this.capabilities, updates);
907
791
  }
908
792
 
909
793
  protected async sendDataBreakpoints(): Promise<void> {
910
794
  if (!this.capabilities.supportsDataBreakpoints) { return; }
911
- const known = this._breakpoints.get(BreakpointManager.DATA_URI.toString());
912
- const all = this.breakpoints.getDataBreakpoints().map<DebugDataBreakpoint>(bp =>
913
- known?.find((candidate): candidate is DebugDataBreakpoint => candidate instanceof DebugDataBreakpoint && candidate.id === bp.id)
914
- ?? new DebugDataBreakpoint(bp, this.asDebugBreakpointOptions())
915
- );
795
+ const all = this.breakpoints.getDataBreakpoints();
916
796
  const enabled = all.filter(bp => bp.enabled);
797
+ const updates = new Map<string, DebugProtocol.Breakpoint>();
917
798
  try {
918
799
  const response = await this.sendRequest('setDataBreakpoints', {
919
800
  breakpoints: enabled.map(({ origin }) => origin.raw)
920
801
  });
921
- response.body.breakpoints.forEach((raw, index) => enabled[index].update({ raw }));
802
+ response.body.breakpoints.forEach((raw, index) => enabled[index] && updates.set(enabled[index].id, raw));
922
803
  } catch {
923
- enabled.forEach(breakpoint => breakpoint.update({ raw: { verified: false } }));
804
+ enabled.forEach(breakpoint => updates.set(breakpoint.id, { verified: false }));
924
805
  }
925
- this.setBreakpoints(BreakpointManager.DATA_URI, all);
926
- }
927
-
928
- protected setBreakpoints(uri: URI, breakpoints: DebugBreakpoint[]): void {
929
- this._breakpoints.set(uri.toString(), breakpoints);
930
- this.fireDidChangeBreakpoints(uri);
931
- }
932
-
933
- protected setSourceBreakpoints(uri: URI, breakpoints: DebugSourceBreakpoint[]): void {
934
- const distinct = this.dedupSourceBreakpoints(breakpoints);
935
- this.setBreakpoints(uri, distinct);
936
- }
937
-
938
- protected dedupSourceBreakpoints(all: DebugSourceBreakpoint[]): DebugSourceBreakpoint[] {
939
- const positions = new Map<string, DebugSourceBreakpoint>();
940
- for (const breakpoint of all) {
941
- let primary = positions.get(breakpoint.renderPosition()) || breakpoint;
942
- if (primary !== breakpoint) {
943
- let secondary = breakpoint;
944
- if (secondary.raw && secondary.raw.line === secondary.origin.raw.line && secondary.raw.column === secondary.origin.raw.column) {
945
- [primary, secondary] = [breakpoint, primary];
946
- }
947
- primary.origins.push(...secondary.origins);
948
- }
949
- positions.set(primary.renderPosition(), primary);
950
- }
951
- return [...positions.values()];
806
+ this.breakpoints.updateSessionData(this.id, this.capabilities, updates);
952
807
  }
953
808
 
954
809
  protected *getAffectedUris(uri?: URI): IterableIterator<URI> {
@@ -964,11 +819,6 @@ export class DebugSession implements CompositeTreeElement {
964
819
  }
965
820
  }
966
821
 
967
- protected asDebugBreakpointOptions(): DebugBreakpointOptions {
968
- const { labelProvider, breakpoints, editorManager } = this;
969
- return { labelProvider, breakpoints, editorManager, session: this };
970
- }
971
-
972
822
  get label(): string {
973
823
  const suffixes = [];
974
824
  if (InternalDebugSessionOptions.is(this.options) && this.options.id) {
@@ -69,7 +69,7 @@ export class BreakpointRenderer implements ITableRenderer<DisassembledInstructio
69
69
  // click show hint while waiting for BP to resolve.
70
70
  icon.classList.add(this._breakpointHintIcon);
71
71
  if (currentElement.element.isBreakpointSet) {
72
- this._debugService.removeInstructionBreakpoint(currentElement.element.instruction.address);
72
+ this._debugService.removeInstructionBreakpointAt(currentElement.element.instruction.address);
73
73
 
74
74
  } else if (currentElement.element.allowBreakpoint && !currentElement.element.isBreakpointSet) {
75
75
  this._debugService.addInstructionBreakpoint(currentElement.element.instruction.address, 0);
@@ -168,40 +168,34 @@ export class DisassemblyViewWidget extends BaseWidget {
168
168
  // draw viewable BP
169
169
  let changed = false;
170
170
  bpEvent.added?.forEach(bp => {
171
- if (InstructionBreakpoint.is(bp)) {
172
- const index = this.getIndexFromAddress(bp.instructionReference);
173
- if (index >= 0) {
174
- this._disassembledInstructions!.row(index).isBreakpointSet = true;
175
- this._disassembledInstructions!.row(index).isBreakpointEnabled = bp.enabled;
176
- changed = true;
177
- }
171
+ const index = this.getIndexFromAddress(bp.origin.raw.instructionReference);
172
+ if (index >= 0) {
173
+ this._disassembledInstructions!.row(index).isBreakpointSet = true;
174
+ this._disassembledInstructions!.row(index).isBreakpointEnabled = bp.enabled;
175
+ changed = true;
178
176
  }
179
177
  });
180
178
 
181
179
  bpEvent.removed?.forEach(bp => {
182
- if (InstructionBreakpoint.is(bp)) {
183
- const index = this.getIndexFromAddress(bp.instructionReference);
184
- if (index >= 0) {
185
- this._disassembledInstructions!.row(index).isBreakpointSet = false;
186
- changed = true;
187
- }
180
+ const index = this.getIndexFromAddress(bp.origin.raw.instructionReference);
181
+ if (index >= 0) {
182
+ this._disassembledInstructions!.row(index).isBreakpointSet = false;
183
+ changed = true;
188
184
  }
189
185
  });
190
186
 
191
187
  bpEvent.changed?.forEach(bp => {
192
- if (InstructionBreakpoint.is(bp)) {
193
- const index = this.getIndexFromAddress(bp.instructionReference);
194
- if (index >= 0) {
195
- if (this._disassembledInstructions!.row(index).isBreakpointEnabled !== bp.enabled) {
196
- this._disassembledInstructions!.row(index).isBreakpointEnabled = bp.enabled;
197
- changed = true;
198
- }
188
+ const index = this.getIndexFromAddress(bp.origin.raw.instructionReference);
189
+ if (index >= 0) {
190
+ if (this._disassembledInstructions!.row(index).isBreakpointEnabled !== bp.enabled) {
191
+ this._disassembledInstructions!.row(index).isBreakpointEnabled = bp.enabled;
192
+ changed = true;
199
193
  }
200
194
  }
201
195
  });
202
196
 
203
197
  // get an updated list so that items beyond the current range would render when reached.
204
- this._instructionBpList = this.breakpointManager.getInstructionBreakpoints();
198
+ this._instructionBpList = this.breakpointManager.getInstructionBreakpoints().map(({ origin }) => origin);
205
199
 
206
200
  if (changed) {
207
201
  this._onDidChangeStackFrame.fire();
@@ -344,7 +338,7 @@ export class DisassemblyViewWidget extends BaseWidget {
344
338
  let lastLocation: DebugProtocol.Source | undefined;
345
339
  let lastLine: IRange | undefined;
346
340
  for (let i = 0; i < resultEntries.length; i++) {
347
- const found = this._instructionBpList.find(p => p.instructionReference === resultEntries[i].address);
341
+ const found = this._instructionBpList.find(p => p.raw.instructionReference === resultEntries[i].address);
348
342
  const instruction = resultEntries[i];
349
343
 
350
344
  // Forward fill the missing location as detailed in the DAP spec.
@@ -424,7 +418,7 @@ export class DisassemblyViewWidget extends BaseWidget {
424
418
  if (this._disassembledInstructions) {
425
419
  this._loadingLock = true; // stop scrolling during the load.
426
420
  this._disassembledInstructions.splice(0, this._disassembledInstructions.length, [disassemblyNotAvailable]);
427
- this._instructionBpList = this.breakpointManager.getInstructionBreakpoints();
421
+ this._instructionBpList = this.breakpointManager.getInstructionBreakpoints().map(({ origin }) => origin);
428
422
  this.loadDisassembledInstructions(targetAddress, -DisassemblyViewWidget.NUM_INSTRUCTIONS_TO_LOAD * 4, DisassemblyViewWidget.NUM_INSTRUCTIONS_TO_LOAD * 8).then(() => {
429
423
  // on load, set the target instruction in the middle of the page.
430
424
  if (this._disassembledInstructions!.length > 0) {