Skip to content

Commit cc5d0a4

Browse files
committed
add support for complex data types
1 parent 90481f7 commit cc5d0a4

File tree

3 files changed

+61
-19
lines changed

3 files changed

+61
-19
lines changed

src/debug-session/gdbtarget-debug-session.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export class GDBTargetDebugSession {
5454
this._cbuildRunParsePromise = undefined;
5555
}
5656

57-
public async evaluateGlobalExpression(expression: string, context = 'hover'): Promise<string> {
57+
public async evaluateGlobalExpression(expression: string, context = 'hover'): Promise<DebugProtocol.EvaluateResponse['body'] | string> {
5858
try {
5959
const frameId = (vscode.debug.activeStackItem as vscode.DebugStackFrame)?.frameId ?? 0;
6060
const args: DebugProtocol.EvaluateArguments = {
@@ -63,7 +63,7 @@ export class GDBTargetDebugSession {
6363
context: context
6464
};
6565
const response = await this.session.customRequest('evaluate', args) as DebugProtocol.EvaluateResponse['body'];
66-
return response.result;
66+
return response;
6767
} catch (error: unknown) {
6868
const errorMessage = (error as Error)?.message;
6969
logger.debug(`Session '${this.session.name}': Failed to evaluate global expression '${expression}' - '${errorMessage}'`);

src/features/cpu-states/cpu-states.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,10 @@ export class CpuStates {
215215

216216
protected async getFrequency(): Promise<number|undefined> {
217217
const result = await this.activeSession?.evaluateGlobalExpression('SystemCoreClock');
218-
const frequencyString = result?.match(/\d+/) ? result : undefined;
218+
if (typeof result == 'string') {
219+
return undefined;
220+
}
221+
const frequencyString = result?.result.match(/\d+/) ? result.result : undefined;
219222
if (!frequencyString) {
220223
return undefined;
221224
}

src/views/live-watch/live-watch.ts

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,14 @@ import { GDBTargetDebugSession, GDBTargetDebugTracker } from '../../debug-sessio
2020
interface LiveWatchNode {
2121
id: number;
2222
expression: string;
23-
value: string;
2423
parent: LiveWatchNode | undefined; // if undefined, it's a root node
25-
children?: LiveWatchNode[]; // keep for future grouping; flat list for now
24+
children: LiveWatchNode[]; // keep for future grouping; flat list for now
25+
value: EvaluateNodeResponse
26+
}
27+
28+
interface EvaluateNodeResponse {
29+
result: string;
30+
variablesReference: number;
2631
}
2732

2833
export class LiveWatchTreeDataProvider implements vscode.TreeDataProvider<LiveWatchNode> {
@@ -45,18 +50,40 @@ export class LiveWatchTreeDataProvider implements vscode.TreeDataProvider<LiveWa
4550
}
4651
}
4752

48-
public getChildren(element?: LiveWatchNode): Promise<LiveWatchNode[]> {
53+
public async getChildren(element?: LiveWatchNode): Promise<LiveWatchNode[]> {
4954
if (!element) {
5055
return Promise.resolve(this.roots);
5156
}
52-
return Promise.resolve(element.children ?? []);
57+
try {
58+
const children = await this._activeSession?.session.customRequest('variables', { variablesReference: element.value.variablesReference });
59+
const childNodes: LiveWatchNode[] = [];
60+
for(const child of children?.variables || []) {
61+
const childNode: LiveWatchNode = {
62+
id: this.nodeID++,
63+
expression: child.name,
64+
children: [],
65+
parent: element,
66+
value: {
67+
result: child.value,
68+
variablesReference: child.variablesReference
69+
}
70+
};
71+
childNodes.push(childNode);
72+
}
73+
// We do not store children of nodes in the tree, as they are dynamic
74+
return Promise.resolve(childNodes);
75+
} catch (error) {
76+
console.error('Error fetching children:', error);
77+
return Promise.resolve([]);
78+
}
5379
}
5480

5581
public getTreeItem(element: LiveWatchNode): vscode.TreeItem {
56-
const item = new vscode.TreeItem(element.expression + ' = ', vscode.TreeItemCollapsibleState.None);
57-
item.description = element.value || '';
82+
const item = new vscode.TreeItem(element.expression + ' = ');
83+
item.description = element.value.result || '';
5884
item.contextValue = 'expression';
5985
item.tooltip = element.expression;
86+
item.collapsibleState = element.value.variablesReference !== 0 ? vscode.TreeItemCollapsibleState.Collapsed : vscode.TreeItemCollapsibleState.None;
6087
return item;
6188
}
6289

@@ -123,7 +150,7 @@ export class LiveWatchTreeDataProvider implements vscode.TreeDataProvider<LiveWa
123150
if (!expression) {
124151
return;
125152
}
126-
await this.add(expression);
153+
await this.addToRoots(expression);
127154
}
128155

129156
private async registerDeleteAllCommand() {
@@ -148,22 +175,32 @@ export class LiveWatchTreeDataProvider implements vscode.TreeDataProvider<LiveWa
148175
await this.rename(node, expression);
149176
}
150177

151-
private async evaluate(expression: string): Promise<string> {
178+
private async evaluate(expression: string): Promise<EvaluateNodeResponse> {
179+
const response: EvaluateNodeResponse = { result: '', variablesReference: 0 };
152180
if (!this._activeSession) {
153-
return 'No active session';
181+
response.result = 'No active session';
182+
return response;
154183
}
155184
const result = await this._activeSession.evaluateGlobalExpression(expression, 'watch');
156-
return result;
185+
if (typeof result == 'string') {
186+
response.result = result;
187+
return response;
188+
}
189+
response.result = result.result;
190+
response.variablesReference = result.variablesReference;
191+
return response;
157192
}
158193

159-
private async add(expression: string, parent?: LiveWatchNode) {
194+
private async addToRoots(expression: string, parent?: LiveWatchNode) {
160195
// Create a new node with a unique ID and evaluate its value
161196
const newNode: LiveWatchNode = {
162-
id: ++this.nodeID,
197+
id: this.nodeID++,
198+
children: [],
163199
expression,
164-
value : await this.evaluate(expression),
165-
parent: parent ?? undefined
200+
parent: parent ?? undefined,
201+
value: await this.evaluate(expression)
166202
};
203+
167204
if (!parent) {
168205
this.roots.push(newNode);
169206
} else {
@@ -176,6 +213,7 @@ export class LiveWatchTreeDataProvider implements vscode.TreeDataProvider<LiveWa
176213
// Clear all nodes by resetting the roots array
177214
this.roots = [];
178215
await this.refresh();
216+
await this.context.workspaceState.update(this.STORAGE_KEY, undefined);
179217
}
180218

181219
private async delete(node: LiveWatchNode) {
@@ -196,8 +234,8 @@ export class LiveWatchTreeDataProvider implements vscode.TreeDataProvider<LiveWa
196234
this._onDidChangeTreeData.fire(node);
197235
return;
198236
}
199-
for (const n of this.roots) {
200-
n.value = await this.evaluate(n.expression);
237+
for (const node of this.roots) {
238+
node.value = await this.evaluate(node.expression);
201239
}
202240
this._onDidChangeTreeData.fire();
203241
}
@@ -206,3 +244,4 @@ export class LiveWatchTreeDataProvider implements vscode.TreeDataProvider<LiveWa
206244
await this.context.workspaceState.update(this.STORAGE_KEY, this.roots);
207245
}
208246
}
247+

0 commit comments

Comments
 (0)