Even better stack chains with VM async/await. It turns out the VM can generate frames that have the previous method's name in the <..._async_body> member. R=rnystrom@google.com Review URL: https://codereview.chromium.org//936643002
diff --git a/pkgs/stack_trace/CHANGELOG.md b/pkgs/stack_trace/CHANGELOG.md index 47bd9b1..43d547a 100644 --- a/pkgs/stack_trace/CHANGELOG.md +++ b/pkgs/stack_trace/CHANGELOG.md
@@ -1,3 +1,7 @@ +## 1.2.1 + +* Further improve stack chains when using the VM's async/await implementation. + ## 1.2.0 * Add a `terse` argument to `Trace.foldFrames()` and `Chain.foldFrames()`. This
diff --git a/pkgs/stack_trace/lib/src/frame.dart b/pkgs/stack_trace/lib/src/frame.dart index 8ecd19f..c06fd60 100644 --- a/pkgs/stack_trace/lib/src/frame.dart +++ b/pkgs/stack_trace/lib/src/frame.dart
@@ -57,6 +57,10 @@ final _friendlyFrame = new RegExp( r'^(\S+)(?: (\d+)(?::(\d+))?)?\s+([^\d]\S*)$'); +/// A regular expression that matches asynchronous member names generated by the +/// VM. +final _asyncBody = new RegExp(r'<(<anonymous closure>|[^>]+)_async_body>'); + final _initialDot = new RegExp(r"^\."); /// A single stack frame. Each frame points to a precise location in Dart code. @@ -137,7 +141,7 @@ // Get the pieces out of the regexp match. Function, URI and line should // always be found. The column is optional. var member = match[1] - .replaceAll("<<anonymous closure>_async_body>", "<async>") + .replaceAll(_asyncBody, "<async>") .replaceAll("<anonymous closure>", "<fn>"); var uri = Uri.parse(match[2]);
diff --git a/pkgs/stack_trace/lib/src/vm_trace.dart b/pkgs/stack_trace/lib/src/vm_trace.dart index 89474f5..7991160 100644 --- a/pkgs/stack_trace/lib/src/vm_trace.dart +++ b/pkgs/stack_trace/lib/src/vm_trace.dart
@@ -23,8 +23,9 @@ return frames.map((frame) { var number = padRight("#${i++}", 8); var member = frame.member - .replaceAll("<fn>", "<anonymous closure>") - .replaceAll("<async>", "<<anonymous closure>_async_body>"); + .replaceAllMapped(new RegExp(r"[^.]+\.<async>"), + (match) => "${match[1]}.<${match[1]}_async_body>") + .replaceAll("<fn>", "<anonymous closure>"); var line = frame.line == null ? 0 : frame.line; var column = frame.column == null ? 0 : frame.column; return "$number$member (${frame.uri}:$line:$column)\n";
diff --git a/pkgs/stack_trace/pubspec.yaml b/pkgs/stack_trace/pubspec.yaml index 01b1550..35c419e 100644 --- a/pkgs/stack_trace/pubspec.yaml +++ b/pkgs/stack_trace/pubspec.yaml
@@ -7,7 +7,7 @@ # # When the major version is upgraded, you *must* update that version constraint # in pub to stay in sync with this. -version: 1.2.0 +version: 1.2.1-dev author: "Dart Team <misc@dartlang.org>" homepage: http://github.com/dart-lang/stack_trace description: >
diff --git a/pkgs/stack_trace/test/frame_test.dart b/pkgs/stack_trace/test/frame_test.dart index 638d1d7..c2cb80e 100644 --- a/pkgs/stack_trace/test/frame_test.dart +++ b/pkgs/stack_trace/test/frame_test.dart
@@ -56,9 +56,9 @@ expect(frame.member, equals('Foo.<async>')); }); - test('converts "<<anonymous closure>_async_body>" to "<async>"', () { + test('converts "<function_name_async_body>" to "<async>"', () { var frame = new Frame.parseVM( - '#0 Foo.<<anonymous closure>_async_body> (foo:0:0)'); + '#0 Foo.<function_name_async_body> (foo:0:0)'); expect(frame.member, equals('Foo.<async>')); });