Skip to content

Commit

Permalink
breakpoints: bound in some process
Browse files Browse the repository at this point in the history
fixes #55106
  • Loading branch information
isidorn committed Sep 20, 2019
1 parent bcf67c8 commit 1c4c8ce
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 55 deletions.
4 changes: 1 addition & 3 deletions src/vs/workbench/contrib/debug/browser/debugService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,7 @@ export class DebugService implements IDebugService {
this.toDispose.push(this.viewModel.onDidFocusStackFrame(() => {
this.onStateChange();
}));
this.toDispose.push(this.viewModel.onDidFocusSession(session => {
const id = session ? session.getId() : undefined;
this.model.setBreakpointsSessionId(id);
this.toDispose.push(this.viewModel.onDidFocusSession(() => {
this.onStateChange();
}));
}
Expand Down
1 change: 1 addition & 0 deletions src/vs/workbench/contrib/debug/browser/debugSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,7 @@ export class DebugSession implements IDebugSession {

this.rawListeners.push(this.raw.onDidExitAdapter(event => {
this.initialized = true;
this.model.setBreakpointSessionData(this.getId(), undefined);
this._onDidEndAdapter.fire(event);
}));
}
Expand Down
101 changes: 49 additions & 52 deletions src/vs/workbench/contrib/debug/common/debugModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ export class Enablement implements IEnablement {
export class BaseBreakpoint extends Enablement implements IBaseBreakpoint {

private sessionData = new Map<string, DebugProtocol.Breakpoint>();
private sessionId: string | undefined;
protected data: DebugProtocol.Breakpoint | undefined;

constructor(
enabled: boolean,
Expand All @@ -516,30 +516,34 @@ export class BaseBreakpoint extends Enablement implements IBaseBreakpoint {
}
}

protected getSessionData(): DebugProtocol.Breakpoint | undefined {
return this.sessionId ? this.sessionData.get(this.sessionId) : undefined;
}

setSessionData(sessionId: string, data: DebugProtocol.Breakpoint): void {
this.sessionData.set(sessionId, data);
}
setSessionData(sessionId: string, data: DebugProtocol.Breakpoint | undefined): void {
if (!data) {
this.sessionData.delete(sessionId);
} else {
this.sessionData.set(sessionId, data);
}

setSessionId(sessionId: string | undefined): void {
this.sessionId = sessionId;
const allData = Array.from(this.sessionData.values());
const verifiedData = distinct(allData.filter(d => d.verified), d => `${d.line}:${d.column}`);
if (verifiedData.length) {
// In case multiple session verified the breakpoint and they provide different data show the intial data that the user set (corner case)
this.data = verifiedData.length === 1 ? verifiedData[0] : undefined;
} else {
// No session verified the breakpoint
this.data = allData.length ? allData[0] : undefined;
}
}

get message(): string | undefined {
const data = this.getSessionData();
if (!data) {
if (!this.data) {
return undefined;
}

return data.message;
return this.data.message;
}

get verified(): boolean {
const data = this.getSessionData();
return data ? data.verified : true;
return this.data ? this.data.verified : true;
}

getIdFromAdapter(sessionId: string): number | undefined {
Expand Down Expand Up @@ -576,23 +580,20 @@ export class Breakpoint extends BaseBreakpoint implements IBreakpoint {
}

get lineNumber(): number {
const data = this.getSessionData();
return this.verified && data && typeof data.line === 'number' ? data.line : this._lineNumber;
return this.verified && this.data && typeof this.data.line === 'number' ? this.data.line : this._lineNumber;
}

get verified(): boolean {
const data = this.getSessionData();
if (data) {
return data.verified && !this.textFileService.isDirty(this.uri);
if (this.data) {
return this.data.verified && !this.textFileService.isDirty(this.uri);
}

return true;
}

get column(): number | undefined {
const data = this.getSessionData();
// Only respect the column if the user explictly set the column to have an inline breakpoint
return data && typeof data.column === 'number' && typeof this._column === 'number' ? data.column : this._column;
return this.verified && this.data && typeof this.data.column === 'number' && typeof this._column === 'number' ? this.data.column : this._column;
}

get message(): string | undefined {
Expand All @@ -604,18 +605,15 @@ export class Breakpoint extends BaseBreakpoint implements IBreakpoint {
}

get adapterData(): any {
const data = this.getSessionData();
return data && data.source && data.source.adapterData ? data.source.adapterData : this._adapterData;
return this.data && this.data.source && this.data.source.adapterData ? this.data.source.adapterData : this._adapterData;
}

get endLineNumber(): number | undefined {
const data = this.getSessionData();
return data ? data.endLine : undefined;
return this.verified && this.data ? this.data.endLine : undefined;
}

get endColumn(): number | undefined {
const data = this.getSessionData();
return data ? data.endColumn : undefined;
return this.verified && this.data ? this.data.endColumn : undefined;
}

get sessionAgnosticData(): { lineNumber: number, column: number | undefined } {
Expand All @@ -625,7 +623,7 @@ export class Breakpoint extends BaseBreakpoint implements IBreakpoint {
};
}

setSessionData(sessionId: string, data: DebugProtocol.Breakpoint): void {
setSessionData(sessionId: string, data: DebugProtocol.Breakpoint | undefined): void {
super.setSessionData(sessionId, data);
if (!this._adapterData) {
this._adapterData = this.adapterData;
Expand Down Expand Up @@ -751,7 +749,6 @@ export class DebugModel implements IDebugModel {
private sessions: IDebugSession[];
private toDispose: lifecycle.IDisposable[];
private schedulers = new Map<string, RunOnceScheduler>();
private breakpointsSessionId: string | undefined;
private breakpointsActivated = true;
private readonly _onDidChangeBreakpoints: Emitter<IBreakpointsChangeEvent | undefined>;
private readonly _onDidChangeCallStack: Emitter<void>;
Expand Down Expand Up @@ -945,7 +942,6 @@ export class DebugModel implements IDebugModel {

addBreakpoints(uri: uri, rawData: IBreakpointData[], fireEvent = true): IBreakpoint[] {
const newBreakpoints = rawData.map(rawBp => new Breakpoint(uri, rawBp.lineNumber, rawBp.column, rawBp.enabled === false ? false : true, rawBp.condition, rawBp.hitCondition, rawBp.logMessage, undefined, this.textFileService, rawBp.id));
newBreakpoints.forEach(bp => bp.setSessionId(this.breakpointsSessionId));
this.breakpoints = this.breakpoints.concat(newBreakpoints);
this.breakpointsActivated = true;
this.sortAndDeDup();
Expand Down Expand Up @@ -975,23 +971,35 @@ export class DebugModel implements IDebugModel {
this._onDidChangeBreakpoints.fire({ changed: updated });
}

setBreakpointSessionData(sessionId: string, data: Map<string, DebugProtocol.Breakpoint>): void {
setBreakpointSessionData(sessionId: string, data: Map<string, DebugProtocol.Breakpoint> | undefined): void {
this.breakpoints.forEach(bp => {
const bpData = data.get(bp.getId());
if (bpData) {
bp.setSessionData(sessionId, bpData);
if (!data) {
bp.setSessionData(sessionId, undefined);
} else {
const bpData = data.get(bp.getId());
if (bpData) {
bp.setSessionData(sessionId, bpData);
}
}
});
this.functionBreakpoints.forEach(fbp => {
const fbpData = data.get(fbp.getId());
if (fbpData) {
fbp.setSessionData(sessionId, fbpData);
if (!data) {
fbp.setSessionData(sessionId, undefined);
} else {
const fbpData = data.get(fbp.getId());
if (fbpData) {
fbp.setSessionData(sessionId, fbpData);
}
}
});
this.dataBreakopints.forEach(dbp => {
const dbpData = data.get(dbp.getId());
if (dbpData) {
dbp.setSessionData(sessionId, dbpData);
if (!data) {
dbp.setSessionData(sessionId, undefined);
} else {
const dbpData = data.get(dbp.getId());
if (dbpData) {
dbp.setSessionData(sessionId, dbpData);
}
}
});

Expand All @@ -1000,17 +1008,6 @@ export class DebugModel implements IDebugModel {
});
}

setBreakpointsSessionId(sessionId: string | undefined): void {
this.breakpointsSessionId = sessionId;
this.breakpoints.forEach(bp => bp.setSessionId(sessionId));
this.functionBreakpoints.forEach(fbp => fbp.setSessionId(sessionId));
this.dataBreakopints.forEach(dbp => dbp.setSessionId(sessionId));

this._onDidChangeBreakpoints.fire({
sessionOnly: true
});
}

private sortAndDeDup(): void {
this.breakpoints = this.breakpoints.sort((first, second) => {
if (first.uri.toString() !== second.uri.toString()) {
Expand Down
32 changes: 32 additions & 0 deletions src/vs/workbench/contrib/debug/test/browser/debugModel.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,38 @@ suite('Debug - Model', () => {
assert.equal(model.getFunctionBreakpoints().length, 0);
});

test('breakpoints multiple sessions', () => {
const modelUri = uri.file('/myfolder/myfile.js');
const breakpoints = model.addBreakpoints(modelUri, [{ lineNumber: 5, enabled: true }, { lineNumber: 10, enabled: false }]);
const session = createMockSession(model);
const data = new Map<string, DebugProtocol.Breakpoint>();

assert.equal(breakpoints[0].lineNumber, 5);
assert.equal(breakpoints[1].lineNumber, 10);

data.set(breakpoints[0].getId(), { verified: false, line: 10 });
data.set(breakpoints[1].getId(), { verified: true, line: 50 });
model.setBreakpointSessionData(session.getId(), data);
assert.equal(breakpoints[0].lineNumber, 5);
assert.equal(breakpoints[1].lineNumber, 50);

const session2 = createMockSession(model);
const data2 = new Map<string, DebugProtocol.Breakpoint>();
data2.set(breakpoints[0].getId(), { verified: true, line: 100 });
data2.set(breakpoints[1].getId(), { verified: true, line: 500 });
model.setBreakpointSessionData(session2.getId(), data2);

// Breakpoint is verified only once, show that line
assert.equal(breakpoints[0].lineNumber, 100);
// Breakpoint is verified two times, show the original line
assert.equal(breakpoints[1].lineNumber, 10);

model.setBreakpointSessionData(session.getId(), undefined);
// No more double session verification
assert.equal(breakpoints[0].lineNumber, 100);
assert.equal(breakpoints[1].lineNumber, 500);
});

// Threads

test('threads simple', () => {
Expand Down

0 comments on commit 1c4c8ce

Please sign in to comment.