Skip to content

Commit ebad718

Browse files
authored
Set breakpoints by regex URL (#1078)
- Use `setBreakpointsByUrl` to set breakpoints using a regex based on the module path - Chrome now handles re-establishing breakpoints upon refresh so remove the corresponding deprecated argument Closes #1076
1 parent ad1ce09 commit ebad718

File tree

10 files changed

+70
-57
lines changed

10 files changed

+70
-57
lines changed

dwds/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
**Breaking Changes:**
1515
- Require access to the `.ddc_merged_metadata` file.
16+
- Remove deprecated parameter `restoreBreakpoints` as breakpoints are now
17+
set by regex URL and Chrome automatically reestablishes them.
1618

1719
## 5.0.0
1820

dwds/lib/dwds.dart

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ class Dwds {
9393
// TODO(annagrin): make expressionCompiler argument required
9494
// [issue 881](https://github.com/dart-lang/webdev/issues/881)
9595
ExpressionCompiler expressionCompiler,
96-
@deprecated bool restoreBreakpoints,
9796
}) async {
9897
hostname ??= 'localhost';
9998
enableDebugging ??= true;
@@ -104,7 +103,6 @@ class Dwds {
104103
logWriter ??= (level, message) => print(message);
105104
verbose ??= false;
106105
globalLoadStrategy = loadStrategy;
107-
restoreBreakpoints ??= false;
108106

109107
DevTools devTools;
110108
String extensionUri;
@@ -148,7 +146,6 @@ class Dwds {
148146
logWriter,
149147
extensionBackend,
150148
urlEncoder,
151-
restoreBreakpoints,
152149
useSseForDebugProxy,
153150
serveDevTools,
154151
expressionCompiler,

dwds/lib/src/debugging/debugger.dart

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class Debugger extends Domain {
4848
final AssetReader _assetReader;
4949
final Modules _modules;
5050
final Locations _locations;
51+
final String _root;
5152

5253
Debugger._(
5354
this._remoteDebugger,
@@ -56,12 +57,12 @@ class Debugger extends Domain {
5657
this._assetReader,
5758
this._modules,
5859
this._locations,
59-
String root,
60+
this._root,
6061
) : _breakpoints = _Breakpoints(
6162
locations: _locations,
6263
provider: provider,
6364
remoteDebugger: _remoteDebugger,
64-
root: root),
65+
root: _root),
6566
super(provider);
6667

6768
/// The breakpoints we have set so far, indexable by either
@@ -269,18 +270,52 @@ class Debugger extends Domain {
269270
int column,
270271
}) async {
271272
checkIsolate('addBreakpoint', isolateId);
272-
273273
final breakpoint = await _breakpoints.add(scriptId, line);
274+
_notifyBreakpoint(breakpoint);
275+
return breakpoint;
276+
}
274277

278+
Future<ScriptRef> _updatedScriptRefFor(Breakpoint breakpoint) async {
279+
var oldRef = (breakpoint.location as SourceLocation).script;
280+
var dartUri = DartUri(oldRef.uri, _root);
281+
return await inspector.scriptRefFor(dartUri.serverPath);
282+
}
283+
284+
Future<void> reestablishBreakpoints(
285+
Set<Breakpoint> previousBreakpoints,
286+
Set<Breakpoint> disabledBreakpoints,
287+
) async {
288+
// Previous breakpoints were never removed from Chrome since we use
289+
// `setBreakpointByUrl`. We simply need to update the references.
290+
for (var breakpoint in previousBreakpoints) {
291+
var scriptRef = await _updatedScriptRefFor(breakpoint);
292+
var updatedLocation = await _locations.locationForDart(
293+
DartUri(scriptRef.uri, _root), _lineNumberFor(breakpoint));
294+
var updatedBreakpoint = _breakpoints._dartBreakpoint(
295+
scriptRef, updatedLocation, breakpoint.id);
296+
_breakpoints._note(
297+
bp: updatedBreakpoint,
298+
jsId: _breakpoints._jsIdByDartId[updatedBreakpoint.id]);
299+
_notifyBreakpoint(updatedBreakpoint);
300+
}
301+
// Disabled breakpoints were actually removed from Chrome so simply add
302+
// them back.
303+
for (var breakpoint in disabledBreakpoints) {
304+
await addBreakpoint(
305+
inspector.isolate.id,
306+
(await _updatedScriptRefFor(breakpoint)).id,
307+
_lineNumberFor(breakpoint));
308+
}
309+
}
310+
311+
void _notifyBreakpoint(Breakpoint breakpoint) {
275312
final event = Event(
276313
kind: EventKind.kBreakpointAdded,
277314
timestamp: DateTime.now().millisecondsSinceEpoch,
278315
isolate: inspector.isolateRef,
279316
);
280317
event.breakpoint = breakpoint;
281318
_streamNotify('Debug', event);
282-
283-
return breakpoint;
284319
}
285320

286321
/// Remove a Dart breakpoint.
@@ -624,7 +659,7 @@ class Debugger extends Domain {
624659
}
625660

626661
/// Returns the Dart line number for the provided breakpoint.
627-
int lineNumberFor(Breakpoint breakpoint) =>
662+
int _lineNumberFor(Breakpoint breakpoint) =>
628663
int.parse(breakpoint.id.split('#').last);
629664

630665
/// Returns the breakpoint ID for the provided Dart script ID and Dart line
@@ -699,12 +734,13 @@ class _Breakpoints extends Domain {
699734
Future<String> _setJsBreakpoint(Location location) async {
700735
// Location is 0 based according to:
701736
// https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-Location
702-
var response =
703-
await remoteDebugger.sendCommand('Debugger.setBreakpoint', params: {
704-
'location': {
705-
'scriptId': location.jsLocation.scriptId,
706-
'lineNumber': location.jsLocation.line - 1,
707-
}
737+
738+
// The module can be loaded from a nested path and contain an ETAG suffix.
739+
var urlRegex = '.*${location.modulePath}.*';
740+
var response = await remoteDebugger
741+
.sendCommand('Debugger.setBreakpointByUrl', params: {
742+
'urlRegex': urlRegex,
743+
'lineNumber': location.jsLocation.line - 1,
708744
});
709745
return response.result['breakpointId'] as String;
710746
}
@@ -729,8 +765,6 @@ class _Breakpoints extends Domain {
729765
return _bpByDartId.remove(dartId);
730766
}
731767

732-
String dartId(String jsId) => _dartIdByJsId[jsId];
733-
734768
String jsId(String dartId) => _jsIdByDartId[dartId];
735769
}
736770

dwds/lib/src/debugging/location.dart

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,20 @@ class Location {
2121

2222
final DartLocation dartLocation;
2323

24+
final String modulePath;
25+
2426
/// An arbitrary integer value used to represent this location.
2527
final int tokenPos;
2628

2729
Location._(
2830
this.jsLocation,
2931
this.dartLocation,
32+
this.modulePath,
3033
) : tokenPos = _startTokenId++;
3134

3235
static Location from(
3336
String scriptId,
37+
String modulePath,
3438
TargetLineEntry lineEntry,
3539
TargetEntry entry,
3640
DartUri dartUri,
@@ -41,8 +45,11 @@ class Location {
4145
var jsColumn = entry.column;
4246
// lineEntry data is 0 based according to:
4347
// https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k
44-
return Location._(JsLocation.fromZeroBased(scriptId, jsLine, jsColumn),
45-
DartLocation.fromZeroBased(dartUri, dartLine, dartColumn));
48+
return Location._(
49+
JsLocation.fromZeroBased(scriptId, jsLine, jsColumn),
50+
DartLocation.fromZeroBased(dartUri, dartLine, dartColumn),
51+
modulePath,
52+
);
4653
}
4754

4855
@override
@@ -259,6 +266,7 @@ class Locations {
259266
var dartUri = DartUri(path, _root);
260267
result.add(Location.from(
261268
scriptId,
269+
modulePath,
262270
lineEntry,
263271
entry,
264272
dartUri,

dwds/lib/src/handlers/dev_handler.dart

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ class DevHandler {
6363
final StreamController<DebugConnection> extensionDebugConnections =
6464
StreamController<DebugConnection>();
6565
final UrlEncoder _urlEncoder;
66-
final bool _restoreBreakpoints;
6766
final bool _useSseForDebugProxy;
6867
final bool _serveDevTools;
6968
final ExpressionCompiler _expressionCompiler;
@@ -87,7 +86,6 @@ class DevHandler {
8786
this._logWriter,
8887
this._extensionBackend,
8988
this._urlEncoder,
90-
this._restoreBreakpoints,
9189
this._useSseForDebugProxy,
9290
this._serveDevTools,
9391
this._expressionCompiler,
@@ -197,7 +195,6 @@ class DevHandler {
197195
metadataProvider,
198196
appConnection,
199197
_logWriter,
200-
_restoreBreakpoints,
201198
onResponse: (response) {
202199
if (_verbose) {
203200
if (response['error'] == null) return;
@@ -473,7 +470,6 @@ class DevHandler {
473470
metadataProvider,
474471
connection,
475472
_logWriter,
476-
_restoreBreakpoints,
477473
onResponse: _verbose
478474
? (response) {
479475
if (response['error'] == null) return;

dwds/lib/src/services/chrome_proxy_service.dart

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,6 @@ class ChromeProxyService implements VmServiceInterface {
8080

8181
StreamSubscription<ConsoleAPIEvent> _consoleSubscription;
8282

83-
/// If breakpoints should be restored upon a reload / hot restart.
84-
final bool _restoreBreakpoints;
8583
final _disabledBreakpoints = <Breakpoint>{};
8684
final _previousBreakpoints = <Breakpoint>{};
8785

@@ -96,7 +94,6 @@ class ChromeProxyService implements VmServiceInterface {
9694
this._metadataProvider,
9795
this._modules,
9896
this._locations,
99-
this._restoreBreakpoints,
10097
this.executionContext,
10198
this._logWriter,
10299
) {
@@ -119,7 +116,6 @@ class ChromeProxyService implements VmServiceInterface {
119116
MetadataProvider metadataProvider,
120117
AppConnection appConnection,
121118
LogWriter logWriter,
122-
bool restoreBreakpoints,
123119
ExecutionContext executionContext,
124120
ExpressionCompiler expressionCompiler) async {
125121
final vm = VM(
@@ -137,17 +133,8 @@ class ChromeProxyService implements VmServiceInterface {
137133

138134
var modules = Modules(metadataProvider, tabUrl);
139135
var locations = Locations(assetReader, modules, tabUrl);
140-
var service = ChromeProxyService._(
141-
vm,
142-
tabUrl,
143-
assetReader,
144-
remoteDebugger,
145-
metadataProvider,
146-
modules,
147-
locations,
148-
restoreBreakpoints,
149-
executionContext,
150-
logWriter);
136+
var service = ChromeProxyService._(vm, tabUrl, assetReader, remoteDebugger,
137+
metadataProvider, modules, locations, executionContext, logWriter);
151138
unawaited(service.createIsolate(appConnection));
152139
await service.createEvaluator(expressionCompiler);
153140
return service;
@@ -192,14 +179,9 @@ class ChromeProxyService implements VmServiceInterface {
192179
executionContext,
193180
);
194181

195-
for (var breakpoint in _previousBreakpoints) {
196-
var lineNumber = lineNumberFor(breakpoint);
197-
var oldRef = (breakpoint.location as SourceLocation).script;
198-
var dartUri = DartUri(oldRef.uri, uri);
199-
var newRef = await _inspector.scriptRefFor(dartUri.serverPath);
200-
await (await _debugger)
201-
.addBreakpoint(_inspector.isolate.id, newRef.id, lineNumber);
202-
}
182+
await (await _debugger)
183+
.reestablishBreakpoints(_previousBreakpoints, _disabledBreakpoints);
184+
_disabledBreakpoints.clear();
203185

204186
unawaited(appConnection.onStart.then((_) async {
205187
await (await _debugger).resumeFromStart();
@@ -257,12 +239,8 @@ class ChromeProxyService implements VmServiceInterface {
257239
isolate: _inspector.isolateRef));
258240
_vm.isolates.removeWhere((ref) => ref.id == isolate.id);
259241
_inspector = null;
260-
if (_restoreBreakpoints) {
261-
_previousBreakpoints.clear();
262-
_previousBreakpoints
263-
..addAll(isolate.breakpoints)
264-
..addAll(_disabledBreakpoints);
265-
}
242+
_previousBreakpoints.clear();
243+
_previousBreakpoints.addAll(isolate.breakpoints);
266244
_consoleSubscription.cancel();
267245
_consoleSubscription = null;
268246
}

dwds/lib/src/services/debug_service.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ class DebugService {
134134
MetadataProvider metadataProvider,
135135
AppConnection appConnection,
136136
LogWriter logWriter,
137-
bool restoreBreakpoints,
138137
{void Function(Map<String, dynamic>) onRequest,
139138
void Function(Map<String, dynamic>) onResponse,
140139
bool useSse,
@@ -148,7 +147,6 @@ class DebugService {
148147
metadataProvider,
149148
appConnection,
150149
logWriter,
151-
restoreBreakpoints,
152150
executionContext,
153151
expressionCompiler);
154152
var authToken = _makeAuthToken();

dwds/test/debugger_test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ void main() async {
5858
var lineEntry = TargetLineEntry(92, [entry]);
5959
var location = Location.from(
6060
'foo.dart',
61+
'foo.ddc.js',
6162
lineEntry,
6263
entry,
6364
DartUri('package:foo/foo.dart'),

dwds/test/fixtures/server.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,6 @@ class TestServer {
106106
hostname: hostname,
107107
verbose: true,
108108
urlEncoder: urlEncoder,
109-
// ignore: deprecated_member_use_from_same_package
110-
restoreBreakpoints: restoreBreakpoints,
111109
expressionCompiler: expressionCompiler,
112110
);
113111

dwds/test/reload_test.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,8 @@ void main() {
182182
isolateId = vm.isolates.first.id;
183183
var isolate = await client.getIsolate(isolateId);
184184
expect(isolate.pauseEvent.kind, EventKind.kResume);
185-
expect(isolate.breakpoints.isEmpty, isTrue);
185+
// Previous breakpoint should still exist.
186+
expect(isolate.breakpoints.isNotEmpty, isTrue);
186187
});
187188
});
188189

0 commit comments

Comments
 (0)