Skip to content

Commit

Permalink
WIP fix #3312: complete support of source breakpoints
Browse files Browse the repository at this point in the history
Signed-off-by: Anton Kosyakov <anton.kosyakov@typefox.io>
  • Loading branch information
akosyakov committed Jan 3, 2019
1 parent 49b80d5 commit 27df19a
Show file tree
Hide file tree
Showing 30 changed files with 1,144 additions and 214 deletions.
58 changes: 42 additions & 16 deletions packages/debug/src/browser/breakpoint/breakpoint-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,20 @@
********************************************************************************/

import { injectable, inject } from 'inversify';
import { Emitter, Event } from '@theia/core/lib/common';
import { StorageService } from '@theia/core/lib/browser';
import { Marker } from '@theia/markers/lib/common/marker';
import { MarkerManager } from '@theia/markers/lib/browser/marker-manager';
import URI from '@theia/core/lib/common/uri';
import { SourceBreakpoint, BREAKPOINT_KIND } from './breakpoint-marker';

export interface BreakpointsChangeEvent {
uri: URI
added: SourceBreakpoint[]
removed: SourceBreakpoint[]
changed: SourceBreakpoint[]
}

@injectable()
export class BreakpointManager extends MarkerManager<SourceBreakpoint> {

Expand All @@ -32,6 +41,33 @@ export class BreakpointManager extends MarkerManager<SourceBreakpoint> {
return BREAKPOINT_KIND;
}

protected readonly onDidChangeBreakpointsEmitter = new Emitter<BreakpointsChangeEvent>();
readonly onDidChangeBreakpoints: Event<BreakpointsChangeEvent> = this.onDidChangeBreakpointsEmitter.event;

setMarkers(uri: URI, owner: string, newMarkers: SourceBreakpoint[]): Marker<SourceBreakpoint>[] {
const result = super.setMarkers(uri, owner, newMarkers);
const added: SourceBreakpoint[] = [];
const removed: SourceBreakpoint[] = [];
const changed: SourceBreakpoint[] = [];
const oldMarkers = new Map(result.map(({ data }) => [data.id, data] as [string, SourceBreakpoint]));
const ids = new Set<string>();
for (const newMarker of newMarkers) {
ids.add(newMarker.id);
if (oldMarkers.has(newMarker.id)) {
changed.push(newMarker);
} else {
added.push(newMarker);
}
}
for (const [id, data] of oldMarkers.entries()) {
if (!ids.has(id)) {
removed.push(data);
}
}
this.onDidChangeBreakpointsEmitter.fire({ uri, added, removed, changed });
return result;
}

getBreakpoint(uri: URI, line: number): SourceBreakpoint | undefined {
const marker = this.findMarkers({
uri,
Expand All @@ -48,26 +84,16 @@ export class BreakpointManager extends MarkerManager<SourceBreakpoint> {
this.setMarkers(uri, this.owner, breakpoints.sort((a, b) => a.raw.line - b.raw.line));
}

addBreakpoint(uri: URI, line: number, column?: number): void {
addBreakpoint(breakpoint: SourceBreakpoint): boolean {
const uri = new URI(breakpoint.uri);
const breakpoints = this.getBreakpoints(uri);
const newBreakpoints = breakpoints.filter(({ raw }) => raw.line !== line);
const newBreakpoints = breakpoints.filter(({ raw }) => raw.line !== breakpoint.raw.line);
if (breakpoints.length === newBreakpoints.length) {
newBreakpoints.push({
uri: uri.toString(),
enabled: true,
raw: {
line,
column
}
});
newBreakpoints.push(breakpoint);
this.setBreakpoints(uri, newBreakpoints);
return true;
}
}

deleteBreakpoint(uri: URI, line: number, column?: number): void {
const breakpoints = this.getBreakpoints(uri);
const newBreakpoints = breakpoints.filter(({ raw }) => raw.line !== line);
this.setBreakpoints(uri, newBreakpoints);
return false;
}

enableAllBreakpoints(enabled: boolean): void {
Expand Down
17 changes: 16 additions & 1 deletion packages/debug/src/browser/breakpoint/breakpoint-marker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,36 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { UUID } from '@phosphor/coreutils';
import URI from '@theia/core/lib/common/uri';
import { Marker } from '@theia/markers/lib/common/marker';
import { DebugProtocol } from 'vscode-debugprotocol/lib/debugProtocol';

export const BREAKPOINT_KIND = 'breakpoint';

export interface SourceBreakpoint {
id: string;
uri: string;
enabled: boolean;
raw: DebugProtocol.SourceBreakpoint
}
export namespace SourceBreakpoint {
export function create(uri: URI, data: DebugProtocol.SourceBreakpoint, origin?: SourceBreakpoint): SourceBreakpoint {
return {
id: origin ? origin.id : UUID.uuid4(),
uri: uri.toString(),
enabled: origin ? origin.enabled : true,
raw: {
...(origin && origin.raw),
...data
}
};
}
}

export interface BreakpointMarker extends Marker<SourceBreakpoint> {
kind: 'breakpoint'
}

export namespace BreakpointMarker {
export function is(node: Marker<object>): node is BreakpointMarker {
return 'kind' in node && node.kind === BREAKPOINT_KIND;
Expand Down
Loading

0 comments on commit 27df19a

Please sign in to comment.