From 367f4f2abdeb26326671ccbfa65de7068cd7ea0a Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Mon, 1 Aug 2022 12:27:23 -0700 Subject: [PATCH 01/10] Try repro mixed mode ddc bug --- fixtures/_testSound/lib/library.dart | 1 + webdev/test/e2e_test.dart | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/fixtures/_testSound/lib/library.dart b/fixtures/_testSound/lib/library.dart index 0689836de..cd0d20689 100644 --- a/fixtures/_testSound/lib/library.dart +++ b/fixtures/_testSound/lib/library.dart @@ -2,6 +2,7 @@ // 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 /// A library that we can import. library test_library; diff --git a/webdev/test/e2e_test.dart b/webdev/test/e2e_test.dart index e568895a5..96d4ae6bb 100644 --- a/webdev/test/e2e_test.dart +++ b/webdev/test/e2e_test.dart @@ -277,7 +277,7 @@ void main() { }); group('should work with ', () { - for (var soundNullSafety in [false, true]) { + for (var soundNullSafety in [/*false,*/ true]) { var nullSafetyOption = soundNullSafety ? 'sound' : 'unsound'; group('--null-safety=$nullSafetyOption', () { group('and --enable-expression-evaluation:', () { @@ -289,6 +289,7 @@ void main() { 'web:$openPort', '--enable-expression-evaluation', '--verbose', + '--null-safety=unsound', ]; var process = await runWebDev(args, workingDirectory: @@ -348,6 +349,7 @@ void main() { 'web:$openPort', '--enable-expression-evaluation', '--verbose', + '--null-safety=unsound', ]; var process = await runWebDev(args, workingDirectory: From 364e71c7b90af2a44263b853e1be6a966ce19bdd Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Mon, 1 Aug 2022 12:56:47 -0700 Subject: [PATCH 02/10] Added logging --- .../_testPackageSound/lib/src/test_part.dart | 2 +- .../_testPackageSound/lib/test_library.dart | 2 +- fixtures/_testSound/lib/deferred_library.dart | 1 + webdev/test/e2e_test.dart | 27 ++++++++++++++++++- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/fixtures/_testPackageSound/lib/src/test_part.dart b/fixtures/_testPackageSound/lib/src/test_part.dart index adef00b29..5297abd0d 100644 --- a/fixtures/_testPackageSound/lib/src/test_part.dart +++ b/fixtures/_testPackageSound/lib/src/test_part.dart @@ -1,7 +1,7 @@ // Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file // 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 part of '../test_library.dart'; int testPartLibraryValue = 4; diff --git a/fixtures/_testPackageSound/lib/test_library.dart b/fixtures/_testPackageSound/lib/test_library.dart index 087f25067..037e68791 100644 --- a/fixtures/_testPackageSound/lib/test_library.dart +++ b/fixtures/_testPackageSound/lib/test_library.dart @@ -1,7 +1,7 @@ // Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file // 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 part 'src/test_part.dart'; int testLibraryValue = 3; diff --git a/fixtures/_testSound/lib/deferred_library.dart b/fixtures/_testSound/lib/deferred_library.dart index e550ee822..f5f764411 100644 --- a/fixtures/_testSound/lib/deferred_library.dart +++ b/fixtures/_testSound/lib/deferred_library.dart @@ -2,6 +2,7 @@ // 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 /// A library that we can import. library test_deferred_library; diff --git a/webdev/test/e2e_test.dart b/webdev/test/e2e_test.dart index 96d4ae6bb..04bbd8f8b 100644 --- a/webdev/test/e2e_test.dart +++ b/webdev/test/e2e_test.dart @@ -8,6 +8,7 @@ import 'dart:io'; import 'package:io/io.dart'; +import 'package:logging/logging.dart'; import 'package:path/path.dart' as p; import 'package:pub_semver/pub_semver.dart' as semver; import 'package:test/test.dart'; @@ -15,6 +16,7 @@ import 'package:test_descriptor/test_descriptor.dart' as d; import 'package:test_process/test_process.dart'; import 'package:vm_service/vm_service.dart'; import 'package:vm_service/vm_service_io.dart'; +import 'package:webdev/src/logging.dart'; import 'package:webdev/src/pubspec.dart'; import 'package:webdev/src/serve/utils.dart'; import 'package:webdev/src/util.dart'; @@ -33,10 +35,19 @@ const _testItems = { 'main.unsound.ddc.js': true, }; + void _logWriter(Level level, String message, + {String error, String loggerName, String stackTrace}) { + //if (level >= Level.INFO) { + print('[$level] $loggerName: $message'); + //} + } + void main() { String exampleDirectory; String soundExampleDirectory; setUpAll(() async { + Logger.root.level = Level.ALL; + configureLogWriter(true, customLogWriter: _logWriter); exampleDirectory = p.absolute(p.join(p.current, '..', 'fixtures', '_webdevSmoke')); soundExampleDirectory = @@ -277,10 +288,20 @@ void main() { }); group('should work with ', () { + setUp(() async { + configureLogWriter(true, customLogWriter: _logWriter); + }); + for (var soundNullSafety in [/*false,*/ true]) { var nullSafetyOption = soundNullSafety ? 'sound' : 'unsound'; group('--null-safety=$nullSafetyOption', () { + setUp(() async { + configureLogWriter(true, customLogWriter: _logWriter); + }); group('and --enable-expression-evaluation:', () { + setUp(() async { + configureLogWriter(true, customLogWriter: _logWriter); + }); test('evaluateInFrame', () async { var openPort = await findUnusedPort(); // running daemon command that starts dwds without keyboard input @@ -296,6 +317,10 @@ void main() { soundNullSafety ? soundExampleDirectory : exampleDirectory); VmService vmService; + + process.stdoutStream().listen(Logger.root.info); + process.stderrStream().listen(Logger.root.warning); + try { // Wait for debug service Uri String wsUri; @@ -494,7 +519,7 @@ void main() { await process.shouldExit(); } }, timeout: const Timeout.factor(2)); - }); + }, skip: true); }); } }); From 5a1a45f6e05a1b89ff351438e2d7c3640e6f782d Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Mon, 1 Aug 2022 12:58:39 -0700 Subject: [PATCH 03/10] format --- webdev/test/e2e_test.dart | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/webdev/test/e2e_test.dart b/webdev/test/e2e_test.dart index 04bbd8f8b..6ee77b5b8 100644 --- a/webdev/test/e2e_test.dart +++ b/webdev/test/e2e_test.dart @@ -35,12 +35,12 @@ const _testItems = { 'main.unsound.ddc.js': true, }; - void _logWriter(Level level, String message, - {String error, String loggerName, String stackTrace}) { - //if (level >= Level.INFO) { - print('[$level] $loggerName: $message'); - //} - } +void _logWriter(Level level, String message, + {String error, String loggerName, String stackTrace}) { + //if (level >= Level.INFO) { + print('[$level] $loggerName: $message'); + //} +} void main() { String exampleDirectory; @@ -295,11 +295,11 @@ void main() { for (var soundNullSafety in [/*false,*/ true]) { var nullSafetyOption = soundNullSafety ? 'sound' : 'unsound'; group('--null-safety=$nullSafetyOption', () { - setUp(() async { + setUp(() async { configureLogWriter(true, customLogWriter: _logWriter); }); group('and --enable-expression-evaluation:', () { - setUp(() async { + setUp(() async { configureLogWriter(true, customLogWriter: _logWriter); }); test('evaluateInFrame', () async { @@ -317,7 +317,6 @@ void main() { soundNullSafety ? soundExampleDirectory : exampleDirectory); VmService vmService; - process.stdoutStream().listen(Logger.root.info); process.stderrStream().listen(Logger.root.warning); From 7eee3b9ee6f9ac83b3e1e4b569978b53286cef5e Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Mon, 15 Aug 2022 18:06:12 -0700 Subject: [PATCH 04/10] Make module uris match directory structure --- dwds/lib/asset_reader.dart | 2 +- dwds/lib/dwds.dart | 2 +- dwds/lib/src/debugging/debugger.dart | 15 +- dwds/lib/src/debugging/inspector.dart | 8 +- dwds/lib/src/debugging/location.dart | 47 +++++- dwds/lib/src/debugging/metadata/provider.dart | 21 ++- dwds/lib/src/debugging/modules.dart | 13 ++ .../src/loaders/frontend_server_require.dart | 34 ++++- dwds/lib/src/loaders/require.dart | 4 +- dwds/lib/src/readers/asset_reader.dart | 71 ++++++++++ .../readers/proxy_server_asset_reader.dart | 3 + .../src/services/chrome_proxy_service.dart | 4 +- dwds/lib/src/utilities/dart_uri.dart | 5 +- dwds/test/evaluate_common.dart | 4 +- dwds/test/fixtures/context.dart | 11 +- dwds/test/fixtures/fakes.dart | 5 +- .../lib/src/asset_server.dart | 134 +++++++++++------- frontend_server_common/lib/src/devfs.dart | 59 ++++---- .../lib/src/frontend_server_client.dart | 2 +- .../lib/src/resident_runner.dart | 13 +- frontend_server_common/lib/src/utilities.dart | 2 +- 21 files changed, 335 insertions(+), 124 deletions(-) diff --git a/dwds/lib/asset_reader.dart b/dwds/lib/asset_reader.dart index f7aeaf1c8..783375c68 100644 --- a/dwds/lib/asset_reader.dart +++ b/dwds/lib/asset_reader.dart @@ -2,4 +2,4 @@ // 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. -export 'src/readers/asset_reader.dart' show AssetReader, UrlEncoder; +export 'src/readers/asset_reader.dart' show AssetReader, UrlEncoder, PackageUriMapper; diff --git a/dwds/lib/dwds.dart b/dwds/lib/dwds.dart index 40f103467..ae02a4d41 100644 --- a/dwds/lib/dwds.dart +++ b/dwds/lib/dwds.dart @@ -17,7 +17,7 @@ export 'src/loaders/frontend_server_require.dart' export 'src/loaders/legacy.dart' show LegacyStrategy; export 'src/loaders/require.dart' show RequireStrategy; export 'src/loaders/strategy.dart' show LoadStrategy, ReloadConfiguration; -export 'src/readers/asset_reader.dart' show AssetReader, UrlEncoder; +export 'src/readers/asset_reader.dart' show AssetReader, UrlEncoder, PackageUriMapper; export 'src/readers/frontend_server_asset_reader.dart' show FrontendServerAssetReader; export 'src/readers/proxy_server_asset_reader.dart' show ProxyServerAssetReader; diff --git a/dwds/lib/src/debugging/debugger.dart b/dwds/lib/src/debugging/debugger.dart index 05540f7aa..39df3a146 100644 --- a/dwds/lib/src/debugging/debugger.dart +++ b/dwds/lib/src/debugging/debugger.dart @@ -506,8 +506,10 @@ class Debugger extends Domain { 'cannot find url for script ${location.scriptId}'); return null; } + logger.info('XXX url for frame $frame: $url'); final bestLocation = await _locations.locationForJs(url, line, column ?? 0); + logger.info('XXX bestLocation for frame $frame: $bestLocation'); if (bestLocation == null) return null; final script = @@ -546,7 +548,7 @@ class Debugger extends Domain { /// Handles pause events coming from the Chrome connection. Future _pauseHandler(DebuggerPausedEvent e) async { final isolate = inspector.isolate; - + logger.info('XXX received debugger paused event: $e'); Event event; final timestamp = DateTime.now().millisecondsSinceEpoch; final jsBreakpointIds = e.hitBreakpoints ?? []; @@ -651,6 +653,7 @@ class Debugger extends Domain { // DevTools is showing an overlay. Both cannot be shown at the same time. // _showPausedOverlay(); isolate.pauseEvent = event; + logger.info('XXX send pause notification: $event: ${event.topFrame}'); _streamNotify('Debug', event); } @@ -794,10 +797,12 @@ class _Breakpoints extends Domain { Future _createBreakpoint( String id, String scriptId, int line, int column) async { final dartScript = inspector.scriptWithId(scriptId); + _logger.info('XXX dart script for $id: $dartScript'); final dartScriptUri = dartScript?.uri; Location? location; if (dartScriptUri != null) { final dartUri = DartUri(dartScriptUri, root); + _logger.info('XXX looking for dart location for ${dartScript?.uri}($dartUri):$line:$column'); location = await locations.locationForDart(dartUri, line, column); } // TODO: Handle cases where a breakpoint can't be set exactly at that line. @@ -808,8 +813,8 @@ class _Breakpoints extends Domain { throw RPCError( 'addBreakpoint', 102, - 'The VM is unable to add a breakpoint ' - 'at the specified line or function'); + 'The VM is unable to add a breakpoint $id ' + 'at the specified line or function: ($scriptId:$line:$column): cannot find Dart location.'); } try { @@ -822,8 +827,8 @@ class _Breakpoints extends Domain { throw RPCError( 'addBreakpoint', 102, - 'The VM is unable to add a breakpoint ' - 'at the specified line or function'); + 'The VM is unable to add a breakpoint $id ' + 'at the specified line or function: ($scriptId:$line:$column): cannot set JS breakpoint at $location'); } _note(jsId: jsBreakpointId, bp: dartBreakpoint); return dartBreakpoint; diff --git a/dwds/lib/src/debugging/inspector.dart b/dwds/lib/src/debugging/inspector.dart index 3b1e22bbc..7c112d5c7 100644 --- a/dwds/lib/src/debugging/inspector.dart +++ b/dwds/lib/src/debugging/inspector.dart @@ -571,9 +571,11 @@ class AppInspector implements AppInspectorInterface { /// Look up the script by id in an isolate. @override - ScriptRef? scriptWithId(String? scriptId) => - scriptId == null ? null : _scriptRefsById[scriptId]; - + ScriptRef? scriptWithId(String? scriptId) { + final ret = scriptId == null ? null : _scriptRefsById[scriptId]; + _logger.info('XXX scripts: ${_scriptRefsById.length}'); + return ret; + } /// Runs an eval on the page to compute all existing registered extensions. Future> _getExtensionRpcs() async { final expression = diff --git a/dwds/lib/src/debugging/location.dart b/dwds/lib/src/debugging/location.dart index 5bf69980c..b11aecac2 100644 --- a/dwds/lib/src/debugging/location.dart +++ b/dwds/lib/src/debugging/location.dart @@ -162,8 +162,18 @@ class Locations { /// Returns all [Location] data for a provided JS server path. Future> locationsForUrl(String url) async { + //final uri = Uri.parse(url); + //final segments = uri.pathSegments.first == '/'? uri.pathSegments.skip(1): uri.pathSegments; + //final serverPath = p.joinAll(segments); + + final dartUri = DartUri(url, _root); + final serverPath = dartUri.serverPath; + _logger.info('XXX looking for locations for js $url(server path $serverPath)'); + final module = await globalLoadStrategy.moduleForServerPath( - _entrypoint, Uri.parse(url).path); + _entrypoint, serverPath); + + _logger.info('XXX module for url: $url($serverPath): $module'); final cache = _moduleToLocations[module]; if (cache != null) return cache; if (module != null) { @@ -177,7 +187,10 @@ class Locations { /// The [line] number is 1-based. Future locationForDart(DartUri uri, int line, int column) async { final locations = await locationsForDart(uri.serverPath); - return _bestDartLocation(locations, line, column); + _logger.fine('XXX locations for dart $uri:$line:$column: $locations'); + final ret = _bestDartLocation(locations, line, column); + _logger.info('XXX Best location for dart ${uri.serverPath}:$line:$column: $ret'); + return ret; } /// Find the [Location] for the given JS source position. @@ -185,7 +198,10 @@ class Locations { /// The [line] number is 0-based. Future locationForJs(String url, int line, int? column) async { final locations = await locationsForUrl(url); - return _bestJsLocation(locations, line, column); + _logger.fine('XXX locations for js $url:$line:$column: $locations'); + final ret = _bestJsLocation(locations, line, column); + _logger.info('XXX Best location for js $url:$line:$column: $ret'); + return ret; } /// Find closest existing Dart location for the line and column. @@ -287,6 +303,11 @@ class Locations { final sourceMapContents = await _assetReader.sourceMapContents(sourceMapPath); final scriptLocation = p.url.dirname('/${relativizePath(modulePath)}'); + + _logger.info('XXX modulePath: $modulePath'); + _logger.info('XXX sourceMapPath: $sourceMapPath'); + _logger.info('XXX sourceMapContents: ${sourceMapContents != null}'); + if (sourceMapContents == null) return result; // This happens to be a [SingleMapping] today in DDC. final mapping = parse(sourceMapContents); @@ -301,9 +322,26 @@ class Locations { // This works on Windows because path treats both / and \ as separators. // It will fail if the path has both separators in it. final relativeSegments = p.split(mapping.urls[index]); + final path = p.url.normalize( p.url.joinAll([scriptLocation, ...relativeSegments])); + + // detect reference to another package: + // scriptLocation: '/packages/home/pages' + // relativeSegments: '../../../account_presentation/lib/controller/sign_in_controller.dart + //if (scriptLocation.startsWith('/packages/') && !path.startsWith('/packages/')) { + // path = "/packages${path.replaceAll('/lib/', '/')}"; + //} + + //if (scriptLocation.startsWith('/packages/') && relativeSegments.contains('lib') && relativeSegments.first == '..') { + // relativeSegments = relativeSegments.skip(1).where((e) => e != 'lib').toList(); + //} final dartUri = DartUri(path, _root); + _logger.info('XXX adding location for $path($dartUri)'); + //if (path.contains('sign_in_controller')) { + // _logger.info('XXX script location: $scriptLocation, relative segments: $relativeSegments'); + // _logger.info('XXX add location $modulePath:$lineEntry:$entry at $path($dartUri)'); + //} result.add(Location.from( modulePath, lineEntry, @@ -319,6 +357,9 @@ class Locations { location.dartLocation.uri.serverPath, () => {}) .add(location); } + if (module.contains('welcome_page.dart')) { + _logger.info('XXX locations for module $module computed: $result'); + } return _moduleToLocations[module] = result; }); } diff --git a/dwds/lib/src/debugging/metadata/provider.dart b/dwds/lib/src/debugging/metadata/provider.dart index ae4696e5b..214675a22 100644 --- a/dwds/lib/src/debugging/metadata/provider.dart +++ b/dwds/lib/src/debugging/metadata/provider.dart @@ -6,6 +6,7 @@ import 'dart:async'; import 'dart:convert'; import 'package:async/async.dart'; +import 'package:dwds/src/utilities/dart_uri.dart'; import 'package:logging/logging.dart'; import 'package:path/path.dart' as p; @@ -200,8 +201,8 @@ class MetadataProvider { _addMetadata(metadata); hasUnsoundNullSafety &= !metadata.soundNullSafety; hasSoundNullSafety &= metadata.soundNullSafety; - _logger - .fine('Loaded debug metadata for module: ${metadata.name}'); + //_logger + // .fine('Loaded debug metadata for module: ${metadata.name}'); } catch (e) { _logger.warning('Failed to read metadata: $e'); rethrow; @@ -219,15 +220,25 @@ class MetadataProvider { } void _addMetadata(ModuleMetadata metadata) { - _moduleToSourceMap[metadata.name] = metadata.sourceMapUri; - _modulePathToModule[metadata.moduleUri] = metadata.name; - _moduleToModulePath[metadata.name] = metadata.moduleUri; + //final modulePath = DartUri(metadata.moduleUri).serverPath; + //final sourceMapPath = DartUri(metadata.sourceMapUri).serverPath; + final modulePath = stripLeadingSlashes(metadata.moduleUri); + final sourceMapPath = stripLeadingSlashes(metadata.sourceMapUri); + + _logger.info('XXX Adding module: ${metadata.name} with url: ${metadata.moduleUri} and server path $modulePath'); + + _moduleToSourceMap[metadata.name] = sourceMapPath; + _modulePathToModule[modulePath] = metadata.name; + _moduleToModulePath[metadata.name] = modulePath; for (var library in metadata.libraries.values) { if (library.importUri.startsWith('file:/')) { throw AbsoluteImportUriException(library.importUri); } _libraries.add(library.importUri); + if (library.importUri.contains('sign_in_controller')) { + _logger.info('XXX loading library info for ${library.importUri}'); + } _scripts[library.importUri] = []; _scriptToModule[library.importUri] = metadata.name; diff --git a/dwds/lib/src/debugging/modules.dart b/dwds/lib/src/debugging/modules.dart index 527a458c9..2b7d0ec84 100644 --- a/dwds/lib/src/debugging/modules.dart +++ b/dwds/lib/src/debugging/modules.dart @@ -43,6 +43,13 @@ class Modules { /// Returns the containing module for the provided Dart server path. Future moduleForSource(String serverPath) async { await _moduleMemoizer.runOnce(_initializeMapping); + final module = _sourceToModule[serverPath]; + + if (serverPath.contains('sign_in_controller') && module == null) { + _logger.info('Module for source: $serverPath: $module'); + final line = _sourceToModule.entries.map((p) => '${p.key}: ${p.value}').join('\n\t,'); + _logger.info('all modules: $line'); + } return _sourceToModule[serverPath]; } @@ -78,6 +85,9 @@ class Modules { if (scriptToModule.containsKey(library)) { final module = scriptToModule[library]!; + if (libraryServerPath.contains('sign_in_controller')) { + _logger.info('XXX saving module $module for library $library($libraryServerPath)'); + } _sourceToModule[libraryServerPath] = module; _sourceToLibrary[libraryServerPath] = Uri.parse(library); _libraryToModule[library] = module; @@ -87,6 +97,9 @@ class Modules { ? script : DartUri(script, _root).serverPath; + if (scriptServerPath.contains('sign_in_controller')) { + _logger.info('XXX 2 saving module $module for source $scriptServerPath'); + } _sourceToModule[scriptServerPath] = module; _sourceToLibrary[scriptServerPath] = Uri.parse(library); } diff --git a/dwds/lib/src/loaders/frontend_server_require.dart b/dwds/lib/src/loaders/frontend_server_require.dart index 4a63ea026..58ef25070 100644 --- a/dwds/lib/src/loaders/frontend_server_require.dart +++ b/dwds/lib/src/loaders/frontend_server_require.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:logging/logging.dart'; import 'package:path/path.dart' as p; import '../debugging/metadata/provider.dart'; @@ -12,8 +13,10 @@ import 'require.dart'; /// Provides a [RequireStrategy] suitable for use with Frontend Server. class FrontendServerRequireStrategyProvider { + final _logger = Logger('FrontendServerRequireStrategyProvider'); final ReloadConfiguration _configuration; final AssetReader _assetReader; + final PackageUriMapper _packageUriMapper; final Future> Function() _digestsProvider; final String _basePath; @@ -29,16 +32,19 @@ class FrontendServerRequireStrategyProvider { _assetReader, ); - FrontendServerRequireStrategyProvider(this._configuration, this._assetReader, - this._digestsProvider, this._basePath); + FrontendServerRequireStrategyProvider(this._configuration, this._assetReader, this._packageUriMapper, + this._digestsProvider, this._basePath,); RequireStrategy get strategy => _requireStrategy; String _removeBasePath(String path) { if (_basePath.isEmpty) return path; // If path is a server path it might start with a '/'. - final base = path.startsWith('/') ? '/$_basePath' : _basePath; - return path.startsWith(base) ? path.substring(base.length) : path; + // final base = path.startsWith('/') ? '/$_basePath/' : _basePath; + + final stripped = relativizePath(path); + return relativizePath(stripped.substring(_basePath.length)); + //return path.startsWith(base) ? path.substring(base.length) : path; } String _addBasePath(String serverPath) => _basePath.isEmpty @@ -54,6 +60,12 @@ class FrontendServerRequireStrategyProvider { MetadataProvider metadataProvider, String serverPath) async { final modulePathToModule = await metadataProvider.modulePathToModule; final relativeServerPath = _removeBasePath(serverPath); + modulePathToModule.forEach((key, value) { + if (key.contains(relativeServerPath) || serverPath.contains(key)) { + _logger.info('XXX inexact match: serverPath: $serverPath($relativeServerPath), key: $key'); + } + }); + _logger.info('XXX exact match: serverPath: $serverPath, mpd: ${modulePathToModule[relativeServerPath]}'); return modulePathToModule[relativeServerPath]; } @@ -65,9 +77,16 @@ class FrontendServerRequireStrategyProvider { MetadataProvider metadataProvider, String module) async => _addBasePath((await metadataProvider.moduleToSourceMap)[module] ?? ''); - String? _serverPathForAppUri(String appUri) { - if (appUri.startsWith('org-dartlang-app:')) { - return _addBasePath(Uri.parse(appUri).path); + String? _serverPathForAppUri(String appUrl) { + final appUri = Uri.parse(appUrl); + if (appUri.isScheme('org-dartlang-app')) { + return _addBasePath(appUri.path); + } + if (appUri.isScheme('package')) { + //final resolved = _assetReader.resolvePackageUrl(appUri); + final resolved = _packageUriMapper.packageUriToServerPath(appUri); + //_logger.info('XXX: server path for $appUrl: $resolved'); + return resolved; } return null; } @@ -87,3 +106,4 @@ class FrontendServerRequireStrategyProvider { return result; } } + diff --git a/dwds/lib/src/loaders/require.dart b/dwds/lib/src/loaders/require.dart index b9ba9b6fd..51952515d 100644 --- a/dwds/lib/src/loaders/require.dart +++ b/dwds/lib/src/loaders/require.dart @@ -23,8 +23,8 @@ String basePathForServerUri(String url) { return base = base.startsWith('/') ? base.substring(1) : base; } -String relativizePath(String path) => - path.startsWith('/') ? path.substring(1) : path; +String relativizePath(String path) => stripLeadingSlashes(path); + // path.startsWith('/') ? path.substring(1) : path; String removeJsExtension(String path) => path.endsWith('.js') ? p.withoutExtension(path) : path; diff --git a/dwds/lib/src/readers/asset_reader.dart b/dwds/lib/src/readers/asset_reader.dart index 39ef444ed..033eedcde 100644 --- a/dwds/lib/src/readers/asset_reader.dart +++ b/dwds/lib/src/readers/asset_reader.dart @@ -2,6 +2,10 @@ // 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. +import 'package:file/file.dart'; +import 'package:logging/logging.dart'; +import 'package:package_config/package_config.dart'; + typedef UrlEncoder = Future Function(String url); /// A reader for Dart sources and related source maps. @@ -21,3 +25,70 @@ abstract class AssetReader { /// Closes connections Future close(); } + +class PackageUriMapper { + final _logger = Logger('PackageUriMapper'); + final PackageConfig packageConfig; + + static Future create(FileSystem fileSystem, Uri packageConfigFile) async { + final packageConfig = await loadPackageConfig(fileSystem.file(packageConfigFile)); + return PackageUriMapper(packageConfig); + } + + PackageUriMapper(this.packageConfig); + + // TODO: use package directories instead of package names + // Note: needs to be the same as `urlForComponentUri` in javascript_bundle.dart in SDK + String? packageUriToServerPath(Uri packageUri) { + if (packageUri.isScheme('package')) { + final Uri? resolvedUri = packageConfig.resolve(packageUri); + final Package? package = packageConfig.packageOf(resolvedUri!); + final Uri root = package!.root; + final String relativeUrl = resolvedUri.toString().replaceFirst('$root', ''); + final relativeRoot = _getRelativeRoot(root); + _logger.info('XXX package: ${package.name} ($relativeRoot)}'); + final String ret = 'packages/$relativeRoot/$relativeUrl'; + return ret; + } + _logger.severe('Expected package uri, but found $packageUri'); + return null; + } + + // Needs to match the code above + Uri? serverPathToResolvedUri(String serverPath) { + serverPath = stripLeadingSlashes(serverPath); + final segments = serverPath.split('/'); + if (segments.first == 'packages') { + final String relativeRoot = segments.skip(1).first; + _logger.info('XXX package root: $relativeRoot'); + + final String relativeUrl = segments.skip(2).join('/'); + _logger.info('XXX relativeUrl: $relativeUrl'); + + final Package package = packageConfig.packages.firstWhere((Package p) => _getRelativeRoot(p.root) == relativeRoot); + _logger.info('XXX package: ${package.name}($relativeRoot)'); + + final Uri resolvedUri = package.root.resolve(relativeUrl); + _logger.info('XXX Server path: $serverPath -> $resolvedUri'); + + return resolvedUri; + } + return null; + } + + String? _getRelativeRoot(Uri root) { + final segments = root.pathSegments; + if (segments.isNotEmpty && segments.last.isEmpty) { + final subset = segments.getRange(0, segments.length-1); + return subset.isNotEmpty? subset.last: null; + } + return segments.isNotEmpty? segments.last: null; + } +} + +String stripLeadingSlashes(String path) { + while (path.startsWith('/')) { + path = path.substring(1); + } + return path; +} \ No newline at end of file diff --git a/dwds/lib/src/readers/proxy_server_asset_reader.dart b/dwds/lib/src/readers/proxy_server_asset_reader.dart index 960809eca..08b43d00c 100644 --- a/dwds/lib/src/readers/proxy_server_asset_reader.dart +++ b/dwds/lib/src/readers/proxy_server_asset_reader.dart @@ -69,6 +69,9 @@ class ProxyServerAssetReader implements AssetReader { Future metadataContents(String serverPath) => _readResource(serverPath); + @override + String? resolvePackageUrl(Uri packageUri) => null; + @override Future close() async => _client.close(); } diff --git a/dwds/lib/src/services/chrome_proxy_service.dart b/dwds/lib/src/services/chrome_proxy_service.dart index 2d3a89e1f..1bfd4488f 100644 --- a/dwds/lib/src/services/chrome_proxy_service.dart +++ b/dwds/lib/src/services/chrome_proxy_service.dart @@ -373,7 +373,9 @@ class ChromeProxyService implements VmServiceInterface { 'at the specified line or function: $scriptUri:$line:$column: ' 'cannot find script ID for ${dartUri.serverPath}'); } - return (await debuggerFuture).addBreakpoint(scriptId, line, column: column); + final bp = await (await debuggerFuture).addBreakpoint(scriptId, line, column: column); + _logger.info('XXX added breakpoint: $bp'); + return bp; } @override diff --git a/dwds/lib/src/utilities/dart_uri.dart b/dwds/lib/src/utilities/dart_uri.dart index 4b8b4af79..f5c16d7a7 100644 --- a/dwds/lib/src/utilities/dart_uri.dart +++ b/dwds/lib/src/utilities/dart_uri.dart @@ -31,6 +31,9 @@ class DartUri { factory DartUri(String uri, [String? root]) { final serverPath = globalLoadStrategy.serverPathForAppUri(uri); if (serverPath != null) { + if (serverPath.startsWith('packages/')) { + return DartUri._fromRelativePath(serverPath, root: root); + } return DartUri._(serverPath); } // TODO(annagrin): Support creating DartUris from `dart:` uris. @@ -41,7 +44,7 @@ class DartUri { if (uri.startsWith('file:')) { return DartUri._fromFileUri(uri, root: root); } - if (uri.startsWith('/packages/')) { + if (uri.startsWith('packages/')) { return DartUri._fromRelativePath(uri, root: root); } if (uri.startsWith('/')) { diff --git a/dwds/test/evaluate_common.dart b/dwds/test/evaluate_common.dart index 4c8eb17de..3df74292f 100644 --- a/dwds/test/evaluate_common.dart +++ b/dwds/test/evaluate_common.dart @@ -160,7 +160,7 @@ void testAll({ contains('Using scope for expression evaluation ' 'in frame is not supported'))); }); - }); + }/*, solo: true, retry: 0, timeout: Timeout.none*/); test('local', () async { await onBreakPoint(isolate.id, mainScript, 'printLocal', () async { @@ -409,7 +409,7 @@ void testAll({ isA().having( (instance) => instance.valueAsString, 'valueAsString', '23')); }); - }); + }/*, solo: true, retry: 0, timeout: Timeout.none*/); test('evaluate expression in a class constructor in a library', () async { await onBreakPoint( diff --git a/dwds/test/fixtures/context.dart b/dwds/test/fixtures/context.dart index 09cfa2ec0..24a2fd8c2 100644 --- a/dwds/test/fixtures/context.dart +++ b/dwds/test/fixtures/context.dart @@ -23,10 +23,12 @@ import 'package:dwds/src/services/expression_compiler_service.dart'; import 'package:dwds/src/utilities/dart_uri.dart'; import 'package:dwds/src/utilities/sdk_configuration.dart'; import 'package:dwds/src/utilities/shared.dart'; +import 'package:file/local.dart'; import 'package:frontend_server_common/src/resident_runner.dart'; import 'package:http/http.dart'; import 'package:http/io_client.dart'; import 'package:logging/logging.dart' as logging; +import 'package:package_config/package_config.dart'; import 'package:path/path.dart' as p; import 'package:shelf/shelf.dart'; import 'package:shelf_proxy/shelf_proxy.dart'; @@ -269,11 +271,14 @@ class TestContext { final entry = p.toUri(_entryFile.path .substring(_projectDirectory.toFilePath().length + 1)); + final fileSystem = LocalFileSystem(); + final packageUriMapper = await PackageUriMapper.create(fileSystem, _packageConfigFile); + _webRunner = ResidentWebRunner( entry, urlEncoder, _projectDirectory, - _packageConfigFile, + packageUriMapper, [_projectDirectory], 'org-dartlang-app', outputDir.path, @@ -282,7 +287,7 @@ class TestContext { ); final assetServerPort = await findUnusedPort(); - await webRunner.run( + await webRunner.run(fileSystem, hostname, assetServerPort, p.join(pathToServe, path)); if (enableExpressionEvaluation) { @@ -294,7 +299,7 @@ class TestContext { assetHandler = webRunner.devFS.assetServer.handleRequest; requireStrategy = FrontendServerRequireStrategyProvider( - reloadConfiguration, assetReader, () async => {}, basePath) + reloadConfiguration, assetReader, packageUriMapper, () async => {}, basePath) .strategy; buildResults = const Stream.empty(); diff --git a/dwds/test/fixtures/fakes.dart b/dwds/test/fixtures/fakes.dart index 0ebd84772..f0a59b8be 100644 --- a/dwds/test/fixtures/fakes.dart +++ b/dwds/test/fixtures/fakes.dart @@ -316,7 +316,7 @@ class FakeStrategy implements LoadStrategy { ''; @override - String serverPathForAppUri(String appUri) => ''; + String? serverPathForAppUri(String appUri) => ''; @override MetadataProvider metadataProviderFor(String entrypoint) => @@ -356,6 +356,9 @@ class FakeAssetReader implements AssetReader { Future sourceMapContents(String serverPath) { return _throwUnimplementedOrReturnContents(_sourceMap); } + + //@override + //String? resolvePackageUrl(Uri packageUri) => null; @override Future close() async {} diff --git a/frontend_server_common/lib/src/asset_server.dart b/frontend_server_common/lib/src/asset_server.dart index 7b6753572..cabf3d208 100644 --- a/frontend_server_common/lib/src/asset_server.dart +++ b/frontend_server_common/lib/src/asset_server.dart @@ -13,14 +13,13 @@ import 'package:dwds/asset_reader.dart'; import 'package:file/file.dart'; import 'package:logging/logging.dart'; import 'package:mime/mime.dart' as mime; -import 'package:package_config/package_config.dart'; // ignore: deprecated_member_use -import 'package:path/path.dart' as p; +//import 'package:path/path.dart' as p; import 'package:shelf/shelf.dart' as shelf; import 'utilities.dart'; class TestAssetServer implements AssetReader { - final String basePath; + late final String basePath; final String index; final _logger = Logger('TestAssetServer'); @@ -34,16 +33,18 @@ class TestAssetServer implements AssetReader { final Map _sourceMaps = {}; final Map _metadata = {}; late String _mergedMetadata; - final PackageConfig _packageConfig; + final PackageUriMapper _packageUriMapper; final InternetAddress internetAddress; TestAssetServer( this.index, this._httpServer, - this._packageConfig, + this._packageUriMapper, this.internetAddress, this._fileSystem, - ) : basePath = _parseBasePathFromIndexHtml(index); + ) { + basePath = _parseBasePathFromIndexHtml(index); + } bool hasFile(String path) => _files.containsKey(path); Uint8List getFile(String path) => _files[path]!; @@ -64,17 +65,27 @@ class TestAssetServer implements AssetReader { String hostname, int port, UrlEncoder? urlTunneler, - PackageConfig packageConfig, + PackageUriMapper packageUriMapper, ) async { var address = (await InternetAddress.lookup(hostname)).first; var httpServer = await HttpServer.bind(address, port); var server = - TestAssetServer(index, httpServer, packageConfig, address, fileSystem); + TestAssetServer(index, httpServer, packageUriMapper, address, fileSystem); return server; } // handle requests for JavaScript source, dart sources maps, or asset files. Future handleRequest(shelf.Request request) async { + if (request.method != 'GET') { + // Assets are served via GET only. + return shelf.Response.notFound(''); + } + + final requestPath = _stripBasePath(request.url.path, basePath); + if (requestPath == null) { + return shelf.Response.notFound(''); + } + var headers = {}; if (request.url.path.endsWith('index.html')) { @@ -89,14 +100,14 @@ class TestAssetServer implements AssetReader { } // NOTE: shelf removes leading `/` for some reason. - var requestPath = request.url.path; - requestPath = requestPath.startsWith('/') ? requestPath : '/$requestPath'; + //var requestPath = request.url.path; + //requestPath = requestPath.startsWith('/') ? requestPath : '/$requestPath'; - if (!request.url.path.endsWith('/require.js') && - !request.url.path.endsWith('/dart_stack_trace_mapper.js')) { - requestPath = _stripBasePath(requestPath, basePath) ?? requestPath; + //if (!request.url.path.endsWith('require.js') && + // !request.url.path.endsWith('dart_stack_trace_mapper.js')) { + // requestPath = _stripBasePath(requestPath, basePath) ?? requestPath; - requestPath = requestPath.startsWith('/') ? requestPath : '/$requestPath'; + // requestPath = requestPath.startsWith('/') ? requestPath : '/$requestPath'; // If this is a JavaScript file, it must be in the in-memory cache. // Attempt to look up the file by URI. @@ -114,7 +125,15 @@ class TestAssetServer implements AssetReader { headers[HttpHeaders.contentTypeHeader] = 'application/json'; return shelf.Response.ok(bytes, headers: headers); } - } + // If this is a metadata file, then it might be in the in-memory cache. + // Attempt to lookup the file by URI. + if (hasMetadata(requestPath)) { + final List bytes = getMetadata(requestPath); + headers[HttpHeaders.contentLengthHeader] = bytes.length.toString(); + headers[HttpHeaders.contentTypeHeader] = 'application/json'; + return shelf.Response.ok(bytes, headers: headers); + } + //} var file = _resolveDartFile(requestPath); if (!file.existsSync()) { return shelf.Response.notFound(''); @@ -183,7 +202,10 @@ class TestAssetServer implements AssetReader { codeStart, codeEnd - codeStart, ); - _files[filePath] = byteView; + + final fileName = + filePath.startsWith('/') ? filePath.substring(1) : filePath; + _files[fileName] = byteView; var sourcemapStart = sourcemapOffsets[0]; var sourcemapEnd = sourcemapOffsets[1]; @@ -196,7 +218,7 @@ class TestAssetServer implements AssetReader { sourcemapStart, sourcemapEnd - sourcemapStart, ); - _sourceMaps['$filePath.map'] = sourcemapView; + _sourceMaps['$fileName.map'] = sourcemapView; var metadataStart = metadataOffsets[0]; var metadataEnd = metadataOffsets[1]; @@ -209,9 +231,9 @@ class TestAssetServer implements AssetReader { metadataStart, metadataEnd - metadataStart, ); - _metadata['$filePath.metadata'] = metadataView; + _metadata['$fileName.metadata'] = metadataView; - modules.add(filePath); + modules.add(fileName); } _mergedMetadata = _metadata.values @@ -226,25 +248,32 @@ class TestAssetServer implements AssetReader { // If this is a dart file, it must be on the local file system and is // likely coming from a source map request. The tool doesn't currently // consider the case of Dart files as assets. - var dartFile = + /*var dartFile = _fileSystem.file(_fileSystem.currentDirectory.uri.resolve(path)); if (dartFile.existsSync()) { return dartFile; - } + }*/ - var segments = p.split(path); - if (segments.first.isEmpty) { - segments.removeAt(0); + //final relativePath = _stripLeadingSlashes(path); + final dartFile = + _fileSystem.file(_fileSystem.currentDirectory.uri.resolve(path)); + if (dartFile.existsSync()) { + return dartFile; } + final segments = path.split('/'); + // The file might have been a package file which is signaled by a // `/packages//` request. if (segments.first == 'packages') { - var packageFile = _fileSystem.file(_packageConfig - .resolve(Uri(scheme: 'package', pathSegments: segments.skip(1)))); + //var packageFile = _fileSystem.file(_packageConfig + // .resolve(Uri(scheme: 'package', pathSegments: segments.skip(1)))); + var packageFile = _fileSystem.file(_packageUriMapper.serverPathToResolvedUri(path)); if (packageFile.existsSync()) { + _logger.info('XXX Found: $path -> $packageFile'); return packageFile; } + _logger.severe('Package file not found: $path ($packageFile)'); } // Otherwise it must be a Dart SDK source. @@ -271,9 +300,8 @@ class TestAssetServer implements AssetReader { Future sourceMapContents(String serverPath) async { final stripped = _stripBasePath(serverPath, basePath); if (stripped != null) { - var path = '/$stripped'; - if (hasSourceMap(path)) { - return utf8.decode(getSourceMap(path)); + if (hasSourceMap(stripped)) { + return utf8.decode(getSourceMap(stripped)); } } _logger.severe('Source map not found: $serverPath'); @@ -287,14 +315,36 @@ class TestAssetServer implements AssetReader { if (stripped.endsWith('.ddc_merged_metadata')) { return _mergedMetadata; } - var path = '/$stripped'; - if (hasMetadata(path)) { - return utf8.decode(getMetadata(path)); + if (hasMetadata(stripped)) { + return utf8.decode(getMetadata(stripped)); } } _logger.severe('Metadata not found: $serverPath'); return null; } + + String _parseBasePathFromIndexHtml(String index) { + final file = _fileSystem.file(index); + if (!file.existsSync()) { + throw StateError('Index file $index is not found'); + } + final contents = file.readAsStringSync(); + final matches = RegExp(r'').allMatches(contents); + if (matches.isEmpty) return ''; + return matches.first.group(1) ?? ''; + } + + String? _stripBasePath(String path, String basePath) { + path = _stripLeadingSlashes(path); + if (path.startsWith(basePath)) { + path = path.substring(basePath.length); + } else { + // The given path isn't under base path, return null to indicate that. + _logger.severe('Path is not under $basePath: $path'); + return null; + } + return _stripLeadingSlashes(path); + } } /// Given a data structure which is a Map of String to dynamic values, return @@ -311,24 +361,4 @@ String _stripLeadingSlashes(String path) { return path; } -String? _stripBasePath(String path, String basePath) { - path = _stripLeadingSlashes(path); - if (path.startsWith(basePath)) { - path = path.substring(basePath.length); - } else { - // The given path isn't under base path, return null to indicate that. - return null; - } - return _stripLeadingSlashes(path); -} -String _parseBasePathFromIndexHtml(String index) { - final file = fileSystem.file(index); - if (!file.existsSync()) { - throw StateError('Index file $index is not found'); - } - final contents = file.readAsStringSync(); - final matches = RegExp(r'').allMatches(contents); - if (matches.isEmpty) return ''; - return matches.first.group(1) ?? ''; -} diff --git a/frontend_server_common/lib/src/devfs.dart b/frontend_server_common/lib/src/devfs.dart index d11e1f970..aecf43c18 100644 --- a/frontend_server_common/lib/src/devfs.dart +++ b/frontend_server_common/lib/src/devfs.dart @@ -8,7 +8,6 @@ import 'dart:io'; import 'package:dwds/asset_reader.dart'; import 'package:file/file.dart'; -import 'package:package_config/package_config.dart'; import 'package:path/path.dart' as p; import 'asset_server.dart'; @@ -24,7 +23,7 @@ class WebDevFS { required this.hostname, required this.port, required this.projectDirectory, - required this.packageConfigFile, + required this.packageUriMapper, required this.index, required this.soundNullSafety, this.urlTunneler, @@ -35,23 +34,19 @@ class WebDevFS { final String hostname; final int port; final Uri projectDirectory; - final Uri packageConfigFile; + final PackageUriMapper packageUriMapper; final String index; final UrlEncoder? urlTunneler; final bool soundNullSafety; late final Directory _savedCurrentDirectory; - late final PackageConfig _packageConfig; Future create() async { _savedCurrentDirectory = fileSystem.currentDirectory; fileSystem.currentDirectory = projectDirectory.toFilePath(); - _packageConfig = await loadPackageConfigUri(packageConfigFile, - loader: (Uri uri) => fileSystem.file(uri).readAsBytes()); - assetServer = await TestAssetServer.start( - fileSystem, index, hostname, port, urlTunneler, _packageConfig); + fileSystem, index, hostname, port, urlTunneler, packageUriMapper); return Uri.parse('http://$hostname:$port'); } @@ -70,34 +65,39 @@ class WebDevFS { final outputDirectoryPath = fileSystem.file(mainPath).parent.path; final entryPoint = mainUri.toString(); + assetServer.writeFile(entryPoint, fileSystem.file(mainPath).readAsStringSync()); + assetServer.writeFile('require.js', requireJS.readAsStringSync()); + assetServer.writeFile( + 'stack_trace_mapper.js', stackTraceMapper.readAsStringSync()); assetServer.writeFile( - '/main.dart.js', + 'main.dart.js', generateBootstrapScript( - requireUrl: _filePathToUriFragment(requireJS.path), - mapperUrl: _filePathToUriFragment(stackTraceMapper.path), + requireUrl: 'require.js', //_filePathToUriFragment(requireJS.path), + mapperUrl: 'stack_trace_mapper.js', //_filePathToUriFragment(stackTraceMapper.path), entrypoint: entryPoint, ), ); assetServer.writeFile( - '/main_module.bootstrap.js', + 'main_module.bootstrap.js', generateMainModule( entrypoint: entryPoint, ), ); - assetServer.writeFile('/main_module.digests', '{}'); + assetServer.writeFile('main_module.digests', '{}'); + var sdk = soundNullSafety ? dartSdkSound : dartSdk; var sdkSourceMap = soundNullSafety ? dartSdkSourcemapSound : dartSdkSourcemap; - assetServer.writeFile('/dart_sdk.js', sdk.readAsStringSync()); - assetServer.writeFile('/dart_sdk.js.map', sdkSourceMap.readAsStringSync()); - + assetServer.writeFile('dart_sdk.js', sdk.readAsStringSync()); + assetServer.writeFile('dart_sdk.js.map', sdkSourceMap.readAsStringSync()); + generator.reset(); var compilerOutput = await generator.recompile( Uri.parse('org-dartlang-app:///$mainUri'), invalidatedFiles, outputPath: p.join(dillOutputPath, 'app.dill'), - packageConfig: _packageConfig, + packageConfig: packageUriMapper.packageConfig, ); if (compilerOutput == null || compilerOutput.errorCount > 0) { return UpdateFSReport(success: false); @@ -170,6 +170,19 @@ class WebDevFS { 'web', 'dart_stack_trace_mapper.js', )); +/* + String _filePathToUriFragment(String path, ) { + if (Platform.isWindows) { + var startWithSlash = path.startsWith('/'); + var partial = + fileSystem.path.split(path).skip(startWithSlash ? 2 : 1).join('/'); + if (partial.startsWith('/')) { + return partial; + } + return '/$partial'; + } + return path; + }*/ } class UpdateFSReport { @@ -196,15 +209,3 @@ class UpdateFSReport { List? invalidatedModules; } -String _filePathToUriFragment(String path) { - if (Platform.isWindows) { - var startWithSlash = path.startsWith('/'); - var partial = - fileSystem.path.split(path).skip(startWithSlash ? 2 : 1).join('/'); - if (partial.startsWith('/')) { - return partial; - } - return '/$partial'; - } - return path; -} diff --git a/frontend_server_common/lib/src/frontend_server_client.dart b/frontend_server_common/lib/src/frontend_server_client.dart index 8f5a4a201..c706536d8 100644 --- a/frontend_server_common/lib/src/frontend_server_client.dart +++ b/frontend_server_common/lib/src/frontend_server_client.dart @@ -613,7 +613,7 @@ class TestExpressionCompiler implements ExpressionCompiler { if (compilerOutput != null) { var content = utf8.decode( - fileSystem.file(compilerOutput.outputFilename).readAsBytesSync()); + localFileSystem.file(compilerOutput.outputFilename).readAsBytesSync()); return ExpressionCompilationResult( content, compilerOutput.errorCount > 0); } diff --git a/frontend_server_common/lib/src/resident_runner.dart b/frontend_server_common/lib/src/resident_runner.dart index 4bbeab8e9..292b4470f 100644 --- a/frontend_server_common/lib/src/resident_runner.dart +++ b/frontend_server_common/lib/src/resident_runner.dart @@ -3,12 +3,13 @@ // found in the LICENSE file. // Note: this is a copy from flutter tools, updated to work with dwds tests, -// and some functionality remioved (does not support hot reload yet) +// and some functionality removed (does not support hot reload yet) import 'dart:async'; import 'package:dwds/asset_reader.dart'; import 'package:dwds/expression_compiler.dart'; +import 'package:file/file.dart'; import 'package:logging/logging.dart'; import 'package:path/path.dart' as p; @@ -28,7 +29,7 @@ class ResidentWebRunner { this.mainUri, this.urlTunneler, this.projectDirectory, - this.packageConfigFile, + this.packageUriMapper, this.fileSystemRoots, this.fileSystemScheme, this.outputPath, @@ -37,7 +38,7 @@ class ResidentWebRunner { generator = ResidentCompiler( dartSdkPath, projectDirectory: projectDirectory, - packageConfigFile: packageConfigFile, + packageConfigFile: packageUriMapper.packageConfigFile, platformDill: soundNullSafety ? '$platformDillSound' : '$platformDillUnsound', fileSystemRoots: fileSystemRoots, @@ -50,7 +51,7 @@ class ResidentWebRunner { final UrlEncoder? urlTunneler; final Uri mainUri; final Uri projectDirectory; - final Uri packageConfigFile; + final PackageUriMapper packageUriMapper; final String outputPath; final List fileSystemRoots; final String fileSystemScheme; @@ -62,13 +63,13 @@ class ResidentWebRunner { late Uri uri; late Iterable modules; - Future run(String? hostname, int port, String index) async { + Future run(FileSystem fileSystem, String? hostname, int port, String index) async { devFS = WebDevFS( fileSystem: fileSystem, hostname: hostname ?? 'localhost', port: port, projectDirectory: projectDirectory, - packageConfigFile: packageConfigFile, + packageUriMapper: packageUriMapper, index: index, urlTunneler: urlTunneler, soundNullSafety: soundNullSafety, diff --git a/frontend_server_common/lib/src/utilities.dart b/frontend_server_common/lib/src/utilities.dart index 859ab8ad8..1c68b52e6 100644 --- a/frontend_server_common/lib/src/utilities.dart +++ b/frontend_server_common/lib/src/utilities.dart @@ -19,4 +19,4 @@ final String _sdkDir = (() { final String dartSdkPath = _sdkDir; -const fs.FileSystem fileSystem = LocalFileSystem(); +const fs.FileSystem localFileSystem = LocalFileSystem(); From 9209e8516c3fcba72bde0de16d83411a35cbe30a Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Mon, 29 Aug 2022 18:49:36 -0700 Subject: [PATCH 05/10] Use debugger module names, add tests --- dwds/CHANGELOG.md | 5 + dwds/lib/asset_reader.dart | 3 +- dwds/lib/dwds.dart | 3 +- dwds/lib/src/debugging/debugger.dart | 8 +- dwds/lib/src/debugging/inspector.dart | 8 +- dwds/lib/src/debugging/location.dart | 50 +---- dwds/lib/src/debugging/metadata/provider.dart | 8 - dwds/lib/src/debugging/modules.dart | 14 +- .../lib/src/loaders/build_runner_require.dart | 12 +- .../src/loaders/frontend_server_require.dart | 37 ++-- dwds/lib/src/loaders/require.dart | 3 - dwds/lib/src/readers/asset_reader.dart | 68 +++---- .../readers/proxy_server_asset_reader.dart | 3 - .../src/services/chrome_proxy_service.dart | 4 +- dwds/lib/src/utilities/dart_uri.dart | 34 ++-- .../build_daemon_circular_evaluate_test.dart | 25 +++ dwds/test/evaluate_circular_common.dart | 172 ++++++++++++++++++ dwds/test/evaluate_common.dart | 29 +-- dwds/test/fixtures/context.dart | 27 ++- dwds/test/fixtures/fakes.dart | 3 - ...rontend_server_circular_evaluate_test.dart | 45 +++++ dwds/test/frontend_server_evaluate_test.dart | 46 ++--- fixtures/_test/lib/deferred_library.dart | 2 + fixtures/_test/lib/library.dart | 2 + fixtures/_testCircular1/lib/library1.dart | 14 ++ fixtures/_testCircular1/pubspec.yaml | 18 ++ .../_testCircular1Sound/lib/library1.dart | 12 ++ fixtures/_testCircular1Sound/pubspec.yaml | 18 ++ fixtures/_testCircular2/lib/library2.dart | 12 ++ fixtures/_testCircular2/pubspec.yaml | 19 ++ fixtures/_testCircular2/web/base_index.html | 8 + fixtures/_testCircular2/web/index.html | 7 + fixtures/_testCircular2/web/main.dart | 21 +++ .../_testCircular2Sound/lib/library2.dart | 10 + fixtures/_testCircular2Sound/pubspec.yaml | 19 ++ .../_testCircular2Sound/web/base_index.html | 8 + fixtures/_testCircular2Sound/web/index.html | 7 + fixtures/_testCircular2Sound/web/main.dart | 19 ++ fixtures/_testPackage/lib/src/test_part.dart | 4 +- fixtures/_testPackage/lib/test_library.dart | 4 +- .../_testPackageSound/lib/src/test_part.dart | 4 +- .../_testPackageSound/lib/test_library.dart | 4 +- fixtures/_testSound/lib/deferred_library.dart | 1 - fixtures/_testSound/lib/library.dart | 1 - .../lib/src/asset_server.dart | 24 +-- .../lib/src/frontend_server_client.dart | 4 + .../lib/src/resident_runner.dart | 5 +- 47 files changed, 626 insertions(+), 228 deletions(-) create mode 100644 dwds/test/build_daemon_circular_evaluate_test.dart create mode 100644 dwds/test/evaluate_circular_common.dart create mode 100644 dwds/test/frontend_server_circular_evaluate_test.dart create mode 100644 fixtures/_testCircular1/lib/library1.dart create mode 100644 fixtures/_testCircular1/pubspec.yaml create mode 100644 fixtures/_testCircular1Sound/lib/library1.dart create mode 100644 fixtures/_testCircular1Sound/pubspec.yaml create mode 100644 fixtures/_testCircular2/lib/library2.dart create mode 100644 fixtures/_testCircular2/pubspec.yaml create mode 100644 fixtures/_testCircular2/web/base_index.html create mode 100644 fixtures/_testCircular2/web/index.html create mode 100644 fixtures/_testCircular2/web/main.dart create mode 100644 fixtures/_testCircular2Sound/lib/library2.dart create mode 100644 fixtures/_testCircular2Sound/pubspec.yaml create mode 100644 fixtures/_testCircular2Sound/web/base_index.html create mode 100644 fixtures/_testCircular2Sound/web/index.html create mode 100644 fixtures/_testCircular2Sound/web/main.dart diff --git a/dwds/CHANGELOG.md b/dwds/CHANGELOG.md index 898c2f0e3..4287409eb 100644 --- a/dwds/CHANGELOG.md +++ b/dwds/CHANGELOG.md @@ -11,11 +11,16 @@ - Migrate `package:dwds` to null safety. - Make `ChromeProxyService.getStack` wait for the debugger to perform initial resume operation. This avoids race conditions on isolate start. +- Make server paths match directory structure + - Allows correct relative source map paths resolution. + - Add `PackageUriMapper` class to allow mapping uris to server paths. **Breaking changes** - Remove no longer used `ExpressionCompilerService.handler`. - Remove `assetHandler` parameter from `ExpressionCompilerService` constructor. +- Add `packageUriMapper` parameter to the constructor of + `FrontendServerRequireStrategyProvider`. ## 15.0.0 diff --git a/dwds/lib/asset_reader.dart b/dwds/lib/asset_reader.dart index 783375c68..9066a04b1 100644 --- a/dwds/lib/asset_reader.dart +++ b/dwds/lib/asset_reader.dart @@ -2,4 +2,5 @@ // 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. -export 'src/readers/asset_reader.dart' show AssetReader, UrlEncoder, PackageUriMapper; +export 'src/readers/asset_reader.dart' + show AssetReader, UrlEncoder, PackageUriMapper, stripLeadingSlashes; diff --git a/dwds/lib/dwds.dart b/dwds/lib/dwds.dart index ae02a4d41..84bf219ee 100644 --- a/dwds/lib/dwds.dart +++ b/dwds/lib/dwds.dart @@ -17,7 +17,8 @@ export 'src/loaders/frontend_server_require.dart' export 'src/loaders/legacy.dart' show LegacyStrategy; export 'src/loaders/require.dart' show RequireStrategy; export 'src/loaders/strategy.dart' show LoadStrategy, ReloadConfiguration; -export 'src/readers/asset_reader.dart' show AssetReader, UrlEncoder, PackageUriMapper; +export 'src/readers/asset_reader.dart' + show AssetReader, UrlEncoder, PackageUriMapper; export 'src/readers/frontend_server_asset_reader.dart' show FrontendServerAssetReader; export 'src/readers/proxy_server_asset_reader.dart' show ProxyServerAssetReader; diff --git a/dwds/lib/src/debugging/debugger.dart b/dwds/lib/src/debugging/debugger.dart index 0c046a46d..e4bfd3d96 100644 --- a/dwds/lib/src/debugging/debugger.dart +++ b/dwds/lib/src/debugging/debugger.dart @@ -506,10 +506,8 @@ class Debugger extends Domain { 'cannot find url for script ${location.scriptId}'); return null; } - logger.info('XXX url for frame $frame: $url'); final bestLocation = await _locations.locationForJs(url, line, column ?? 0); - logger.info('XXX bestLocation for frame $frame: $bestLocation'); if (bestLocation == null) return null; final script = @@ -548,7 +546,6 @@ class Debugger extends Domain { /// Handles pause events coming from the Chrome connection. Future _pauseHandler(DebuggerPausedEvent e) async { final isolate = inspector.isolate; - logger.info('XXX received debugger paused event: $e'); Event event; final timestamp = DateTime.now().millisecondsSinceEpoch; final jsBreakpointIds = e.hitBreakpoints ?? []; @@ -653,7 +650,6 @@ class Debugger extends Domain { // DevTools is showing an overlay. Both cannot be shown at the same time. // _showPausedOverlay(); isolate.pauseEvent = event; - logger.info('XXX send pause notification: $event: ${event.topFrame}'); _streamNotify('Debug', event); } @@ -797,12 +793,10 @@ class _Breakpoints extends Domain { Future _createBreakpoint( String id, String scriptId, int line, int column) async { final dartScript = inspector.scriptWithId(scriptId); - _logger.info('XXX dart script for $id: $dartScript'); final dartScriptUri = dartScript?.uri; Location? location; if (dartScriptUri != null) { final dartUri = DartUri(dartScriptUri, root); - _logger.info('XXX looking for dart location for ${dartScript?.uri}($dartUri):$line:$column'); location = await locations.locationForDart(dartUri, line, column); } // TODO: Handle cases where a breakpoint can't be set exactly at that line. @@ -828,7 +822,7 @@ class _Breakpoints extends Domain { 'addBreakpoint', 102, 'The VM is unable to add a breakpoint $id ' - 'at the specified line or function: ($scriptId:$line:$column): cannot set JS breakpoint at $location'); + 'at the specified line or function: ($scriptId:$line:$column): cannot set JS breakpoint at $location'); } _note(jsId: jsBreakpointId, bp: dartBreakpoint); return dartBreakpoint; diff --git a/dwds/lib/src/debugging/inspector.dart b/dwds/lib/src/debugging/inspector.dart index 7c112d5c7..3b1e22bbc 100644 --- a/dwds/lib/src/debugging/inspector.dart +++ b/dwds/lib/src/debugging/inspector.dart @@ -571,11 +571,9 @@ class AppInspector implements AppInspectorInterface { /// Look up the script by id in an isolate. @override - ScriptRef? scriptWithId(String? scriptId) { - final ret = scriptId == null ? null : _scriptRefsById[scriptId]; - _logger.info('XXX scripts: ${_scriptRefsById.length}'); - return ret; - } + ScriptRef? scriptWithId(String? scriptId) => + scriptId == null ? null : _scriptRefsById[scriptId]; + /// Runs an eval on the page to compute all existing registered extensions. Future> _getExtensionRpcs() async { final expression = diff --git a/dwds/lib/src/debugging/location.dart b/dwds/lib/src/debugging/location.dart index b11aecac2..9b13a60aa 100644 --- a/dwds/lib/src/debugging/location.dart +++ b/dwds/lib/src/debugging/location.dart @@ -3,7 +3,6 @@ // BSD-style license that can be found in the LICENSE file. 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'; @@ -162,18 +161,13 @@ class Locations { /// Returns all [Location] data for a provided JS server path. Future> locationsForUrl(String url) async { - //final uri = Uri.parse(url); - //final segments = uri.pathSegments.first == '/'? uri.pathSegments.skip(1): uri.pathSegments; - //final serverPath = p.joinAll(segments); - + if (url.isEmpty) return {}; + final dartUri = DartUri(url, _root); final serverPath = dartUri.serverPath; - _logger.info('XXX looking for locations for js $url(server path $serverPath)'); - - final module = await globalLoadStrategy.moduleForServerPath( - _entrypoint, serverPath); + final module = + await globalLoadStrategy.moduleForServerPath(_entrypoint, serverPath); - _logger.info('XXX module for url: $url($serverPath): $module'); final cache = _moduleToLocations[module]; if (cache != null) return cache; if (module != null) { @@ -187,10 +181,7 @@ class Locations { /// The [line] number is 1-based. Future locationForDart(DartUri uri, int line, int column) async { final locations = await locationsForDart(uri.serverPath); - _logger.fine('XXX locations for dart $uri:$line:$column: $locations'); - final ret = _bestDartLocation(locations, line, column); - _logger.info('XXX Best location for dart ${uri.serverPath}:$line:$column: $ret'); - return ret; + return _bestDartLocation(locations, line, column); } /// Find the [Location] for the given JS source position. @@ -198,10 +189,7 @@ class Locations { /// The [line] number is 0-based. Future locationForJs(String url, int line, int? column) async { final locations = await locationsForUrl(url); - _logger.fine('XXX locations for js $url:$line:$column: $locations'); - final ret = _bestJsLocation(locations, line, column); - _logger.info('XXX Best location for js $url:$line:$column: $ret'); - return ret; + return _bestJsLocation(locations, line, column); } /// Find closest existing Dart location for the line and column. @@ -302,11 +290,8 @@ class Locations { await globalLoadStrategy.sourceMapPathForModule(_entrypoint, module); final sourceMapContents = await _assetReader.sourceMapContents(sourceMapPath); - final scriptLocation = p.url.dirname('/${relativizePath(modulePath)}'); - - _logger.info('XXX modulePath: $modulePath'); - _logger.info('XXX sourceMapPath: $sourceMapPath'); - _logger.info('XXX sourceMapContents: ${sourceMapContents != null}'); + final scriptLocation = + p.url.dirname('/${stripLeadingSlashes(modulePath)}'); if (sourceMapContents == null) return result; // This happens to be a [SingleMapping] today in DDC. @@ -322,26 +307,10 @@ class Locations { // This works on Windows because path treats both / and \ as separators. // It will fail if the path has both separators in it. final relativeSegments = p.split(mapping.urls[index]); - final path = p.url.normalize( p.url.joinAll([scriptLocation, ...relativeSegments])); - // detect reference to another package: - // scriptLocation: '/packages/home/pages' - // relativeSegments: '../../../account_presentation/lib/controller/sign_in_controller.dart - //if (scriptLocation.startsWith('/packages/') && !path.startsWith('/packages/')) { - // path = "/packages${path.replaceAll('/lib/', '/')}"; - //} - - //if (scriptLocation.startsWith('/packages/') && relativeSegments.contains('lib') && relativeSegments.first == '..') { - // relativeSegments = relativeSegments.skip(1).where((e) => e != 'lib').toList(); - //} final dartUri = DartUri(path, _root); - _logger.info('XXX adding location for $path($dartUri)'); - //if (path.contains('sign_in_controller')) { - // _logger.info('XXX script location: $scriptLocation, relative segments: $relativeSegments'); - // _logger.info('XXX add location $modulePath:$lineEntry:$entry at $path($dartUri)'); - //} result.add(Location.from( modulePath, lineEntry, @@ -357,9 +326,6 @@ class Locations { location.dartLocation.uri.serverPath, () => {}) .add(location); } - if (module.contains('welcome_page.dart')) { - _logger.info('XXX locations for module $module computed: $result'); - } return _moduleToLocations[module] = result; }); } diff --git a/dwds/lib/src/debugging/metadata/provider.dart b/dwds/lib/src/debugging/metadata/provider.dart index 214675a22..fda9e92ef 100644 --- a/dwds/lib/src/debugging/metadata/provider.dart +++ b/dwds/lib/src/debugging/metadata/provider.dart @@ -6,7 +6,6 @@ import 'dart:async'; import 'dart:convert'; import 'package:async/async.dart'; -import 'package:dwds/src/utilities/dart_uri.dart'; import 'package:logging/logging.dart'; import 'package:path/path.dart' as p; @@ -220,13 +219,9 @@ class MetadataProvider { } void _addMetadata(ModuleMetadata metadata) { - //final modulePath = DartUri(metadata.moduleUri).serverPath; - //final sourceMapPath = DartUri(metadata.sourceMapUri).serverPath; final modulePath = stripLeadingSlashes(metadata.moduleUri); final sourceMapPath = stripLeadingSlashes(metadata.sourceMapUri); - _logger.info('XXX Adding module: ${metadata.name} with url: ${metadata.moduleUri} and server path $modulePath'); - _moduleToSourceMap[metadata.name] = sourceMapPath; _modulePathToModule[modulePath] = metadata.name; _moduleToModulePath[metadata.name] = modulePath; @@ -236,9 +231,6 @@ class MetadataProvider { throw AbsoluteImportUriException(library.importUri); } _libraries.add(library.importUri); - if (library.importUri.contains('sign_in_controller')) { - _logger.info('XXX loading library info for ${library.importUri}'); - } _scripts[library.importUri] = []; _scriptToModule[library.importUri] = metadata.name; diff --git a/dwds/lib/src/debugging/modules.dart b/dwds/lib/src/debugging/modules.dart index 2b7d0ec84..fc51c648c 100644 --- a/dwds/lib/src/debugging/modules.dart +++ b/dwds/lib/src/debugging/modules.dart @@ -43,13 +43,6 @@ class Modules { /// Returns the containing module for the provided Dart server path. Future moduleForSource(String serverPath) async { await _moduleMemoizer.runOnce(_initializeMapping); - final module = _sourceToModule[serverPath]; - - if (serverPath.contains('sign_in_controller') && module == null) { - _logger.info('Module for source: $serverPath: $module'); - final line = _sourceToModule.entries.map((p) => '${p.key}: ${p.value}').join('\n\t,'); - _logger.info('all modules: $line'); - } return _sourceToModule[serverPath]; } @@ -85,9 +78,7 @@ class Modules { if (scriptToModule.containsKey(library)) { final module = scriptToModule[library]!; - if (libraryServerPath.contains('sign_in_controller')) { - _logger.info('XXX saving module $module for library $library($libraryServerPath)'); - } + _sourceToModule[libraryServerPath] = module; _sourceToLibrary[libraryServerPath] = Uri.parse(library); _libraryToModule[library] = module; @@ -97,9 +88,6 @@ class Modules { ? script : DartUri(script, _root).serverPath; - if (scriptServerPath.contains('sign_in_controller')) { - _logger.info('XXX 2 saving module $module for source $scriptServerPath'); - } _sourceToModule[scriptServerPath] = module; _sourceToLibrary[scriptServerPath] = Uri.parse(library); } diff --git a/dwds/lib/src/loaders/build_runner_require.dart b/dwds/lib/src/loaders/build_runner_require.dart index b679e21bf..6da17236e 100644 --- a/dwds/lib/src/loaders/build_runner_require.dart +++ b/dwds/lib/src/loaders/build_runner_require.dart @@ -75,7 +75,7 @@ class BuildRunnerRequireStrategyProvider { Future _moduleForServerPath( MetadataProvider metadataProvider, String serverPath) async { final modulePathToModule = await metadataProvider.modulePathToModule; - final relativePath = relativizePath(serverPath); + final relativePath = stripLeadingSlashes(serverPath); for (var e in modulePathToModule.entries) { if (stripTopLevelDirectory(e.key) == relativePath) { return e.value; @@ -97,10 +97,14 @@ class BuildRunnerRequireStrategyProvider { return stripTopLevelDirectory(path); } - String? _serverPathForAppUri(String appUri) { - if (appUri.startsWith('org-dartlang-app:')) { + String? _serverPathForAppUri(String appUrl) { + final appUri = Uri.parse(appUrl); + if (appUri.isScheme('org-dartlang-app')) { // We skip the root from which we are serving. - return Uri.parse(appUri).pathSegments.skip(1).join('/'); + return appUri.pathSegments.skip(1).join('/'); + } + if (appUri.isScheme('package')) { + return '/packages/${appUri.path}'; } return null; } diff --git a/dwds/lib/src/loaders/frontend_server_require.dart b/dwds/lib/src/loaders/frontend_server_require.dart index 58ef25070..63b66af7f 100644 --- a/dwds/lib/src/loaders/frontend_server_require.dart +++ b/dwds/lib/src/loaders/frontend_server_require.dart @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:logging/logging.dart'; import 'package:path/path.dart' as p; import '../debugging/metadata/provider.dart'; @@ -13,7 +12,6 @@ import 'require.dart'; /// Provides a [RequireStrategy] suitable for use with Frontend Server. class FrontendServerRequireStrategyProvider { - final _logger = Logger('FrontendServerRequireStrategyProvider'); final ReloadConfiguration _configuration; final AssetReader _assetReader; final PackageUriMapper _packageUriMapper; @@ -32,40 +30,36 @@ class FrontendServerRequireStrategyProvider { _assetReader, ); - FrontendServerRequireStrategyProvider(this._configuration, this._assetReader, this._packageUriMapper, - this._digestsProvider, this._basePath,); + FrontendServerRequireStrategyProvider( + this._configuration, + this._assetReader, + this._packageUriMapper, + this._digestsProvider, + this._basePath, + ); RequireStrategy get strategy => _requireStrategy; String _removeBasePath(String path) { if (_basePath.isEmpty) return path; - // If path is a server path it might start with a '/'. - // final base = path.startsWith('/') ? '/$_basePath/' : _basePath; - final stripped = relativizePath(path); - return relativizePath(stripped.substring(_basePath.length)); - //return path.startsWith(base) ? path.substring(base.length) : path; + final stripped = stripLeadingSlashes(path); + return stripLeadingSlashes(stripped.substring(_basePath.length)); } String _addBasePath(String serverPath) => _basePath.isEmpty - ? relativizePath(serverPath) - : '$_basePath/${relativizePath(serverPath)}'; + ? stripLeadingSlashes(serverPath) + : '$_basePath/${stripLeadingSlashes(serverPath)}'; Future> _moduleProvider( MetadataProvider metadataProvider) async => (await metadataProvider.moduleToModulePath).map((key, value) => - MapEntry(key, relativizePath(removeJsExtension(value)))); + MapEntry(key, stripLeadingSlashes(removeJsExtension(value)))); Future _moduleForServerPath( MetadataProvider metadataProvider, String serverPath) async { final modulePathToModule = await metadataProvider.modulePathToModule; final relativeServerPath = _removeBasePath(serverPath); - modulePathToModule.forEach((key, value) { - if (key.contains(relativeServerPath) || serverPath.contains(key)) { - _logger.info('XXX inexact match: serverPath: $serverPath($relativeServerPath), key: $key'); - } - }); - _logger.info('XXX exact match: serverPath: $serverPath, mpd: ${modulePathToModule[relativeServerPath]}'); return modulePathToModule[relativeServerPath]; } @@ -83,10 +77,10 @@ class FrontendServerRequireStrategyProvider { return _addBasePath(appUri.path); } if (appUri.isScheme('package')) { - //final resolved = _assetReader.resolvePackageUrl(appUri); final resolved = _packageUriMapper.packageUriToServerPath(appUri); - //_logger.info('XXX: server path for $appUrl: $resolved'); - return resolved; + if (resolved != null) { + return _addBasePath(resolved); + } } return null; } @@ -106,4 +100,3 @@ class FrontendServerRequireStrategyProvider { return result; } } - diff --git a/dwds/lib/src/loaders/require.dart b/dwds/lib/src/loaders/require.dart index 51952515d..fe9807386 100644 --- a/dwds/lib/src/loaders/require.dart +++ b/dwds/lib/src/loaders/require.dart @@ -23,9 +23,6 @@ String basePathForServerUri(String url) { return base = base.startsWith('/') ? base.substring(1) : base; } -String relativizePath(String path) => stripLeadingSlashes(path); - // path.startsWith('/') ? path.substring(1) : path; - String removeJsExtension(String path) => path.endsWith('.js') ? p.withoutExtension(path) : path; diff --git a/dwds/lib/src/readers/asset_reader.dart b/dwds/lib/src/readers/asset_reader.dart index 033eedcde..abdb6a070 100644 --- a/dwds/lib/src/readers/asset_reader.dart +++ b/dwds/lib/src/readers/asset_reader.dart @@ -2,6 +2,7 @@ // 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. +import 'package:collection/collection.dart'; import 'package:file/file.dart'; import 'package:logging/logging.dart'; import 'package:package_config/package_config.dart'; @@ -29,60 +30,62 @@ abstract class AssetReader { class PackageUriMapper { final _logger = Logger('PackageUriMapper'); final PackageConfig packageConfig; - - static Future create(FileSystem fileSystem, Uri packageConfigFile) async { - final packageConfig = await loadPackageConfig(fileSystem.file(packageConfigFile)); - return PackageUriMapper(packageConfig); + final bool useDebuggerModuleNames; + + static Future create( + FileSystem fileSystem, Uri packageConfigFile, + {bool useDebuggerModuleNames = false}) async { + final packageConfig = + await loadPackageConfig(fileSystem.file(packageConfigFile)); + return PackageUriMapper(packageConfig, + useDebuggerModuleNames: useDebuggerModuleNames); } - PackageUriMapper(this.packageConfig); + PackageUriMapper(this.packageConfig, {this.useDebuggerModuleNames = false}); - // TODO: use package directories instead of package names - // Note: needs to be the same as `urlForComponentUri` in javascript_bundle.dart in SDK + /// Compute server path for package uri. + /// + /// Note: needs to match `urlForComponentUri` in javascript_bundle.dart + /// in SDK code. String? packageUriToServerPath(Uri packageUri) { if (packageUri.isScheme('package')) { + if (!useDebuggerModuleNames) { + return ('/packages/${packageUri.path}'); + } final Uri? resolvedUri = packageConfig.resolve(packageUri); final Package? package = packageConfig.packageOf(resolvedUri!); final Uri root = package!.root; - final String relativeUrl = resolvedUri.toString().replaceFirst('$root', ''); - final relativeRoot = _getRelativeRoot(root); - _logger.info('XXX package: ${package.name} ($relativeRoot)}'); - final String ret = 'packages/$relativeRoot/$relativeUrl'; + final String relativeUrl = + resolvedUri.toString().replaceFirst('$root', ''); + final String? relativeRoot = _getRelativeRoot(root); + final String ret = relativeRoot == null + ? 'packages/$relativeUrl' + : 'packages/$relativeRoot/$relativeUrl'; return ret; - } + } _logger.severe('Expected package uri, but found $packageUri'); return null; } - // Needs to match the code above + /// Compute resolved file uri for a server path. Uri? serverPathToResolvedUri(String serverPath) { serverPath = stripLeadingSlashes(serverPath); final segments = serverPath.split('/'); if (segments.first == 'packages') { + if (!useDebuggerModuleNames) { + return packageConfig + .resolve(Uri(scheme: 'package', pathSegments: segments.skip(1))); + } final String relativeRoot = segments.skip(1).first; - _logger.info('XXX package root: $relativeRoot'); - final String relativeUrl = segments.skip(2).join('/'); - _logger.info('XXX relativeUrl: $relativeUrl'); - - final Package package = packageConfig.packages.firstWhere((Package p) => _getRelativeRoot(p.root) == relativeRoot); - _logger.info('XXX package: ${package.name}($relativeRoot)'); - + final Package package = packageConfig.packages + .firstWhere((Package p) => _getRelativeRoot(p.root) == relativeRoot); final Uri resolvedUri = package.root.resolve(relativeUrl); - _logger.info('XXX Server path: $serverPath -> $resolvedUri'); return resolvedUri; } + _logger.severe('Expected "packages/" path, but found $serverPath'); return null; - } - - String? _getRelativeRoot(Uri root) { - final segments = root.pathSegments; - if (segments.isNotEmpty && segments.last.isEmpty) { - final subset = segments.getRange(0, segments.length-1); - return subset.isNotEmpty? subset.last: null; - } - return segments.isNotEmpty? segments.last: null; } } @@ -91,4 +94,7 @@ String stripLeadingSlashes(String path) { path = path.substring(1); } return path; -} \ No newline at end of file +} + +String? _getRelativeRoot(Uri root) => + root.pathSegments.lastWhereOrNull((segment) => segment.isNotEmpty); diff --git a/dwds/lib/src/readers/proxy_server_asset_reader.dart b/dwds/lib/src/readers/proxy_server_asset_reader.dart index 08b43d00c..960809eca 100644 --- a/dwds/lib/src/readers/proxy_server_asset_reader.dart +++ b/dwds/lib/src/readers/proxy_server_asset_reader.dart @@ -69,9 +69,6 @@ class ProxyServerAssetReader implements AssetReader { Future metadataContents(String serverPath) => _readResource(serverPath); - @override - String? resolvePackageUrl(Uri packageUri) => null; - @override Future close() async => _client.close(); } diff --git a/dwds/lib/src/services/chrome_proxy_service.dart b/dwds/lib/src/services/chrome_proxy_service.dart index 1bfd4488f..2d3a89e1f 100644 --- a/dwds/lib/src/services/chrome_proxy_service.dart +++ b/dwds/lib/src/services/chrome_proxy_service.dart @@ -373,9 +373,7 @@ class ChromeProxyService implements VmServiceInterface { 'at the specified line or function: $scriptUri:$line:$column: ' 'cannot find script ID for ${dartUri.serverPath}'); } - final bp = await (await debuggerFuture).addBreakpoint(scriptId, line, column: column); - _logger.info('XXX added breakpoint: $bp'); - return bp; + return (await debuggerFuture).addBreakpoint(scriptId, line, column: column); } @override diff --git a/dwds/lib/src/utilities/dart_uri.dart b/dwds/lib/src/utilities/dart_uri.dart index f5c16d7a7..03dc060c4 100644 --- a/dwds/lib/src/utilities/dart_uri.dart +++ b/dwds/lib/src/utilities/dart_uri.dart @@ -29,22 +29,18 @@ class DartUri { /// /// The optional [root] is the directory the app is served from. factory DartUri(String uri, [String? root]) { - final serverPath = globalLoadStrategy.serverPathForAppUri(uri); - if (serverPath != null) { - if (serverPath.startsWith('packages/')) { - return DartUri._fromRelativePath(serverPath, root: root); - } - return DartUri._(serverPath); - } // TODO(annagrin): Support creating DartUris from `dart:` uris. // Issue: https://github.com/dart-lang/webdev/issues/1584 + if (uri.startsWith('org-dartlang-app:')) { + return DartUri._fromDartLangUri(uri); + } if (uri.startsWith('package:')) { return DartUri._fromPackageUri(uri, root: root); } if (uri.startsWith('file:')) { return DartUri._fromFileUri(uri, root: root); } - if (uri.startsWith('packages/')) { + if (uri.startsWith('packages/') || uri.startsWith('/packages/')) { return DartUri._fromRelativePath(uri, root: root); } if (uri.startsWith('/')) { @@ -54,20 +50,30 @@ class DartUri { return DartUri(Uri.parse(uri).path); } - throw FormatException('Unsupported URI form', uri); + throw FormatException('Unsupported URI form: $uri'); } @override String toString() => 'DartUri: $serverPath'; + /// Construct from a package: URI + factory DartUri._fromDartLangUri(String uri) { + var serverPath = globalLoadStrategy.serverPathForAppUri(uri); + if (serverPath == null) { + _logger.severe('Cannot find server path for $uri'); + serverPath = uri; + } + return DartUri._(serverPath); + } + /// Construct from a package: URI factory DartUri._fromPackageUri(String uri, {String? root}) { - final packagePath = 'packages/${uri.substring("package:".length)}'; - if (root != null) { - final relativePath = p.url.join(root, packagePath); - return DartUri._fromRelativePath(relativePath); + var serverPath = globalLoadStrategy.serverPathForAppUri(uri); + if (serverPath == null) { + _logger.severe('Cannot find server path for $uri'); + serverPath = uri; } - return DartUri._(packagePath); + return DartUri._fromRelativePath(serverPath); } /// Construct from a file: URI diff --git a/dwds/test/build_daemon_circular_evaluate_test.dart b/dwds/test/build_daemon_circular_evaluate_test.dart new file mode 100644 index 000000000..6ff523a75 --- /dev/null +++ b/dwds/test/build_daemon_circular_evaluate_test.dart @@ -0,0 +1,25 @@ +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// 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. + +@TestOn('vm') + +import 'package:test/test.dart'; + +import 'fixtures/context.dart'; +import 'evaluate_circular_common.dart'; + +void main() async { + // Enable verbose logging for debugging. + final debug = false; + + for (var nullSafety in NullSafety.values) { + group('${nullSafety.name} null safety |', () { + testAll( + compilationMode: CompilationMode.buildDaemon, + nullSafety: nullSafety, + debug: debug, + ); + }); + } +} diff --git a/dwds/test/evaluate_circular_common.dart b/dwds/test/evaluate_circular_common.dart new file mode 100644 index 000000000..0de304df4 --- /dev/null +++ b/dwds/test/evaluate_circular_common.dart @@ -0,0 +1,172 @@ +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// 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. + +@TestOn('vm') +import 'dart:async'; + +import 'package:dwds/src/connections/debug_connection.dart'; +import 'package:dwds/src/services/chrome_proxy_service.dart'; +import 'package:path/path.dart' as p; +import 'package:test/test.dart'; +import 'package:vm_service/vm_service.dart'; +import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; + +import 'fixtures/context.dart'; +import 'fixtures/logging.dart'; + +class TestSetup { + static TestContext createContext(String index, String packageRoot) => + TestContext( + directory: p.join('..', 'fixtures', packageRoot), + entry: p.join('..', 'fixtures', packageRoot, 'web', 'main.dart'), + path: index, + pathToServe: 'web'); + + static TestContext contextUnsound(String index) => + createContext(index, '_testCircular2'); + + static TestContext contextSound(String index) => + createContext(index, '_testCircular2Sound'); + + TestContext context; + + TestSetup.sound(IndexBaseMode baseMode) + : context = contextSound(_index(baseMode)); + + TestSetup.unsound(IndexBaseMode baseMode) + : context = contextUnsound(_index(baseMode)); + + factory TestSetup.create(NullSafety? nullSafety, IndexBaseMode baseMode) => + nullSafety == NullSafety.sound + ? TestSetup.sound(baseMode) + : TestSetup.unsound(baseMode); + + ChromeProxyService get service => + fetchChromeProxyService(context.debugConnection); + WipConnection get tabConnection => context.tabConnection; + + static String _index(IndexBaseMode baseMode) => + baseMode == IndexBaseMode.base ? 'base_index.html' : 'index.html'; +} + +void testAll({ + CompilationMode compilationMode = CompilationMode.buildDaemon, + IndexBaseMode indexBaseMode = IndexBaseMode.noBase, + NullSafety nullSafety = NullSafety.sound, + bool useDebuggerModuleNames = false, + bool debug = false, +}) { + if (compilationMode == CompilationMode.buildDaemon && + indexBaseMode == IndexBaseMode.base) { + throw StateError( + 'build daemon scenario does not support non-empty base in index file'); + } + final setup = TestSetup.create(nullSafety, indexBaseMode); + final context = setup.context; + + Future onBreakPoint(String isolate, ScriptRef script, + String breakPointId, Future Function() body) async { + Breakpoint? bp; + try { + final line = + await context.findBreakpointLine(breakPointId, isolate, script); + bp = await setup.service + .addBreakpointWithScriptUri(isolate, script.uri!, line); + await body(); + } finally { + // Remove breakpoint so it doesn't impact other tests or retries. + if (bp != null) { + await setup.service.removeBreakpoint(isolate, bp.id!); + } + } + } + + group('shared context with evaluation', () { + setUpAll(() async { + setCurrentLogWriter(debug: debug); + await context.setUp( + compilationMode: compilationMode, + nullSafety: nullSafety, + enableExpressionEvaluation: true, + useDebuggerModuleNames: useDebuggerModuleNames, + verboseCompiler: debug, + ); + }); + + tearDownAll(() async { + await context.tearDown(); + }); + + setUp(() => setCurrentLogWriter(debug: debug)); + + group('evaluateInFrame', () { + VM vm; + late Isolate isolate; + late String isolateId; + ScriptList scripts; + late ScriptRef test1LibraryScript; + late ScriptRef test2LibraryScript; + late Stream stream; + + setUp(() async { + setCurrentLogWriter(debug: debug); + vm = await setup.service.getVM(); + isolate = await setup.service.getIsolate(vm.isolates!.first.id!); + isolateId = isolate.id!; + scripts = await setup.service.getScripts(isolateId); + + await setup.service.streamListen('Debug'); + stream = setup.service.onEvent('Debug'); + + final soundNullSafety = nullSafety == NullSafety.sound; + final test1 = + soundNullSafety ? '_test_circular1_sound' : '_test_circular1'; + final test2 = + soundNullSafety ? '_test_circular2_sound' : '_test_circular2'; + + test1LibraryScript = scripts.scripts!.firstWhere( + (each) => each.uri!.contains('package:$test1/library1.dart')); + test2LibraryScript = scripts.scripts!.firstWhere( + (each) => each.uri!.contains('package:$test2/library2.dart')); + }); + + tearDown(() async { + await setup.service.resume(isolateId); + }); + + test('evaluate expression in _test_circular1/library', () async { + await onBreakPoint(isolateId, test1LibraryScript, 'Concatenate', + () async { + final event = await stream + .firstWhere((event) => event.kind == EventKind.kPauseBreakpoint); + + final result = await setup.service + .evaluateInFrame(isolateId, event.topFrame!.index!, 'a'); + + expect( + result, + isA().having( + (instance) => instance.valueAsString, 'valueAsString', 'a')); + }); + }); + + test('evaluate expression in _test_circular2/library', () async { + await onBreakPoint( + isolateId, test2LibraryScript, 'testCircularDependencies', + () async { + final event = await stream + .firstWhere((event) => event.kind == EventKind.kPauseBreakpoint); + + final result = await setup.service + .evaluateInFrame(isolateId, event.topFrame!.index!, 'true'); + + expect( + result, + isA().having((instance) => instance.valueAsString, + 'valueAsString', 'true')); + }); + }); + }); + }); +} diff --git a/dwds/test/evaluate_common.dart b/dwds/test/evaluate_common.dart index 83dcabd0c..3ca60cc9c 100644 --- a/dwds/test/evaluate_common.dart +++ b/dwds/test/evaluate_common.dart @@ -16,17 +16,18 @@ import 'fixtures/context.dart'; import 'fixtures/logging.dart'; class TestSetup { - static TestContext contextUnsound(String index) => TestContext( - directory: p.join('..', 'fixtures', '_testPackage'), - entry: p.join('..', 'fixtures', '_testPackage', 'web', 'main.dart'), - path: index, - pathToServe: 'web'); - - static TestContext contextSound(String index) => TestContext( - directory: p.join('..', 'fixtures', '_testPackageSound'), - entry: p.join('..', 'fixtures', '_testPackageSound', 'web', 'main.dart'), - path: index, - pathToServe: 'web'); + static TestContext createContext(String index, String packageRoot) => + TestContext( + directory: p.join('..', 'fixtures', packageRoot), + entry: p.join('..', 'fixtures', packageRoot, 'web', 'main.dart'), + path: index, + pathToServe: 'web'); + + static TestContext contextUnsound(String index) => + createContext(index, '_testPackage'); + + static TestContext contextSound(String index) => + createContext(index, '_testPackageSound'); TestContext context; @@ -53,6 +54,7 @@ void testAll({ CompilationMode compilationMode = CompilationMode.buildDaemon, IndexBaseMode indexBaseMode = IndexBaseMode.noBase, NullSafety nullSafety = NullSafety.sound, + bool useDebuggerModuleNames = false, bool debug = false, }) { if (compilationMode == CompilationMode.buildDaemon && @@ -87,6 +89,7 @@ void testAll({ compilationMode: compilationMode, nullSafety: nullSafety, enableExpressionEvaluation: true, + useDebuggerModuleNames: useDebuggerModuleNames, verboseCompiler: debug, ); }); @@ -160,7 +163,7 @@ void testAll({ contains('Using scope for expression evaluation ' 'in frame is not supported'))); }); - }/*, solo: true, retry: 0, timeout: Timeout.none*/); + }); test('local', () async { await onBreakPoint(isolateId, mainScript, 'printLocal', () async { @@ -409,7 +412,7 @@ void testAll({ isA().having( (instance) => instance.valueAsString, 'valueAsString', '23')); }); - }/*, solo: true, retry: 0, timeout: Timeout.none*/); + }); test('evaluate expression in a class constructor in a library', () async { await onBreakPoint( diff --git a/dwds/test/fixtures/context.dart b/dwds/test/fixtures/context.dart index 221df9b7d..8ae594a7f 100644 --- a/dwds/test/fixtures/context.dart +++ b/dwds/test/fixtures/context.dart @@ -28,12 +28,12 @@ import 'package:frontend_server_common/src/resident_runner.dart'; import 'package:http/http.dart'; import 'package:http/io_client.dart'; import 'package:logging/logging.dart' as logging; -import 'package:package_config/package_config.dart'; import 'package:path/path.dart' as p; import 'package:shelf/shelf.dart'; import 'package:shelf_proxy/shelf_proxy.dart'; import 'package:test/test.dart'; import 'package:vm_service/vm_service.dart'; +import 'package:pub_semver/pub_semver.dart' as semver; import 'package:webdriver/io.dart'; import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; @@ -41,6 +41,13 @@ import 'logging.dart'; import 'server.dart'; import 'utilities.dart'; +final _currentSdkVersion = semver.Version.parse(Platform.version.split(' ')[0]); +final _useDebuggerModuleNamesSdkVersion = + semver.Version(2, 19, 0, pre: '149.0.dev'); + +final isDebuggerModuleNamesFeatureSupported = + _currentSdkVersion.compareTo(_useDebuggerModuleNamesSdkVersion) > 0; + final _exeExt = Platform.isWindows ? '.exe' : ''; const isRPCError = TypeMatcher(); @@ -161,6 +168,7 @@ class TestContext { bool enableExpressionEvaluation = false, bool verboseCompiler = false, SdkConfigurationProvider? sdkConfigurationProvider, + bool useDebuggerModuleNames = false, }) async { sdkConfigurationProvider ??= DefaultSdkConfigurationProvider(); @@ -274,12 +282,17 @@ class TestContext { .substring(_projectDirectory.toFilePath().length + 1)); final fileSystem = LocalFileSystem(); - final packageUriMapper = await PackageUriMapper.create(fileSystem, _packageConfigFile); + final packageUriMapper = await PackageUriMapper.create( + fileSystem, + _packageConfigFile, + useDebuggerModuleNames: useDebuggerModuleNames, + ); _webRunner = ResidentWebRunner( entry, urlEncoder, _projectDirectory, + _packageConfigFile, packageUriMapper, [_projectDirectory], 'org-dartlang-app', @@ -289,8 +302,8 @@ class TestContext { ); final assetServerPort = await findUnusedPort(); - await webRunner.run(fileSystem, - hostname, assetServerPort, p.join(pathToServe, path)); + await webRunner.run(fileSystem, hostname, assetServerPort, + p.join(pathToServe, path)); if (enableExpressionEvaluation) { expressionCompiler = webRunner.expressionCompiler; @@ -301,7 +314,11 @@ class TestContext { _assetHandler = webRunner.devFS.assetServer.handleRequest; requireStrategy = FrontendServerRequireStrategyProvider( - reloadConfiguration, assetReader, packageUriMapper, () async => {}, basePath) + reloadConfiguration, + assetReader, + packageUriMapper, + () async => {}, + basePath) .strategy; buildResults = const Stream.empty(); diff --git a/dwds/test/fixtures/fakes.dart b/dwds/test/fixtures/fakes.dart index 60c9985e4..525fb129b 100644 --- a/dwds/test/fixtures/fakes.dart +++ b/dwds/test/fixtures/fakes.dart @@ -356,9 +356,6 @@ class FakeAssetReader implements AssetReader { Future sourceMapContents(String serverPath) { return _throwUnimplementedOrReturnContents(_sourceMap); } - - //@override - //String? resolvePackageUrl(Uri packageUri) => null; @override Future close() async {} diff --git a/dwds/test/frontend_server_circular_evaluate_test.dart b/dwds/test/frontend_server_circular_evaluate_test.dart new file mode 100644 index 000000000..8c48562a6 --- /dev/null +++ b/dwds/test/frontend_server_circular_evaluate_test.dart @@ -0,0 +1,45 @@ +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// 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. + +@TestOn('vm') + +import 'dart:io'; + +import 'package:test/test.dart'; + +import 'fixtures/context.dart'; +import 'evaluate_circular_common.dart'; + +void main() async { + // Enable verbose logging for debugging. + final debug = false; + + group('Context with circular dependencies |', () { + for (var nullSafety in NullSafety.values) { + group('${nullSafety.name} null safety |', () { + for (var indexBaseMode in IndexBaseMode.values) { + group( + 'with ${indexBaseMode.name} |', + () { + testAll( + compilationMode: CompilationMode.frontendServer, + indexBaseMode: indexBaseMode, + nullSafety: nullSafety, + useDebuggerModuleNames: true, + debug: debug, + ); + }, + skip: + // https://github.com/dart-lang/sdk/issues/49277 + indexBaseMode == IndexBaseMode.base && Platform.isWindows || + // https://github.com/dart-lang/webdev/issues/1591); + nullSafety == NullSafety.sound || + // Needs debugger module names change in the SDK to work. + !isDebuggerModuleNamesFeatureSupported, + ); + } + }); + } + }); +} diff --git a/dwds/test/frontend_server_evaluate_test.dart b/dwds/test/frontend_server_evaluate_test.dart index 770cd90fa..5c71434f8 100644 --- a/dwds/test/frontend_server_evaluate_test.dart +++ b/dwds/test/frontend_server_evaluate_test.dart @@ -15,27 +15,31 @@ void main() async { // Enable verbose logging for debugging. final debug = false; - for (var nullSafety in NullSafety.values) { - group('${nullSafety.name} null safety |', () { - for (var indexBaseMode in IndexBaseMode.values) { - group( - 'with ${indexBaseMode.name} |', - () { - testAll( - compilationMode: CompilationMode.frontendServer, - indexBaseMode: indexBaseMode, - nullSafety: nullSafety, - debug: debug, - ); - }, - skip: (nullSafety == - NullSafety - .sound) // https://github.com/dart-lang/webdev/issues/1591 - || - (indexBaseMode == IndexBaseMode.base && - Platform - .isWindows), // https://github.com/dart-lang/sdk/issues/49277 - ); + for (var useDebuggerModuleNames in [false, true]) { + group('Debugger module names: $useDebuggerModuleNames |', () { + for (var nullSafety in NullSafety.values) { + group('${nullSafety.name} null safety |', () { + for (var indexBaseMode in IndexBaseMode.values) { + group('with ${indexBaseMode.name} |', () { + testAll( + compilationMode: CompilationMode.frontendServer, + indexBaseMode: indexBaseMode, + nullSafety: nullSafety, + useDebuggerModuleNames: useDebuggerModuleNames, + debug: debug, + ); + }, + skip: + // https://github.com/dart-lang/sdk/issues/49277 + (indexBaseMode == IndexBaseMode.base && + Platform.isWindows) || + // https://github.com/dart-lang/webdev/issues/1591 + (nullSafety == NullSafety.sound) || + // Needs debugger module names feature in SDK. + (useDebuggerModuleNames && + !isDebuggerModuleNamesFeatureSupported)); + } + }); } }); } diff --git a/fixtures/_test/lib/deferred_library.dart b/fixtures/_test/lib/deferred_library.dart index e550ee822..bd0b1f152 100644 --- a/fixtures/_test/lib/deferred_library.dart +++ b/fixtures/_test/lib/deferred_library.dart @@ -2,6 +2,8 @@ // 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 + /// A library that we can import. library test_deferred_library; diff --git a/fixtures/_test/lib/library.dart b/fixtures/_test/lib/library.dart index c16783b04..5d00634a9 100644 --- a/fixtures/_test/lib/library.dart +++ b/fixtures/_test/lib/library.dart @@ -2,6 +2,8 @@ // 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 + /// A library that we can import. library test_library; diff --git a/fixtures/_testCircular1/lib/library1.dart b/fixtures/_testCircular1/lib/library1.dart new file mode 100644 index 000000000..f9f2637c2 --- /dev/null +++ b/fixtures/_testCircular1/lib/library1.dart @@ -0,0 +1,14 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// 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 + +/// A library that we can import. +library _test_circular1; + +import 'package:_test_circular2/library2.dart'; + +String concatenate(String a, String b) { + return '$a$b'; // Breakpoint: Concatenate +} diff --git a/fixtures/_testCircular1/pubspec.yaml b/fixtures/_testCircular1/pubspec.yaml new file mode 100644 index 000000000..69e4d87cc --- /dev/null +++ b/fixtures/_testCircular1/pubspec.yaml @@ -0,0 +1,18 @@ +name: _test_circular1 +version: 1.0.0 +description: >- + A fake package used for testing +publish_to: none + +environment: + sdk: ">=2.5.0 <3.0.0" + +dependencies: + intl: ^0.16.0 + path: ^1.6.1 + _test_circular2: + path: ../_testCircular2 + +dev_dependencies: + build_runner: ^2.0.0 + build_web_compilers: ^3.0.0 diff --git a/fixtures/_testCircular1Sound/lib/library1.dart b/fixtures/_testCircular1Sound/lib/library1.dart new file mode 100644 index 000000000..568f82257 --- /dev/null +++ b/fixtures/_testCircular1Sound/lib/library1.dart @@ -0,0 +1,12 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// 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. + +/// A library that we can import. +library _test_circular1_sound; + +import 'package:_test_circular2_sound/library2.dart'; + +String concatenate(String a, String b) { + return '$a$b'; // Breakpoint: Concatenate +} diff --git a/fixtures/_testCircular1Sound/pubspec.yaml b/fixtures/_testCircular1Sound/pubspec.yaml new file mode 100644 index 000000000..d5a7a9886 --- /dev/null +++ b/fixtures/_testCircular1Sound/pubspec.yaml @@ -0,0 +1,18 @@ +name: _test_circular1_sound +version: 1.0.0 +description: >- + A fake package used for testing +publish_to: none + +environment: + sdk: ">=2.5.0 <3.0.0" + +dependencies: + intl: ^0.16.0 + path: ^1.6.1 + _test_circular2_sound: + path: ../_testCircular2Sound + +dev_dependencies: + build_runner: ^2.0.0 + build_web_compilers: ^3.0.0 diff --git a/fixtures/_testCircular2/lib/library2.dart b/fixtures/_testCircular2/lib/library2.dart new file mode 100644 index 000000000..7a1c8d410 --- /dev/null +++ b/fixtures/_testCircular2/lib/library2.dart @@ -0,0 +1,12 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// 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:_test_circular1/library1.dart'; + +void testCircularDependencies() { + print(concatenate('a', 'b')); // Breakpoint: testCircularDependencies +} + diff --git a/fixtures/_testCircular2/pubspec.yaml b/fixtures/_testCircular2/pubspec.yaml new file mode 100644 index 000000000..44a59a923 --- /dev/null +++ b/fixtures/_testCircular2/pubspec.yaml @@ -0,0 +1,19 @@ +name: _test_circular2 +version: 1.0.0 +description: >- + A fake package used for testing imports. Imports _test. + This code is for testing that debugger works with weak null safety so we + should not migrate it to null safety. Once Dart 3.0 is released, we should + delete this directory. +publish_to: none + +environment: + sdk: ">=2.10.0 <3.0.0" + +dependencies: + _test_circular1: + path: ../_testCircular1 + +dev_dependencies: + build_runner: ^2.0.0 + build_web_compilers: ^3.0.0 diff --git a/fixtures/_testCircular2/web/base_index.html b/fixtures/_testCircular2/web/base_index.html new file mode 100644 index 000000000..affdbcb5c --- /dev/null +++ b/fixtures/_testCircular2/web/base_index.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/fixtures/_testCircular2/web/index.html b/fixtures/_testCircular2/web/index.html new file mode 100644 index 000000000..d93440a94 --- /dev/null +++ b/fixtures/_testCircular2/web/index.html @@ -0,0 +1,7 @@ + + + + + + + diff --git a/fixtures/_testCircular2/web/main.dart b/fixtures/_testCircular2/web/main.dart new file mode 100644 index 000000000..cf8ac1181 --- /dev/null +++ b/fixtures/_testCircular2/web/main.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// 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 'dart:async'; +import 'dart:core'; +import 'dart:html'; + +import 'package:_test_circular1/library1.dart'; +import 'package:_test_circular2/library2.dart'; + +void main() { + // For setting breakpoints. + Timer.periodic(const Duration(seconds: 1), (_) { + testCircularDependencies(); + }); + + document.body.appendText(concatenate('Program', ' is running!')); +} diff --git a/fixtures/_testCircular2Sound/lib/library2.dart b/fixtures/_testCircular2Sound/lib/library2.dart new file mode 100644 index 000000000..b176c7c72 --- /dev/null +++ b/fixtures/_testCircular2Sound/lib/library2.dart @@ -0,0 +1,10 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// 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. + +import 'package:_test_circular1_sound/library1.dart'; + +void testCircularDependencies() { + print(concatenate('a', 'b')); // Breakpoint: testCircularDependencies +} + diff --git a/fixtures/_testCircular2Sound/pubspec.yaml b/fixtures/_testCircular2Sound/pubspec.yaml new file mode 100644 index 000000000..090859c6c --- /dev/null +++ b/fixtures/_testCircular2Sound/pubspec.yaml @@ -0,0 +1,19 @@ +name: _test_circular2_sound +version: 1.0.0 +description: >- + A fake package used for testing imports. Imports _test. + This code is for testing that debugger works with weak null safety so we + should not migrate it to null safety. Once Dart 3.0 is released, we should + delete this directory. +publish_to: none + +environment: + sdk: ">=2.10.0 <3.0.0" + +dependencies: + _test_circular1_sound: + path: ../_testCircular1Sound + +dev_dependencies: + build_runner: ^2.0.0 + build_web_compilers: ^3.0.0 diff --git a/fixtures/_testCircular2Sound/web/base_index.html b/fixtures/_testCircular2Sound/web/base_index.html new file mode 100644 index 000000000..affdbcb5c --- /dev/null +++ b/fixtures/_testCircular2Sound/web/base_index.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/fixtures/_testCircular2Sound/web/index.html b/fixtures/_testCircular2Sound/web/index.html new file mode 100644 index 000000000..d93440a94 --- /dev/null +++ b/fixtures/_testCircular2Sound/web/index.html @@ -0,0 +1,7 @@ + + + + + + + diff --git a/fixtures/_testCircular2Sound/web/main.dart b/fixtures/_testCircular2Sound/web/main.dart new file mode 100644 index 000000000..d9b634a07 --- /dev/null +++ b/fixtures/_testCircular2Sound/web/main.dart @@ -0,0 +1,19 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// 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. + +import 'dart:async'; +import 'dart:core'; +import 'dart:html'; + +import 'package:_test_circular1_sound/library1.dart'; +import 'package:_test_circular2_sound/library2.dart'; + +void main() { + // For setting breakpoints. + Timer.periodic(const Duration(seconds: 1), (_) { + testCircularDependencies(); + }); + + document.body.appendText(concatenate('Program', ' is running!')); +} diff --git a/fixtures/_testPackage/lib/src/test_part.dart b/fixtures/_testPackage/lib/src/test_part.dart index adef00b29..55e99f025 100644 --- a/fixtures/_testPackage/lib/src/test_part.dart +++ b/fixtures/_testPackage/lib/src/test_part.dart @@ -2,6 +2,8 @@ // 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 + part of '../test_library.dart'; int testPartLibraryValue = 4; @@ -15,7 +17,7 @@ class TestLibraryPartClass { final int _field; TestLibraryPartClass(this.field, this._field) { - print('Contructor'); // Breakpoint: testLibraryPartClassConstructor + print('Constructor'); // Breakpoint: testLibraryPartClassConstructor } @override diff --git a/fixtures/_testPackage/lib/test_library.dart b/fixtures/_testPackage/lib/test_library.dart index c1004cb05..ee8f3866c 100644 --- a/fixtures/_testPackage/lib/test_library.dart +++ b/fixtures/_testPackage/lib/test_library.dart @@ -2,6 +2,8 @@ // 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 + part 'src/test_part.dart'; int testLibraryValue = 3; @@ -14,7 +16,7 @@ class TestLibraryClass { final int field; final int _field; TestLibraryClass(this.field, this._field) { - print('Contructor'); // Breakpoint: testLibraryClassConstructor + print('Constructor'); // Breakpoint: testLibraryClassConstructor } @override diff --git a/fixtures/_testPackageSound/lib/src/test_part.dart b/fixtures/_testPackageSound/lib/src/test_part.dart index 5297abd0d..5478db276 100644 --- a/fixtures/_testPackageSound/lib/src/test_part.dart +++ b/fixtures/_testPackageSound/lib/src/test_part.dart @@ -1,7 +1,7 @@ // Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file // 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 + part of '../test_library.dart'; int testPartLibraryValue = 4; @@ -15,7 +15,7 @@ class TestLibraryPartClass { final int _field; TestLibraryPartClass(this.field, this._field) { - print('Contructor'); // Breakpoint: testLibraryPartClassConstructor + print('Constructor'); // Breakpoint: testLibraryPartClassConstructor } @override diff --git a/fixtures/_testPackageSound/lib/test_library.dart b/fixtures/_testPackageSound/lib/test_library.dart index 037e68791..ac9eb90fa 100644 --- a/fixtures/_testPackageSound/lib/test_library.dart +++ b/fixtures/_testPackageSound/lib/test_library.dart @@ -1,7 +1,7 @@ // Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file // 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 + part 'src/test_part.dart'; int testLibraryValue = 3; @@ -14,7 +14,7 @@ class TestLibraryClass { final int field; final int _field; TestLibraryClass(this.field, this._field) { - print('Contructor'); // Breakpoint: testLibraryClassConstructor + print('Constructor'); // Breakpoint: testLibraryClassConstructor } @override diff --git a/fixtures/_testSound/lib/deferred_library.dart b/fixtures/_testSound/lib/deferred_library.dart index f5f764411..e550ee822 100644 --- a/fixtures/_testSound/lib/deferred_library.dart +++ b/fixtures/_testSound/lib/deferred_library.dart @@ -2,7 +2,6 @@ // 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 /// A library that we can import. library test_deferred_library; diff --git a/fixtures/_testSound/lib/library.dart b/fixtures/_testSound/lib/library.dart index cd0d20689..0689836de 100644 --- a/fixtures/_testSound/lib/library.dart +++ b/fixtures/_testSound/lib/library.dart @@ -2,7 +2,6 @@ // 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 /// A library that we can import. library test_library; diff --git a/frontend_server_common/lib/src/asset_server.dart b/frontend_server_common/lib/src/asset_server.dart index cabf3d208..eb0fb18a8 100644 --- a/frontend_server_common/lib/src/asset_server.dart +++ b/frontend_server_common/lib/src/asset_server.dart @@ -13,7 +13,6 @@ import 'package:dwds/asset_reader.dart'; import 'package:file/file.dart'; import 'package:logging/logging.dart'; import 'package:mime/mime.dart' as mime; -//import 'package:path/path.dart' as p; import 'package:shelf/shelf.dart' as shelf; import 'utilities.dart'; @@ -248,13 +247,6 @@ class TestAssetServer implements AssetReader { // If this is a dart file, it must be on the local file system and is // likely coming from a source map request. The tool doesn't currently // consider the case of Dart files as assets. - /*var dartFile = - _fileSystem.file(_fileSystem.currentDirectory.uri.resolve(path)); - if (dartFile.existsSync()) { - return dartFile; - }*/ - - //final relativePath = _stripLeadingSlashes(path); final dartFile = _fileSystem.file(_fileSystem.currentDirectory.uri.resolve(path)); if (dartFile.existsSync()) { @@ -266,11 +258,9 @@ class TestAssetServer implements AssetReader { // The file might have been a package file which is signaled by a // `/packages//` request. if (segments.first == 'packages') { - //var packageFile = _fileSystem.file(_packageConfig - // .resolve(Uri(scheme: 'package', pathSegments: segments.skip(1)))); - var packageFile = _fileSystem.file(_packageUriMapper.serverPathToResolvedUri(path)); + final resolved = _packageUriMapper.serverPathToResolvedUri(path); + final packageFile = _fileSystem.file(resolved); if (packageFile.existsSync()) { - _logger.info('XXX Found: $path -> $packageFile'); return packageFile; } _logger.severe('Package file not found: $path ($packageFile)'); @@ -335,7 +325,7 @@ class TestAssetServer implements AssetReader { } String? _stripBasePath(String path, String basePath) { - path = _stripLeadingSlashes(path); + path = stripLeadingSlashes(path); if (path.startsWith(basePath)) { path = path.substring(basePath.length); } else { @@ -343,7 +333,7 @@ class TestAssetServer implements AssetReader { _logger.severe('Path is not under $basePath: $path'); return null; } - return _stripLeadingSlashes(path); + return stripLeadingSlashes(path); } } @@ -354,11 +344,5 @@ Map _castStringKeyedMap(dynamic untyped) { return map.cast(); } -String _stripLeadingSlashes(String path) { - while (path.startsWith('/')) { - path = path.substring(1); - } - return path; -} diff --git a/frontend_server_common/lib/src/frontend_server_client.dart b/frontend_server_common/lib/src/frontend_server_client.dart index be918e999..d34cf71ee 100644 --- a/frontend_server_common/lib/src/frontend_server_client.dart +++ b/frontend_server_common/lib/src/frontend_server_client.dart @@ -255,6 +255,7 @@ class ResidentCompiler { this.sdkRoot, { required this.projectDirectory, required this.packageConfigFile, + required this.useDebuggerModuleNames, required this.fileSystemRoots, required this.fileSystemScheme, required this.platformDill, @@ -264,6 +265,7 @@ class ResidentCompiler { final Uri projectDirectory; final Uri packageConfigFile; + final bool useDebuggerModuleNames; final List fileSystemRoots; final String fileSystemScheme; final String platformDill; @@ -382,6 +384,8 @@ class ResidentCompiler { '--platform', platformDill, ], + if (useDebuggerModuleNames) + '--debugger-module-names', '--experimental-emit-debug-metadata', if (verbose) '--verbose' ]; diff --git a/frontend_server_common/lib/src/resident_runner.dart b/frontend_server_common/lib/src/resident_runner.dart index 292b4470f..6e6d395e1 100644 --- a/frontend_server_common/lib/src/resident_runner.dart +++ b/frontend_server_common/lib/src/resident_runner.dart @@ -29,6 +29,7 @@ class ResidentWebRunner { this.mainUri, this.urlTunneler, this.projectDirectory, + this.packageConfigFile, this.packageUriMapper, this.fileSystemRoots, this.fileSystemScheme, @@ -38,7 +39,8 @@ class ResidentWebRunner { generator = ResidentCompiler( dartSdkPath, projectDirectory: projectDirectory, - packageConfigFile: packageUriMapper.packageConfigFile, + packageConfigFile: packageConfigFile, + useDebuggerModuleNames: packageUriMapper.useDebuggerModuleNames, platformDill: soundNullSafety ? '$platformDillSound' : '$platformDillUnsound', fileSystemRoots: fileSystemRoots, @@ -51,6 +53,7 @@ class ResidentWebRunner { final UrlEncoder? urlTunneler; final Uri mainUri; final Uri projectDirectory; + final Uri packageConfigFile; final PackageUriMapper packageUriMapper; final String outputPath; final List fileSystemRoots; From d645806216e73cef04316455f0a20391dbdeb85c Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 30 Aug 2022 09:39:12 -0700 Subject: [PATCH 06/10] Cleanup --- dwds/lib/src/debugging/debugger.dart | 6 +- dwds/lib/src/debugging/metadata/provider.dart | 4 +- dwds/test/fixtures/context.dart | 8 --- ...rontend_server_circular_evaluate_test.dart | 8 ++- dwds/test/frontend_server_evaluate_test.dart | 43 +++++++----- fixtures/_testCircular2/lib/library2.dart | 3 +- .../_testCircular2Sound/lib/library2.dart | 3 +- .../lib/src/asset_server.dart | 67 ++++++++----------- frontend_server_common/lib/src/devfs.dart | 27 ++------ .../lib/src/frontend_server_client.dart | 8 +-- .../lib/src/resident_runner.dart | 3 +- webdev/lib/src/pubspec.dart | 4 +- webdev/test/e2e_test.dart | 31 ++++----- 13 files changed, 93 insertions(+), 122 deletions(-) diff --git a/dwds/lib/src/debugging/debugger.dart b/dwds/lib/src/debugging/debugger.dart index e4bfd3d96..8444ff7e2 100644 --- a/dwds/lib/src/debugging/debugger.dart +++ b/dwds/lib/src/debugging/debugger.dart @@ -808,7 +808,8 @@ class _Breakpoints extends Domain { 'addBreakpoint', 102, 'The VM is unable to add a breakpoint $id ' - 'at the specified line or function: ($scriptId:$line:$column): cannot find Dart location.'); + 'at the specified line or function: ($scriptId:$line:$column): ' + ' cannot find Dart location.'); } try { @@ -822,7 +823,8 @@ class _Breakpoints extends Domain { 'addBreakpoint', 102, 'The VM is unable to add a breakpoint $id ' - 'at the specified line or function: ($scriptId:$line:$column): cannot set JS breakpoint at $location'); + 'at the specified line or function: ($scriptId:$line:$column): ' + 'cannot set JS breakpoint at $location'); } _note(jsId: jsBreakpointId, bp: dartBreakpoint); return dartBreakpoint; diff --git a/dwds/lib/src/debugging/metadata/provider.dart b/dwds/lib/src/debugging/metadata/provider.dart index fda9e92ef..b045cbfb7 100644 --- a/dwds/lib/src/debugging/metadata/provider.dart +++ b/dwds/lib/src/debugging/metadata/provider.dart @@ -200,8 +200,8 @@ class MetadataProvider { _addMetadata(metadata); hasUnsoundNullSafety &= !metadata.soundNullSafety; hasSoundNullSafety &= metadata.soundNullSafety; - //_logger - // .fine('Loaded debug metadata for module: ${metadata.name}'); + _logger + .fine('Loaded debug metadata for module: ${metadata.name}'); } catch (e) { _logger.warning('Failed to read metadata: $e'); rethrow; diff --git a/dwds/test/fixtures/context.dart b/dwds/test/fixtures/context.dart index 88e71d6f1..c72e9f16f 100644 --- a/dwds/test/fixtures/context.dart +++ b/dwds/test/fixtures/context.dart @@ -33,7 +33,6 @@ import 'package:shelf/shelf.dart'; import 'package:shelf_proxy/shelf_proxy.dart'; import 'package:test/test.dart'; import 'package:vm_service/vm_service.dart'; -import 'package:pub_semver/pub_semver.dart' as semver; import 'package:webdriver/io.dart'; import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; @@ -41,13 +40,6 @@ import 'logging.dart'; import 'server.dart'; import 'utilities.dart'; -final _currentSdkVersion = semver.Version.parse(Platform.version.split(' ')[0]); -final _useDebuggerModuleNamesSdkVersion = - semver.Version(2, 19, 0, pre: '149.0.dev'); - -final isDebuggerModuleNamesFeatureSupported = - _currentSdkVersion.compareTo(_useDebuggerModuleNamesSdkVersion) > 0; - final _exeExt = Platform.isWindows ? '.exe' : ''; const isRPCError = TypeMatcher(); diff --git a/dwds/test/frontend_server_circular_evaluate_test.dart b/dwds/test/frontend_server_circular_evaluate_test.dart index 8c48562a6..448f83280 100644 --- a/dwds/test/frontend_server_circular_evaluate_test.dart +++ b/dwds/test/frontend_server_circular_evaluate_test.dart @@ -6,6 +6,7 @@ import 'dart:io'; +import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; import 'fixtures/context.dart'; @@ -15,6 +16,11 @@ void main() async { // Enable verbose logging for debugging. final debug = false; + // TODO(annagrin): Remove when 2.19.0-150.0.dev is in stable. + final debuggerModuleNamesSupported = + Version.parse(Platform.version.split(' ').first) >= + Version.parse('2.19.0-150.0.dev'); + group('Context with circular dependencies |', () { for (var nullSafety in NullSafety.values) { group('${nullSafety.name} null safety |', () { @@ -36,7 +42,7 @@ void main() async { // https://github.com/dart-lang/webdev/issues/1591); nullSafety == NullSafety.sound || // Needs debugger module names change in the SDK to work. - !isDebuggerModuleNamesFeatureSupported, + !debuggerModuleNamesSupported, ); } }); diff --git a/dwds/test/frontend_server_evaluate_test.dart b/dwds/test/frontend_server_evaluate_test.dart index 5c71434f8..56441ddb9 100644 --- a/dwds/test/frontend_server_evaluate_test.dart +++ b/dwds/test/frontend_server_evaluate_test.dart @@ -6,6 +6,7 @@ import 'dart:io'; +import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; import 'fixtures/context.dart'; @@ -15,29 +16,35 @@ void main() async { // Enable verbose logging for debugging. final debug = false; + // TODO(annagrin): Remove when 2.19.0-150.0.dev is in stable. + final debuggerModuleNamesSupported = + Version.parse(Platform.version.split(' ').first) >= + Version.parse('2.19.0-150.0.dev'); + for (var useDebuggerModuleNames in [false, true]) { group('Debugger module names: $useDebuggerModuleNames |', () { for (var nullSafety in NullSafety.values) { group('${nullSafety.name} null safety |', () { for (var indexBaseMode in IndexBaseMode.values) { - group('with ${indexBaseMode.name} |', () { - testAll( - compilationMode: CompilationMode.frontendServer, - indexBaseMode: indexBaseMode, - nullSafety: nullSafety, - useDebuggerModuleNames: useDebuggerModuleNames, - debug: debug, - ); - }, - skip: - // https://github.com/dart-lang/sdk/issues/49277 - (indexBaseMode == IndexBaseMode.base && - Platform.isWindows) || - // https://github.com/dart-lang/webdev/issues/1591 - (nullSafety == NullSafety.sound) || - // Needs debugger module names feature in SDK. - (useDebuggerModuleNames && - !isDebuggerModuleNamesFeatureSupported)); + group( + 'with ${indexBaseMode.name} |', + () { + testAll( + compilationMode: CompilationMode.frontendServer, + indexBaseMode: indexBaseMode, + nullSafety: nullSafety, + useDebuggerModuleNames: useDebuggerModuleNames, + debug: debug, + ); + }, + skip: + // https://github.com/dart-lang/sdk/issues/49277 + (indexBaseMode == IndexBaseMode.base && Platform.isWindows) || + // https://github.com/dart-lang/webdev/issues/1591 + (nullSafety == NullSafety.sound) || + // Needs debugger module names feature in SDK. + (useDebuggerModuleNames && !debuggerModuleNamesSupported), + ); } }); } diff --git a/fixtures/_testCircular2/lib/library2.dart b/fixtures/_testCircular2/lib/library2.dart index 7a1c8d410..4179dbbec 100644 --- a/fixtures/_testCircular2/lib/library2.dart +++ b/fixtures/_testCircular2/lib/library2.dart @@ -7,6 +7,5 @@ import 'package:_test_circular1/library1.dart'; void testCircularDependencies() { - print(concatenate('a', 'b')); // Breakpoint: testCircularDependencies + print(concatenate('a', 'b')); // Breakpoint: testCircularDependencies } - diff --git a/fixtures/_testCircular2Sound/lib/library2.dart b/fixtures/_testCircular2Sound/lib/library2.dart index b176c7c72..9a31ffb79 100644 --- a/fixtures/_testCircular2Sound/lib/library2.dart +++ b/fixtures/_testCircular2Sound/lib/library2.dart @@ -5,6 +5,5 @@ import 'package:_test_circular1_sound/library1.dart'; void testCircularDependencies() { - print(concatenate('a', 'b')); // Breakpoint: testCircularDependencies + print(concatenate('a', 'b')); // Breakpoint: testCircularDependencies } - diff --git a/frontend_server_common/lib/src/asset_server.dart b/frontend_server_common/lib/src/asset_server.dart index eb0fb18a8..6e56e9478 100644 --- a/frontend_server_common/lib/src/asset_server.dart +++ b/frontend_server_common/lib/src/asset_server.dart @@ -68,8 +68,8 @@ class TestAssetServer implements AssetReader { ) async { var address = (await InternetAddress.lookup(hostname)).first; var httpServer = await HttpServer.bind(address, port); - var server = - TestAssetServer(index, httpServer, packageUriMapper, address, fileSystem); + var server = TestAssetServer( + index, httpServer, packageUriMapper, address, fileSystem); return server; } @@ -98,41 +98,31 @@ class TestAssetServer implements AssetReader { return shelf.Response.notFound(''); } - // NOTE: shelf removes leading `/` for some reason. - //var requestPath = request.url.path; - //requestPath = requestPath.startsWith('/') ? requestPath : '/$requestPath'; - - //if (!request.url.path.endsWith('require.js') && - // !request.url.path.endsWith('dart_stack_trace_mapper.js')) { - // requestPath = _stripBasePath(requestPath, basePath) ?? requestPath; - - // requestPath = requestPath.startsWith('/') ? requestPath : '/$requestPath'; + // If this is a JavaScript file, it must be in the in-memory cache. + // Attempt to look up the file by URI. + if (hasFile(requestPath)) { + final List bytes = getFile(requestPath); + headers[HttpHeaders.contentLengthHeader] = bytes.length.toString(); + headers[HttpHeaders.contentTypeHeader] = 'application/javascript'; + return shelf.Response.ok(bytes, headers: headers); + } + // If this is a sourcemap file, then it might be in the in-memory cache. + // Attempt to lookup the file by URI. + if (hasSourceMap(requestPath)) { + final List bytes = getSourceMap(requestPath); + headers[HttpHeaders.contentLengthHeader] = bytes.length.toString(); + headers[HttpHeaders.contentTypeHeader] = 'application/json'; + return shelf.Response.ok(bytes, headers: headers); + } + // If this is a metadata file, then it might be in the in-memory cache. + // Attempt to lookup the file by URI. + if (hasMetadata(requestPath)) { + final List bytes = getMetadata(requestPath); + headers[HttpHeaders.contentLengthHeader] = bytes.length.toString(); + headers[HttpHeaders.contentTypeHeader] = 'application/json'; + return shelf.Response.ok(bytes, headers: headers); + } - // If this is a JavaScript file, it must be in the in-memory cache. - // Attempt to look up the file by URI. - if (hasFile(requestPath)) { - final List bytes = getFile(requestPath); - headers[HttpHeaders.contentLengthHeader] = bytes.length.toString(); - headers[HttpHeaders.contentTypeHeader] = 'application/javascript'; - return shelf.Response.ok(bytes, headers: headers); - } - // If this is a sourcemap file, then it might be in the in-memory cache. - // Attempt to lookup the file by URI. - if (hasSourceMap(requestPath)) { - final List bytes = getSourceMap(requestPath); - headers[HttpHeaders.contentLengthHeader] = bytes.length.toString(); - headers[HttpHeaders.contentTypeHeader] = 'application/json'; - return shelf.Response.ok(bytes, headers: headers); - } - // If this is a metadata file, then it might be in the in-memory cache. - // Attempt to lookup the file by URI. - if (hasMetadata(requestPath)) { - final List bytes = getMetadata(requestPath); - headers[HttpHeaders.contentLengthHeader] = bytes.length.toString(); - headers[HttpHeaders.contentTypeHeader] = 'application/json'; - return shelf.Response.ok(bytes, headers: headers); - } - //} var file = _resolveDartFile(requestPath); if (!file.existsSync()) { return shelf.Response.notFound(''); @@ -201,7 +191,7 @@ class TestAssetServer implements AssetReader { codeStart, codeEnd - codeStart, ); - + final fileName = filePath.startsWith('/') ? filePath.substring(1) : filePath; _files[fileName] = byteView; @@ -343,6 +333,3 @@ Map _castStringKeyedMap(dynamic untyped) { var map = untyped as Map; return map.cast(); } - - - diff --git a/frontend_server_common/lib/src/devfs.dart b/frontend_server_common/lib/src/devfs.dart index aecf43c18..25cd5c5ac 100644 --- a/frontend_server_common/lib/src/devfs.dart +++ b/frontend_server_common/lib/src/devfs.dart @@ -4,8 +4,6 @@ // Note: this is a copy from flutter tools, updated to work with dwds tests -import 'dart:io'; - import 'package:dwds/asset_reader.dart'; import 'package:file/file.dart'; import 'package:path/path.dart' as p; @@ -65,15 +63,16 @@ class WebDevFS { final outputDirectoryPath = fileSystem.file(mainPath).parent.path; final entryPoint = mainUri.toString(); - assetServer.writeFile(entryPoint, fileSystem.file(mainPath).readAsStringSync()); + assetServer.writeFile( + entryPoint, fileSystem.file(mainPath).readAsStringSync()); assetServer.writeFile('require.js', requireJS.readAsStringSync()); assetServer.writeFile( 'stack_trace_mapper.js', stackTraceMapper.readAsStringSync()); assetServer.writeFile( 'main.dart.js', generateBootstrapScript( - requireUrl: 'require.js', //_filePathToUriFragment(requireJS.path), - mapperUrl: 'stack_trace_mapper.js', //_filePathToUriFragment(stackTraceMapper.path), + requireUrl: 'require.js', + mapperUrl: 'stack_trace_mapper.js', entrypoint: entryPoint, ), ); @@ -85,13 +84,13 @@ class WebDevFS { ); assetServer.writeFile('main_module.digests', '{}'); - + var sdk = soundNullSafety ? dartSdkSound : dartSdk; var sdkSourceMap = soundNullSafety ? dartSdkSourcemapSound : dartSdkSourcemap; assetServer.writeFile('dart_sdk.js', sdk.readAsStringSync()); assetServer.writeFile('dart_sdk.js.map', sdkSourceMap.readAsStringSync()); - + generator.reset(); var compilerOutput = await generator.recompile( Uri.parse('org-dartlang-app:///$mainUri'), @@ -170,19 +169,6 @@ class WebDevFS { 'web', 'dart_stack_trace_mapper.js', )); -/* - String _filePathToUriFragment(String path, ) { - if (Platform.isWindows) { - var startWithSlash = path.startsWith('/'); - var partial = - fileSystem.path.split(path).skip(startWithSlash ? 2 : 1).join('/'); - if (partial.startsWith('/')) { - return partial; - } - return '/$partial'; - } - return path; - }*/ } class UpdateFSReport { @@ -208,4 +194,3 @@ class UpdateFSReport { /// Only used for JavaScript compilation. List? invalidatedModules; } - diff --git a/frontend_server_common/lib/src/frontend_server_client.dart b/frontend_server_common/lib/src/frontend_server_client.dart index d34cf71ee..321c6ac14 100644 --- a/frontend_server_common/lib/src/frontend_server_client.dart +++ b/frontend_server_common/lib/src/frontend_server_client.dart @@ -384,8 +384,7 @@ class ResidentCompiler { '--platform', platformDill, ], - if (useDebuggerModuleNames) - '--debugger-module-names', + if (useDebuggerModuleNames) '--debugger-module-names', '--experimental-emit-debug-metadata', if (verbose) '--verbose' ]; @@ -615,8 +614,9 @@ class TestExpressionCompiler implements ExpressionCompiler { line, column, jsModules, jsFrameValues, moduleName, expression); if (compilerOutput != null) { - var content = utf8.decode( - localFileSystem.file(compilerOutput.outputFilename).readAsBytesSync()); + var content = utf8.decode(localFileSystem + .file(compilerOutput.outputFilename) + .readAsBytesSync()); return ExpressionCompilationResult( content, compilerOutput.errorCount > 0); } diff --git a/frontend_server_common/lib/src/resident_runner.dart b/frontend_server_common/lib/src/resident_runner.dart index 6e6d395e1..16c793b8a 100644 --- a/frontend_server_common/lib/src/resident_runner.dart +++ b/frontend_server_common/lib/src/resident_runner.dart @@ -66,7 +66,8 @@ class ResidentWebRunner { late Uri uri; late Iterable modules; - Future run(FileSystem fileSystem, String? hostname, int port, String index) async { + Future run( + FileSystem fileSystem, String? hostname, int port, String index) async { devFS = WebDevFS( fileSystem: fileSystem, hostname: hostname ?? 'localhost', diff --git a/webdev/lib/src/pubspec.dart b/webdev/lib/src/pubspec.dart index dc67a400e..a5be96f83 100644 --- a/webdev/lib/src/pubspec.dart +++ b/webdev/lib/src/pubspec.dart @@ -163,7 +163,7 @@ Future> _validateBuildDaemonVersion( } final buildRunnerConstraint = VersionConstraint.parse('>=1.6.2 <3.0.0'); -final buildWebCompilersContraint = VersionConstraint.parse('>=2.12.0 <4.0.0'); +final buildWebCompilersConstraint = VersionConstraint.parse('>=2.12.0 <4.0.0'); // Note the minimum versions should never be dev versions as users will not // get them by default. @@ -178,7 +178,7 @@ Future checkPubspecLock(PubspecLock pubspecLock, if (requireBuildWebCompilers) { issues.addAll(pubspecLock.checkPackage( - 'build_web_compilers', buildWebCompilersContraint)); + 'build_web_compilers', buildWebCompilersConstraint)); } if (buildRunnerIssues.isEmpty) { diff --git a/webdev/test/e2e_test.dart b/webdev/test/e2e_test.dart index 6ee77b5b8..29a4b6b1e 100644 --- a/webdev/test/e2e_test.dart +++ b/webdev/test/e2e_test.dart @@ -35,19 +35,14 @@ const _testItems = { 'main.unsound.ddc.js': true, }; -void _logWriter(Level level, String message, - {String error, String loggerName, String stackTrace}) { - //if (level >= Level.INFO) { - print('[$level] $loggerName: $message'); - //} -} - void main() { + // Change to true for debugging. + final debug = false; + String exampleDirectory; String soundExampleDirectory; setUpAll(() async { - Logger.root.level = Level.ALL; - configureLogWriter(true, customLogWriter: _logWriter); + configureLogWriter(debug); exampleDirectory = p.absolute(p.join(p.current, '..', 'fixtures', '_webdevSmoke')); soundExampleDirectory = @@ -81,10 +76,10 @@ void main() { expect(smokeYaml['dev_dependencies']['build_runner'], equals(buildRunnerConstraint.toString())); expect(smokeYaml['dev_dependencies']['build_web_compilers'], - equals(buildWebCompilersContraint.toString())); + equals(buildWebCompilersConstraint.toString())); }); - test('build should fail if targetting an existing directory', () async { + test('build should fail if targeting an existing directory', () async { await d.file('simple thing', 'throw-away').create(); var args = ['build', '-o', 'web:${d.sandbox}']; @@ -289,18 +284,18 @@ void main() { group('should work with ', () { setUp(() async { - configureLogWriter(true, customLogWriter: _logWriter); + configureLogWriter(debug); }); - for (var soundNullSafety in [/*false,*/ true]) { + for (var soundNullSafety in [false, true]) { var nullSafetyOption = soundNullSafety ? 'sound' : 'unsound'; group('--null-safety=$nullSafetyOption', () { setUp(() async { - configureLogWriter(true, customLogWriter: _logWriter); + configureLogWriter(debug); }); group('and --enable-expression-evaluation:', () { setUp(() async { - configureLogWriter(true, customLogWriter: _logWriter); + configureLogWriter(debug); }); test('evaluateInFrame', () async { var openPort = await findUnusedPort(); @@ -310,14 +305,13 @@ void main() { 'web:$openPort', '--enable-expression-evaluation', '--verbose', - '--null-safety=unsound', ]; var process = await runWebDev(args, workingDirectory: soundNullSafety ? soundExampleDirectory : exampleDirectory); VmService vmService; - process.stdoutStream().listen(Logger.root.info); + process.stdoutStream().listen(Logger.root.fine); process.stderrStream().listen(Logger.root.warning); try { @@ -373,7 +367,6 @@ void main() { 'web:$openPort', '--enable-expression-evaluation', '--verbose', - '--null-safety=unsound', ]; var process = await runWebDev(args, workingDirectory: @@ -518,7 +511,7 @@ void main() { await process.shouldExit(); } }, timeout: const Timeout.factor(2)); - }, skip: true); + }); }); } }); From 3bdf57d67c35d9f0b87a41511592f8e9484d6ad5 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 30 Aug 2022 14:56:17 -0700 Subject: [PATCH 07/10] Added package_uri_mapper_tests, fixed failures in dart_uri tests --- .../src/loaders/frontend_server_require.dart | 2 +- dwds/lib/src/utilities/dart_uri.dart | 2 +- dwds/test/dart_uri_test.dart | 10 +++- dwds/test/package_uri_mapper_test.dart | 59 +++++++++++++++++++ 4 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 dwds/test/package_uri_mapper_test.dart diff --git a/dwds/lib/src/loaders/frontend_server_require.dart b/dwds/lib/src/loaders/frontend_server_require.dart index 63b66af7f..1b3dce2c8 100644 --- a/dwds/lib/src/loaders/frontend_server_require.dart +++ b/dwds/lib/src/loaders/frontend_server_require.dart @@ -79,7 +79,7 @@ class FrontendServerRequireStrategyProvider { if (appUri.isScheme('package')) { final resolved = _packageUriMapper.packageUriToServerPath(appUri); if (resolved != null) { - return _addBasePath(resolved); + return resolved; } } return null; diff --git a/dwds/lib/src/utilities/dart_uri.dart b/dwds/lib/src/utilities/dart_uri.dart index 03dc060c4..9c3e7d228 100644 --- a/dwds/lib/src/utilities/dart_uri.dart +++ b/dwds/lib/src/utilities/dart_uri.dart @@ -73,7 +73,7 @@ class DartUri { _logger.severe('Cannot find server path for $uri'); serverPath = uri; } - return DartUri._fromRelativePath(serverPath); + return DartUri._fromRelativePath(serverPath, root: root); } /// Construct from a file: URI diff --git a/dwds/test/dart_uri_test.dart b/dwds/test/dart_uri_test.dart index e44658206..ff271305c 100644 --- a/dwds/test/dart_uri_test.dart +++ b/dwds/test/dart_uri_test.dart @@ -16,8 +16,14 @@ import 'fixtures/fakes.dart'; class TestStrategy extends FakeStrategy { @override - String? serverPathForAppUri(String appUri) { - if (appUri.startsWith('org-dartlang-app:')) return 'foo'; + String? serverPathForAppUri(String appUrl) { + final appUri = Uri.parse(appUrl); + if (appUri.isScheme('org-dartlang-app')) { + return 'foo'; + } + if (appUri.isScheme('package')) { + return '/packages/${appUri.path}'; + } return null; } } diff --git a/dwds/test/package_uri_mapper_test.dart b/dwds/test/package_uri_mapper_test.dart new file mode 100644 index 000000000..e6e6d3e3e --- /dev/null +++ b/dwds/test/package_uri_mapper_test.dart @@ -0,0 +1,59 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// 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. + +@TestOn('vm') + +import 'package:dwds/dwds.dart'; +import 'package:file/local.dart'; +import 'package:path/path.dart' as p; +import 'package:test/test.dart'; + +void main() { + for (final useDebuggerModuleNames in [true, false]) { + group( + 'Package uri mapper with debugger module names: ' + ' $useDebuggerModuleNames |', () { + final fileSystem = LocalFileSystem(); + + final packageUri = + Uri(scheme: 'package', path: '_test_package/test_library.dart'); + + final serverPath = useDebuggerModuleNames + ? 'packages/_testPackage/lib/test_library.dart' + : '/packages/_test_package/test_library.dart'; + + final resolvedPath = + '/webdev/fixtures/_testPackage/lib/test_library.dart'; + + final packageConfigFile = Uri.file(p.normalize(p.absolute(p.join( + '..', + 'fixtures', + '_testPackage', + '.dart_tool', + 'package_config.json', + )))); + + late final PackageUriMapper packageUriMapper; + setUpAll(() async { + packageUriMapper = await PackageUriMapper.create( + fileSystem, + packageConfigFile, + useDebuggerModuleNames: useDebuggerModuleNames, + ); + }); + + test('Can convert package urls to server paths', () { + expect(packageUriMapper.packageUriToServerPath(packageUri), serverPath); + }); + + test('Can convert server paths to file paths', () { + expect( + packageUriMapper.serverPathToResolvedUri(serverPath), + isA() + .having((uri) => uri.scheme, 'scheme', 'file') + .having((uri) => uri.path, 'path', endsWith(resolvedPath))); + }); + }); + } +} From 13ede04f144ab54e5ae91706ac42ec83b6fe074d Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 30 Aug 2022 15:17:44 -0700 Subject: [PATCH 08/10] Fix location test failures --- dwds/test/location_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dwds/test/location_test.dart b/dwds/test/location_test.dart index ab5d93bce..92acf636a 100644 --- a/dwds/test/location_test.dart +++ b/dwds/test/location_test.dart @@ -23,7 +23,7 @@ void main() { const lineLength = 150; globalLoadStrategy = MockLoadStrategy(); - final dartUri = DartUri('org-dartlang://web/main.dart'); + final dartUri = DartUri('org-dartlang-app://web/main.dart'); final assetReader = FakeAssetReader(sourceMap: sourceMapContents); final modules = MockModules(); @@ -175,7 +175,7 @@ Matcher _matchJsLocation(int line, int column) => isA() .having((l) => l.column, 'column', column); const _module = 'packages/module'; -const _serverPath = 'package/module.js'; +const _serverPath = 'web/main.dart'; const _sourceMapPath = 'packages/module.js.map'; class MockLoadStrategy extends FakeStrategy { From ce78183cf68a062cbb807864b0c5536d18c72ae7 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 30 Aug 2022 17:22:43 -0700 Subject: [PATCH 09/10] Addressed CR comments, run dart uri tests with useDebuggerModuleNames flag --- dwds/lib/src/readers/asset_reader.dart | 15 +++++-- dwds/test/dart_uri_file_uri_test.dart | 56 ++++++++++++++------------ dwds/test/fixtures/context.dart | 1 + 3 files changed, 43 insertions(+), 29 deletions(-) diff --git a/dwds/lib/src/readers/asset_reader.dart b/dwds/lib/src/readers/asset_reader.dart index abdb6a070..435916db2 100644 --- a/dwds/lib/src/readers/asset_reader.dart +++ b/dwds/lib/src/readers/asset_reader.dart @@ -48,13 +48,22 @@ class PackageUriMapper { /// Note: needs to match `urlForComponentUri` in javascript_bundle.dart /// in SDK code. String? packageUriToServerPath(Uri packageUri) { + final defaultServerPath = '/packages/${packageUri.path}'; if (packageUri.isScheme('package')) { if (!useDebuggerModuleNames) { - return ('/packages/${packageUri.path}'); + return defaultServerPath; } final Uri? resolvedUri = packageConfig.resolve(packageUri); - final Package? package = packageConfig.packageOf(resolvedUri!); - final Uri root = package!.root; + if (resolvedUri == null) { + _logger.severe('Cannot resolve package uri $packageUri'); + return defaultServerPath; + } + final Package? package = packageConfig.packageOf(resolvedUri); + if (package == null) { + _logger.severe('Cannot find package for package uri $packageUri'); + return defaultServerPath; + } + final Uri root = package.root; final String relativeUrl = resolvedUri.toString().replaceFirst('$root', ''); final String? relativeRoot = _getRelativeRoot(root); diff --git a/dwds/test/dart_uri_file_uri_test.dart b/dwds/test/dart_uri_file_uri_test.dart index 828f80475..c8dc415b6 100644 --- a/dwds/test/dart_uri_file_uri_test.dart +++ b/dwds/test/dart_uri_file_uri_test.dart @@ -30,30 +30,34 @@ String get testPackageDir => context.workingDirectory; // These tests are separated out because we need a running isolate in order to // look up packages. void main() { - setUpAll(() async { - await context.setUp(); - }); - - tearDownAll(() async { - await context.tearDown(); - }); - - test('file path to org-dartlang-app', () { - final webMain = Uri.file(p.join(testPackageDir, 'web', 'main.dart')); - final uri = DartUri('$webMain'); - expect(uri.serverPath, 'main.dart'); - }); - - test('file path to this package', () { - final testPackageLib = - Uri.file(p.join(testPackageDir, 'lib', 'test_library.dart')); - final uri = DartUri('$testPackageLib'); - expect(uri.serverPath, 'packages/_test_package/test_library.dart'); - }); - - test('file path to another package', () { - final testLib = Uri.file(p.join(testDir, 'lib', 'library.dart')); - final dartUri = DartUri('$testLib'); - expect(dartUri.serverPath, 'packages/_test/library.dart'); - }); + for (final useDebuggerModuleNames in [false, true]) { + group('Debugger module names: $useDebuggerModuleNames', () { + setUpAll(() async { + await context.setUp(useDebuggerModuleNames: useDebuggerModuleNames); + }); + + tearDownAll(() async { + await context.tearDown(); + }); + + test('file path to org-dartlang-app', () { + final webMain = Uri.file(p.join(testPackageDir, 'web', 'main.dart')); + final uri = DartUri('$webMain'); + expect(uri.serverPath, 'main.dart'); + }); + + test('file path to this package', () { + final testPackageLib = + Uri.file(p.join(testPackageDir, 'lib', 'test_library.dart')); + final uri = DartUri('$testPackageLib'); + expect(uri.serverPath, 'packages/_test_package/test_library.dart'); + }); + + test('file path to another package', () { + final testLib = Uri.file(p.join(testDir, 'lib', 'library.dart')); + final dartUri = DartUri('$testLib'); + expect(dartUri.serverPath, 'packages/_test/library.dart'); + }); + }); + } } diff --git a/dwds/test/fixtures/context.dart b/dwds/test/fixtures/context.dart index c72e9f16f..830c1658f 100644 --- a/dwds/test/fixtures/context.dart +++ b/dwds/test/fixtures/context.dart @@ -165,6 +165,7 @@ class TestContext { sdkConfigurationProvider ??= DefaultSdkConfigurationProvider(); try { + DartUri.currentDirectory = workingDirectory; configureLogWriter(); _client = IOClient(HttpClient() From 49b9b46abcdefeaa3e809cd79479bcb48ee47ed5 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 30 Aug 2022 17:56:59 -0700 Subject: [PATCH 10/10] Run dart_uri_file_uri test with frontend server as well --- dwds/test/dart_uri_file_uri_test.dart | 90 +++++++++++++++++---------- 1 file changed, 58 insertions(+), 32 deletions(-) diff --git a/dwds/test/dart_uri_file_uri_test.dart b/dwds/test/dart_uri_file_uri_test.dart index c8dc415b6..80825dacc 100644 --- a/dwds/test/dart_uri_file_uri_test.dart +++ b/dwds/test/dart_uri_file_uri_test.dart @@ -12,52 +12,78 @@ import 'package:test/test.dart'; import 'fixtures/context.dart'; final context = TestContext( - directory: '../fixtures/_testPackage', + directory: p.join('..', 'fixtures', '_testPackage'), + entry: p.join('..', 'fixtures', '_testPackage', 'web', 'main.dart'), path: 'index.html', pathToServe: 'web'); -String get dwdsDir => Directory.current.absolute.path; +final dwdsDir = Directory.current.absolute.path; /// The directory for the general _test package. -String get testDir => p.join(p.dirname(dwdsDir), 'fixtures', '_test'); +final testDir = p.join(p.dirname(dwdsDir), 'fixtures', '_test'); /// The directory for the _testPackage package (contained within dwds), which /// imports _test. -String get testPackageDir => context.workingDirectory; +final testPackageDir = context.workingDirectory; // This tests converting file Uris into our internal paths. // // These tests are separated out because we need a running isolate in order to // look up packages. void main() { - for (final useDebuggerModuleNames in [false, true]) { - group('Debugger module names: $useDebuggerModuleNames', () { - setUpAll(() async { - await context.setUp(useDebuggerModuleNames: useDebuggerModuleNames); - }); - - tearDownAll(() async { - await context.tearDown(); - }); - - test('file path to org-dartlang-app', () { - final webMain = Uri.file(p.join(testPackageDir, 'web', 'main.dart')); - final uri = DartUri('$webMain'); - expect(uri.serverPath, 'main.dart'); - }); - - test('file path to this package', () { - final testPackageLib = - Uri.file(p.join(testPackageDir, 'lib', 'test_library.dart')); - final uri = DartUri('$testPackageLib'); - expect(uri.serverPath, 'packages/_test_package/test_library.dart'); - }); - - test('file path to another package', () { - final testLib = Uri.file(p.join(testDir, 'lib', 'library.dart')); - final dartUri = DartUri('$testLib'); - expect(dartUri.serverPath, 'packages/_test/library.dart'); - }); + for (final compilationMode in CompilationMode.values) { + group('$compilationMode |', () { + for (final useDebuggerModuleNames in [false, true]) { + group('Debugger module names: $useDebuggerModuleNames |', () { + final appServerPath = + compilationMode == CompilationMode.frontendServer + ? 'web/main.dart' + : 'main.dart'; + + final serverPath = + compilationMode == CompilationMode.frontendServer && + useDebuggerModuleNames + ? 'packages/_testPackage/lib/test_library.dart' + : 'packages/_test_package/test_library.dart'; + + final anotherServerPath = + compilationMode == CompilationMode.frontendServer && + useDebuggerModuleNames + ? 'packages/_test/lib/library.dart' + : 'packages/_test/library.dart'; + + setUpAll(() async { + await context.setUp( + compilationMode: compilationMode, + useDebuggerModuleNames: useDebuggerModuleNames, + ); + }); + + tearDownAll(() async { + await context.tearDown(); + }); + + test('file path to org-dartlang-app', () { + final webMain = + Uri.file(p.join(testPackageDir, 'web', 'main.dart')); + final uri = DartUri('$webMain'); + expect(uri.serverPath, appServerPath); + }); + + test('file path to this package', () { + final testPackageLib = + Uri.file(p.join(testPackageDir, 'lib', 'test_library.dart')); + final uri = DartUri('$testPackageLib'); + expect(uri.serverPath, serverPath); + }); + + test('file path to another package', () { + final testLib = Uri.file(p.join(testDir, 'lib', 'library.dart')); + final dartUri = DartUri('$testLib'); + expect(dartUri.serverPath, anotherServerPath); + }); + }); + } }); } }