Skip to content

Commit

Permalink
debug: do not massage output in the repl specially.
Browse files Browse the repository at this point in the history
  • Loading branch information
isidorn committed Nov 22, 2016
1 parent 7324191 commit d2a4e2e
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 60 deletions.
65 changes: 19 additions & 46 deletions src/vs/workbench/parts/debug/common/debugModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { generateUuid } from 'vs/base/common/uuid';
import { clone } from 'vs/base/common/objects';
import severity from 'vs/base/common/severity';
import { isObject, isString } from 'vs/base/common/types';
import * as strings from 'vs/base/common/strings';
import { distinct } from 'vs/base/common/arrays';
import { IRange } from 'vs/editor/common/editorCommon';
import { Range } from 'vs/editor/common/core/range';
Expand Down Expand Up @@ -40,7 +41,6 @@ export class ValueOutputElement extends OutputElement {
constructor(
public value: string,
public severity: severity,
public category?: string,
public counter = 1
) {
super();
Expand Down Expand Up @@ -288,7 +288,6 @@ export class Variable extends ExpressionContainer implements debug.IExpression {
this.namedVariables = response.body.namedVariables;
this.indexedVariables = response.body.indexedVariables;
}
// TODO@Isidor notify stackFrame that a change has happened so watch expressions get revelauted
}, err => {
this.errorMessage = err.message;
});
Expand Down Expand Up @@ -808,63 +807,37 @@ export class Model implements debug.IModel {

public addReplExpression(process: debug.IProcess, stackFrame: debug.IStackFrame, name: string): TPromise<void> {
const expression = new Expression(name);
this.addReplElements([expression]);
this.addReplElement(expression);
return expression.evaluate(process, stackFrame, 'repl')
.then(() => this._onDidChangeREPLElements.fire());
}

public logToRepl(value: string | { [key: string]: any }, severity?: severity): void {
let elements: OutputElement[] = [];
let previousOutput = this.replElements.length && (<ValueOutputElement>this.replElements[this.replElements.length - 1]);
public appendReplOutput(value: string | { [key: string]: any }, severity?: severity): void {
const previousOutput = this.replElements.length && (this.replElements[this.replElements.length - 1] as ValueOutputElement);

// string message
if (typeof value === 'string') {
if (value && value.trim() && previousOutput && previousOutput.value === value && previousOutput.severity === severity) {
previousOutput.counter++; // we got the same output (but not an empty string when trimmed) so we just increment the counter
const groupTogether = previousOutput instanceof ValueOutputElement && severity === previousOutput.severity;
if (groupTogether) {
if (strings.endsWith(previousOutput.value, '\n') && previousOutput.value === value && value.trim()) {
// we got the same output (but not an empty string when trimmed) so we just increment the counter
previousOutput.counter++;
} else {
// append to previous line if same group
previousOutput.value += value;
}
} else {
let lines = value.trim().split('\n');
lines.forEach((line, index) => {
elements.push(new ValueOutputElement(line, severity));
});
this.addReplElement(new ValueOutputElement(value, severity));
}
} else {
// key-value output
this.addReplElement(new KeyValueOutputElement((<any>value).prototype, value, nls.localize('snapshotObj', "Only primitive values are shown for this object.")));
}

// key-value output
else {
elements.push(new KeyValueOutputElement((<any>value).prototype, value, nls.localize('snapshotObj', "Only primitive values are shown for this object.")));
}

if (elements.length) {
this.addReplElements(elements);
}
this._onDidChangeREPLElements.fire();
}

public appendReplOutput(value: string, severity?: severity): void {
const elements: OutputElement[] = [];
const previousOutput = this.replElements.length && (<ValueOutputElement>this.replElements[this.replElements.length - 1]);
const lines = value.split('\n');
const groupTogether = !!previousOutput && (previousOutput.category === 'output' && severity === previousOutput.severity);

if (groupTogether) {
// append to previous line if same group
previousOutput.value += lines.shift();
} else if (previousOutput && previousOutput.value === '') {
// remove potential empty lines between different output types
this.replElements.pop();
}

// fill in lines as output value elements
lines.forEach((line, index) => {
elements.push(new ValueOutputElement(line, severity, 'output'));
});

this.addReplElements(elements);
this._onDidChangeREPLElements.fire();
}

private addReplElements(newElements: debug.ITreeElement[]): void {
this.replElements.push(...newElements);
private addReplElement(newElement: debug.ITreeElement): void {
this.replElements.push(newElement);
if (this.replElements.length > MAX_REPL_LENGTH) {
this.replElements.splice(0, this.replElements.length - MAX_REPL_LENGTH);
}
Expand Down
6 changes: 3 additions & 3 deletions src/vs/workbench/parts/debug/electron-browser/debugService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,12 @@ export class DebugService implements debug.IDebugService {

// flush any existing simple values logged
if (simpleVals.length) {
this.model.logToRepl(simpleVals.join(' '), sev);
this.model.appendReplOutput(simpleVals.join(' '), sev);
simpleVals = [];
}

// show object
this.model.logToRepl(a, sev);
this.model.appendReplOutput(a, sev);
}

// string: watch out for % replacement directive
Expand Down Expand Up @@ -229,7 +229,7 @@ export class DebugService implements debug.IDebugService {

// flush simple values
if (simpleVals.length) {
this.model.logToRepl(simpleVals.join(' '), sev);
this.model.appendReplOutput(simpleVals.join(' '), sev);
}
}
}
Expand Down
33 changes: 22 additions & 11 deletions src/vs/workbench/parts/debug/test/node/debugModel.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,34 +331,45 @@ suite('Debug - Model', () => {
// Repl output

test('repl output', () => {
model.logToRepl('first line', severity.Error);
model.logToRepl('second line', severity.Warning);
model.logToRepl('second line', severity.Warning);
model.logToRepl('second line', severity.Error);
model.appendReplOutput('first line\n', severity.Error);
model.appendReplOutput('second line\n', severity.Warning);
model.appendReplOutput('second line\n', severity.Warning);
model.appendReplOutput('second line\n', severity.Error);

let elements = <debugmodel.ValueOutputElement[]>model.getReplElements();
assert.equal(elements.length, 3);
assert.equal(elements[0].value, 'first line');
assert.equal(elements[0].value, 'first line\n');
assert.equal(elements[0].counter, 1);
assert.equal(elements[0].severity, severity.Error);
assert.equal(elements[1].value, 'second line');
assert.equal(elements[1].value, 'second line\n');
assert.equal(elements[1].counter, 2);
assert.equal(elements[1].severity, severity.Warning);

model.appendReplOutput('1', severity.Error);
model.appendReplOutput('2', severity.Error);
model.appendReplOutput('3', severity.Error);
model.appendReplOutput('1', severity.Warning);
model.appendReplOutput('2', severity.Warning);
model.appendReplOutput('3', severity.Warning);
elements = <debugmodel.ValueOutputElement[]>model.getReplElements();
assert.equal(elements.length, 4);
assert.equal(elements[3].value, '123');
assert.equal(elements[3].severity, severity.Error);
assert.equal(elements[3].severity, severity.Warning);

const keyValueObject = { 'key1': 2, 'key2': 'value' };
model.logToRepl(keyValueObject);
model.appendReplOutput(keyValueObject);
const element = <debugmodel.KeyValueOutputElement>model.getReplElements()[4];
assert.equal(element.value, 'Object');
assert.deepEqual(element.valueObj, keyValueObject);

const multiLineContent = 'multi line \n string \n last line';
model.appendReplOutput(multiLineContent);
const multiLineElement = <debugmodel.ValueOutputElement>model.getReplElements()[5];
assert.equal(multiLineElement.value, multiLineContent);
assert.equal(model.getReplElements().length, 6);

model.appendReplOutput('second line', severity.Warning);
model.appendReplOutput('second line', severity.Warning);

assert.equal((<debugmodel.ValueOutputElement>model.getReplElements()[6]).value, 'second linesecond line');

model.removeReplExpressions();
assert.equal(model.getReplElements().length, 0);
});
Expand Down

0 comments on commit d2a4e2e

Please sign in to comment.