From 37be66028b518461228a22eab43a40bf975f9767 Mon Sep 17 00:00:00 2001 From: Danny Tuppeny Date: Wed, 26 Oct 2022 14:26:01 +0000 Subject: [PATCH] [dds/dap] Allow debug adapters to register multiple mappings for org-dartland-sdk URIs Change-Id: Ibcb0f145d64c7cd7712c031737741b2dbc4aaab8 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/265500 Reviewed-by: Ben Konyi Commit-Queue: Ben Konyi --- pkg/dds/CHANGELOG.md | 3 +- pkg/dds/lib/src/dap/adapters/dart.dart | 58 ++++++++------- pkg/dds/lib/src/dap/isolate_manager.dart | 4 +- pkg/dds/pubspec.yaml | 2 +- pkg/dds/test/dap/base_adapter_test.dart | 94 ++++++++++++++++++------ pkg/dds/test/dap/mocks.dart | 13 +--- 6 files changed, 109 insertions(+), 65 deletions(-) diff --git a/pkg/dds/CHANGELOG.md b/pkg/dds/CHANGELOG.md index b3a64a8b9aa..9c2353ee128 100644 --- a/pkg/dds/CHANGELOG.md +++ b/pkg/dds/CHANGELOG.md @@ -1,7 +1,8 @@ -# 2.5.0-dev +# 2.5.0 - [DAP] `variables` requests now treat lists from `dart:typed_data` (such as `Uint8List`) like standard `List` instances and return their elements instead of class fields. - [DAP] `variables` requests now return information about the number of items in lists to allow the client to page through them. - [DAP] `terminated` events are now always sent when detaching whether or not the debuggee terminates after unpause. +- [DAP] Debug adapters can now add/overwrite `orgDartlangSdkMappings` to control mappings of `org-dartlang-sdk:///` paths. # 2.4.0 - [DAP] Added support for sending progress notifications via `DartDebugAdapter.startProgressNotification`. diff --git a/pkg/dds/lib/src/dap/adapters/dart.dart b/pkg/dds/lib/src/dap/adapters/dart.dart index 73a2775b60a..908ee1e62f7 100644 --- a/pkg/dds/lib/src/dap/adapters/dart.dart +++ b/pkg/dds/lib/src/dap/adapters/dart.dart @@ -325,7 +325,14 @@ abstract class DartDebugAdapter orgDartlangSdkMappings = {}; /// The DDS instance that was started and that [vmService] is connected to. /// @@ -450,7 +457,8 @@ abstract class DartDebugAdapter shutdown()); final vmPath = Platform.resolvedExecutable; - sdkRoot = path.dirname(path.dirname(vmPath)); + dartSdkRoot = path.dirname(path.dirname(vmPath)); + orgDartlangSdkMappings[dartSdkRoot] = Uri.parse('org-dartlang-sdk:///sdk'); _isolateManager = IsolateManager(this); _converter = ProtocolConverter(this); @@ -1316,16 +1324,6 @@ abstract class DartDebugAdapter _defaultDartlangSdkRootUri; - /// Converts a URI in the form org-dartlang-sdk:///sdk/lib/collection/hash_set.dart /// to a local file path based on the current SDK. String? convertOrgDartlangSdkToPath(Uri uri) { @@ -1337,12 +1335,15 @@ abstract class DartDebugAdapter- A library used to spawn the Dart Developer Service, used to communicate with a Dart VM Service instance. diff --git a/pkg/dds/test/dap/base_adapter_test.dart b/pkg/dds/test/dap/base_adapter_test.dart index 14608bcc8a5..c049d361e34 100644 --- a/pkg/dds/test/dap/base_adapter_test.dart +++ b/pkg/dds/test/dap/base_adapter_test.dart @@ -2,8 +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 'dart:async'; import 'dart:io'; +import 'package:dds/src/dap/protocol_stream.dart'; import 'package:path/path.dart' as path; import 'package:test/test.dart'; @@ -14,54 +16,104 @@ main() { final vmPath = Platform.resolvedExecutable; final sdkRoot = path.dirname(path.dirname(vmPath)); - final sdkCorePath = path.join(sdkRoot, 'lib', 'core.dart'); - final defaultCoreUri = Uri.parse('org-dartlang-sdk:///sdk/lib/core.dart'); - - group('default org-dartlang-sdk', () { + group('default Dart SDK', () { + final testPath = path.join(sdkRoot, 'lib', 'core.dart'); + final testUri = Uri.parse('org-dartlang-sdk:///sdk/lib/core.dart'); final adapter = MockDartCliDebugAdapter(); - test('can SDK paths to org-dartlang-sdk:///', () async { + test('converts SDK paths to org-dartlang-sdk:///', () async { expect( - adapter.convertPathToOrgDartlangSdk(sdkCorePath), - defaultCoreUri, + adapter.convertPathToOrgDartlangSdk(testPath), + testUri, ); }); test('converts org-dartlang-sdk:/// to SDK paths', () async { expect( - adapter.convertOrgDartlangSdkToPath(defaultCoreUri), - sdkCorePath, + adapter.convertOrgDartlangSdkToPath(testUri), + testPath, ); }); }); - group('custom org-dartlang-sdk', () { - final adapter = MockDartCliDebugAdapter() - ..dartlangSdkRootUriOverride = - Uri.parse('org-dartlang-sdk:///custom/sdk'); - final customCoreUri = - Uri.parse('org-dartlang-sdk:///custom/sdk/lib/core.dart'); + group('custom Dart SDK', () { + final testPath = path.join(sdkRoot, 'lib', 'core.dart'); + final testUri = + Uri.parse('org-dartlang-sdk:///custom-dart/sdk/lib/core.dart'); + final defaultSdkTestUri = + Uri.parse('org-dartlang-sdk:///sdk/lib/core.dart'); + final adapter = MockCustomDartCliDebugAdapter( + {sdkRoot: Uri.parse('org-dartlang-sdk:///custom-dart/sdk')}); test('converts SDK paths to custom org-dartlang-sdk:///', () async { expect( - adapter.convertPathToOrgDartlangSdk(sdkCorePath), - customCoreUri, + adapter.convertPathToOrgDartlangSdk(testPath), + testUri, ); }); test('converts custom org-dartlang-sdk:/// to SDK paths', () async { expect( - adapter.convertOrgDartlangSdkToPath(customCoreUri), - sdkCorePath, + adapter.convertOrgDartlangSdkToPath(testUri), + testPath, ); }); - test('does not convert default org-dartlang-sdk:///', () async { + test('does not convert default org-dartlang-sdk:/// to SDK paths', + () async { expect( - adapter.convertOrgDartlangSdkToPath(defaultCoreUri), + adapter.convertOrgDartlangSdkToPath(defaultSdkTestUri), isNull, ); }); }); + + group('additional SDKs', () { + final customSdkRootPath = path.join('my', 'flutter', 'sdk'); + final customSdkRootUri = Uri.parse('org-dartlang-sdk:///flutter/sdk'); + final testPath = path.join(customSdkRootPath, 'lib', 'ui.dart'); + final testUri = Uri.parse('org-dartlang-sdk:///flutter/sdk/lib/ui.dart'); + final adapter = MockCustomDartCliDebugAdapter({ + customSdkRootPath: customSdkRootUri, + }); + + test('converts additional SDK paths to custom org-dartlang-sdk:///', + () async { + expect( + adapter.convertPathToOrgDartlangSdk(testPath), + testUri, + ); + }); + + test('converts additional SDK org-dartlang-sdk:/// to paths', () async { + expect( + adapter.convertOrgDartlangSdkToPath(testUri), + testPath, + ); + }); + }); }); } + +class MockCustomDartCliDebugAdapter extends MockDartCliDebugAdapter { + factory MockCustomDartCliDebugAdapter(Map customMappings) { + final stdinController = StreamController>(); + final stdoutController = StreamController>(); + final channel = ByteStreamServerChannel( + stdinController.stream, stdoutController.sink, null); + + return MockCustomDartCliDebugAdapter._( + customMappings, stdinController.sink, stdoutController.stream, channel); + } + + MockCustomDartCliDebugAdapter._( + Map customMappings, + StreamSink> stdin, + Stream> stdout, + ByteStreamServerChannel channel) + : super.withStreams(stdin, stdout, channel) { + orgDartlangSdkMappings + ..clear() + ..addAll(customMappings); + } +} diff --git a/pkg/dds/test/dap/mocks.dart b/pkg/dds/test/dap/mocks.dart index fb810a9b9f5..c9c8b9713a3 100644 --- a/pkg/dds/test/dap/mocks.dart +++ b/pkg/dds/test/dap/mocks.dart @@ -26,20 +26,11 @@ class MockDartCliDebugAdapter extends DartCliDebugAdapter { final channel = ByteStreamServerChannel( stdinController.stream, stdoutController.sink, null); - return MockDartCliDebugAdapter._( + return MockDartCliDebugAdapter.withStreams( stdinController.sink, stdoutController.stream, channel); } - /// An override for [dartlangSdkRootUri]. - /// - /// If not set, the default base value will be used. - Uri? dartlangSdkRootUriOverride; - - @override - Uri get dartlangSdkRootUri => - dartlangSdkRootUriOverride ?? super.dartlangSdkRootUri; - - MockDartCliDebugAdapter._( + MockDartCliDebugAdapter.withStreams( this.stdin, this.stdout, ByteStreamServerChannel channel) : super(channel);