2
2
// for details. All rights reserved. Use of this source code is governed by a
3
3
// BSD-style license that can be found in the LICENSE file.import 'dart:async';
4
4
5
- // @dart = 2.9
6
-
7
5
import 'package:async/async.dart' ;
6
+ import 'package:collection/collection.dart' ;
8
7
import 'package:logging/logging.dart' ;
9
8
import 'package:vm_service/vm_service.dart' ;
10
9
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart' ;
@@ -67,9 +66,9 @@ class AppInspector implements AppInspectorInterface {
67
66
68
67
final ExecutionContext _executionContext;
69
68
70
- LibraryHelper _libraryHelper;
71
- ClassHelper _classHelper;
72
- InstanceHelper _instanceHelper;
69
+ late final LibraryHelper _libraryHelper;
70
+ late final ClassHelper _classHelper;
71
+ late final InstanceHelper _instanceHelper;
73
72
74
73
final AssetReader _assetReader;
75
74
final Locations _locations;
@@ -106,15 +105,17 @@ class AppInspector implements AppInspectorInterface {
106
105
107
106
final libraries = await _libraryHelper.libraryRefs;
108
107
isolate.rootLib = await _libraryHelper.rootLib;
109
- isolate.libraries.addAll (libraries);
108
+ isolate.libraries? .addAll (libraries);
110
109
111
110
final scripts = await scriptRefs;
112
111
113
112
await DartUri .initialize (_sdkConfiguration);
114
- await DartUri .recordAbsoluteUris (libraries.map ((lib) => lib.uri));
115
- await DartUri .recordAbsoluteUris (scripts.map ((script) => script.uri));
113
+ await DartUri .recordAbsoluteUris (
114
+ libraries.map ((lib) => lib.uri).whereNotNull ());
115
+ await DartUri .recordAbsoluteUris (
116
+ scripts.map ((script) => script.uri).whereNotNull ());
116
117
117
- isolate.extensionRPCs.addAll (await _getExtensionRpcs ());
118
+ isolate.extensionRPCs? .addAll (await _getExtensionRpcs ());
118
119
}
119
120
120
121
static IsolateRef _toIsolateRef (Isolate isolate) => IsolateRef (
@@ -187,7 +188,7 @@ class AppInspector implements AppInspectorInterface {
187
188
188
189
/// Returns the ID for the execution context or null if not found.
189
190
@override
190
- Future <int > get contextId async {
191
+ Future <int ? > get contextId async {
191
192
try {
192
193
return await _executionContext.id;
193
194
} catch (e, s) {
@@ -236,15 +237,16 @@ class AppInspector implements AppInspectorInterface {
236
237
String evalExpression, List <RemoteObject > arguments,
237
238
{bool returnByValue = false }) async {
238
239
final jsArguments = arguments.map (callArgumentFor).toList ();
239
- final result =
240
+ final response =
240
241
await remoteDebugger.sendCommand ('Runtime.callFunctionOn' , params: {
241
242
'functionDeclaration' : evalExpression,
242
243
'arguments' : jsArguments,
243
244
'objectId' : receiver.objectId,
244
245
'returnByValue' : returnByValue,
245
246
});
246
- handleErrorIfPresent (result, evalContents: evalExpression);
247
- return RemoteObject (result.result['result' ] as Map <String , Object >);
247
+ final result =
248
+ getResultOrHandleError (response, evalContents: evalExpression);
249
+ return RemoteObject (result);
248
250
}
249
251
250
252
/// Calls Chrome's Runtime.callFunctionOn method with a global function.
@@ -255,15 +257,16 @@ class AppInspector implements AppInspectorInterface {
255
257
String evalExpression, List <Object > arguments,
256
258
{bool returnByValue = false }) async {
257
259
final jsArguments = arguments.map (callArgumentFor).toList ();
258
- final result =
260
+ final response =
259
261
await remoteDebugger.sendCommand ('Runtime.callFunctionOn' , params: {
260
262
'functionDeclaration' : evalExpression,
261
263
'arguments' : jsArguments,
262
264
'executionContextId' : await contextId,
263
265
'returnByValue' : returnByValue,
264
266
});
265
- handleErrorIfPresent (result, evalContents: evalExpression);
266
- return RemoteObject (result.result['result' ] as Map <String , Object >);
267
+ final result =
268
+ getResultOrHandleError (response, evalContents: evalExpression);
269
+ return RemoteObject (result);
267
270
}
268
271
269
272
/// Invoke the function named [selector] on the object identified by
@@ -303,26 +306,28 @@ class AppInspector implements AppInspectorInterface {
303
306
Future <RemoteObject > jsEvaluate (String expression,
304
307
{bool returnByValue = false , bool awaitPromise = false }) async {
305
308
// TODO(alanknight): Support a version with arguments if needed.
306
- WipResponse result;
307
- result = await remoteDebugger.sendCommand ('Runtime.evaluate' , params: {
309
+ final response =
310
+ await remoteDebugger.sendCommand ('Runtime.evaluate' , params: {
308
311
'expression' : expression,
309
312
'returnByValue' : returnByValue,
310
313
'awaitPromise' : awaitPromise,
311
314
'contextId' : await contextId,
312
315
});
313
- handleErrorIfPresent (result, evalContents: expression, additionalDetails: {
314
- 'Dart expression' : expression,
315
- });
316
- return RemoteObject (result.result['result' ] as Map <String , dynamic >);
316
+ final result = getResultOrHandleError (response, evalContents: expression);
317
+ return RemoteObject (result);
317
318
}
318
319
319
320
/// Evaluate the JS function with source [jsFunction] in the context of
320
321
/// [library] with [arguments] .
321
322
Future <RemoteObject > _evaluateInLibrary (
322
323
Library library, String jsFunction, List <RemoteObject > arguments) async {
324
+ final libraryUri = library.uri;
325
+ if (libraryUri == null ) {
326
+ throwInvalidParam ('invoke' , 'library uri is null' );
327
+ }
323
328
final findLibrary = '''
324
329
(function() {
325
- ${globalLoadStrategy .loadLibrarySnippet (library . uri )};
330
+ ${globalLoadStrategy .loadLibrarySnippet (libraryUri )};
326
331
return library;
327
332
})();
328
333
''' ;
@@ -339,25 +344,25 @@ class AppInspector implements AppInspectorInterface {
339
344
}
340
345
341
346
@override
342
- Future <InstanceRef > instanceRefFor (Object value) =>
347
+ Future <InstanceRef ? > instanceRefFor (Object value) =>
343
348
_instanceHelper.instanceRefFor (value);
344
349
345
- Future <Instance > instanceFor (Object value) =>
350
+ Future <Instance ? > instanceFor (RemoteObject value) =>
346
351
_instanceHelper.instanceFor (value);
347
352
348
353
@override
349
- Future <LibraryRef > libraryRefFor (String objectId) =>
354
+ Future <LibraryRef ? > libraryRefFor (String objectId) =>
350
355
_libraryHelper.libraryRefFor (objectId);
351
356
352
357
@override
353
- Future <Library > getLibrary (String objectId) async {
358
+ Future <Library ? > getLibrary (String objectId) async {
354
359
final libraryRef = await libraryRefFor (objectId);
355
360
if (libraryRef == null ) return null ;
356
361
return _libraryHelper.libraryFor (libraryRef);
357
362
}
358
363
359
364
@override
360
- Future <Obj > getObject (String objectId, {int offset, int count}) async {
365
+ Future <Obj ? > getObject (String objectId, {int ? offset, int ? count}) async {
361
366
try {
362
367
final library = await getLibrary (objectId);
363
368
if (library != null ) {
@@ -384,9 +389,13 @@ class AppInspector implements AppInspectorInterface {
384
389
'are supported for getObject' );
385
390
}
386
391
387
- Future <Script > _getScript (ScriptRef scriptRef) async {
392
+ Future <Script ? > _getScript (ScriptRef scriptRef) async {
388
393
final libraryId = _scriptIdToLibraryId[scriptRef.id];
389
- final serverPath = DartUri (scriptRef.uri, _root).serverPath;
394
+ final scriptUri = scriptRef.uri;
395
+ final scriptId = scriptRef.id;
396
+ if (libraryId == null || scriptUri == null || scriptId == null ) return null ;
397
+
398
+ final serverPath = DartUri (scriptUri, _root).serverPath;
390
399
final source = await _assetReader.dartSourceContents (serverPath);
391
400
if (source == null ) {
392
401
throw RPCError ('getObject' , RPCError .kInvalidParams,
@@ -395,16 +404,17 @@ class AppInspector implements AppInspectorInterface {
395
404
return Script (
396
405
uri: scriptRef.uri,
397
406
library: await libraryRefFor (libraryId),
398
- id: scriptRef.id )
407
+ id: scriptId )
399
408
..tokenPosTable = await _locations.tokenPosTableFor (serverPath)
400
409
..source = source;
401
410
}
402
411
403
412
@override
404
- Future <MemoryUsage > getMemoryUsage () async {
413
+ Future <MemoryUsage ? > getMemoryUsage () async {
405
414
final response = await remoteDebugger.sendCommand ('Runtime.getHeapUsage' );
406
-
407
- final jsUsage = HeapUsage (response.result);
415
+ final result = response.result;
416
+ if (result == null ) return null ;
417
+ final jsUsage = HeapUsage (result);
408
418
return MemoryUsage .parse ({
409
419
'heapUsage' : jsUsage.usedSize,
410
420
'heapCapacity' : jsUsage.totalSize,
@@ -414,7 +424,7 @@ class AppInspector implements AppInspectorInterface {
414
424
415
425
/// Returns the [ScriptRef] for the provided Dart server path [uri] .
416
426
@override
417
- Future <ScriptRef > scriptRefFor (String uri) async {
427
+ Future <ScriptRef ? > scriptRefFor (String uri) async {
418
428
await _populateScriptCaches ();
419
429
return _serverPathToScriptRef[uri];
420
430
}
@@ -423,7 +433,7 @@ class AppInspector implements AppInspectorInterface {
423
433
@override
424
434
Future <List <ScriptRef >> scriptRefsForLibrary (String libraryId) async {
425
435
await _populateScriptCaches ();
426
- return _libraryIdToScriptRefs[libraryId];
436
+ return _libraryIdToScriptRefs[libraryId] ?? [] ;
427
437
}
428
438
429
439
/// Return the VM SourceReport for the given parameters.
@@ -432,12 +442,12 @@ class AppInspector implements AppInspectorInterface {
432
442
@override
433
443
Future <SourceReport > getSourceReport (
434
444
List <String > reports, {
435
- String scriptId,
436
- int tokenPos,
437
- int endTokenPos,
438
- bool forceCompile,
439
- bool reportLines,
440
- List <String > libraryFilters,
445
+ String ? scriptId,
446
+ int ? tokenPos,
447
+ int ? endTokenPos,
448
+ bool ? forceCompile,
449
+ bool ? reportLines,
450
+ List <String >? libraryFilters,
441
451
}) {
442
452
if (reports.contains (SourceReportKind .kCoverage)) {
443
453
throwInvalidParam ('getSourceReport' ,
@@ -457,15 +467,19 @@ class AppInspector implements AppInspectorInterface {
457
467
return _getPossibleBreakpoints (scriptId);
458
468
}
459
469
460
- Future <SourceReport > _getPossibleBreakpoints (String scriptId) async {
470
+ Future <SourceReport > _getPossibleBreakpoints (String ? scriptId) async {
461
471
// TODO(devoncarew): Consider adding some caching for this method.
462
472
463
473
final scriptRef = scriptWithId (scriptId);
464
474
if (scriptRef == null ) {
465
- throwInvalidParam ('getSourceReport' , 'scriptId not found: $scriptId ' );
475
+ throwInvalidParam ('getSourceReport' , 'scriptRef not found for $scriptId ' );
476
+ }
477
+ final scriptUri = scriptRef.uri;
478
+ if (scriptUri == null ) {
479
+ throwInvalidParam ('getSourceReport' , 'scriptUri not found for $scriptId ' );
466
480
}
467
481
468
- final dartUri = DartUri (scriptRef.uri , _root);
482
+ final dartUri = DartUri (scriptUri , _root);
469
483
final mappedLocations =
470
484
await _locations.locationsForDart (dartUri.serverPath);
471
485
// Unlike the Dart VM, the token positions match exactly to the possible
@@ -505,7 +519,9 @@ class AppInspector implements AppInspectorInterface {
505
519
/// Returns the list of scripts refs cached.
506
520
Future <List <ScriptRef >> _populateScriptCaches () async {
507
521
return _scriptCacheMemoizer.runOnce (() async {
508
- final libraryUris = [for (var library in isolate.libraries) library.uri];
522
+ final libraryUris = [
523
+ for (var library in isolate.libraries ?? []) library.uri
524
+ ];
509
525
final scripts = await globalLoadStrategy
510
526
.metadataProviderFor (appConnection.request.entrypointPath)
511
527
.scripts;
@@ -517,16 +533,24 @@ class AppInspector implements AppInspectorInterface {
517
533
final parts = scripts[uri];
518
534
final scriptRefs = [
519
535
ScriptRef (uri: uri, id: createId ()),
520
- for (var part in parts) ScriptRef (uri: part, id: createId ())
536
+ for (var part in parts ?? [] ) ScriptRef (uri: part, id: createId ())
521
537
];
522
538
final libraryRef = await _libraryHelper.libraryRefFor (uri);
523
- _libraryIdToScriptRefs.putIfAbsent (libraryRef.id, () => < ScriptRef > []);
524
- for (var scriptRef in scriptRefs) {
525
- _scriptRefsById[scriptRef.id] = scriptRef;
526
- _scriptIdToLibraryId[scriptRef.id] = libraryRef.id;
527
- _serverPathToScriptRef[DartUri (scriptRef.uri, _root).serverPath] =
528
- scriptRef;
529
- _libraryIdToScriptRefs[libraryRef.id].add (scriptRef);
539
+ final libraryId = libraryRef? .id;
540
+ if (libraryId != null ) {
541
+ final libraryIdToScriptRefs = _libraryIdToScriptRefs.putIfAbsent (
542
+ libraryId, () => < ScriptRef > []);
543
+ for (var scriptRef in scriptRefs) {
544
+ final scriptId = scriptRef.id;
545
+ final scriptUri = scriptRef.uri;
546
+ if (scriptId != null && scriptUri != null ) {
547
+ _scriptRefsById[scriptId] = scriptRef;
548
+ _scriptIdToLibraryId[scriptId] = libraryId;
549
+ _serverPathToScriptRef[DartUri (scriptUri, _root).serverPath] =
550
+ scriptRef;
551
+ libraryIdToScriptRefs.add (scriptRef);
552
+ }
553
+ }
530
554
}
531
555
}
532
556
return _scriptRefsById.values.toList ();
@@ -535,7 +559,8 @@ class AppInspector implements AppInspectorInterface {
535
559
536
560
/// Look up the script by id in an isolate.
537
561
@override
538
- ScriptRef scriptWithId (String scriptId) => _scriptRefsById[scriptId];
562
+ ScriptRef ? scriptWithId (String ? scriptId) =>
563
+ scriptId == null ? null : _scriptRefsById[scriptId];
539
564
540
565
/// Runs an eval on the page to compute all existing registered extensions.
541
566
Future <List <String >> _getExtensionRpcs () async {
@@ -548,11 +573,10 @@ class AppInspector implements AppInspectorInterface {
548
573
'contextId' : await contextId,
549
574
};
550
575
try {
551
- final extensionsResult =
576
+ final response =
552
577
await remoteDebugger.sendCommand ('Runtime.evaluate' , params: params);
553
- handleErrorIfPresent (extensionsResult, evalContents: expression);
554
- extensionRpcs.addAll (
555
- List .from (extensionsResult.result['result' ]['value' ] as List ));
578
+ final result = getResultOrHandleError (response, evalContents: expression);
579
+ extensionRpcs.addAll (List .from (result['value' ] as List ? ?? []));
556
580
} catch (e, s) {
557
581
_logger.severe (
558
582
'Error calling Runtime.evaluate with params $params ' , e, s);
@@ -571,7 +595,7 @@ class AppInspector implements AppInspectorInterface {
571
595
} catch (_) {
572
596
return description;
573
597
}
574
- final mappedStack = mapperResult? .value? .toString ();
598
+ final mappedStack = mapperResult.value? .toString ();
575
599
if (mappedStack == null || mappedStack.isEmpty) {
576
600
return description;
577
601
}
0 commit comments