Skip to content

Commit 0005ea8

Browse files
committed
Merge branch 'main' of github.com:dart-lang/webdev into 25.1.1_release
2 parents cbd91cb + 3ab8fca commit 0005ea8

29 files changed

+594
-70
lines changed

dwds/CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
## 25.1.1
1+
## 26.0.0
22

3-
- Bump SDK constraint to ^3.10.0.
3+
- Bump SDK constraint to ^3.10.0
4+
- Added 'scriptUri' parameter to compileExpressionToJs
5+
- Fix an issue in `reloadSources` where a `PauseInterrupted` event was sent. - [#61560](https://github.com/dart-lang/sdk/issues/61560)
46
- Expose `dtdUri` via `DebugConnection`.
57

68
## 25.1.0

dwds/lib/src/debugging/debugger.dart

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,28 @@ class Debugger extends Domain {
9696
bool _isStepping = false;
9797
DartLocation? _previousSteppingLocation;
9898

99+
// If not null and not completed, the pause handler completes this instead of
100+
// sending a `PauseInterrupted` event to the event stream.
101+
//
102+
// In some cases e.g. a hot reload, DWDS pauses the execution itself in order
103+
// to handle debugging logic like breakpoints. In such cases, sending the
104+
// event to the event stream may trigger the client to believe that the user
105+
// sent the event. To avoid that and still signal that a pause is completed,
106+
// this completer is used. See https://github.com/dart-lang/sdk/issues/61560
107+
// for more details.
108+
Completer<void>? _internalPauseCompleter;
109+
99110
void updateInspector(AppInspectorInterface appInspector) {
100111
inspector = appInspector;
101112
_breakpoints.inspector = appInspector;
102113
}
103114

104-
Future<Success> pause() async {
115+
Future<Success> pause({bool internalPause = false}) async {
105116
_isStepping = false;
117+
if (internalPause) _internalPauseCompleter = Completer<void>();
106118
final result = await _remoteDebugger.pause();
107119
handleErrorIfPresent(result);
120+
await _internalPauseCompleter?.future;
108121
return Success();
109122
}
110123

@@ -632,7 +645,14 @@ class Debugger extends Domain {
632645
// DevTools is showing an overlay. Both cannot be shown at the same time.
633646
// _showPausedOverlay();
634647
isolate.pauseEvent = event;
635-
_streamNotify('Debug', event);
648+
final internalPauseCompleter = _internalPauseCompleter;
649+
if (event.kind == EventKind.kPauseInterrupted &&
650+
internalPauseCompleter != null &&
651+
!internalPauseCompleter.isCompleted) {
652+
internalPauseCompleter.complete();
653+
} else {
654+
_streamNotify('Debug', event);
655+
}
636656
}
637657

638658
/// Handles resume events coming from the Chrome connection.

dwds/lib/src/debugging/modules.dart

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ class Modules {
2222

2323
// The Dart server path to library import uri
2424
final _sourceToLibrary = <String, Uri>{};
25+
26+
// The Dart server path to library/part import uri
27+
final _sourceToLibraryOrPart = <String, Uri>{};
28+
29+
// Library import uri to list of script (parts) dart server path for the
30+
// library.
31+
final _scriptsForLibrary = <Uri, List<String>>{};
32+
2533
var _moduleMemoizer = AsyncMemoizer<void>();
2634

2735
final Map<String, String> _libraryToModule = {};
@@ -45,7 +53,18 @@ class Modules {
4553
assert(_entrypoint == entrypoint);
4654
for (final library in modifiedModuleReport.modifiedLibraries) {
4755
final libraryServerPath = _getLibraryServerPath(library);
48-
_sourceToLibrary.remove(libraryServerPath);
56+
final libraryUri = _sourceToLibrary.remove(libraryServerPath);
57+
_sourceToLibraryOrPart.remove(libraryServerPath);
58+
if (libraryUri != null) {
59+
final scriptServerPaths = _scriptsForLibrary[libraryUri];
60+
if (scriptServerPaths != null) {
61+
for (final scriptServerPath in scriptServerPaths) {
62+
_sourceToLibraryOrPart.remove(scriptServerPath);
63+
_sourceToLibrary.remove(scriptServerPath);
64+
}
65+
_scriptsForLibrary.remove(libraryUri);
66+
}
67+
}
4968
_sourceToModule.remove(libraryServerPath);
5069
_libraryToModule.remove(library);
5170
}
@@ -57,6 +76,8 @@ class Modules {
5776
}
5877
_entrypoint = entrypoint;
5978
_sourceToLibrary.clear();
79+
_sourceToLibraryOrPart.clear();
80+
_scriptsForLibrary.clear();
6081
_sourceToModule.clear();
6182
_libraryToModule.clear();
6283
_moduleToSources.clear();
@@ -81,6 +102,13 @@ class Modules {
81102
return _sourceToLibrary[serverPath];
82103
}
83104

105+
/// Returns the importUri of the library or part for the provided Dart server
106+
/// path.
107+
Future<Uri?> libraryOrPartForSource(String serverPath) async {
108+
await _moduleMemoizer.runOnce(_initializeMapping);
109+
return _sourceToLibraryOrPart[serverPath];
110+
}
111+
84112
Future<String?> moduleForLibrary(String libraryUri) async {
85113
await _moduleMemoizer.runOnce(_initializeMapping);
86114
return _libraryToModule[libraryUri];
@@ -105,7 +133,8 @@ class Modules {
105133
? library
106134
: DartUri(library, _root).serverPath;
107135

108-
/// Initializes [_sourceToModule], [_moduleToSources], and [_sourceToLibrary].
136+
/// Initializes [_sourceToModule], [_moduleToSources], [_sourceToLibrary] and
137+
/// [_sourceToLibraryOrPart].
109138
///
110139
/// If [modifiedModuleReport] is not null, only updates the maps for the
111140
/// modified libraries in the report.
@@ -125,6 +154,7 @@ class Modules {
125154
// it, so it's okay to only process the modified libraries.
126155
continue;
127156
}
157+
final libraryUri = Uri.parse(library);
128158
final scripts = libraryToScripts[library]!;
129159
final libraryServerPath = _getLibraryServerPath(library);
130160

@@ -133,15 +163,17 @@ class Modules {
133163

134164
_sourceToModule[libraryServerPath] = module;
135165
_moduleToSources.putIfAbsent(module, () => {}).add(libraryServerPath);
136-
_sourceToLibrary[libraryServerPath] = Uri.parse(library);
166+
_sourceToLibrary[libraryServerPath] = libraryUri;
167+
_sourceToLibraryOrPart[libraryServerPath] = libraryUri;
137168
_libraryToModule[library] = module;
138169

139170
for (final script in scripts) {
140171
final scriptServerPath = _getLibraryServerPath(script);
141-
142172
_sourceToModule[scriptServerPath] = module;
143173
_moduleToSources[module]!.add(scriptServerPath);
144-
_sourceToLibrary[scriptServerPath] = Uri.parse(library);
174+
_sourceToLibrary[scriptServerPath] = libraryUri;
175+
_sourceToLibraryOrPart[scriptServerPath] = Uri.parse(script);
176+
(_scriptsForLibrary[libraryUri] ??= []).add(scriptServerPath);
145177
}
146178
} else {
147179
_logger.warning('No module found for library $library');

dwds/lib/src/injected/client.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dwds/lib/src/services/chrome_proxy_service.dart

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,14 +1029,24 @@ class ChromeProxyService extends ProxyService {
10291029
}).stream;
10301030
}
10311031

1032+
/// If [internalPause] is true, indicates that this was a pause triggered
1033+
/// within DWDS, and therefore a `PauseInterrupted` event is never sent to the
1034+
/// VM service event stream. Instead, we just wait for the pause to be
1035+
/// completed.
10321036
@override
1033-
Future<Success> pause(String isolateId) =>
1034-
wrapInErrorHandlerAsync('pause', () => _pause(isolateId));
1037+
Future<Success> pause(String isolateId, {bool internalPause = false}) =>
1038+
wrapInErrorHandlerAsync(
1039+
'pause',
1040+
() => _pause(isolateId, internalPause: internalPause),
1041+
);
10351042

1036-
Future<Success> _pause(String isolateId) async {
1043+
Future<Success> _pause(
1044+
String isolateId, {
1045+
required bool internalPause,
1046+
}) async {
10371047
await isInitialized;
10381048
_checkIsolate('pause', isolateId);
1039-
return (await debuggerFuture).pause();
1049+
return (await debuggerFuture).pause(internalPause: internalPause);
10401050
}
10411051

10421052
// Note: Ignore the optional local parameter, when it is set to `true` the
@@ -1180,9 +1190,7 @@ class ChromeProxyService extends ProxyService {
11801190
};
11811191

11821192
// Pause and wait for the pause to occur before managing breakpoints.
1183-
final pausedEvent = _firstStreamEvent('Debug', EventKind.kPauseInterrupted);
1184-
await pause(isolateId);
1185-
await pausedEvent;
1193+
await pause(isolateId, internalPause: true);
11861194

11871195
await _reinitializeForHotReload(reloadedModulesToLibraries);
11881196

@@ -1513,11 +1521,6 @@ class ChromeProxyService extends ProxyService {
15131521
});
15141522
}
15151523

1516-
Future<void> _firstStreamEvent(String streamId, String eventKind) {
1517-
final controller = streamControllers[streamId]!;
1518-
return controller.stream.firstWhere((event) => event.kind == eventKind);
1519-
}
1520-
15211524
Future<void> _handleDeveloperLog(
15221525
IsolateRef isolateRef,
15231526
ConsoleAPIEvent event,

dwds/lib/src/services/expression_compiler.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ abstract class ExpressionCompiler {
6363
Future<ExpressionCompilationResult> compileExpressionToJs(
6464
String isolateId,
6565
String libraryUri,
66+
String scriptUri,
6667
int line,
6768
int column,
6869
Map<String, String> jsModules,

dwds/lib/src/services/expression_compiler_service.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ class _Compiler {
144144

145145
Future<ExpressionCompilationResult> compileExpressionToJs(
146146
String libraryUri,
147+
String scriptUri,
147148
int line,
148149
int column,
149150
Map<String, String> jsModules,
@@ -171,6 +172,7 @@ class _Compiler {
171172
'jsModules': jsModules,
172173
'jsScope': jsFrameValues,
173174
'libraryUri': libraryUri,
175+
'scriptUri': scriptUri,
174176
'moduleName': moduleName,
175177
});
176178

@@ -241,6 +243,7 @@ class ExpressionCompilerService implements ExpressionCompiler {
241243
Future<ExpressionCompilationResult> compileExpressionToJs(
242244
String isolateId,
243245
String libraryUri,
246+
String scriptUri,
244247
int line,
245248
int column,
246249
Map<String, String> jsModules,
@@ -249,6 +252,7 @@ class ExpressionCompilerService implements ExpressionCompiler {
249252
String expression,
250253
) async => (await _compiler.future).compileExpressionToJs(
251254
libraryUri,
255+
scriptUri,
252256
line,
253257
column,
254258
jsModules,

dwds/lib/src/services/expression_evaluator.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ class ExpressionEvaluator {
125125
final compilationResult = await _compiler.compileExpressionToJs(
126126
isolateId,
127127
libraryUri.toString(),
128+
// Evaluating at "the library level" (and passing line 0 column 0) we'll
129+
// also just pass the library uri as the script uri.
130+
libraryUri.toString(),
128131
0,
129132
0,
130133
{},
@@ -280,6 +283,7 @@ class ExpressionEvaluator {
280283
final dartLocation = locationMap.dartLocation;
281284
final dartSourcePath = dartLocation.uri.serverPath;
282285
final libraryUri = await _modules.libraryForSource(dartSourcePath);
286+
final scriptUri = await _modules.libraryOrPartForSource(dartSourcePath);
283287
if (libraryUri == null) {
284288
return createError(
285289
EvaluationErrorKind.internal,
@@ -298,6 +302,7 @@ class ExpressionEvaluator {
298302
_logger.finest(
299303
'Evaluating "$expression" at $module, '
300304
'$libraryUri:${dartLocation.line}:${dartLocation.column} '
305+
'or rather $scriptUri:${dartLocation.line}:${dartLocation.column} '
301306
'with scope: $scope',
302307
);
303308

@@ -317,6 +322,7 @@ class ExpressionEvaluator {
317322
final compilationResult = await _compiler.compileExpressionToJs(
318323
isolateId,
319324
libraryUri.toString(),
325+
scriptUri.toString(),
320326
dartLocation.line,
321327
dartLocation.column,
322328
{},

dwds/lib/src/version.dart

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dwds/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: dwds
22
# Every time this changes you need to run `dart run build_runner build`.
3-
version: 25.1.1
3+
version: 26.0.0
44

55
description: >-
66
A service that proxies between the Chrome debug protocol and the Dart VM

0 commit comments

Comments
 (0)