11import { DebugSession , InitializedEvent , TerminatedEvent , StoppedEvent , OutputEvent , Thread , StackFrame , Scope , Source , Handles } from 'vscode-debugadapter' ;
22import { DebugProtocol } from 'vscode-debugprotocol' ;
3- import { Breakpoint , IBackend , Variable } from './backend/backend' ;
3+ import { Breakpoint , IBackend , Variable , VariableObject } from './backend/backend' ;
44import { MINode } from './backend/mi_parse' ;
55import { expandValue , isExpandable } from './backend/gdb_expansion' ;
66import { MI2 } from './backend/mi2/mi2' ;
@@ -22,7 +22,8 @@ const STACK_HANDLES_START = 1000;
2222const VAR_HANDLES_START = 2000 ;
2323
2424export class MI2DebugSession extends DebugSession {
25- protected variableHandles = new Handles < string | ExtendedVariable > ( VAR_HANDLES_START ) ;
25+ protected variableHandles = new Handles < string | VariableObject | ExtendedVariable > ( VAR_HANDLES_START ) ;
26+ protected variableHandlesReverse : { [ id : string ] : number } = { } ;
2627 protected quit : boolean ;
2728 protected attached : boolean ;
2829 protected needContinue : boolean ;
@@ -266,7 +267,7 @@ export class MI2DebugSession extends DebugSession {
266267
267268 protected async variablesRequest ( response : DebugProtocol . VariablesResponse , args : DebugProtocol . VariablesArguments ) : Promise < void > {
268269 const variables : DebugProtocol . Variable [ ] = [ ] ;
269- let id : number | string | ExtendedVariable ;
270+ let id : number | string | VariableObject | ExtendedVariable ;
270271 if ( args . variablesReference < VAR_HANDLES_START ) {
271272 id = args . variablesReference - STACK_HANDLES_START ;
272273 }
@@ -281,28 +282,16 @@ export class MI2DebugSession extends DebugSession {
281282 return this . variableHandles . create ( arg ) ;
282283 } ;
283284
284- let miVarObjToVariable = ( varObj : any ) : DebugProtocol . Variable => {
285- const evaluateName = MINode . valueOf ( varObj , "name" ) ;
286- const value = MINode . valueOf ( varObj , "value" ) ;
287- const numChild = parseInt ( MINode . valueOf ( varObj , "numchild" ) ) ;
288- const dynamic = MINode . valueOf ( varObj , "dynamic" ) || 0 ;
289- let displayHint , hasMore ;
290- if ( dynamic ) {
291- displayHint = MINode . valueOf ( varObj , "displayhint" ) ;
292- hasMore = parseInt ( MINode . valueOf ( varObj , "has_more" ) ) ;
285+ let findOrCreateVariable = ( varObj : VariableObject ) : number => {
286+ let id : number ;
287+ if ( this . variableHandlesReverse . hasOwnProperty ( varObj . name ) ) {
288+ id = this . variableHandlesReverse [ varObj . name ] ;
293289 }
294- const isCompound = numChild > 0 ||
295- value === "{...}" ||
296- ( dynamic > 0 && ( displayHint === "array" || displayHint === "map" ) ) ;
297-
298- let res = {
299- name : MINode . valueOf ( varObj , "exp" ) ,
300- evaluateName,
301- type : MINode . valueOf ( varObj , "type" ) ,
302- value : value || "<value>" ,
303- variablesReference : isCompound ? createVariable ( evaluateName ) : 0
304- } as DebugProtocol . Variable ;
305- return res ;
290+ else {
291+ id = createVariable ( varObj ) ;
292+ this . variableHandlesReverse [ varObj . name ] = id ;
293+ }
294+ return varObj . isCompound ( ) ? id : 0 ;
306295 } ;
307296
308297 if ( typeof id == "number" ) {
@@ -311,10 +300,26 @@ export class MI2DebugSession extends DebugSession {
311300 stack = await this . miDebugger . getStackVariables ( this . threadID , id ) ;
312301 for ( const variable of stack ) {
313302 try {
314- const varObj = await this . miDebugger . varCreate ( variable . name ) ;
315- let v = miVarObjToVariable ( varObj . resultRecords . results ) ;
316- v . name = variable . name ;
317- variables . push ( v ) ;
303+ let varObj : VariableObject ;
304+ try {
305+ const changes = await this . miDebugger . varUpdate ( variable . name ) ;
306+ const changelist = changes . result ( "changelist" ) ;
307+ changelist . forEach ( ( change ) => {
308+ const name = MINode . valueOf ( change , "name" ) ;
309+ const vId = this . variableHandlesReverse [ variable . name ] ;
310+ const v = this . variableHandles . get ( vId ) as any ;
311+ v . applyChanges ( change ) ;
312+ } ) ;
313+ const varId = this . variableHandlesReverse [ variable . name ] ;
314+ varObj = this . variableHandles . get ( varId ) as any ;
315+ }
316+ catch ( err ) {
317+ varObj = await this . miDebugger . varCreate ( variable . name , variable . name ) ;
318+ const varId = findOrCreateVariable ( varObj ) ;
319+ varObj . exp = variable . name ;
320+ varObj . id = varId ;
321+ }
322+ variables . push ( varObj . toProtocolVariable ( ) ) ;
318323 }
319324 catch ( err ) {
320325 variables . push ( {
@@ -333,27 +338,28 @@ export class MI2DebugSession extends DebugSession {
333338 this . sendErrorResponse ( response , 1 , `Could not expand variable: ${ err } ` ) ;
334339 }
335340 }
336- else if ( typeof id == "string" ) {
337- // Variable members
338- let listChildren ;
339- try {
340- listChildren = await this . miDebugger . varListChildren ( id ) ;
341- const children : any [ ] = listChildren . result ( "children" ) ;
342- // TODO: use hasMore when it's > 0
343- // const hasMore = parseInt(listChildren.result("has_more"));
344- const vars = children . map ( child => miVarObjToVariable ( child [ 1 ] ) ) ;
341+ else if ( typeof id == "object" ) {
342+ if ( id instanceof VariableObject ) {
343+ // Variable members
344+ let children : VariableObject [ ] ;
345+ try {
346+ children = await this . miDebugger . varListChildren ( id . name ) ;
347+ const vars = children . map ( child => {
348+ const varId = findOrCreateVariable ( child ) ;
349+ child . id = varId ;
350+ return child . toProtocolVariable ( ) ;
351+ } ) ;
345352
346- response . body = {
347- variables : vars
353+ response . body = {
354+ variables : vars
355+ }
356+ this . sendResponse ( response ) ;
357+ }
358+ catch ( err ) {
359+ this . sendErrorResponse ( response , 1 , `Could not expand variable: ${ err } ` ) ;
348360 }
349- this . sendResponse ( response ) ;
350- }
351- catch ( err ) {
352- this . sendErrorResponse ( response , 1 , `Could not expand variable: ${ err } ` ) ;
353361 }
354- }
355- else if ( typeof id == "object" ) {
356- if ( id instanceof ExtendedVariable ) {
362+ else if ( id instanceof ExtendedVariable ) {
357363 let varReq = id ;
358364 if ( varReq . options . arg ) {
359365 let strArr = [ ] ;
0 commit comments