@@ -299,7 +299,7 @@ export class WebKitDebugAdapter implements IDebugAdapter {
299
299
private onScriptParsed ( script : WebKitProtocol . Debugger . Script ) : void {
300
300
this . _scriptsById . set ( script . scriptId , script ) ;
301
301
302
- if ( ! this . isExtensionScript ( script ) ) {
302
+ if ( this . scriptIsNotAnonymous ( script ) ) {
303
303
this . fireEvent ( { seq : 0 , type : 'event' , event : 'scriptParsed' , body : { scriptUrl : script . url , sourceMapURL : script . sourceMapURL } } ) ;
304
304
}
305
305
}
@@ -491,28 +491,50 @@ export class WebKitDebugAdapter implements IDebugAdapter {
491
491
492
492
const stackFrames : DebugProtocol . StackFrame [ ] = stack
493
493
. map ( ( callFrame : WebKitProtocol . Debugger . CallFrame , i : number ) => {
494
- const script = this . _scriptsById . get ( callFrame . location . scriptId ) ;
495
- const line = callFrame . location . lineNumber ;
496
- const column = callFrame . location . columnNumber ;
494
+ const sourceReference = scriptIdToSourceReference ( callFrame . location . scriptId ) ;
495
+ const scriptId = callFrame . location . scriptId ;
496
+ const script = this . _scriptsById . get ( scriptId ) ;
497
497
498
498
let source : DebugProtocol . Source ;
499
- if ( script ) {
500
- // When the script has a url and isn't a content script, send the name and path fields. PathTransformer will
501
- // attempt to resolve it to a script in the workspace. Otherwise, send the name and sourceReference fields.
502
- source = ( script . url && ! this . isExtensionScript ( script ) ) ?
503
- {
499
+ if ( this . scriptIsNotUnknown ( scriptId ) ) {
500
+ // We have received Debugger.scriptParsed event for the script.
501
+ if ( this . scriptIsNotAnonymous ( script ) ) {
502
+ /**
503
+ * We have received non-empty url with the Debugger.scriptParsed event.
504
+ * We set the url value to the path property. Later on, the PathTransformer will attempt to resolve it to a script in the app root folder.
505
+ * In case it fails to resolve it, we also set the sourceReference field in order to allow the client to send source request to retrieve the source.
506
+ * If the PathTransformer resolves the url successfully, it will change the value of sourceReference to 0.
507
+ */
508
+ source = {
504
509
name : path . basename ( script . url ) ,
505
510
path : script . url ,
506
511
sourceReference : scriptIdToSourceReference ( script . scriptId ) // will be 0'd out by PathTransformer if not needed
507
- } :
508
- {
509
- // Name should be undefined, work around VS Code bug 20274
510
- name : undefined ,
511
- sourceReference : scriptIdToSourceReference ( script . scriptId )
512
512
} ;
513
+ }
514
+ else {
515
+ /**
516
+ * We have received Debugger.scriptParsed event with empty url value.
517
+ * Sending only the sourceId will make the client to send source request to retrieve the source of the script.
518
+ */
519
+ source = {
520
+ name : 'anonymous source' ,
521
+ sourceReference : sourceReference
522
+ } ;
523
+ }
513
524
}
514
525
else {
515
- source = { name : 'eval: Unknown' } ;
526
+ /**
527
+ * Unknown script. No Debugger.scriptParsed event received for the script.
528
+ *
529
+ * Some 'internal scripts' are intentionally referenced by id equal to 0. Others have id > 0 but no Debugger.scriptParsed event is sent when parsed.
530
+ * In both cases we can't get its source code. If we send back a zero sourceReference the VS Code client will not send source request.
531
+ * The most we can do is to include a dummy stack frame with no source associated and without specifing the sourceReference.
532
+ */
533
+ source = {
534
+ name : 'unknown source' ,
535
+ origin : 'internal module' ,
536
+ sourceReference : 0
537
+ } ;
516
538
}
517
539
518
540
// If the frame doesn't have a function name, it's either an anonymous function
@@ -521,9 +543,9 @@ export class WebKitDebugAdapter implements IDebugAdapter {
521
543
return {
522
544
id : i ,
523
545
name : frameName ,
524
- source,
525
- line : line ,
526
- column
546
+ source : source ,
547
+ line : callFrame . location . lineNumber ,
548
+ column : callFrame . location . columnNumber
527
549
} ;
528
550
} ) ;
529
551
@@ -588,6 +610,9 @@ export class WebKitDebugAdapter implements IDebugAdapter {
588
610
589
611
public source ( args : DebugProtocol . SourceArguments ) : Promise < ISourceResponseBody > {
590
612
return this . _webKitConnection . debugger_getScriptSource ( sourceReferenceToScriptId ( args . sourceReference ) ) . then ( webkitResponse => {
613
+ if ( webkitResponse . error ) {
614
+ throw new Error ( webkitResponse . error . message ) ;
615
+ }
591
616
return { content : webkitResponse . result . scriptSource } ;
592
617
} ) ;
593
618
}
@@ -606,8 +631,12 @@ export class WebKitDebugAdapter implements IDebugAdapter {
606
631
public evaluate ( args : DebugProtocol . EvaluateArguments ) : Promise < IEvaluateResponseBody > {
607
632
let evalPromise : Promise < any > ;
608
633
if ( this . paused ) {
609
- const callFrameId = this . _currentStack [ args . frameId ] . callFrameId ;
610
- evalPromise = this . _webKitConnection . debugger_evaluateOnCallFrame ( callFrameId , args . expression ) ;
634
+ const callFrame = this . _currentStack [ args . frameId ] ;
635
+ if ( ! this . scriptIsNotUnknown ( callFrame . location . scriptId ) ) {
636
+ // The iOS debugger backend hangs and stops responding after receiving evaluate request on call frame which has unknown source.
637
+ throw new Error ( '-' ) ; // The message will be printed in the VS Code UI
638
+ }
639
+ evalPromise = this . _webKitConnection . debugger_evaluateOnCallFrame ( callFrame . callFrameId , args . expression ) ;
611
640
} else {
612
641
evalPromise = this . _webKitConnection . runtime_evaluate ( args . expression ) ;
613
642
}
@@ -648,8 +677,14 @@ export class WebKitDebugAdapter implements IDebugAdapter {
648
677
return result ;
649
678
}
650
679
651
- private isExtensionScript ( script : WebKitProtocol . Debugger . Script ) : boolean {
652
- return script . isContentScript || ! script . url || script . url . startsWith ( 'extensions::' ) || script . url . startsWith ( 'chrome-extension://' ) ;
680
+ // Returns true if the script has url supplied in Debugger.scriptParsed event
681
+ private scriptIsNotAnonymous ( script : WebKitProtocol . Debugger . Script ) : boolean {
682
+ return script && ! ! script . url ;
683
+ }
684
+
685
+ // Returns true if Debugger.scriptParsed event is received for the provided script id
686
+ private scriptIsNotUnknown ( scriptId : WebKitProtocol . Debugger . ScriptId ) : boolean {
687
+ return ! ! this . _scriptsById . get ( scriptId ) ;
653
688
}
654
689
}
655
690
0 commit comments