fix: show binary data inspector on top-level watch expressions (#170320)

Fixes #164124
This commit is contained in:
Connor Peet 2022-12-30 17:07:27 -08:00 committed by GitHub
parent 6d7e511b5c
commit 4c0cecf300
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 31 additions and 12 deletions

View file

@ -180,8 +180,8 @@ registerDebugViewMenuItem(MenuId.DebugWatchContext, ADD_WATCH_ID, ADD_WATCH_LABE
registerDebugViewMenuItem(MenuId.DebugWatchContext, EDIT_EXPRESSION_COMMAND_ID, nls.localize('editWatchExpression', "Edit Expression"), 20, CONTEXT_WATCH_ITEM_TYPE.isEqualTo('expression'), undefined, '3_modification');
registerDebugViewMenuItem(MenuId.DebugWatchContext, SET_EXPRESSION_COMMAND_ID, nls.localize('setValue', "Set Value"), 30, ContextKeyExpr.or(ContextKeyExpr.and(CONTEXT_WATCH_ITEM_TYPE.isEqualTo('expression'), CONTEXT_SET_EXPRESSION_SUPPORTED), ContextKeyExpr.and(CONTEXT_WATCH_ITEM_TYPE.isEqualTo('variable'), CONTEXT_SET_VARIABLE_SUPPORTED)), CONTEXT_VARIABLE_IS_READONLY.toNegated(), '3_modification');
registerDebugViewMenuItem(MenuId.DebugWatchContext, COPY_VALUE_ID, nls.localize('copyValue', "Copy Value"), 40, ContextKeyExpr.or(CONTEXT_WATCH_ITEM_TYPE.isEqualTo('expression'), CONTEXT_WATCH_ITEM_TYPE.isEqualTo('variable')), CONTEXT_IN_DEBUG_MODE, '3_modification');
registerDebugViewMenuItem(MenuId.DebugWatchContext, VIEW_MEMORY_ID, nls.localize('viewMemory', "View Binary Data"), 50, CONTEXT_CAN_VIEW_MEMORY, CONTEXT_IN_DEBUG_MODE, '3_modification');
registerDebugViewMenuItem(MenuId.DebugWatchContext, REMOVE_EXPRESSION_COMMAND_ID, nls.localize('removeWatchExpression', "Remove Expression"), 10, CONTEXT_WATCH_ITEM_TYPE.isEqualTo('expression'), undefined, 'inline', icons.watchExpressionRemove);
registerDebugViewMenuItem(MenuId.DebugWatchContext, VIEW_MEMORY_ID, nls.localize('viewMemory', "View Binary Data"), 10, CONTEXT_CAN_VIEW_MEMORY, undefined, 'inline', icons.debugInspectMemory);
registerDebugViewMenuItem(MenuId.DebugWatchContext, REMOVE_EXPRESSION_COMMAND_ID, nls.localize('removeWatchExpression', "Remove Expression"), 20, CONTEXT_WATCH_ITEM_TYPE.isEqualTo('expression'), undefined, 'inline', icons.watchExpressionRemove);
registerDebugViewMenuItem(MenuId.DebugWatchContext, REMOVE_WATCH_EXPRESSIONS_COMMAND_ID, REMOVE_WATCH_EXPRESSIONS_LABEL, 20, undefined, undefined, 'z_commands');
// Touch Bar

View file

@ -322,7 +322,7 @@ export class DebugSession implements IDebugSession {
supportsInvalidatedEvent: true, // #106745
supportsMemoryReferences: true, //#129684
supportsArgsCanBeInterpretedByShell: true, // #149910
supportsMemoryEvent: true
supportsMemoryEvent: true, // #133643
});
this.initialized = true;

View file

@ -525,9 +525,27 @@ const HEX_EDITOR_EDITOR_ID = 'hexEditor.hexedit';
CommandsRegistry.registerCommand({
id: VIEW_MEMORY_ID,
handler: async (accessor: ServicesAccessor, arg: IVariablesContext, ctx?: (Variable | Expression)[]) => {
if (!arg.sessionId || !arg.variable.memoryReference) {
return;
handler: async (accessor: ServicesAccessor, arg: IVariablesContext | IExpression, ctx?: (Variable | Expression)[]) => {
const debugService = accessor.get(IDebugService);
let sessionId: string;
let memoryReference: string;
if ('sessionId' in arg) { // IVariablesContext
if (!arg.sessionId || !arg.variable.memoryReference) {
return;
}
sessionId = arg.sessionId;
memoryReference = arg.variable.memoryReference;
} else { // IExpression
if (!arg.memoryReference) {
return;
}
const focused = debugService.getViewModel().focusedSession;
if (!focused) {
return;
}
sessionId = focused.getId();
memoryReference = arg.memoryReference;
}
const commandService = accessor.get(ICommandService);
@ -536,7 +554,6 @@ CommandsRegistry.registerCommand({
const progressService = accessor.get(IProgressService);
const extensionService = accessor.get(IExtensionService);
const telemetryService = accessor.get(ITelemetryService);
const debugService = accessor.get(IDebugService);
const ext = await extensionService.getExtension(HEX_EDITOR_EXTENSION_ID);
if (ext || await tryInstallHexEditor(notifications, progressService, extensionService, commandService)) {
@ -547,11 +564,11 @@ CommandsRegistry.registerCommand({
}
*/
telemetryService.publicLog('debug/didViewMemory', {
debugType: debugService.getModel().getSession(arg.sessionId)?.configuration.type,
debugType: debugService.getModel().getSession(sessionId)?.configuration.type,
});
await editorService.openEditor({
resource: getUriForDebugMemory(arg.sessionId, arg.variable.memoryReference),
resource: getUriForDebugMemory(sessionId, memoryReference),
options: {
revealIfOpened: true,
override: HEX_EDITOR_EDITOR_ID,

View file

@ -5,7 +5,7 @@
import { RunOnceScheduler } from 'vs/base/common/async';
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
import { IDebugService, IExpression, CONTEXT_WATCH_EXPRESSIONS_FOCUSED, WATCH_VIEW_ID, CONTEXT_WATCH_EXPRESSIONS_EXIST, CONTEXT_WATCH_ITEM_TYPE, CONTEXT_VARIABLE_IS_READONLY } from 'vs/workbench/contrib/debug/common/debug';
import { IDebugService, IExpression, CONTEXT_WATCH_EXPRESSIONS_FOCUSED, WATCH_VIEW_ID, CONTEXT_WATCH_EXPRESSIONS_EXIST, CONTEXT_WATCH_ITEM_TYPE, CONTEXT_VARIABLE_IS_READONLY, CONTEXT_CAN_VIEW_MEMORY } from 'vs/workbench/contrib/debug/common/debug';
import { Expression, Variable } from 'vs/workbench/contrib/debug/common/debugModel';
import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
@ -335,7 +335,7 @@ class WatchExpressionsRenderer extends AbstractExpressionsRenderer {
}
protected override renderActionBar(actionBar: ActionBar, expression: IExpression) {
const contextKeyService = getContextForWatchExpressionMenu(this.contextKeyService);
const contextKeyService = getContextForWatchExpressionMenu(this.contextKeyService, expression);
const menu = this.menuService.createMenu(MenuId.DebugWatchContext, contextKeyService);
const primary: IAction[] = [];
@ -351,8 +351,9 @@ class WatchExpressionsRenderer extends AbstractExpressionsRenderer {
/**
* Gets a context key overlay that has context for the given expression.
*/
function getContextForWatchExpressionMenu(parentContext: IContextKeyService) {
function getContextForWatchExpressionMenu(parentContext: IContextKeyService, expression: IExpression) {
return parentContext.createOverlay([
[CONTEXT_CAN_VIEW_MEMORY.key, expression.memoryReference !== undefined],
[CONTEXT_WATCH_ITEM_TYPE.key, 'expression']
]);
}

View file

@ -143,6 +143,7 @@ export interface IExpressionContainer extends ITreeElement {
evaluateLazy(): Promise<void>;
getChildren(): Promise<IExpression[]>;
readonly reference?: number;
readonly memoryReference?: string;
readonly value: string;
readonly type?: string;
valueChanged?: boolean;