mirror of
https://github.com/Microsoft/vscode
synced 2024-10-30 04:17:37 +00:00
parent
f492317890
commit
f178d6c30f
4 changed files with 63 additions and 60 deletions
|
@ -24,39 +24,6 @@ function massageValue(value: string): string {
|
|||
return value ? value.replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/\t/g, '\\t') : value;
|
||||
}
|
||||
|
||||
export function evaluateExpression(stackFrame: debug.IStackFrame, expression: Expression, context: string): TPromise<Expression> {
|
||||
if (!stackFrame || !stackFrame.thread.process) {
|
||||
expression.value = context === 'repl' ? nls.localize('startDebugFirst', "Please start a debug session to evaluate") : Expression.DEFAULT_VALUE;
|
||||
expression.available = false;
|
||||
expression.reference = 0;
|
||||
return TPromise.as(expression);
|
||||
}
|
||||
expression.stackFrame = stackFrame;
|
||||
|
||||
return stackFrame.thread.process.session.evaluate({
|
||||
expression: expression.name,
|
||||
frameId: stackFrame ? stackFrame.frameId : undefined,
|
||||
context
|
||||
}).then(response => {
|
||||
expression.available = !!(response && response.body);
|
||||
if (response && response.body) {
|
||||
expression.value = response.body.result;
|
||||
expression.reference = response.body.variablesReference;
|
||||
expression.namedVariables = response.body.namedVariables;
|
||||
expression.indexedVariables = response.body.indexedVariables;
|
||||
expression.type = response.body.type;
|
||||
}
|
||||
|
||||
return expression;
|
||||
}, err => {
|
||||
expression.value = err.message;
|
||||
expression.available = false;
|
||||
expression.reference = 0;
|
||||
|
||||
return expression;
|
||||
});
|
||||
}
|
||||
|
||||
export class OutputElement implements debug.ITreeElement {
|
||||
private static ID_COUNTER = 0;
|
||||
|
||||
|
@ -238,6 +205,39 @@ export class Expression extends ExpressionContainer implements debug.IExpression
|
|||
this.value = Expression.DEFAULT_VALUE;
|
||||
this.available = false;
|
||||
}
|
||||
|
||||
public evaluate(process: debug.IProcess, stackFrame: debug.IStackFrame, context: string): TPromise<void> {
|
||||
if (!process) {
|
||||
this.value = context === 'repl' ? nls.localize('startDebugFirst', "Please start a debug session to evaluate") : Expression.DEFAULT_VALUE;
|
||||
this.available = false;
|
||||
this.reference = 0;
|
||||
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
// Create a fake stack frame which is just used as a container for the process.
|
||||
// TODO@Isidor revisit if variables should have a reference to the StackFrame or a process after all
|
||||
this.stackFrame = stackFrame || new StackFrame(new Thread(process, undefined, undefined), undefined, undefined, undefined, undefined, undefined);
|
||||
|
||||
return process.session.evaluate({
|
||||
expression: this.name,
|
||||
frameId: stackFrame ? stackFrame.frameId : undefined,
|
||||
context
|
||||
}).then(response => {
|
||||
this.available = !!(response && response.body);
|
||||
if (response && response.body) {
|
||||
this.value = response.body.result;
|
||||
this.reference = response.body.variablesReference;
|
||||
this.namedVariables = response.body.namedVariables;
|
||||
this.indexedVariables = response.body.indexedVariables;
|
||||
this.type = response.body.type;
|
||||
}
|
||||
}, err => {
|
||||
this.value = err.message;
|
||||
this.available = false;
|
||||
this.reference = 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class Variable extends ExpressionContainer implements debug.IExpression {
|
||||
|
@ -800,10 +800,10 @@ export class Model implements debug.IModel {
|
|||
return this.replElements;
|
||||
}
|
||||
|
||||
public addReplExpression(stackFrame: debug.IStackFrame, name: string): TPromise<void> {
|
||||
public addReplExpression(process: debug.IProcess, stackFrame: debug.IStackFrame, name: string): TPromise<void> {
|
||||
const expression = new Expression(name, true);
|
||||
this.addReplElements([expression]);
|
||||
return evaluateExpression(stackFrame, expression, 'repl')
|
||||
return expression.evaluate(process, stackFrame, 'repl')
|
||||
.then(() => this._onDidChangeREPLElements.fire());
|
||||
}
|
||||
|
||||
|
@ -875,7 +875,7 @@ export class Model implements debug.IModel {
|
|||
return this.watchExpressions;
|
||||
}
|
||||
|
||||
public addWatchExpression(stackFrame: debug.IStackFrame, name: string): TPromise<void> {
|
||||
public addWatchExpression(process: debug.IProcess, stackFrame: debug.IStackFrame, name: string): TPromise<void> {
|
||||
const we = new Expression(name, false);
|
||||
this.watchExpressions.push(we);
|
||||
if (!name) {
|
||||
|
@ -883,14 +883,14 @@ export class Model implements debug.IModel {
|
|||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
return this.evaluateWatchExpressions(stackFrame, we.getId());
|
||||
return this.evaluateWatchExpressions(process, stackFrame, we.getId());
|
||||
}
|
||||
|
||||
public renameWatchExpression(stackFrame: debug.IStackFrame, id: string, newName: string): TPromise<void> {
|
||||
public renameWatchExpression(process: debug.IProcess, stackFrame: debug.IStackFrame, id: string, newName: string): TPromise<void> {
|
||||
const filtered = this.watchExpressions.filter(we => we.getId() === id);
|
||||
if (filtered.length === 1) {
|
||||
filtered[0].name = newName;
|
||||
return evaluateExpression(stackFrame, filtered[0], 'watch').then(() => {
|
||||
return filtered[0].evaluate(process, stackFrame, 'watch').then(() => {
|
||||
this._onDidChangeWatchExpressions.fire(filtered[0]);
|
||||
});
|
||||
}
|
||||
|
@ -898,19 +898,19 @@ export class Model implements debug.IModel {
|
|||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
public evaluateWatchExpressions(stackFrame: debug.IStackFrame, id: string = null): TPromise<void> {
|
||||
public evaluateWatchExpressions(process: debug.IProcess, stackFrame: debug.IStackFrame, id: string = null): TPromise<void> {
|
||||
if (id) {
|
||||
const filtered = this.watchExpressions.filter(we => we.getId() === id);
|
||||
if (filtered.length !== 1) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
return evaluateExpression(stackFrame, filtered[0], 'watch').then(() => {
|
||||
return filtered[0].evaluate(process, stackFrame, 'watch').then(() => {
|
||||
this._onDidChangeWatchExpressions.fire(filtered[0]);
|
||||
});
|
||||
}
|
||||
|
||||
return TPromise.join(this.watchExpressions.map(we => evaluateExpression(stackFrame, we, 'watch'))).then(() => {
|
||||
return TPromise.join(this.watchExpressions.map(we => we.evaluate(process, stackFrame, 'watch'))).then(() => {
|
||||
this._onDidChangeWatchExpressions.fire();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import { IConfigurationChangedEvent } from 'vs/editor/common/editorCommon';
|
|||
import editorbrowser = require('vs/editor/browser/editorBrowser');
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import debug = require('vs/workbench/parts/debug/common/debug');
|
||||
import { evaluateExpression, Expression } from 'vs/workbench/parts/debug/common/debugModel';
|
||||
import { Expression } from 'vs/workbench/parts/debug/common/debugModel';
|
||||
import viewer = require('vs/workbench/parts/debug/electron-browser/debugViewer');
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
|
@ -158,13 +158,16 @@ export class DebugHoverWidget implements editorbrowser.IContentWidget {
|
|||
const expressionRange = this.getExactExpressionRange(lineContent, range);
|
||||
// use regex to extract the sub-expression #9821
|
||||
const matchingExpression = lineContent.substring(expressionRange.startColumn - 1, expressionRange.endColumn);
|
||||
let promise: TPromise<debug.IExpression>;
|
||||
if (process.session.configuration.capabilities.supportsEvaluateForHovers) {
|
||||
const result = new Expression(matchingExpression, true);
|
||||
promise = result.evaluate(process, focusedStackFrame, 'hover').then(() => result);
|
||||
} else {
|
||||
promise = this.findExpressionInStackFrame(matchingExpression.split('.').map(word => word.trim()).filter(word => !!word));
|
||||
}
|
||||
|
||||
const evaluatedExpression = process.session.configuration.capabilities.supportsEvaluateForHovers ?
|
||||
evaluateExpression(focusedStackFrame, new Expression(matchingExpression, true), 'hover') :
|
||||
this.findExpressionInStackFrame(matchingExpression.split('.').map(word => word.trim()).filter(word => !!word));
|
||||
|
||||
return evaluatedExpression.then(expression => {
|
||||
if (!expression || !expression.available) {
|
||||
return promise.then(expression => {
|
||||
if (!expression || (expression instanceof Expression && !expression.available)) {
|
||||
this.hide();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -451,7 +451,7 @@ export class DebugService implements debug.IDebugService {
|
|||
this.viewModel.setFocusedStackFrame(focusedStackFrame, process);
|
||||
this._onDidChangeState.fire();
|
||||
if (focusedStackFrame) {
|
||||
return this.model.evaluateWatchExpressions(focusedStackFrame);
|
||||
return this.model.evaluateWatchExpressions(process, focusedStackFrame);
|
||||
} else {
|
||||
this.model.clearWatchExpressionValues();
|
||||
return TPromise.as(null);
|
||||
|
@ -512,7 +512,7 @@ export class DebugService implements debug.IDebugService {
|
|||
|
||||
public addReplExpression(name: string): TPromise<void> {
|
||||
this.telemetryService.publicLog('debugService/addReplExpression');
|
||||
return this.model.addReplExpression(this.viewModel.focusedStackFrame, name)
|
||||
return this.model.addReplExpression(this.viewModel.focusedProcess, this.viewModel.focusedStackFrame, name)
|
||||
// Evaluate all watch expressions again since repl evaluation might have changed some.
|
||||
.then(() => this.setFocusedStackFrameAndEvaluate(this.viewModel.focusedStackFrame));
|
||||
}
|
||||
|
@ -530,11 +530,11 @@ export class DebugService implements debug.IDebugService {
|
|||
}
|
||||
|
||||
public addWatchExpression(name: string): TPromise<void> {
|
||||
return this.model.addWatchExpression(this.viewModel.focusedStackFrame, name);
|
||||
return this.model.addWatchExpression(this.viewModel.focusedProcess, this.viewModel.focusedStackFrame, name);
|
||||
}
|
||||
|
||||
public renameWatchExpression(id: string, newName: string): TPromise<void> {
|
||||
return this.model.renameWatchExpression(this.viewModel.focusedStackFrame, id, newName);
|
||||
return this.model.renameWatchExpression(this.viewModel.focusedProcess, this.viewModel.focusedStackFrame, id, newName);
|
||||
}
|
||||
|
||||
public removeWatchExpressions(id?: string): void {
|
||||
|
|
|
@ -294,13 +294,13 @@ suite('Debug - Model', () => {
|
|||
const process = new debugmodel.Process('mockProcess', rawSession);
|
||||
const thread = new debugmodel.Thread(process, 'mockthread', 1);
|
||||
const stackFrame = new debugmodel.StackFrame(thread, 1, null, 'app.js', 1, 1);
|
||||
model.addWatchExpression(stackFrame, 'console').done();
|
||||
model.addWatchExpression(stackFrame, 'console').done();
|
||||
model.addWatchExpression(process, stackFrame, 'console').done();
|
||||
model.addWatchExpression(process, stackFrame, 'console').done();
|
||||
const watchExpressions = model.getWatchExpressions();
|
||||
assertWatchExpressions(watchExpressions, 'console');
|
||||
|
||||
model.renameWatchExpression(stackFrame, watchExpressions[0].getId(), 'new_name').done();
|
||||
model.renameWatchExpression(stackFrame, watchExpressions[1].getId(), 'new_name').done();
|
||||
model.renameWatchExpression(process, stackFrame, watchExpressions[0].getId(), 'new_name').done();
|
||||
model.renameWatchExpression(process, stackFrame, watchExpressions[1].getId(), 'new_name').done();
|
||||
assertWatchExpressions(model.getWatchExpressions(), 'new_name');
|
||||
|
||||
model.clearWatchExpressionValues();
|
||||
|
@ -315,9 +315,9 @@ suite('Debug - Model', () => {
|
|||
const process = new debugmodel.Process('mockProcess', rawSession);
|
||||
const thread = new debugmodel.Thread(process, 'mockthread', 1);
|
||||
const stackFrame = new debugmodel.StackFrame(thread, 1, null, 'app.js', 1, 1);
|
||||
model.addReplExpression(stackFrame, 'myVariable').done();
|
||||
model.addReplExpression(stackFrame, 'myVariable').done();
|
||||
model.addReplExpression(stackFrame, 'myVariable').done();
|
||||
model.addReplExpression(process, stackFrame, 'myVariable').done();
|
||||
model.addReplExpression(process, stackFrame, 'myVariable').done();
|
||||
model.addReplExpression(process, stackFrame, 'myVariable').done();
|
||||
|
||||
assert.equal(model.getReplElements().length, 3);
|
||||
model.getReplElements().forEach(re => {
|
||||
|
|
Loading…
Reference in a new issue