@@ -131,6 +131,7 @@ export class Session extends DebugSession {
131
131
private _sourceFileWatcher ?: FileSystemWatcher ;
132
132
private _activeThreadId : number = 0 ; // the one being debugged
133
133
private _localRoot : string = '' ;
134
+ private _sourceBreakpointsMap : Map < string , DebugProtocol . SourceBreakpoint [ ] | undefined > = new Map ( ) ;
134
135
private _sourceMapRoot ?: string ;
135
136
private _generatedSourceRoot ?: string ;
136
137
private _inlineSourceMap : boolean = false ;
@@ -246,7 +247,7 @@ export class Session extends DebugSession {
246
247
// VSCode extension has been activated due to the 'onDebug' activation request defined in packages.json
247
248
protected initializeRequest (
248
249
response : DebugProtocol . InitializeResponse ,
249
- args : DebugProtocol . InitializeRequestArguments
250
+ _args : DebugProtocol . InitializeRequestArguments
250
251
) : void {
251
252
const capabilities : DebugProtocol . Capabilities = {
252
253
// indicates VSCode should send the configurationDoneRequest
@@ -269,9 +270,9 @@ export class Session extends DebugSession {
269
270
270
271
// VSCode starts MC exe, then waits for MC to boot and connect back to a listening VSCode
271
272
protected async launchRequest (
272
- response : DebugProtocol . LaunchResponse ,
273
- args : DebugProtocol . LaunchRequestArguments ,
274
- request ?: DebugProtocol . Request
273
+ _response : DebugProtocol . LaunchResponse ,
274
+ _args : DebugProtocol . LaunchRequestArguments ,
275
+ _request ?: DebugProtocol . Request
275
276
) {
276
277
// not implemented
277
278
}
@@ -280,7 +281,7 @@ export class Session extends DebugSession {
280
281
protected async attachRequest (
281
282
response : DebugProtocol . AttachResponse ,
282
283
args : IAttachRequestArguments ,
283
- request ?: DebugProtocol . Request
284
+ _request ?: DebugProtocol . Request
284
285
) {
285
286
this . closeSession ( ) ;
286
287
@@ -337,7 +338,7 @@ export class Session extends DebugSession {
337
338
protected async setBreakPointsRequest (
338
339
response : DebugProtocol . SetBreakpointsResponse ,
339
340
args : DebugProtocol . SetBreakpointsArguments ,
340
- request ?: DebugProtocol . Request
341
+ _request ?: DebugProtocol . Request
341
342
) {
342
343
response . body = {
343
344
breakpoints : [ ] ,
@@ -348,52 +349,81 @@ export class Session extends DebugSession {
348
349
return ;
349
350
}
350
351
351
- let originalLocalAbsolutePath = path . normalize ( args . source . path ) ;
352
+ // store source breakpoints per file
353
+ this . _sourceBreakpointsMap . set ( args . source . path , args . breakpoints ) ;
352
354
353
- const originalBreakpoints = args . breakpoints || [ ] ;
354
- const generatedBreakpoints : DebugProtocol . SourceBreakpoint [ ] = [ ] ;
355
- let generatedRemoteLocalPath = undefined ;
355
+ // rebuild the generated breakpoints map each time a breakpoint is changed in any file
356
+ let generatedBreakpointsMap : Map < string , DebugProtocol . SourceBreakpoint [ ] > = new Map ( ) ;
356
357
357
- try {
358
- // first get generated remote file path, will throw if fails
359
- generatedRemoteLocalPath = await this . _sourceMaps . getGeneratedRemoteRelativePath ( originalLocalAbsolutePath ) ;
360
-
361
- // for all breakpoint positions set on the source file, get generated/mapped positions
362
- if ( originalBreakpoints . length ) {
363
- for ( let originalBreakpoint of originalBreakpoints ) {
364
- const generatedPosition = await this . _sourceMaps . getGeneratedPositionFor ( {
365
- source : originalLocalAbsolutePath ,
366
- column : originalBreakpoint . column || 0 ,
367
- line : originalBreakpoint . line ,
368
- } ) ;
369
- generatedBreakpoints . push ( {
370
- line : generatedPosition . line || 0 ,
371
- column : 0 ,
372
- } ) ;
358
+ // get generated breakpoints from all sources
359
+ for ( let [ sourcePath , sourceBreakpoints ] of this . _sourceBreakpointsMap ) {
360
+ let originalLocalAbsolutePath = path . normalize ( sourcePath ) ;
361
+
362
+ const originalBreakpoints = sourceBreakpoints ?? [ ] ;
363
+ let generatedRemoteLocalPath = undefined ;
364
+
365
+ try {
366
+ // first get generated remote file path, will throw if fails
367
+ generatedRemoteLocalPath = await this . _sourceMaps . getGeneratedRemoteRelativePath (
368
+ originalLocalAbsolutePath
369
+ ) ;
370
+
371
+ // append to any existing breakpoints for this generated file
372
+ if ( ! generatedBreakpointsMap . has ( generatedRemoteLocalPath ) ) {
373
+ generatedBreakpointsMap . set ( generatedRemoteLocalPath , [ ] ) ;
373
374
}
375
+ const generatedBreakpoints = generatedBreakpointsMap . get ( generatedRemoteLocalPath ) ! ;
376
+
377
+ // for all breakpoint positions set on the source file, get generated/mapped positions
378
+ if ( originalBreakpoints . length ) {
379
+ for ( let originalBreakpoint of originalBreakpoints ) {
380
+ const generatedPosition = await this . _sourceMaps . getGeneratedPositionFor ( {
381
+ source : originalLocalAbsolutePath ,
382
+ column : originalBreakpoint . column ?? 0 ,
383
+ line : originalBreakpoint . line ,
384
+ } ) ;
385
+ generatedBreakpoints . push ( {
386
+ line : generatedPosition . line ?? 0 ,
387
+ column : 0 ,
388
+ } ) ;
389
+ }
390
+ }
391
+ } catch ( e ) {
392
+ this . log ( ( e as Error ) . message , LogLevel . Error ) ;
393
+ this . sendErrorResponse (
394
+ response ,
395
+ 1002 ,
396
+ `Failed to resolve breakpoint for ${ originalLocalAbsolutePath } .`
397
+ ) ;
398
+ continue ;
374
399
}
375
- } catch ( e ) {
376
- this . log ( ( e as Error ) . message , LogLevel . Error ) ;
377
- this . sendErrorResponse ( response , 1002 , `Failed to resolve breakpoint for ${ originalLocalAbsolutePath } .` ) ;
378
- return ;
379
400
}
380
401
381
- const envelope = {
382
- type : 'breakpoints' ,
383
- breakpoints : {
384
- path : generatedRemoteLocalPath ,
385
- breakpoints : generatedBreakpoints . length ? generatedBreakpoints : undefined ,
386
- } ,
387
- } ;
402
+ // send full set of breakpoints for each generated file, a message per file
403
+ for ( let [ generatedRemoteLocalPath , generatedBreakpoints ] of generatedBreakpointsMap ) {
404
+ const envelope = {
405
+ type : 'breakpoints' ,
406
+ breakpoints : {
407
+ path : generatedRemoteLocalPath ,
408
+ breakpoints : generatedBreakpoints . length ? generatedBreakpoints : undefined ,
409
+ } ,
410
+ } ;
411
+ this . sendDebuggeeMessage ( envelope ) ;
412
+ }
413
+
414
+ // if all bps are removed from this file, ok to remove map entry after sending empty list to client
415
+ if ( args . breakpoints === undefined || args . breakpoints . length === 0 ) {
416
+ this . _sourceBreakpointsMap . delete ( args . source . path ) ;
417
+ }
388
418
389
- this . sendDebuggeeMessage ( envelope ) ;
419
+ // notify vscode breakpoints have been set
390
420
this . sendResponse ( response ) ;
391
421
}
392
422
393
423
protected setExceptionBreakPointsRequest (
394
424
response : DebugProtocol . SetExceptionBreakpointsResponse ,
395
425
args : DebugProtocol . SetExceptionBreakpointsArguments ,
396
- request ?: DebugProtocol . Request
426
+ _request ?: DebugProtocol . Request
397
427
) : void {
398
428
this . sendDebuggeeMessage ( {
399
429
type : 'stopOnException' ,
@@ -405,8 +435,8 @@ export class Session extends DebugSession {
405
435
406
436
protected configurationDoneRequest (
407
437
response : DebugProtocol . ConfigurationDoneResponse ,
408
- args : DebugProtocol . ConfigurationDoneArguments ,
409
- request ?: DebugProtocol . Request
438
+ _args : DebugProtocol . ConfigurationDoneArguments ,
439
+ _request ?: DebugProtocol . Request
410
440
) : void {
411
441
this . sendDebuggeeMessage ( {
412
442
type : 'resume' ,
@@ -416,7 +446,7 @@ export class Session extends DebugSession {
416
446
}
417
447
418
448
// VSCode wants current threads (substitute JS contexts)
419
- protected threadsRequest ( response : DebugProtocol . ThreadsResponse , request ?: DebugProtocol . Request ) : void {
449
+ protected threadsRequest ( response : DebugProtocol . ThreadsResponse , _request ?: DebugProtocol . Request ) : void {
420
450
response . body = {
421
451
threads : Array . from ( this . _threads . keys ( ) ) . map (
422
452
thread => new Thread ( thread , `thread 0x${ thread . toString ( 16 ) } ` )
@@ -478,7 +508,7 @@ export class Session extends DebugSession {
478
508
protected variablesRequest (
479
509
response : DebugProtocol . VariablesResponse ,
480
510
args : DebugProtocol . VariablesArguments ,
481
- request ?: DebugProtocol . Request
511
+ _request ?: DebugProtocol . Request
482
512
) {
483
513
// get variables at this reference (all vars in scope or vars in object/array)
484
514
this . sendDebugeeRequest ( this . _activeThreadId , response , args , ( body : any ) => {
@@ -513,7 +543,7 @@ export class Session extends DebugSession {
513
543
protected pauseRequest (
514
544
response : DebugProtocol . PauseResponse ,
515
545
args : DebugProtocol . PauseArguments ,
516
- request ?: DebugProtocol . Request
546
+ _request ?: DebugProtocol . Request
517
547
) {
518
548
this . sendDebugeeRequest ( args . threadId , response , args , ( body : any ) => {
519
549
response . body = body ;
@@ -531,7 +561,7 @@ export class Session extends DebugSession {
531
561
protected stepInRequest (
532
562
response : DebugProtocol . StepInResponse ,
533
563
args : DebugProtocol . StepInArguments ,
534
- request ?: DebugProtocol . Request
564
+ _request ?: DebugProtocol . Request
535
565
) {
536
566
this . sendDebugeeRequest ( args . threadId , response , args , ( body : any ) => {
537
567
response . body = body ;
@@ -542,7 +572,7 @@ export class Session extends DebugSession {
542
572
protected stepOutRequest (
543
573
response : DebugProtocol . StepOutResponse ,
544
574
args : DebugProtocol . StepOutArguments ,
545
- request ?: DebugProtocol . Request
575
+ _request ?: DebugProtocol . Request
546
576
) {
547
577
this . sendDebugeeRequest ( args . threadId , response , args , ( body : any ) => {
548
578
response . body = body ;
@@ -552,8 +582,8 @@ export class Session extends DebugSession {
552
582
553
583
protected disconnectRequest (
554
584
response : DebugProtocol . DisconnectResponse ,
555
- args : DebugProtocol . DisconnectArguments ,
556
- request ?: DebugProtocol . Request
585
+ _args : DebugProtocol . DisconnectArguments ,
586
+ _request ?: DebugProtocol . Request
557
587
) : void {
558
588
// closeSession triggers the 'close' event on the socket which will call terminateSession
559
589
this . closeServer ( ) ;
@@ -719,7 +749,7 @@ export class Session extends DebugSession {
719
749
// ------------------------------------------------------------------------
720
750
721
751
// async send message of type 'request' with promise and await results.
722
- private sendDebugeeRequestAsync ( thread : number , response : DebugProtocol . Response , args : any ) : Promise < any > {
752
+ private sendDebugeeRequestAsync ( _thread : number , response : DebugProtocol . Response , args : any ) : Promise < any > {
723
753
let promise = new Promise ( ( resolve , reject ) => {
724
754
let requestSeq = response . request_seq ;
725
755
this . _requests . set ( requestSeq , {
@@ -733,7 +763,7 @@ export class Session extends DebugSession {
733
763
}
734
764
735
765
// send message of type 'request' and callback with results.
736
- private sendDebugeeRequest ( thread : number , response : DebugProtocol . Response , args : any , callback : Function ) {
766
+ private sendDebugeeRequest ( _thread : number , response : DebugProtocol . Response , args : any , callback : Function ) {
737
767
let requestSeq = response . request_seq ;
738
768
this . _requests . set ( requestSeq , {
739
769
onSuccess : callback ,
0 commit comments