From ce0e5c4330880d6c43bab5f17fe2334e490cc6e8 Mon Sep 17 00:00:00 2001 From: Danny Tuppeny Date: Tue, 2 Jul 2024 23:56:17 +0100 Subject: [PATCH] [flutter_tools] Update the mapping for the Dart SDK internal URI (#151170) This changes the mapping for the Dart SDK inside Flutter from `org-dartlang-sdk:///third_party/dart/sdk` to org-dartlang-sdk:///flutter/third_party/dart/sdk`. This URI changed in https://github.com/flutter/engine/pull/51917 but was not caught by tests because they only tested a specific set of mappings and there were no integration tests checking what URIs were actually produced by a running app. So, this change also adds an integration tests that ensures that a real running app produces URIs that are then correctly mapped. Fixes https://github.com/Dart-Code/Dart-Code/issues/5164. --- .../debug_adapters/flutter_base_adapter.dart | 4 +- .../dap/flutter_adapter_test.dart | 4 +- .../debug_adapter/flutter_adapter_test.dart | 41 ++++++++++++++++++- .../debug_adapter/test_client.dart | 31 ++++++++++++++ 4 files changed, 75 insertions(+), 5 deletions(-) diff --git a/packages/flutter_tools/lib/src/debug_adapters/flutter_base_adapter.dart b/packages/flutter_tools/lib/src/debug_adapters/flutter_base_adapter.dart index fb11605ca0b..fd8d848c6d0 100644 --- a/packages/flutter_tools/lib/src/debug_adapters/flutter_base_adapter.dart +++ b/packages/flutter_tools/lib/src/debug_adapters/flutter_base_adapter.dart @@ -100,9 +100,9 @@ abstract class FlutterBaseDebugAdapter extends DartDebugAdapter>[ + dap.client.stdoutOutput.firstWhere((String output) => output.startsWith('topLevelFunction')), + dap.client.start( + launch: () => dap.client.launch( + cwd: project.dir.path, + debugSdkLibraries: true, + toolArgs: ['-d', 'flutter-tester'], + ), + ), + ], eagerError: true); + + // Add a breakpoint to the `print()` line and hit it. + unawaited(dap.client.setBreakpoint(breakpointFilePath, breakpointLine)); + int stoppedThreadId = (await dap.client.stoppedEvents.firstWhere((StoppedEventBody e) => e.reason == 'breakpoint')).threadId!; + + // Step into `print()` and wait for the next stop. + unawaited(dap.client.stepIn(stoppedThreadId)); + stoppedThreadId = (await dap.client.stoppedEvents.first).threadId!; + + // Fetch the top stack frame and ensure it's been mapped to a local file + // correctly. + final StackFrame topFrame = (await dap.client.getValidStack(stoppedThreadId, startFrame: 0, numFrames: 1)).stackFrames.single; + expect(topFrame.source!.name, 'dart:core/print.dart'); + // We should have a resolved path ending with the path to the print library. + expect(topFrame.source!.path, endsWith(expectedPrintLibraryPath)); + + await dap.client.terminate(); + }); + }); }); group('attach', () { @@ -697,7 +737,6 @@ The relevant error-causing widget was: // Trigger the detach. dap.client.terminate(), ]); - }); }); } diff --git a/packages/flutter_tools/test/integration.shard/debug_adapter/test_client.dart b/packages/flutter_tools/test/integration.shard/debug_adapter/test_client.dart index 6eea88b864a..6ae76ac304d 100644 --- a/packages/flutter_tools/test/integration.shard/debug_adapter/test_client.dart +++ b/packages/flutter_tools/test/integration.shard/debug_adapter/test_client.dart @@ -430,6 +430,37 @@ extension DapTestClientExtension on DapTestClient { Future continue_(int threadId) => sendRequest(ContinueArguments(threadId: threadId)); + /// Sends a stepIn request for the given thread. + /// + /// Returns a Future that completes when the server returns a corresponding + /// response. + Future stepIn(int threadId) => + sendRequest(StepInArguments(threadId: threadId)); + + /// Fetches a stack trace and asserts it was a valid response. + Future getValidStack(int threadId, + {required int startFrame, required int numFrames}) async { + final Response response = await stackTrace(threadId, + startFrame: startFrame, numFrames: numFrames); + assert(response.success); + assert(response.command == 'stackTrace'); + return StackTraceResponseBody.fromJson( + response.body! as Map); + } + + /// Sends a stackTrace request to the server to request the call stack for a + /// given thread. + /// + /// If [startFrame] and/or [numFrames] are supplied, only a slice of the + /// frames will be returned. + /// + /// Returns a Future that completes when the server returns a corresponding + /// response. + Future stackTrace(int threadId, + {int? startFrame, int? numFrames}) => + sendRequest(StackTraceArguments( + threadId: threadId, startFrame: startFrame, levels: numFrames)); + /// Clears breakpoints in [file]. Future clearBreakpoints(String filePath) async { await sendRequest(