From 813d9049e134d08627f877798febf823e0c9b976 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Thu, 23 Jun 2022 10:43:34 -0700 Subject: [PATCH 1/2] Migrate modules and locations to null safety --- dwds/lib/src/debugging/location.dart | 47 ++++++++++++++++++---------- dwds/lib/src/debugging/modules.dart | 42 ++++++++++++++----------- dwds/test/debugger_test.dart | 1 + dwds/test/location_test.dart | 1 + 4 files changed, 56 insertions(+), 35 deletions(-) diff --git a/dwds/lib/src/debugging/location.dart b/dwds/lib/src/debugging/location.dart index 30419d815..b9aacf699 100644 --- a/dwds/lib/src/debugging/location.dart +++ b/dwds/lib/src/debugging/location.dart @@ -2,10 +2,9 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -// @dart = 2.9 - import 'package:async/async.dart'; import 'package:dwds/src/loaders/require.dart'; +import 'package:logging/logging.dart'; import 'package:path/path.dart' as p; import 'package:source_maps/parser.dart'; import 'package:source_maps/source_maps.dart'; @@ -46,7 +45,7 @@ class Location { // https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k return Location._( JsLocation.fromZeroBased(module, jsLine, jsColumn), - DartLocation.fromZeroBased(dartUri, dartLine, dartColumn), + DartLocation.fromZeroBased(dartUri, dartLine ?? 0, dartColumn ?? 0), ); } @@ -118,6 +117,8 @@ class JsLocation { /// Contains meta data for known [Location]s. class Locations { + final _logger = Logger('Locations'); + /// [Location] data for Dart server path. final Map> _sourceToLocation = {}; final Map>> _locationMemoizer = {}; @@ -134,7 +135,7 @@ class Locations { final Modules _modules; final String _root; - String _entrypoint; + late String _entrypoint; Locations(this._assetReader, this._modules, this._root); @@ -151,7 +152,11 @@ class Locations { /// Returns all [Location] data for a provided Dart source. Future> locationsForDart(String serverPath) async { final module = await _modules.moduleForSource(serverPath); - await _locationsForModule(module); + if (module == null) { + _logger.warning('No module for server path $serverPath'); + } else { + await _locationsForModule(module); + } return _sourceToLocation[serverPath] ?? {}; } @@ -161,13 +166,18 @@ class Locations { _entrypoint, Uri.parse(url).path); final cache = _moduleToLocations[module]; if (cache != null) return cache; - return await _locationsForModule(module) ?? {}; + if (module == null) { + _logger.warning('No module for $url'); + } else { + await _locationsForModule(module); + } + return _moduleToLocations[module] ?? {}; } /// Find the [Location] for the given Dart source position. /// /// The [line] number is 1-based. - Future locationForDart(DartUri uri, int line, int column) async { + Future locationForDart(DartUri uri, int line, int column) async { final locations = await locationsForDart(uri.serverPath); return _bestDartLocation(locations, line, column); } @@ -175,7 +185,7 @@ class Locations { /// Find the [Location] for the given JS source position. /// /// The [line] number is 0-based. - Future locationForJs(String url, int line, int column) async { + Future locationForJs(String url, int line, int column) async { final locations = await locationsForUrl(url); return _bestJsLocation(locations, line, column); } @@ -185,9 +195,9 @@ class Locations { /// Dart columns for breakpoints are either exact or start at the /// beginning of the line - return the first existing location /// that comes after the given column. - Location _bestDartLocation( + Location? _bestDartLocation( Iterable locations, int line, int column) { - Location bestLocation; + Location? bestLocation; for (var location in locations) { if (location.dartLocation.line == line && location.dartLocation.column >= column) { @@ -209,8 +219,9 @@ class Locations { /// the closest location to the current one: /// /// https://github.com/microsoft/vscode-js-debug/blob/536f96bae61a3d87546b61bc7916097904c81429/src/common/sourceUtils.ts#L286 - Location _bestJsLocation(Iterable locations, int line, int column) { - Location bestLocation; + Location? _bestJsLocation( + Iterable locations, int line, int column) { + Location? bestLocation; for (var location in locations) { if (location.jsLocation.compareToLine(line, column) <= 0) { bestLocation ??= location; @@ -239,9 +250,10 @@ class Locations { .add(location); } for (var lineNumber in lineNumberToLocation.keys) { + final location = lineNumberToLocation[lineNumber]!; tokenPosTable.add([ lineNumber, - for (var location in lineNumberToLocation[lineNumber]) ...[ + for (var location in location) ...[ location.tokenPos, location.dartLocation.column ] @@ -259,11 +271,12 @@ class Locations { Future> _locationsForModule(String module) async { _locationMemoizer.putIfAbsent(module, () => AsyncMemoizer()); - return await _locationMemoizer[module].runOnce(() async { - if (module == null) return {}; - if (_moduleToLocations[module] != null) return _moduleToLocations[module]; + return await _locationMemoizer[module]!.runOnce(() async { + if (_moduleToLocations.containsKey(module)) { + return _moduleToLocations[module]!; + } final result = {}; - if (module?.isEmpty ?? true) return _moduleToLocations[module] = result; + if (module.isEmpty) return _moduleToLocations[module] = result; if (module.endsWith('dart_sdk') || module.endsWith('dart_library')) { return result; } diff --git a/dwds/lib/src/debugging/modules.dart b/dwds/lib/src/debugging/modules.dart index 4b41f10f9..5b3e994c1 100644 --- a/dwds/lib/src/debugging/modules.dart +++ b/dwds/lib/src/debugging/modules.dart @@ -2,15 +2,15 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -// @dart = 2.9 - import 'package:async/async.dart'; +import 'package:logging/logging.dart'; import '../loaders/strategy.dart'; import '../utilities/dart_uri.dart'; /// Tracks modules for the compiled application. class Modules { + final _logger = Logger('Modules'); final String _root; // The Dart server path to containing module. @@ -22,9 +22,9 @@ class Modules { final Map _libraryToModule = {}; - String _entrypoint; + late String _entrypoint; - Modules(String root) : _root = root == '' ? '/' : root; + Modules(this._root); /// Initializes the mapping from source to module. /// @@ -41,18 +41,18 @@ class Modules { } /// Returns the containing module for the provided Dart server path. - Future moduleForSource(String serverPath) async { + Future moduleForSource(String serverPath) async { await _moduleMemoizer.runOnce(_initializeMapping); return _sourceToModule[serverPath]; } /// Returns the containing library importUri for the provided Dart server path. - Future libraryForSource(String serverPath) async { + Future libraryForSource(String serverPath) async { await _moduleMemoizer.runOnce(_initializeMapping); return _sourceToLibrary[serverPath]; } - Future moduleForlibrary(String libraryUri) async { + Future moduleForlibrary(String libraryUri) async { await _moduleMemoizer.runOnce(_initializeMapping); return _libraryToModule[libraryUri]; } @@ -71,21 +71,27 @@ class Modules { final scriptToModule = await provider.scriptToModule; for (var library in libraryToScripts.keys) { + final scripts = libraryToScripts[library]!; final libraryServerPath = library.startsWith('dart:') ? library : DartUri(library, _root).serverPath; - _sourceToModule[libraryServerPath] = scriptToModule[library]; - _sourceToLibrary[libraryServerPath] = Uri.parse(library); - _libraryToModule[library] = scriptToModule[library]; - - for (var script in libraryToScripts[library]) { - final scriptServerPath = script.startsWith('dart:') - ? script - : DartUri(script, _root).serverPath; - - _sourceToModule[scriptServerPath] = scriptToModule[library]; - _sourceToLibrary[scriptServerPath] = Uri.parse(library); + if (scriptToModule.containsKey(library)) { + final module = scriptToModule[library]!; + _sourceToModule[libraryServerPath] = module; + _sourceToLibrary[libraryServerPath] = Uri.parse(library); + _libraryToModule[library] = module; + + for (var script in scripts) { + final scriptServerPath = script.startsWith('dart:') + ? script + : DartUri(script, _root).serverPath; + + _sourceToModule[scriptServerPath] = module; + _sourceToLibrary[scriptServerPath] = Uri.parse(library); + } + } else { + _logger.warning('No module found for library $library'); } } } diff --git a/dwds/test/debugger_test.dart b/dwds/test/debugger_test.dart index bf82829cf..5c3c49f0f 100644 --- a/dwds/test/debugger_test.dart +++ b/dwds/test/debugger_test.dart @@ -102,6 +102,7 @@ void main() async { globalLoadStrategy = TestStrategy(); final root = 'fakeRoot'; locations = Locations(FakeAssetReader(), FakeModules(), root); + locations.initialize('fake_entrypoint'); skipLists = SkipLists(); debugger = await Debugger.create( webkitDebugger, diff --git a/dwds/test/location_test.dart b/dwds/test/location_test.dart index 22d837f51..6390b6c8e 100644 --- a/dwds/test/location_test.dart +++ b/dwds/test/location_test.dart @@ -24,6 +24,7 @@ void main() { final assetReader = FakeAssetReader(); final modules = MockModules(); final locations = Locations(assetReader, modules, ''); + locations.initialize('fake_entrypoint'); group('JS locations |', () { group('location |', () { From f150f314dcb180c26b4eb15779e65df44bdfa73b Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Fri, 24 Jun 2022 09:51:43 -0700 Subject: [PATCH 2/2] Address CR comments --- dwds/lib/src/debugging/location.dart | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dwds/lib/src/debugging/location.dart b/dwds/lib/src/debugging/location.dart index b9aacf699..07ddba58f 100644 --- a/dwds/lib/src/debugging/location.dart +++ b/dwds/lib/src/debugging/location.dart @@ -250,10 +250,10 @@ class Locations { .add(location); } for (var lineNumber in lineNumberToLocation.keys) { - final location = lineNumberToLocation[lineNumber]!; + final locations = lineNumberToLocation[lineNumber]!; tokenPosTable.add([ lineNumber, - for (var location in location) ...[ + for (var location in locations) ...[ location.tokenPos, location.dartLocation.column ] @@ -269,9 +269,10 @@ class Locations { /// /// This will populate the [_sourceToLocation] and [_moduleToLocations] maps. Future> _locationsForModule(String module) async { - _locationMemoizer.putIfAbsent(module, () => AsyncMemoizer()); + final memoizer = + _locationMemoizer.putIfAbsent(module, () => AsyncMemoizer()); - return await _locationMemoizer[module]!.runOnce(() async { + return await memoizer.runOnce(() async { if (_moduleToLocations.containsKey(module)) { return _moduleToLocations[module]!; }