Skip to content

Update library heuristics as short term solution for missing metadata. #1293

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions dwds/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 10.0.2-dev

- Fix missing sdk libraries in `getObject()` calls.
- Fix incorrect `rootLib` returned by `ChromeProxyService`.

## 10.0.1

- Support `webkit_inspection_protocol` version `^1.0.0`.
Expand Down
6 changes: 6 additions & 0 deletions dwds/lib/src/debugging/classes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,14 @@ class ClassHelper extends Domain {
throw UnsupportedError('unknown library: $libraryId');
}
var libraryRef = await inspector.libraryHelper.libraryRefFor(libraryId);
if (libraryRef == null) {
throw Exception('Could not find library: $libraryId');
}
var classRef = classRefFor(libraryId, splitId.last);
clazz = await _constructClass(libraryRef, classRef);
if (clazz == null) {
throw Exception('Could not contruct class: $classRef');
}
return _classes[objectId] = clazz;
}

Expand Down
45 changes: 27 additions & 18 deletions dwds/lib/src/debugging/inspector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

// @dart = 2.9

import 'package:logging/logging.dart';
import 'package:path/path.dart' as p;
import 'package:vm_service/vm_service.dart';
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';
Expand Down Expand Up @@ -33,6 +34,8 @@ class AppInspector extends Domain {

Future<List<ScriptRef>> get scriptRefs => _cachedScriptRefs ??= _getScripts();

final _logger = Logger('AppInspector');

/// Map of scriptRef ID to [ScriptRef].
final _scriptRefsById = <String, ScriptRef>{};

Expand Down Expand Up @@ -80,18 +83,11 @@ class AppInspector extends Domain {

Future<void> _initialize() async {
var libraries = await libraryHelper.libraryRefs;
isolate.libraries.addAll(libraries);
isolate.rootLib = await libraryHelper.rootLib;

isolate.libraries.addAll(libraries);
await DartUri.recordAbsoluteUris(libraries.map((lib) => lib.uri));

// This relies on the convention that the 2nd to last library is the root
// library (and the last one is the bootstrap library).
if (libraries.length >= 2) {
isolate.rootLib = libraries[libraries.length - 2];
} else {
isolate.rootLib = libraries.last;
}

isolate.extensionRPCs.addAll(await _getExtensionRpcs());
}

Expand Down Expand Up @@ -328,15 +324,28 @@ function($argsString) {

Future<Obj> getObject(String isolateId, String objectId,
{int offset, int count}) async {
var library = await _getLibrary(isolateId, objectId);
if (library != null) return library;
var clazz = await classHelper.forObjectId(objectId);
if (clazz != null) return clazz;
var scriptRef = _scriptRefsById[objectId];
if (scriptRef != null) return await _getScript(isolateId, scriptRef);
var instance = await instanceHelper.instanceFor(remoteObjectFor(objectId),
offset: offset, count: count);
if (instance != null) return instance;
try {
var library = await _getLibrary(isolateId, objectId);
if (library != null) {
return library;
}
var clazz = await classHelper.forObjectId(objectId);
if (clazz != null) {
return clazz;
}
var scriptRef = _scriptRefsById[objectId];
if (scriptRef != null) {
return await _getScript(isolateId, scriptRef);
}
var instance = await instanceHelper.instanceFor(remoteObjectFor(objectId),
offset: offset, count: count);
if (instance != null) {
return instance;
}
} catch (e, s) {
_logger.log(Level.FINE, 'getObject failed with exception: $e:$s');
rethrow;
}
throw UnsupportedError('Only libraries, instances, classes, and scripts '
'are supported for getObject');
}
Expand Down
14 changes: 14 additions & 0 deletions dwds/lib/src/debugging/libraries.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,22 @@ class LibraryHelper extends Domain {
/// Map of libraryRef ID to [LibraryRef].
final _libraryRefsById = <String, LibraryRef>{};

LibraryRef _rootLib;

LibraryHelper(AppInspector Function() provider) : super(provider);

Future<LibraryRef> get rootLib async {
if (_rootLib != null) return _rootLib;
// TODO: read entrypoint from app metadata.
// Issue: https://github.com/dart-lang/webdev/issues/1290
var libraries = await libraryRefs;
_rootLib = libraries.firstWhere((lib) => lib.name.contains('org-dartlang'));
_rootLib =
_rootLib ?? libraries.firstWhere((lib) => lib.name.contains('main'));
_rootLib = _rootLib ?? (libraries.isNotEmpty ? libraries.last : null);
return _rootLib;
}

/// Returns all libraryRefs in the app.
///
/// Note this can return a cached result.
Expand Down
50 changes: 50 additions & 0 deletions dwds/lib/src/debugging/metadata/provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,45 @@ class MetadataProvider {
final Map<String, List<String>> _scripts = {};
final _metadataMemoizer = AsyncMemoizer();

/// Implicitly imported libraries in any DDC component.
///
/// Currently dart_sdk module does not come with the metadata.
/// To allow evaluation of expressions that use libraries and
/// types from the SDK (such as a dart Type object), add the
/// metadata for dart_sdk manually.
///
/// TODO: Generate sdk module metadata to be consumed by debugger.
/// Issue: https://github.com/dart-lang/sdk/issues/45477
List<String> get sdkLibraries => const [
'dart:_runtime',
'dart:_debugger',
'dart:_foreign_helper',
'dart:_interceptors',
'dart:_internal',
'dart:_isolate_helper',
'dart:_js_helper',
'dart:_js_primitives',
'dart:_metadata',
'dart:_native_typed_data',
'dart:async',
'dart:collection',
'dart:convert',
'dart:developer',
'dart:io',
'dart:isolate',
'dart:js',
'dart:js_util',
'dart:math',
'dart:typed_data',
'dart:indexed_db',
'dart:html',
'dart:html_common',
'dart:svg',
'dart:web_audio',
'dart:web_gl',
'dart:web_sql'
];

MetadataProvider(this.entrypoint, this._assetReader)
: _soundNullSafety = false;

Expand Down Expand Up @@ -150,6 +189,7 @@ class MetadataProvider {
entrypoint.replaceAll('.bootstrap.js', '.ddc_merged_metadata');
var merged = await _assetReader.metadataContents(serverPath);
if (merged != null) {
_addSdkMetadata();
for (var contents in merged.split('\n')) {
try {
if (contents == null ||
Expand Down Expand Up @@ -197,6 +237,16 @@ class MetadataProvider {
}
}
}

void _addSdkMetadata() {
var moduleName = 'dart_sdk';

for (var lib in sdkLibraries) {
_libraries.add(lib);
_scripts[lib] = [];
_scriptToModule[lib] = moduleName;
}
}
}

class AbsoluteImportUriException implements Exception {
Expand Down
5 changes: 4 additions & 1 deletion dwds/lib/src/debugging/modules.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@ class Modules {

var scriptToModule = await provider.scriptToModule;
for (var script in scriptToModule.keys) {
var serverPath = DartUri(script, _root).serverPath;
var serverPath = script.startsWith('dart:')
? script
: DartUri(script, _root).serverPath;

_sourceToModule[serverPath] = scriptToModule[script];
_sourceToLibrary[serverPath] = Uri.parse(script);
_libraryToModule[script] = scriptToModule[script];
Expand Down
Loading