Work around issue 11901 in stack_trace.

For some reason, timer_impl.dart in dart:async has the incorrect URL
in VM stack traces. This adds manual handling for that in the
stack_trace package.

R=rnystrom@google.com
BUG=

Review URL: https://codereview.chromium.org//63393004

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/stack_trace@30318 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkgs/stack_trace/lib/src/frame.dart b/pkgs/stack_trace/lib/src/frame.dart
index 3bead03..6a88a26 100644
--- a/pkgs/stack_trace/lib/src/frame.dart
+++ b/pkgs/stack_trace/lib/src/frame.dart
@@ -118,6 +118,10 @@
     // always be found. The column is optional.
     var member = match[1].replaceAll("<anonymous closure>", "<fn>");
     var uri = Uri.parse(match[2]);
+    // Work around issue 11901.
+    if (uri == new Uri(path: 'timer_impl.dart')) {
+      uri = Uri.parse('dart:async/timer_impl.dart');
+    }
     var line = int.parse(match[3]);
     var column = null;
     var columnMatch = match[4];
diff --git a/pkgs/stack_trace/test/frame_test.dart b/pkgs/stack_trace/test/frame_test.dart
index 87a8c4d..bd09ed8 100644
--- a/pkgs/stack_trace/test/frame_test.dart
+++ b/pkgs/stack_trace/test/frame_test.dart
@@ -30,6 +30,15 @@
       expect(frame.member, equals('Foo._bar'));
     });
 
+    test('parses a stack frame with timer_impl correctly', () {
+      var frame = new Frame.parseVM("#1      Foo._bar "
+          "(timer_impl.dart:24)");
+      expect(frame.uri, equals(Uri.parse("dart:async/timer_impl.dart")));
+      expect(frame.line, equals(24));
+      expect(frame.column, null);
+      expect(frame.member, equals('Foo._bar'));
+    });
+
     test('converts "<anonymous closure>" to "<fn>"', () {
       String parsedMember(String member) =>
           new Frame.parseVM('#0 $member (foo:0:0)').member;