Skip to content

Commit 3079873

Browse files
authored
[flutter_tools/dap] Map org-dartlang-sdk URIs to the location of the source files found by the analyzer (#114369)
1 parent 1f7bacf commit 3079873

File tree

4 files changed

+100
-7
lines changed

4 files changed

+100
-7
lines changed

packages/flutter_tools/lib/src/debug_adapters/flutter_adapter.dart

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import 'mixins.dart';
1919

2020
/// A DAP Debug Adapter for running and debugging Flutter applications.
2121
class FlutterDebugAdapter extends DartDebugAdapter<FlutterLaunchRequestArguments, FlutterAttachRequestArguments>
22-
with PidTracker {
22+
with PidTracker, FlutterAdapter {
2323
FlutterDebugAdapter(
2424
super.channel, {
2525
required this.fileSystem,
@@ -30,14 +30,21 @@ class FlutterDebugAdapter extends DartDebugAdapter<FlutterLaunchRequestArguments
3030
super.logger,
3131
super.onError,
3232
}) : _enableDds = enableDds,
33+
flutterSdkRoot = Cache.flutterRoot!,
3334
// Always disable in the DAP layer as it's handled in the spawned
3435
// 'flutter' process.
35-
super(enableDds: false);
36+
super(enableDds: false) {
37+
configureOrgDartlangSdkMappings();
38+
}
3639

40+
@override
3741
FileSystem fileSystem;
3842
Platform platform;
3943
Process? _process;
4044

45+
@override
46+
final String flutterSdkRoot;
47+
4148
/// Whether DDS should be enabled in the Flutter process.
4249
///
4350
/// We never enable DDS in the DAP process for Flutter, so this value is not

packages/flutter_tools/lib/src/debug_adapters/flutter_test_adapter.dart

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import 'mixins.dart';
1919

2020
/// A DAP Debug Adapter for running and debugging Flutter tests.
2121
class FlutterTestDebugAdapter extends DartDebugAdapter<FlutterLaunchRequestArguments, FlutterAttachRequestArguments>
22-
with PidTracker, TestAdapter {
22+
with PidTracker, FlutterAdapter, TestAdapter {
2323
FlutterTestDebugAdapter(
2424
super.channel, {
2525
required this.fileSystem,
@@ -30,14 +30,21 @@ class FlutterTestDebugAdapter extends DartDebugAdapter<FlutterLaunchRequestArgum
3030
super.logger,
3131
super.onError,
3232
}) : _enableDds = enableDds,
33+
flutterSdkRoot = Cache.flutterRoot!,
3334
// Always disable in the DAP layer as it's handled in the spawned
3435
// 'flutter' process.
35-
super(enableDds: false);
36+
super(enableDds: false) {
37+
configureOrgDartlangSdkMappings();
38+
}
3639

40+
@override
3741
FileSystem fileSystem;
3842
Platform platform;
3943
Process? _process;
4044

45+
@override
46+
final String flutterSdkRoot;
47+
4148
/// Whether DDS should be enabled in the Flutter process.
4249
///
4350
/// We never enable DDS in the DAP process for Flutter, so this value is not

packages/flutter_tools/lib/src/debug_adapters/mixins.dart

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
import '../base/file_system.dart';
56
import '../base/io.dart';
67

78
/// A mixin for tracking additional PIDs that can be shut down at the end of a debug session.
@@ -22,3 +23,38 @@ mixin PidTracker {
2223
pidsToTerminate.forEach(signal.send);
2324
}
2425
}
26+
27+
mixin FlutterAdapter {
28+
Map<String, Uri> get orgDartlangSdkMappings;
29+
String get flutterSdkRoot;
30+
FileSystem get fileSystem;
31+
32+
void configureOrgDartlangSdkMappings() {
33+
/// When a user navigates into 'dart:xxx' sources in their editor (via the
34+
/// analysis server) they will land in flutter_sdk/bin/cache/pkg/sky_engine.
35+
///
36+
/// The running VM knows nothing about these paths and will resolve these
37+
/// libraries to 'org-dartlang-sdk://' URIs. We need to map between these
38+
/// to ensure that if a user puts a breakpoint inside sky_engine the VM can
39+
/// apply it to the correct place and once hit, we can navigate the user
40+
/// back to the correct file on their disk.
41+
///
42+
/// The mapping is handled by the base adapter but we need to override the
43+
/// paths to match the layout used by Flutter.
44+
///
45+
/// In future this might become unnecessary if
46+
/// https://github.com/dart-lang/sdk/issues/48435 is implemented. Until
47+
/// then, providing these mappings improves the debugging experience.
48+
49+
// Clear original Dart SDK mappings because they're not valid here.
50+
orgDartlangSdkMappings.clear();
51+
52+
// 'dart:ui' maps to /flutter/lib/ui
53+
final String flutterRoot = fileSystem.path.join(flutterSdkRoot, 'bin', 'cache', 'pkg', 'sky_engine', 'lib', 'ui');
54+
orgDartlangSdkMappings[flutterRoot] = Uri.parse('org-dartlang-sdk:///flutter/lib/ui');
55+
56+
// The rest of the Dart SDK maps to /third_party/dart/sdk
57+
final String dartRoot = fileSystem.path.join(flutterSdkRoot, 'bin', 'cache', 'pkg', 'sky_engine');
58+
orgDartlangSdkMappings[dartRoot] = Uri.parse('org-dartlang-sdk:///third_party/dart/sdk');
59+
}
60+
}

packages/flutter_tools/test/general.shard/dap/flutter_adapter_test.dart

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import 'dart:async';
66

77
import 'package:dds/dap.dart';
88
import 'package:file/memory.dart';
9+
import 'package:flutter_tools/src/base/file_system.dart';
910
import 'package:flutter_tools/src/base/platform.dart';
1011
import 'package:flutter_tools/src/cache.dart';
12+
import 'package:flutter_tools/src/debug_adapters/flutter_adapter.dart';
1113
import 'package:flutter_tools/src/debug_adapters/flutter_adapter_args.dart';
1214
import 'package:flutter_tools/src/globals.dart' as globals show platform;
1315
import 'package:test/fake.dart';
@@ -20,16 +22,17 @@ void main() {
2022
// Use the real platform as a base so that Windows bots test paths.
2123
final FakePlatform platform = FakePlatform.fromPlatform(globals.platform);
2224
final FileSystemStyle fsStyle = platform.isWindows ? FileSystemStyle.windows : FileSystemStyle.posix;
25+
final String flutterRoot = platform.isWindows
26+
? r'C:\fake\flutter'
27+
: '/fake/flutter';
2328

2429
group('flutter adapter', () {
2530
final String expectedFlutterExecutable = platform.isWindows
2631
? r'C:\fake\flutter\bin\flutter.bat'
2732
: '/fake/flutter/bin/flutter';
2833

2934
setUpAll(() {
30-
Cache.flutterRoot = platform.isWindows
31-
? r'C:\fake\flutter'
32-
: '/fake/flutter';
35+
Cache.flutterRoot = flutterRoot;
3336
});
3437

3538
group('launchRequest', () {
@@ -314,6 +317,46 @@ void main() {
314317
expect(adapter.processArgs, contains('tool_arg'));
315318
});
316319

320+
group('maps org-dartlang-sdk paths', () {
321+
late FileSystem fs;
322+
late FlutterDebugAdapter adapter;
323+
setUp(() {
324+
fs = MemoryFileSystem.test(style: fsStyle);
325+
adapter = MockFlutterDebugAdapter(
326+
fileSystem: fs,
327+
platform: platform,
328+
);
329+
});
330+
331+
test('dart:ui URI to file path', () async {
332+
expect(
333+
adapter.convertOrgDartlangSdkToPath(Uri.parse('org-dartlang-sdk:///flutter/lib/ui/ui.dart')),
334+
fs.path.join(flutterRoot, 'bin', 'cache', 'pkg', 'sky_engine', 'lib', 'ui', 'ui.dart'),
335+
);
336+
});
337+
338+
test('dart:ui file path to URI', () async {
339+
expect(
340+
adapter.convertPathToOrgDartlangSdk(fs.path.join(flutterRoot, 'bin', 'cache', 'pkg', 'sky_engine', 'lib', 'ui', 'ui.dart')),
341+
Uri.parse('org-dartlang-sdk:///flutter/lib/ui/ui.dart'),
342+
);
343+
});
344+
345+
test('dart:core URI to file path', () async {
346+
expect(
347+
adapter.convertOrgDartlangSdkToPath(Uri.parse('org-dartlang-sdk:///third_party/dart/sdk/lib/core/core.dart')),
348+
fs.path.join(flutterRoot, 'bin', 'cache', 'pkg', 'sky_engine', 'lib', 'core', 'core.dart'),
349+
);
350+
});
351+
352+
test('dart:core file path to URI', () async {
353+
expect(
354+
adapter.convertPathToOrgDartlangSdk(fs.path.join(flutterRoot, 'bin', 'cache', 'pkg', 'sky_engine', 'lib', 'core', 'core.dart')),
355+
Uri.parse('org-dartlang-sdk:///third_party/dart/sdk/lib/core/core.dart'),
356+
);
357+
});
358+
});
359+
317360
group('includes customTool', () {
318361
test('with no args replaced', () async {
319362
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(

0 commit comments

Comments
 (0)