mirror of
https://github.com/Microsoft/vscode
synced 2024-10-05 19:02:54 +00:00
* Implement display variable type setting for vscode (#210258) Created two new settings to be added to .vscode/settings.json ('variableDisplayType.watchView' and 'variableDisplayType.variableView') when set to true it shows the variable type in the format var_name: type = value in the debug panel and variable panel respectively and the hover will now display var_name. When set to false uses the previous expected behaviour (var_name = value) and the hover will display the type. Co-authored-by: Diogo Pinto <diogotfpinto@tecnico.ulisboa.pt> * Implemented the requested changes. Registed new setting in debug.contribution.ts Changed the two settings for a single setting (debug.showVariableTypes) Made the renderer functions listen to changes so it re-renders elements Added a different styling for the type in variable panel Changed function names to use camelCase Co-authored-by: Diogo Pinto <diogotfpinto@tecnico.ulisboa.pt> * Implemented Requested small changes. Removed linkDetector check when rendering the type. Deleted displayType boolean, now we read from config in render Added missing line to renderExpressionElement. Co-authored-by: Diogo Pinto <diogotfpinto@tecnico.ulisboa.pt> --------- Co-authored-by: Diogo Pinto <diogotfpinto@tecnico.ulisboa.pt>
This commit is contained in:
commit
739a9e8579
|
@ -49,6 +49,7 @@ export interface IRenderValueOptions {
|
|||
export interface IVariableTemplateData {
|
||||
expression: HTMLElement;
|
||||
name: HTMLElement;
|
||||
type: HTMLElement;
|
||||
value: HTMLElement;
|
||||
label: HighlightedLabel;
|
||||
lazyButton: HTMLElement;
|
||||
|
@ -130,13 +131,20 @@ export function renderExpressionValue(expressionOrValue: IExpressionValue | stri
|
|||
}
|
||||
}
|
||||
|
||||
export function renderVariable(store: DisposableStore, commandService: ICommandService, hoverService: IHoverService, variable: Variable, data: IVariableTemplateData, showChanged: boolean, highlights: IHighlight[], linkDetector?: LinkDetector): void {
|
||||
export function renderVariable(store: DisposableStore, commandService: ICommandService, hoverService: IHoverService, variable: Variable, data: IVariableTemplateData, showChanged: boolean, highlights: IHighlight[], linkDetector?: LinkDetector, displayType?: boolean): void {
|
||||
if (variable.available) {
|
||||
data.type.textContent = '';
|
||||
let text = variable.name;
|
||||
if (variable.value && typeof variable.name === 'string') {
|
||||
text += ':';
|
||||
if (variable.type && displayType) {
|
||||
text += ': ';
|
||||
data.type.textContent = variable.type + ' =';
|
||||
} else {
|
||||
text += ' =';
|
||||
}
|
||||
}
|
||||
data.label.set(text, highlights, variable.type ? variable.type : variable.name);
|
||||
|
||||
data.label.set(text, highlights, variable.type && !displayType ? variable.type : variable.name);
|
||||
data.name.classList.toggle('virtual', variable.presentationHint?.kind === 'virtual');
|
||||
data.name.classList.toggle('internal', variable.presentationHint?.visibility === 'internal');
|
||||
} else if (variable.value && typeof variable.name === 'string' && variable.name) {
|
||||
|
@ -171,6 +179,7 @@ export interface IInputBoxOptions {
|
|||
export interface IExpressionTemplateData {
|
||||
expression: HTMLElement;
|
||||
name: HTMLSpanElement;
|
||||
type: HTMLSpanElement;
|
||||
value: HTMLSpanElement;
|
||||
inputBoxContainer: HTMLElement;
|
||||
actionBar?: ActionBar;
|
||||
|
@ -228,7 +237,10 @@ export abstract class AbstractExpressionsRenderer<T = IExpression> implements IT
|
|||
const name = dom.append(expression, $('span.name'));
|
||||
const lazyButton = dom.append(expression, $('span.lazy-button'));
|
||||
lazyButton.classList.add(...ThemeIcon.asClassNameArray(Codicon.eye));
|
||||
|
||||
templateDisposable.add(this.hoverService.setupManagedHover(getDefaultHoverDelegate('mouse'), lazyButton, localize('debug.lazyButton.tooltip', "Click to expand")));
|
||||
const type = dom.append(expression, $('span.type'));
|
||||
|
||||
const value = dom.append(expression, $('span.value'));
|
||||
|
||||
const label = templateDisposable.add(new HighlightedLabel(name));
|
||||
|
@ -241,7 +253,7 @@ export abstract class AbstractExpressionsRenderer<T = IExpression> implements IT
|
|||
actionBar = templateDisposable.add(new ActionBar(expression));
|
||||
}
|
||||
|
||||
const template: IExpressionTemplateData = { expression, name, value, label, inputBoxContainer, actionBar, elementDisposable: new DisposableStore(), templateDisposable, lazyButton, currentElement: undefined };
|
||||
const template: IExpressionTemplateData = { expression, name, type, value, label, inputBoxContainer, actionBar, elementDisposable: new DisposableStore(), templateDisposable, lazyButton, currentElement: undefined };
|
||||
|
||||
templateDisposable.add(dom.addDisposableListener(lazyButton, dom.EventType.CLICK, () => {
|
||||
if (template.currentElement) {
|
||||
|
@ -255,7 +267,6 @@ export abstract class AbstractExpressionsRenderer<T = IExpression> implements IT
|
|||
public abstract renderElement(node: ITreeNode<T, FuzzyScore>, index: number, data: IExpressionTemplateData): void;
|
||||
|
||||
protected renderExpressionElement(element: IExpression, node: ITreeNode<T, FuzzyScore>, data: IExpressionTemplateData): void {
|
||||
data.elementDisposable.clear();
|
||||
data.currentElement = element;
|
||||
this.renderExpression(node.element, data, createMatches(node.filterData));
|
||||
if (data.actionBar) {
|
||||
|
|
|
@ -440,6 +440,11 @@ configurationRegistry.registerConfiguration({
|
|||
title: nls.localize('debugConfigurationTitle', "Debug"),
|
||||
type: 'object',
|
||||
properties: {
|
||||
'debug.showVariableTypes': {
|
||||
type: 'boolean',
|
||||
description: nls.localize({ comment: ['This is the description for a setting'], key: 'showVariableTypes' }, "Show variable type in variable pane during debug session"),
|
||||
default: false
|
||||
},
|
||||
'debug.allowBreakpointsEverywhere': {
|
||||
type: 'boolean',
|
||||
description: nls.localize({ comment: ['This is the description for a setting'], key: 'allowBreakpointsEverywhere' }, "Allow setting breakpoints in any file."),
|
||||
|
|
|
@ -35,6 +35,7 @@ export const debugIconStartForeground = registerColor('debugIcon.startForeground
|
|||
export function registerColors() {
|
||||
|
||||
const debugTokenExpressionName = registerColor('debugTokenExpression.name', { dark: '#c586c0', light: '#9b46b0', hcDark: foreground, hcLight: foreground }, 'Foreground color for the token names shown in the debug views (ie. the Variables or Watch view).');
|
||||
const debugTokenExpressionType = registerColor('debugTokenExpression.type', { dark: '#4A90E2', light: '#4A90E2', hcDark: foreground, hcLight: foreground }, 'Foreground color for the token types shown in the debug views (ie. the Variables or Watch view).');
|
||||
const debugTokenExpressionValue = registerColor('debugTokenExpression.value', { dark: '#cccccc99', light: '#6c6c6ccc', hcDark: foreground, hcLight: foreground }, 'Foreground color for the token values shown in the debug views (ie. the Variables or Watch view).');
|
||||
const debugTokenExpressionString = registerColor('debugTokenExpression.string', { dark: '#ce9178', light: '#a31515', hcDark: '#f48771', hcLight: '#a31515' }, 'Foreground color for strings in the debug views (ie. the Variables or Watch view).');
|
||||
const debugTokenExpressionBoolean = registerColor('debugTokenExpression.boolean', { dark: '#4e94ce', light: '#0000ff', hcDark: '#75bdfe', hcLight: '#0000ff' }, 'Foreground color for booleans in the debug views (ie. the Variables or Watch view).');
|
||||
|
@ -210,6 +211,7 @@ export function registerColors() {
|
|||
}
|
||||
|
||||
const tokenNameColor = theme.getColor(debugTokenExpressionName)!;
|
||||
const tokenTypeColor = theme.getColor(debugTokenExpressionType)!;
|
||||
const tokenValueColor = theme.getColor(debugTokenExpressionValue)!;
|
||||
const tokenStringColor = theme.getColor(debugTokenExpressionString)!;
|
||||
const tokenBooleanColor = theme.getColor(debugTokenExpressionBoolean)!;
|
||||
|
@ -221,6 +223,10 @@ export function registerColors() {
|
|||
color: ${tokenNameColor};
|
||||
}
|
||||
|
||||
.monaco-workbench .monaco-list-row .expression .type {
|
||||
color: ${tokenTypeColor};
|
||||
}
|
||||
|
||||
.monaco-workbench .monaco-list-row .expression .value,
|
||||
.monaco-workbench .debug-hover-widget .value {
|
||||
color: ${tokenValueColor};
|
||||
|
|
|
@ -237,6 +237,7 @@ export class ReplVariablesRenderer extends AbstractExpressionsRenderer<IExpressi
|
|||
|
||||
public renderElement(node: ITreeNode<IExpression | ReplVariableElement, FuzzyScore>, _index: number, data: IExpressionTemplateData): void {
|
||||
const element = node.element;
|
||||
data.elementDisposable.clear();
|
||||
super.renderExpressionElement(element instanceof ReplVariableElement ? element.expression : element, node, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ import { IViewDescriptorService } from 'vs/workbench/common/views';
|
|||
import { AbstractExpressionDataSource, AbstractExpressionsRenderer, IExpressionTemplateData, IInputBoxOptions, renderExpressionValue, renderVariable, renderViewTree } from 'vs/workbench/contrib/debug/browser/baseDebugView';
|
||||
import { ADD_TO_WATCH_ID, ADD_TO_WATCH_LABEL, COPY_EVALUATE_PATH_ID, COPY_EVALUATE_PATH_LABEL, COPY_VALUE_ID, COPY_VALUE_LABEL } from 'vs/workbench/contrib/debug/browser/debugCommands';
|
||||
import { LinkDetector } from 'vs/workbench/contrib/debug/browser/linkDetector';
|
||||
import { CONTEXT_BREAK_WHEN_VALUE_CHANGES_SUPPORTED, CONTEXT_BREAK_WHEN_VALUE_IS_ACCESSED_SUPPORTED, CONTEXT_BREAK_WHEN_VALUE_IS_READ_SUPPORTED, CONTEXT_VARIABLES_FOCUSED, DataBreakpointSetType, DebugVisualizationType, IDataBreakpointInfoResponse, IDebugService, IExpression, IScope, IStackFrame, IViewModel, VARIABLES_VIEW_ID } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { CONTEXT_BREAK_WHEN_VALUE_CHANGES_SUPPORTED, CONTEXT_BREAK_WHEN_VALUE_IS_ACCESSED_SUPPORTED, CONTEXT_BREAK_WHEN_VALUE_IS_READ_SUPPORTED, CONTEXT_VARIABLES_FOCUSED, DataBreakpointSetType, DebugVisualizationType, IDataBreakpointInfoResponse, IDebugConfiguration, IDebugService, IExpression, IScope, IStackFrame, IViewModel, VARIABLES_VIEW_ID } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { getContextForVariable } from 'vs/workbench/contrib/debug/common/debugContext';
|
||||
import { ErrorScope, Expression, Scope, StackFrame, Variable, VisualizedExpression, getUriForDebugMemory } from 'vs/workbench/contrib/debug/common/debugModel';
|
||||
import { DebugVisualizer, IDebugVisualizerService } from 'vs/workbench/contrib/debug/common/debugVisualizers';
|
||||
|
@ -455,6 +455,7 @@ export class VisualizedVariableRenderer extends AbstractExpressionsRenderer {
|
|||
}
|
||||
|
||||
public override renderElement(node: ITreeNode<IExpression, FuzzyScore>, index: number, data: IExpressionTemplateData): void {
|
||||
data.elementDisposable.clear();
|
||||
super.renderExpressionElement(node.element, node, data);
|
||||
}
|
||||
|
||||
|
@ -531,6 +532,7 @@ export class VariablesRenderer extends AbstractExpressionsRenderer {
|
|||
@IDebugService debugService: IDebugService,
|
||||
@IContextViewService contextViewService: IContextViewService,
|
||||
@IHoverService hoverService: IHoverService,
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
) {
|
||||
super(debugService, contextViewService, hoverService);
|
||||
}
|
||||
|
@ -540,10 +542,17 @@ export class VariablesRenderer extends AbstractExpressionsRenderer {
|
|||
}
|
||||
|
||||
protected renderExpression(expression: IExpression, data: IExpressionTemplateData, highlights: IHighlight[]): void {
|
||||
renderVariable(data.elementDisposable, this.commandService, this.hoverService, expression as Variable, data, true, highlights, this.linkDetector);
|
||||
const showType = this.configurationService.getValue<IDebugConfiguration>('debug').showVariableTypes;
|
||||
renderVariable(data.elementDisposable, this.commandService, this.hoverService, expression as Variable, data, true, highlights, this.linkDetector, showType);
|
||||
}
|
||||
|
||||
public override renderElement(node: ITreeNode<IExpression, FuzzyScore>, index: number, data: IExpressionTemplateData): void {
|
||||
data.elementDisposable.clear();
|
||||
data.elementDisposable.add(this.configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration('debug.showVariableTypes')) {
|
||||
super.renderExpressionElement(node.element, node, data);
|
||||
}
|
||||
}));
|
||||
super.renderExpressionElement(node.element, node, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ import { AbstractExpressionDataSource, AbstractExpressionsRenderer, IExpressionT
|
|||
import { watchExpressionsAdd, watchExpressionsRemoveAll } from 'vs/workbench/contrib/debug/browser/debugIcons';
|
||||
import { LinkDetector } from 'vs/workbench/contrib/debug/browser/linkDetector';
|
||||
import { VariablesRenderer, VisualizedVariableRenderer } from 'vs/workbench/contrib/debug/browser/variablesView';
|
||||
import { CONTEXT_CAN_VIEW_MEMORY, CONTEXT_VARIABLE_IS_READONLY, CONTEXT_WATCH_EXPRESSIONS_EXIST, CONTEXT_WATCH_EXPRESSIONS_FOCUSED, CONTEXT_WATCH_ITEM_TYPE, IDebugService, IExpression, WATCH_VIEW_ID } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { CONTEXT_CAN_VIEW_MEMORY, CONTEXT_VARIABLE_IS_READONLY, CONTEXT_WATCH_EXPRESSIONS_EXIST, CONTEXT_WATCH_EXPRESSIONS_FOCUSED, CONTEXT_WATCH_ITEM_TYPE, IDebugConfiguration, IDebugService, IExpression, WATCH_VIEW_ID } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { Expression, Variable, VisualizedExpression } from 'vs/workbench/contrib/debug/common/debugModel';
|
||||
|
||||
const MAX_VALUE_RENDER_LENGTH_IN_VIEWLET = 1024;
|
||||
|
@ -274,7 +274,7 @@ class WatchExpressionsDataSource extends AbstractExpressionDataSource<IDebugServ
|
|||
}
|
||||
|
||||
|
||||
class WatchExpressionsRenderer extends AbstractExpressionsRenderer {
|
||||
export class WatchExpressionsRenderer extends AbstractExpressionsRenderer {
|
||||
|
||||
static readonly ID = 'watchexpression';
|
||||
|
||||
|
@ -284,6 +284,7 @@ class WatchExpressionsRenderer extends AbstractExpressionsRenderer {
|
|||
@IDebugService debugService: IDebugService,
|
||||
@IContextViewService contextViewService: IContextViewService,
|
||||
@IHoverService hoverService: IHoverService,
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
) {
|
||||
super(debugService, contextViewService, hoverService);
|
||||
}
|
||||
|
@ -293,16 +294,36 @@ class WatchExpressionsRenderer extends AbstractExpressionsRenderer {
|
|||
}
|
||||
|
||||
public override renderElement(node: ITreeNode<IExpression, FuzzyScore>, index: number, data: IExpressionTemplateData): void {
|
||||
data.elementDisposable.clear();
|
||||
data.elementDisposable.add(this.configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration('debug.showVariableTypes')) {
|
||||
super.renderExpressionElement(node.element, node, data);
|
||||
}
|
||||
}));
|
||||
super.renderExpressionElement(node.element, node, data);
|
||||
}
|
||||
|
||||
protected renderExpression(expression: IExpression, data: IExpressionTemplateData, highlights: IHighlight[]): void {
|
||||
const text = typeof expression.value === 'string' ? `${expression.name}:` : expression.name;
|
||||
let text: string;
|
||||
data.type.textContent = '';
|
||||
const showType = this.configurationService.getValue<IDebugConfiguration>('debug').showVariableTypes;
|
||||
if (showType && expression.type) {
|
||||
text = typeof expression.value === 'string' ? `${expression.name}: ` : expression.name;
|
||||
//render type
|
||||
data.type.textContent = expression.type + ' =';
|
||||
} else {
|
||||
text = typeof expression.value === 'string' ? `${expression.name} =` : expression.name;
|
||||
}
|
||||
|
||||
let title: string;
|
||||
if (expression.type) {
|
||||
title = expression.type === expression.value ?
|
||||
expression.type :
|
||||
`${expression.type}: ${expression.value}`;
|
||||
if (showType) {
|
||||
title = `${expression.name}`;
|
||||
} else {
|
||||
title = expression.type === expression.value ?
|
||||
expression.type :
|
||||
`${expression.type}`;
|
||||
}
|
||||
} else {
|
||||
title = expression.value;
|
||||
}
|
||||
|
|
|
@ -788,6 +788,7 @@ export interface IDebugConfiguration {
|
|||
};
|
||||
autoExpandLazyVariables: boolean;
|
||||
enableStatusBarColor: boolean;
|
||||
showVariableTypes: boolean;
|
||||
}
|
||||
|
||||
export interface IGlobalConfig {
|
||||
|
|
|
@ -10,6 +10,7 @@ import { DisposableStore } from 'vs/base/common/lifecycle';
|
|||
import { isWindows } from 'vs/base/common/platform';
|
||||
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
|
||||
import { NullCommandService } from 'vs/platform/commands/test/common/nullCommandService';
|
||||
import { IHoverService } from 'vs/platform/hover/browser/hover';
|
||||
import { NullHoverService } from 'vs/platform/hover/test/browser/nullHoverService';
|
||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||
import { renderExpressionValue, renderVariable, renderViewTree } from 'vs/workbench/contrib/debug/browser/baseDebugView';
|
||||
|
@ -23,6 +24,66 @@ import { MockSession } from 'vs/workbench/contrib/debug/test/common/mockDebug';
|
|||
import { workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
const $ = dom.$;
|
||||
|
||||
function assertVariable(session: MockSession, scope: Scope, disposables: Pick<DisposableStore, "add">, linkDetector: LinkDetector, displayType: boolean) {
|
||||
let variable = new Variable(session, 1, scope, 2, 'foo', 'bar.foo', undefined, 0, 0, undefined, {}, 'string');
|
||||
let expression = $('.');
|
||||
let name = $('.');
|
||||
let type = $('.');
|
||||
let value = $('.');
|
||||
const label = new HighlightedLabel(name);
|
||||
const lazyButton = $('.');
|
||||
const store = disposables.add(new DisposableStore());
|
||||
renderVariable(store, NullCommandService, NullHoverService, variable, { expression, name, type, value, label, lazyButton }, false, [], undefined, displayType);
|
||||
|
||||
assert.strictEqual(label.element.textContent, 'foo');
|
||||
assert.strictEqual(value.textContent, '');
|
||||
|
||||
variable.value = 'hey';
|
||||
expression = $('.');
|
||||
name = $('.');
|
||||
type = $('.');
|
||||
value = $('.');
|
||||
renderVariable(store, NullCommandService, NullHoverService, variable, { expression, name, type, value, label, lazyButton }, false, [], linkDetector, displayType);
|
||||
assert.strictEqual(value.textContent, 'hey');
|
||||
assert.strictEqual(label.element.textContent, displayType ? 'foo: ' : 'foo =');
|
||||
assert.strictEqual(type.textContent, displayType ? 'string =' : '');
|
||||
|
||||
variable.value = isWindows ? 'C:\\foo.js:5' : '/foo.js:5';
|
||||
expression = $('.');
|
||||
name = $('.');
|
||||
type = $('.');
|
||||
value = $('.');
|
||||
renderVariable(store, NullCommandService, NullHoverService, variable, { expression, name, type, value, label, lazyButton }, false, [], linkDetector, displayType);
|
||||
assert.ok(value.querySelector('a'));
|
||||
assert.strictEqual(value.querySelector('a')!.textContent, variable.value);
|
||||
|
||||
variable = new Variable(session, 1, scope, 2, 'console', 'console', '5', 0, 0, undefined, { kind: 'virtual' });
|
||||
expression = $('.');
|
||||
name = $('.');
|
||||
type = $('.');
|
||||
value = $('.');
|
||||
renderVariable(store, NullCommandService, NullHoverService, variable, { expression, name, type, value, label, lazyButton }, false, [], linkDetector, displayType);
|
||||
assert.strictEqual(name.className, 'virtual');
|
||||
assert.strictEqual(label.element.textContent, 'console =');
|
||||
assert.strictEqual(value.className, 'value number');
|
||||
|
||||
variable = new Variable(session, 1, scope, 2, 'xpto', 'xpto.xpto', undefined, 0, 0, undefined, {}, 'custom-type');
|
||||
renderVariable(store, NullCommandService, NullHoverService, variable, { expression, name, type, value, label, lazyButton }, false, [], linkDetector, displayType);
|
||||
assert.strictEqual(label.element.textContent, 'xpto');
|
||||
assert.strictEqual(value.textContent, '');
|
||||
variable.value = '2';
|
||||
expression = $('.');
|
||||
name = $('.');
|
||||
type = $('.');
|
||||
value = $('.');
|
||||
renderVariable(store, NullCommandService, NullHoverService, variable, { expression, name, type, value, label, lazyButton }, false, [], linkDetector, displayType);
|
||||
assert.strictEqual(value.textContent, '2');
|
||||
assert.strictEqual(label.element.textContent, displayType ? 'xpto: ' : 'xpto =');
|
||||
assert.strictEqual(type.textContent, displayType ? 'custom-type =' : '');
|
||||
|
||||
label.dispose();
|
||||
}
|
||||
|
||||
suite('Debug - Base Debug View', () => {
|
||||
const disposables = ensureNoDisposablesAreLeakedInTestSuite();
|
||||
let linkDetector: LinkDetector;
|
||||
|
@ -33,6 +94,7 @@ suite('Debug - Base Debug View', () => {
|
|||
setup(() => {
|
||||
const instantiationService: TestInstantiationService = workbenchInstantiationService(undefined, disposables);
|
||||
linkDetector = instantiationService.createInstance(LinkDetector);
|
||||
instantiationService.stub(IHoverService, NullHoverService);
|
||||
});
|
||||
|
||||
test('render view tree', () => {
|
||||
|
@ -85,47 +147,32 @@ suite('Debug - Base Debug View', () => {
|
|||
test('render variable', () => {
|
||||
const session = new MockSession();
|
||||
const thread = new Thread(session, 'mockthread', 1);
|
||||
const stackFrame = new StackFrame(thread, 1, null!, 'app.js', 'normal', { startLineNumber: 1, startColumn: 1, endLineNumber: undefined!, endColumn: undefined! }, 0, true);
|
||||
const range = {
|
||||
startLineNumber: 1,
|
||||
startColumn: 1,
|
||||
endLineNumber: undefined!,
|
||||
endColumn: undefined!
|
||||
};
|
||||
const stackFrame = new StackFrame(thread, 1, null!, 'app.js', 'normal', range, 0, true);
|
||||
const scope = new Scope(stackFrame, 1, 'local', 1, false, 10, 10);
|
||||
|
||||
let variable = new Variable(session, 1, scope, 2, 'foo', 'bar.foo', undefined, 0, 0, undefined, {}, 'string');
|
||||
let expression = $('.');
|
||||
let name = $('.');
|
||||
let value = $('.');
|
||||
const label = new HighlightedLabel(name);
|
||||
const lazyButton = $('.');
|
||||
const store = disposables.add(new DisposableStore());
|
||||
renderVariable(store, NullCommandService, NullHoverService, variable, { expression, name, value, label, lazyButton }, false, []);
|
||||
assertVariable(session, scope, disposables, linkDetector, false);
|
||||
|
||||
assert.strictEqual(label.element.textContent, 'foo');
|
||||
assert.strictEqual(value.textContent, '');
|
||||
});
|
||||
|
||||
variable.value = 'hey';
|
||||
expression = $('.');
|
||||
name = $('.');
|
||||
value = $('.');
|
||||
renderVariable(store, NullCommandService, NullHoverService, variable, { expression, name, value, label, lazyButton }, false, [], linkDetector);
|
||||
assert.strictEqual(value.textContent, 'hey');
|
||||
assert.strictEqual(label.element.textContent, 'foo:');
|
||||
test('render variable with display type setting', () => {
|
||||
const session = new MockSession();
|
||||
const thread = new Thread(session, 'mockthread', 1);
|
||||
const range = {
|
||||
startLineNumber: 1,
|
||||
startColumn: 1,
|
||||
endLineNumber: undefined!,
|
||||
endColumn: undefined!
|
||||
};
|
||||
const stackFrame = new StackFrame(thread, 1, null!, 'app.js', 'normal', range, 0, true);
|
||||
const scope = new Scope(stackFrame, 1, 'local', 1, false, 10, 10);
|
||||
|
||||
variable.value = isWindows ? 'C:\\foo.js:5' : '/foo.js:5';
|
||||
expression = $('.');
|
||||
name = $('.');
|
||||
value = $('.');
|
||||
renderVariable(store, NullCommandService, NullHoverService, variable, { expression, name, value, label, lazyButton }, false, [], linkDetector);
|
||||
assert.ok(value.querySelector('a'));
|
||||
assert.strictEqual(value.querySelector('a')!.textContent, variable.value);
|
||||
|
||||
variable = new Variable(session, 1, scope, 2, 'console', 'console', '5', 0, 0, undefined, { kind: 'virtual' });
|
||||
expression = $('.');
|
||||
name = $('.');
|
||||
value = $('.');
|
||||
renderVariable(store, NullCommandService, NullHoverService, variable, { expression, name, value, label, lazyButton }, false, [], linkDetector);
|
||||
assert.strictEqual(name.className, 'virtual');
|
||||
assert.strictEqual(label.element.textContent, 'console:');
|
||||
assert.strictEqual(value.className, 'value number');
|
||||
|
||||
label.dispose();
|
||||
assertVariable(session, scope, disposables, linkDetector, true);
|
||||
});
|
||||
|
||||
test('statusbar in debug mode', () => {
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
|
||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||
import { Scope, StackFrame, Thread, Variable } from 'vs/workbench/contrib/debug/common/debugModel';
|
||||
import { MockDebugService, MockSession } from 'vs/workbench/contrib/debug/test/common/mockDebug';
|
||||
import { workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { IHoverService } from 'vs/platform/hover/browser/hover';
|
||||
import { NullHoverService } from 'vs/platform/hover/test/browser/nullHoverService';
|
||||
import { IDebugService, IViewModel } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { VariablesRenderer } from 'vs/workbench/contrib/debug/browser/variablesView';
|
||||
import { LinkDetector } from 'vs/workbench/contrib/debug/browser/linkDetector';
|
||||
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
|
||||
const $ = dom.$;
|
||||
|
||||
function assertVariable(disposables: Pick<DisposableStore, "add">, variablesRenderer: VariablesRenderer, displayType: boolean) {
|
||||
const session = new MockSession();
|
||||
const thread = new Thread(session, 'mockthread', 1);
|
||||
const range = {
|
||||
startLineNumber: 1,
|
||||
startColumn: 1,
|
||||
endLineNumber: undefined!,
|
||||
endColumn: undefined!
|
||||
};
|
||||
const stackFrame = new StackFrame(thread, 1, null!, 'app.js', 'normal', range, 0, true);
|
||||
const scope = new Scope(stackFrame, 1, 'local', 1, false, 10, 10);
|
||||
const node = {
|
||||
element: new Variable(session, 1, scope, 2, 'foo', 'bar.foo', undefined, 0, 0, undefined, {}, 'string'),
|
||||
depth: 0,
|
||||
visibleChildrenCount: 1,
|
||||
visibleChildIndex: -1,
|
||||
collapsible: false,
|
||||
collapsed: false,
|
||||
visible: true,
|
||||
filterData: undefined,
|
||||
children: []
|
||||
};
|
||||
const expression = $('.');
|
||||
const name = $('.');
|
||||
const type = $('.');
|
||||
const value = $('.');
|
||||
const label = disposables.add(new HighlightedLabel(name));
|
||||
const lazyButton = $('.');
|
||||
const inputBoxContainer = $('.');
|
||||
const elementDisposable = disposables.add(new DisposableStore());
|
||||
const templateDisposable = disposables.add(new DisposableStore());
|
||||
const currentElement = undefined;
|
||||
const data = {
|
||||
expression,
|
||||
name,
|
||||
type,
|
||||
value,
|
||||
label,
|
||||
lazyButton,
|
||||
inputBoxContainer,
|
||||
elementDisposable,
|
||||
templateDisposable,
|
||||
currentElement
|
||||
};
|
||||
variablesRenderer.renderElement(node, 0, data);
|
||||
assert.strictEqual(value.textContent, '');
|
||||
assert.strictEqual(label.element.textContent, 'foo');
|
||||
|
||||
node.element.value = 'xpto';
|
||||
variablesRenderer.renderElement(node, 0, data);
|
||||
assert.strictEqual(value.textContent, 'xpto');
|
||||
assert.strictEqual(type.textContent, displayType ? 'string =' : '');
|
||||
assert.strictEqual(label.element.textContent, displayType ? 'foo: ' : 'foo =');
|
||||
}
|
||||
|
||||
suite('Debug - Variable Debug View', () => {
|
||||
const disposables = ensureNoDisposablesAreLeakedInTestSuite();
|
||||
let variablesRenderer: VariablesRenderer;
|
||||
let instantiationService: TestInstantiationService;
|
||||
let linkDetector: LinkDetector;
|
||||
let configurationService: TestConfigurationService;
|
||||
|
||||
setup(() => {
|
||||
instantiationService = workbenchInstantiationService(undefined, disposables);
|
||||
linkDetector = instantiationService.createInstance(LinkDetector);
|
||||
const debugService = new MockDebugService();
|
||||
instantiationService.stub(IHoverService, NullHoverService);
|
||||
debugService.getViewModel = () => <IViewModel>{ focusedStackFrame: undefined, getSelectedExpression: () => undefined };
|
||||
debugService.getViewModel().getSelectedExpression = () => undefined;
|
||||
instantiationService.stub(IDebugService, debugService);
|
||||
});
|
||||
|
||||
test('variable expressions with display type', () => {
|
||||
configurationService = new TestConfigurationService({
|
||||
debug: {
|
||||
showVariableTypes: true
|
||||
}
|
||||
});
|
||||
instantiationService.stub(IConfigurationService, configurationService);
|
||||
variablesRenderer = instantiationService.createInstance(VariablesRenderer, linkDetector);
|
||||
assertVariable(disposables, variablesRenderer, true);
|
||||
});
|
||||
|
||||
test('variable expressions', () => {
|
||||
configurationService = new TestConfigurationService({
|
||||
debug: {
|
||||
showVariableTypes: false
|
||||
}
|
||||
});
|
||||
instantiationService.stub(IConfigurationService, configurationService);
|
||||
variablesRenderer = instantiationService.createInstance(VariablesRenderer, linkDetector);
|
||||
assertVariable(disposables, variablesRenderer, false);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,114 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
|
||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||
import { WatchExpressionsRenderer } from 'vs/workbench/contrib/debug/browser/watchExpressionsView';
|
||||
import { Scope, StackFrame, Thread, Variable } from 'vs/workbench/contrib/debug/common/debugModel';
|
||||
import { MockDebugService, MockSession } from 'vs/workbench/contrib/debug/test/common/mockDebug';
|
||||
import { workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { IHoverService } from 'vs/platform/hover/browser/hover';
|
||||
import { NullHoverService } from 'vs/platform/hover/test/browser/nullHoverService';
|
||||
import { IDebugService, IViewModel } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
|
||||
const $ = dom.$;
|
||||
|
||||
function assertWatchVariable(disposables: Pick<DisposableStore, "add">, watchExpressionsRenderer: WatchExpressionsRenderer, displayType: boolean) {
|
||||
const session = new MockSession();
|
||||
const thread = new Thread(session, 'mockthread', 1);
|
||||
const range = {
|
||||
startLineNumber: 1,
|
||||
startColumn: 1,
|
||||
endLineNumber: undefined!,
|
||||
endColumn: undefined!
|
||||
};
|
||||
const stackFrame = new StackFrame(thread, 1, null!, 'app.js', 'normal', range, 0, true);
|
||||
const scope = new Scope(stackFrame, 1, 'local', 1, false, 10, 10);
|
||||
const node = {
|
||||
element: new Variable(session, 1, scope, 2, 'foo', 'bar.foo', undefined, 0, 0, undefined, {}, 'string'),
|
||||
depth: 0,
|
||||
visibleChildrenCount: 1,
|
||||
visibleChildIndex: -1,
|
||||
collapsible: false,
|
||||
collapsed: false,
|
||||
visible: true,
|
||||
filterData: undefined,
|
||||
children: []
|
||||
};
|
||||
const expression = $('.');
|
||||
const name = $('.');
|
||||
const type = $('.');
|
||||
const value = $('.');
|
||||
const label = disposables.add(new HighlightedLabel(name));
|
||||
const lazyButton = $('.');
|
||||
const inputBoxContainer = $('.');
|
||||
const elementDisposable = disposables.add(new DisposableStore());
|
||||
const templateDisposable = disposables.add(new DisposableStore());
|
||||
const currentElement = undefined;
|
||||
const data = {
|
||||
expression,
|
||||
name,
|
||||
type,
|
||||
value,
|
||||
label,
|
||||
lazyButton,
|
||||
inputBoxContainer,
|
||||
elementDisposable,
|
||||
templateDisposable,
|
||||
currentElement
|
||||
};
|
||||
watchExpressionsRenderer.renderElement(node, 0, data);
|
||||
assert.strictEqual(value.textContent, '');
|
||||
assert.strictEqual(label.element.textContent, displayType ? 'foo: ' : 'foo =');
|
||||
|
||||
node.element.value = 'xpto';
|
||||
watchExpressionsRenderer.renderElement(node, 0, data);
|
||||
assert.strictEqual(value.textContent, 'xpto');
|
||||
assert.strictEqual(type.textContent, displayType ? 'string =' : '');
|
||||
assert.strictEqual(label.element.textContent, displayType ? 'foo: ' : 'foo =');
|
||||
}
|
||||
|
||||
suite('Debug - Watch Debug View', () => {
|
||||
const disposables = ensureNoDisposablesAreLeakedInTestSuite();
|
||||
let watchExpressionsRenderer: WatchExpressionsRenderer;
|
||||
let instantiationService: TestInstantiationService;
|
||||
let configurationService: TestConfigurationService;
|
||||
|
||||
setup(() => {
|
||||
instantiationService = workbenchInstantiationService(undefined, disposables);
|
||||
const debugService = new MockDebugService();
|
||||
instantiationService.stub(IHoverService, NullHoverService);
|
||||
debugService.getViewModel = () => <IViewModel>{ focusedStackFrame: undefined, getSelectedExpression: () => undefined };
|
||||
debugService.getViewModel().getSelectedExpression = () => undefined;
|
||||
instantiationService.stub(IDebugService, debugService);
|
||||
});
|
||||
|
||||
test('watch expressions with display type', () => {
|
||||
configurationService = new TestConfigurationService({
|
||||
debug: {
|
||||
showVariableTypes: true
|
||||
}
|
||||
});
|
||||
instantiationService.stub(IConfigurationService, configurationService);
|
||||
watchExpressionsRenderer = instantiationService.createInstance(WatchExpressionsRenderer);
|
||||
assertWatchVariable(disposables, watchExpressionsRenderer, true);
|
||||
});
|
||||
|
||||
test('watch expressions', () => {
|
||||
configurationService = new TestConfigurationService({
|
||||
debug: {
|
||||
showVariableTypes: false
|
||||
}
|
||||
});
|
||||
instantiationService.stub(IConfigurationService, configurationService);
|
||||
watchExpressionsRenderer = instantiationService.createInstance(WatchExpressionsRenderer);
|
||||
assertWatchVariable(disposables, watchExpressionsRenderer, false);
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue