mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
[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 <bkonyi@google.com> Commit-Queue: Ben Konyi <bkonyi@google.com>
This commit is contained in:
parent
142bf69440
commit
37be66028b
|
@ -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 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] `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] `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
|
# 2.4.0
|
||||||
- [DAP] Added support for sending progress notifications via `DartDebugAdapter.startProgressNotification`.
|
- [DAP] Added support for sending progress notifications via `DartDebugAdapter.startProgressNotification`.
|
||||||
|
|
|
@ -325,7 +325,14 @@ abstract class DartDebugAdapter<TL extends LaunchRequestArguments,
|
||||||
vm.VmServiceInterface? vmService;
|
vm.VmServiceInterface? vmService;
|
||||||
|
|
||||||
/// The root of the Dart SDK containing the VM running the debug adapter.
|
/// The root of the Dart SDK containing the VM running the debug adapter.
|
||||||
late final String sdkRoot;
|
late final String dartSdkRoot;
|
||||||
|
|
||||||
|
/// Mappings of file paths to 'org-dartlang-sdk:///' URIs used for translating
|
||||||
|
/// URIs/paths between the DAP client and the VM.
|
||||||
|
///
|
||||||
|
/// Keys are the base file paths and the values are the base URIs. Neither
|
||||||
|
/// value should contain trailing slashes.
|
||||||
|
final Map<String, Uri> orgDartlangSdkMappings = {};
|
||||||
|
|
||||||
/// The DDS instance that was started and that [vmService] is connected to.
|
/// The DDS instance that was started and that [vmService] is connected to.
|
||||||
///
|
///
|
||||||
|
@ -450,7 +457,8 @@ abstract class DartDebugAdapter<TL extends LaunchRequestArguments,
|
||||||
channel.closed.then((_) => shutdown());
|
channel.closed.then((_) => shutdown());
|
||||||
|
|
||||||
final vmPath = Platform.resolvedExecutable;
|
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);
|
_isolateManager = IsolateManager(this);
|
||||||
_converter = ProtocolConverter(this);
|
_converter = ProtocolConverter(this);
|
||||||
|
@ -1316,16 +1324,6 @@ abstract class DartDebugAdapter<TL extends LaunchRequestArguments,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The default location for [dartlangSdkRootUri].
|
|
||||||
final _defaultDartlangSdkRootUri = Uri.parse('org-dartlang-sdk:///sdk');
|
|
||||||
|
|
||||||
/// The (org-dartlang-sdk) URI for the root of the Dart SDK.
|
|
||||||
///
|
|
||||||
/// This can be overriden by debug adapters like Flutter where the Dart SDK
|
|
||||||
/// root is at another path (such as
|
|
||||||
/// `org-dartlang-sdk:///third_party/dart/sdk/`).
|
|
||||||
Uri get dartlangSdkRootUri => _defaultDartlangSdkRootUri;
|
|
||||||
|
|
||||||
/// Converts a URI in the form org-dartlang-sdk:///sdk/lib/collection/hash_set.dart
|
/// 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.
|
/// to a local file path based on the current SDK.
|
||||||
String? convertOrgDartlangSdkToPath(Uri uri) {
|
String? convertOrgDartlangSdkToPath(Uri uri) {
|
||||||
|
@ -1337,12 +1335,15 @@ abstract class DartDebugAdapter<TL extends LaunchRequestArguments,
|
||||||
// We currently only handle the sdk folder, as we don't know which runtime
|
// We currently only handle the sdk folder, as we don't know which runtime
|
||||||
// is being used (this code is shared) and do not want to map to the wrong
|
// is being used (this code is shared) and do not want to map to the wrong
|
||||||
// sources.
|
// sources.
|
||||||
if (uri.pathSegments.isNotEmpty &&
|
for (final mapping in orgDartlangSdkMappings.entries) {
|
||||||
uri.path.startsWith(dartlangSdkRootUri.path)) {
|
final mapPath = mapping.key;
|
||||||
return path.joinAll([
|
final mapUri = mapping.value;
|
||||||
sdkRoot,
|
if (uri.isScheme(mapUri.scheme) && uri.path.startsWith(mapUri.path)) {
|
||||||
...uri.pathSegments.skip(dartlangSdkRootUri.pathSegments.length),
|
return path.joinAll([
|
||||||
]);
|
mapPath,
|
||||||
|
...uri.pathSegments.skip(mapUri.pathSegments.length),
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -1351,16 +1352,17 @@ abstract class DartDebugAdapter<TL extends LaunchRequestArguments,
|
||||||
/// Converts a file path inside the current SDK root into a URI in the form
|
/// Converts a file path inside the current SDK root into a URI in the form
|
||||||
/// org-dartlang-sdk:///sdk/lib/collection/hash_set.dart.
|
/// org-dartlang-sdk:///sdk/lib/collection/hash_set.dart.
|
||||||
Uri? convertPathToOrgDartlangSdk(String input) {
|
Uri? convertPathToOrgDartlangSdk(String input) {
|
||||||
if (path.isWithin(sdkRoot, input)) {
|
for (final mapping in orgDartlangSdkMappings.entries) {
|
||||||
final relative = path.relative(input, from: sdkRoot);
|
final mapPath = mapping.key;
|
||||||
return Uri(
|
final mapUri = mapping.value;
|
||||||
scheme: dartlangSdkRootUri.scheme,
|
if (path.isWithin(mapPath, input)) {
|
||||||
host: '',
|
final relative = path.relative(input, from: mapPath);
|
||||||
pathSegments: [
|
return Uri(
|
||||||
...dartlangSdkRootUri.pathSegments,
|
scheme: mapUri.scheme,
|
||||||
...path.split(relative)
|
host: '',
|
||||||
],
|
pathSegments: [...mapUri.pathSegments, ...path.split(relative)],
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -998,10 +998,8 @@ class ThreadInfo {
|
||||||
return null;
|
return null;
|
||||||
} else if (input.isScheme('file')) {
|
} else if (input.isScheme('file')) {
|
||||||
return input.toFilePath();
|
return input.toFilePath();
|
||||||
} else if (input.isScheme(_manager._adapter.dartlangSdkRootUri.scheme)) {
|
|
||||||
return _manager._adapter.convertOrgDartlangSdkToPath(input);
|
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return _manager._adapter.convertOrgDartlangSdkToPath(input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: dds
|
name: dds
|
||||||
version: 2.4.0
|
version: 2.5.0
|
||||||
description: >-
|
description: >-
|
||||||
A library used to spawn the Dart Developer Service, used to communicate with
|
A library used to spawn the Dart Developer Service, used to communicate with
|
||||||
a Dart VM Service instance.
|
a Dart VM Service instance.
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:dds/src/dap/protocol_stream.dart';
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
@ -14,54 +16,104 @@ main() {
|
||||||
final vmPath = Platform.resolvedExecutable;
|
final vmPath = Platform.resolvedExecutable;
|
||||||
final sdkRoot = path.dirname(path.dirname(vmPath));
|
final sdkRoot = path.dirname(path.dirname(vmPath));
|
||||||
|
|
||||||
final sdkCorePath = path.join(sdkRoot, 'lib', 'core.dart');
|
group('default Dart SDK', () {
|
||||||
final defaultCoreUri = Uri.parse('org-dartlang-sdk:///sdk/lib/core.dart');
|
final testPath = path.join(sdkRoot, 'lib', 'core.dart');
|
||||||
|
final testUri = Uri.parse('org-dartlang-sdk:///sdk/lib/core.dart');
|
||||||
group('default org-dartlang-sdk', () {
|
|
||||||
final adapter = MockDartCliDebugAdapter();
|
final adapter = MockDartCliDebugAdapter();
|
||||||
|
|
||||||
test('can SDK paths to org-dartlang-sdk:///', () async {
|
test('converts SDK paths to org-dartlang-sdk:///', () async {
|
||||||
expect(
|
expect(
|
||||||
adapter.convertPathToOrgDartlangSdk(sdkCorePath),
|
adapter.convertPathToOrgDartlangSdk(testPath),
|
||||||
defaultCoreUri,
|
testUri,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('converts org-dartlang-sdk:/// to SDK paths', () async {
|
test('converts org-dartlang-sdk:/// to SDK paths', () async {
|
||||||
expect(
|
expect(
|
||||||
adapter.convertOrgDartlangSdkToPath(defaultCoreUri),
|
adapter.convertOrgDartlangSdkToPath(testUri),
|
||||||
sdkCorePath,
|
testPath,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('custom org-dartlang-sdk', () {
|
group('custom Dart SDK', () {
|
||||||
final adapter = MockDartCliDebugAdapter()
|
final testPath = path.join(sdkRoot, 'lib', 'core.dart');
|
||||||
..dartlangSdkRootUriOverride =
|
final testUri =
|
||||||
Uri.parse('org-dartlang-sdk:///custom/sdk');
|
Uri.parse('org-dartlang-sdk:///custom-dart/sdk/lib/core.dart');
|
||||||
final customCoreUri =
|
final defaultSdkTestUri =
|
||||||
Uri.parse('org-dartlang-sdk:///custom/sdk/lib/core.dart');
|
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 {
|
test('converts SDK paths to custom org-dartlang-sdk:///', () async {
|
||||||
expect(
|
expect(
|
||||||
adapter.convertPathToOrgDartlangSdk(sdkCorePath),
|
adapter.convertPathToOrgDartlangSdk(testPath),
|
||||||
customCoreUri,
|
testUri,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('converts custom org-dartlang-sdk:/// to SDK paths', () async {
|
test('converts custom org-dartlang-sdk:/// to SDK paths', () async {
|
||||||
expect(
|
expect(
|
||||||
adapter.convertOrgDartlangSdkToPath(customCoreUri),
|
adapter.convertOrgDartlangSdkToPath(testUri),
|
||||||
sdkCorePath,
|
testPath,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('does not convert default org-dartlang-sdk:///', () async {
|
test('does not convert default org-dartlang-sdk:/// to SDK paths',
|
||||||
|
() async {
|
||||||
expect(
|
expect(
|
||||||
adapter.convertOrgDartlangSdkToPath(defaultCoreUri),
|
adapter.convertOrgDartlangSdkToPath(defaultSdkTestUri),
|
||||||
isNull,
|
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<String, Uri> customMappings) {
|
||||||
|
final stdinController = StreamController<List<int>>();
|
||||||
|
final stdoutController = StreamController<List<int>>();
|
||||||
|
final channel = ByteStreamServerChannel(
|
||||||
|
stdinController.stream, stdoutController.sink, null);
|
||||||
|
|
||||||
|
return MockCustomDartCliDebugAdapter._(
|
||||||
|
customMappings, stdinController.sink, stdoutController.stream, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
MockCustomDartCliDebugAdapter._(
|
||||||
|
Map<String, Uri> customMappings,
|
||||||
|
StreamSink<List<int>> stdin,
|
||||||
|
Stream<List<int>> stdout,
|
||||||
|
ByteStreamServerChannel channel)
|
||||||
|
: super.withStreams(stdin, stdout, channel) {
|
||||||
|
orgDartlangSdkMappings
|
||||||
|
..clear()
|
||||||
|
..addAll(customMappings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -26,20 +26,11 @@ class MockDartCliDebugAdapter extends DartCliDebugAdapter {
|
||||||
final channel = ByteStreamServerChannel(
|
final channel = ByteStreamServerChannel(
|
||||||
stdinController.stream, stdoutController.sink, null);
|
stdinController.stream, stdoutController.sink, null);
|
||||||
|
|
||||||
return MockDartCliDebugAdapter._(
|
return MockDartCliDebugAdapter.withStreams(
|
||||||
stdinController.sink, stdoutController.stream, channel);
|
stdinController.sink, stdoutController.stream, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An override for [dartlangSdkRootUri].
|
MockDartCliDebugAdapter.withStreams(
|
||||||
///
|
|
||||||
/// If not set, the default base value will be used.
|
|
||||||
Uri? dartlangSdkRootUriOverride;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Uri get dartlangSdkRootUri =>
|
|
||||||
dartlangSdkRootUriOverride ?? super.dartlangSdkRootUri;
|
|
||||||
|
|
||||||
MockDartCliDebugAdapter._(
|
|
||||||
this.stdin, this.stdout, ByteStreamServerChannel channel)
|
this.stdin, this.stdout, ByteStreamServerChannel channel)
|
||||||
: super(channel);
|
: super(channel);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue