Skip to content

Commit 2729b87

Browse files
committed
IDE-322 Support for changing view-format
1 parent 7b2a99f commit 2729b87

10 files changed

+497
-22
lines changed

package.json

+139-3
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@
3939
"Debuggers"
4040
],
4141
"extensionDependencies": [
42-
"ms-vscode.vscode-embedded-tools",
43-
"eclipse-cdt.memory-inspector"
42+
"ms-vscode.vscode-embedded-tools"
4443
],
4544
"private": true,
4645
"dependencies": {
@@ -141,6 +140,16 @@
141140
}
142141
}
143142
},
143+
"submenus": [
144+
{
145+
"id": "iar.variableFormat",
146+
"label": "Format"
147+
},
148+
{
149+
"id": "iar.showAs",
150+
"label": "Show as"
151+
}
152+
],
144153
"menus": {
145154
"debug/toolBar": [
146155
{
@@ -151,6 +160,72 @@
151160
"command": "iar.disableMulticoreLockstepMode",
152161
"when": "debugType == cspy && iar-debug.sessionIsMulticore"
153162
}
163+
],
164+
"debug/variables/context": [
165+
{
166+
"submenu": "iar.variableFormat",
167+
"when": "debugType == cspy"
168+
}
169+
],
170+
"iar.variableFormat":[
171+
{
172+
"command": "iar.showVariableAsDefault",
173+
"when": "debugType == cspy"
174+
},
175+
{
176+
"command": "iar.showVariableAsHex",
177+
"when": "debugType == cspy"
178+
},
179+
{
180+
"command": "iar.showVariableAsBinary",
181+
"when": "debugType == cspy"
182+
},
183+
{
184+
"command": "iar.showVariableAsOctal",
185+
"when": "debugType == cspy"
186+
},
187+
{
188+
"command": "iar.showVariableAsDecimal",
189+
"when": "debugType == cspy"
190+
},
191+
{
192+
"command": "iar.showVariableAsChar",
193+
"when": "debugType == cspy"
194+
},
195+
{
196+
"command": "iar.showVariableAsFloat16",
197+
"when": "!canViewMemory &&debugType == cspy"
198+
},
199+
{
200+
"command": "iar.showVariableAsFloat",
201+
"when": "!canViewMemory && debugType == cspy"
202+
},
203+
{
204+
"command": "iar.showVariableAsDouble",
205+
"when": "!canViewMemory && debugType == cspy"
206+
},
207+
{
208+
"submenu": "iar.showAs",
209+
"when": "canViewMemory && debugType == cspy"
210+
}
211+
],
212+
"iar.showAs":[
213+
{
214+
"command": "iar.showVariableAsIs",
215+
"when": "debugType == cspy"
216+
},
217+
{
218+
"command": "iar.showVariableAsFloat16",
219+
"when": "debugType == cspy"
220+
},
221+
{
222+
"command": "iar.showVariableAsFloat",
223+
"when": "debugType == cspy"
224+
},
225+
{
226+
"command": "iar.showVariableAsDouble",
227+
"when": "debugType == cspy"
228+
}
154229
]
155230
},
156231
"commands": [
@@ -212,6 +287,66 @@
212287
"category": "IAR Debug",
213288
"title": "Restart the session without running prelaunch tasks",
214289
"enablement": "debugType == cspy"
290+
},
291+
{
292+
"command": "iar.showVariableAsDefault",
293+
"category": "IAR Debug",
294+
"title": "Default",
295+
"enablement": "debugType == cspy && focusedView == 'workbench.debug.variablesView'"
296+
},
297+
{
298+
"command": "iar.showVariableAsBinary",
299+
"category": "IAR Debug",
300+
"title": "Binary",
301+
"enablement": "debugType == cspy && focusedView == 'workbench.debug.variablesView'"
302+
},
303+
{
304+
"command": "iar.showVariableAsHex",
305+
"category": "IAR Debug",
306+
"title": "Hexadecimal",
307+
"enablement": "debugType == cspy && focusedView == 'workbench.debug.variablesView'"
308+
},
309+
{
310+
"command": "iar.showVariableAsOctal",
311+
"category": "IAR Debug",
312+
"title": "Octal",
313+
"enablement": "debugType == cspy && focusedView == 'workbench.debug.variablesView'"
314+
},
315+
{
316+
"command": "iar.showVariableAsDecimal",
317+
"category": "IAR Debug",
318+
"title": "Decimal",
319+
"enablement": "debugType == cspy && focusedView == 'workbench.debug.variablesView'"
320+
},
321+
{
322+
"command": "iar.showVariableAsChar",
323+
"category": "IAR Debug",
324+
"title": "Char",
325+
"enablement": "debugType == cspy && focusedView == 'workbench.debug.variablesView'"
326+
},
327+
{
328+
"command": "iar.showVariableAsFloat",
329+
"category": "IAR Debug",
330+
"title": "Float",
331+
"enablement": "debugType == cspy && focusedView == 'workbench.debug.variablesView'"
332+
},
333+
{
334+
"command": "iar.showVariableAsDouble",
335+
"category": "IAR Debug",
336+
"title": "Double",
337+
"enablement": "debugType == cspy && focusedView == 'workbench.debug.variablesView'"
338+
},
339+
{
340+
"command": "iar.showVariableAsFloat16",
341+
"category": "IAR Debug",
342+
"title": "Float16",
343+
"enablement": "debugType == cspy && focusedView == 'workbench.debug.variablesView'"
344+
},
345+
{
346+
"command": "iar.showVariableAsIs",
347+
"category": "IAR Debug",
348+
"title": "As Is",
349+
"enablement": "debugType == cspy && focusedView == 'workbench.debug.variablesView'"
215350
}
216351
],
217352
"viewsContainers": {
@@ -345,7 +480,8 @@
345480
"cpp"
346481
],
347482
"configurationAttributes": {
348-
"attach": {"required": [
483+
"attach": {
484+
"required": [
349485
"workbenchPath"
350486
],
351487
"properties": {

src/customCommandsFrontend.ts

+88-1
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,74 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
44
import * as vscode from "vscode";
5+
import {CustomRequest} from "./dap/customRequest";
56
import { DebugSessionTracker } from "./debugSessionTracker";
7+
import { VariablesUtils } from "./dap/contexts/variablesUtils";
8+
69

710
/**
811
* Manages any global custom commands the extension registers.
912
*/
1013
export namespace CustomCommandsFrontend {
14+
interface Variable {
15+
name: string;
16+
variablesReference: number;
17+
}
18+
19+
interface VariableContext {
20+
container?: Variable;
21+
variable: Variable;
22+
}
23+
24+
function isVariable(obj: unknown): obj is Variable {
25+
if (typeof obj === "object") {
26+
const variable = obj as Variable;
27+
return variable.name !== undefined && variable.variablesReference !== undefined;
28+
}
29+
return false;
30+
}
31+
32+
function isVariableContext(context: unknown): VariableContext | undefined {
33+
if (
34+
typeof context !== "object" ||
35+
!context ||
36+
!("container" in context) ||
37+
!("variable" in context)
38+
) {
39+
return undefined;
40+
}
41+
42+
let container = undefined;
43+
if (isVariable(context.container)) {
44+
container = context.container;
45+
}
46+
if (isVariable(context.variable)) {
47+
return { variable: context.variable, container: container };
48+
}
49+
return undefined;
50+
}
51+
52+
function registerFormatViewCommand(commandId: string, format: VariablesUtils.ViewFormats) {
53+
return vscode.commands.registerCommand(commandId, args => {
54+
const context = isVariableContext(args);
55+
if (!context || !context.container) {
56+
return;
57+
}
58+
59+
const data: CustomRequest.ChangeVariableViewFormatArgs = {
60+
parentReference: context.container.variablesReference,
61+
format: format,
62+
variableReference: context.variable.variablesReference,
63+
variable: context.variable.name,
64+
};
65+
vscode.debug.activeDebugSession?.customRequest(
66+
CustomRequest.Names.CHANGE_VIEW_FORMAT_REQUEST,
67+
data,
68+
);
69+
});
70+
}
71+
72+
1173
export function initialize(
1274
context: vscode.ExtensionContext,
1375
_sessionTracker: DebugSessionTracker
@@ -17,7 +79,32 @@ export namespace CustomCommandsFrontend {
1779
if (vscode.debug.activeDebugSession?.type === "cspy") {
1880
vscode.debug.activeDebugSession.customRequest("restart");
1981
}
20-
})
82+
}),
83+
);
84+
85+
context.subscriptions.push(
86+
registerFormatViewCommand(
87+
"iar.showVariableAsDefault",
88+
VariablesUtils.ViewFormats.kDefault,
89+
),
90+
registerFormatViewCommand(
91+
"iar.showVariableAsHex",
92+
VariablesUtils.ViewFormats.kHexaDecimal,
93+
),
94+
registerFormatViewCommand("iar.showVariableAsBinary", VariablesUtils.ViewFormats.kBinary),
95+
registerFormatViewCommand("iar.showVariableAsOctal", VariablesUtils.ViewFormats.kOctal),
96+
registerFormatViewCommand(
97+
"iar.showVariableAsDecimal",
98+
VariablesUtils.ViewFormats.kDecimal,
99+
),
100+
registerFormatViewCommand("iar.showVariableAsChar", VariablesUtils.ViewFormats.kChar),
101+
registerFormatViewCommand(
102+
"iar.showVariableAsFloat16",
103+
VariablesUtils.ViewFormats.kFloat16,
104+
),
105+
registerFormatViewCommand("iar.showVariableAsFloat", VariablesUtils.ViewFormats.kFloat),
106+
registerFormatViewCommand("iar.showVariableAsDouble", VariablesUtils.ViewFormats.kDouble),
107+
registerFormatViewCommand("iar.showVariableAsIs", VariablesUtils.ViewFormats.kAsIs),
21108
);
22109
}
23110
}

src/dap/contexts/cspyContextService.ts

+15
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { RegistersVariablesProvider } from "./registersVariablesProvider";
2020
import { RegisterInformationService } from "../registerInformationService";
2121
import { CSpyCoresService } from "./cspyCoresService";
2222
import { DebugEventListenerHandler } from "../debugEventListenerHandler";
23+
import { CustomRequest } from "../customRequest";
2324

2425
/**
2526
* Describes a scope, i.e. a C-SPY context used to access the scope,
@@ -302,6 +303,20 @@ export class CSpyContextService implements Disposable.Disposable {
302303
});
303304
}
304305

306+
public async setViewFormat(viewformatRequest: CustomRequest.ChangeVariableViewFormatArgs): Promise<boolean | undefined> {
307+
if (viewformatRequest.parentReference) {
308+
const ref = this.scopeAndVariableHandles.get(viewformatRequest.parentReference);
309+
if (ref instanceof ScopeReference) {
310+
return await ref.provider?.setViewFormat(viewformatRequest.variable, undefined, viewformatRequest.format);
311+
} else if (ref instanceof VariableReference) {
312+
return await ref.provider?.setViewFormat(viewformatRequest.variable, ref.variableReference, viewformatRequest.format);
313+
} else {
314+
throw new Error("No such variable");
315+
}
316+
}
317+
return false;
318+
}
319+
305320
/**
306321
* Register a callback to run when C-SPY's inspection context changes
307322
* spontaneously, i.e. not as a result of a DAP request (fetching variables,

src/dap/contexts/registersVariablesProvider.ts

+17
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { Mutex } from "async-mutex";
1111
import { WindowNames } from "../listWindowConstants";
1212
import { RegisterInformationService } from "../registerInformationService";
1313
import { logger } from "@vscode/debugadapter/lib/logger";
14+
import { VariablesUtils } from "./variablesUtils";
1415

1516
interface RegisterReference {
1617
group: GroupReference,
@@ -57,6 +58,11 @@ export class RegistersVariablesProvider implements VariablesProvider, Disposable
5758
});
5859
}
5960

61+
ownsVariable(variableReference: number): boolean {
62+
const ref = this.variableReferences.get(variableReference);
63+
return ref !== undefined;
64+
}
65+
6066
getSubvariables(variableReference: number): Promise<Variable[]> {
6167
const ref = this.variableReferences.get(variableReference);
6268
if (!ref) {
@@ -111,6 +117,17 @@ export class RegistersVariablesProvider implements VariablesProvider, Disposable
111117
await this.windowClient.clickContextMenu(group.command);
112118
}
113119

120+
public async setViewFormat(variableName: string, variableReference: number | undefined, format: VariablesUtils.ViewFormats): Promise<boolean> {
121+
if (variableReference === undefined) {
122+
return Promise.reject(new Error("No reference specified"));
123+
}
124+
const ref = this.variableReferences.get(variableReference);
125+
if (!ref) {
126+
return Promise.reject(new Error("No windows reference found"));
127+
}
128+
return await this.varProvider.setViewFormat(variableName, ref.windowReference, format);
129+
}
130+
114131
private async fetchGroups() {
115132
const contextItems = await this.windowClient.getContextMenu(new Int64(0), 0);
116133
const start = contextItems.findIndex(item => item.text === ">View Group");

0 commit comments

Comments
 (0)