Support JavaScriptCore stack traces.

R=kevmoo@google.com

Review URL: https://codereview.chromium.org//1062123003
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 53f5cd1..57ff590 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 1.3.0
+
+* Support stack traces generated by JavaScriptCore. They can be explicitly
+  parsed via `new Trace.parseJSCore` and `new Frame.parseJSCore`.
+
 ## 1.2.4
 
 * Fix a type annotation in `LazyTrace`.
diff --git a/lib/src/frame.dart b/lib/src/frame.dart
index c06fd60..9043d2b 100644
--- a/lib/src/frame.dart
+++ b/lib/src/frame.dart
@@ -195,6 +195,9 @@
     }
   }
 
+  /// Parses a string representation of a JavaScriptCore stack trace.
+  factory Frame.parseJSCore(String frame) => new Frame.parseV8(frame);
+
   /// Parses a string representation of an IE stack frame.
   ///
   /// IE10+ frames look just like V8 frames. Prior to IE10, stack traces can't
diff --git a/lib/src/trace.dart b/lib/src/trace.dart
index 954cf45..bf26c51 100644
--- a/lib/src/trace.dart
+++ b/lib/src/trace.dart
@@ -115,6 +115,7 @@
     try {
       if (trace.isEmpty) return new Trace(<Frame>[]);
       if (trace.contains(_v8Trace)) return new Trace.parseV8(trace);
+      if (trace.startsWith("\tat ")) return new Trace.parseJSCore(trace);
       if (trace.contains(_firefoxSafariTrace)) {
         return new Trace.parseFirefox(trace);
       }
@@ -147,6 +148,10 @@
           .skipWhile((line) => !line.startsWith(_v8TraceLine))
           .map((line) => new Frame.parseV8(line)));
 
+  /// Parses a string representation of a JavaScriptCore stack trace.
+  Trace.parseJSCore(String trace)
+      : this(trace.split("\n").map((line) => new Frame.parseV8(line)));
+
   /// Parses a string representation of an Internet Explorer stack trace.
   ///
   /// IE10+ traces look just like V8 traces. Prior to IE10, stack traces can't
diff --git a/pubspec.yaml b/pubspec.yaml
index 296cd2c..912fbd7 100644
--- a/pubspec.yaml
+++ b/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.4
+version: 1.3.0
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://github.com/dart-lang/stack_trace
 description: >
diff --git a/test/trace_test.dart b/test/trace_test.dart
index 1887509..e8f749a 100644
--- a/test/trace_test.dart
+++ b/test/trace_test.dart
@@ -92,6 +92,23 @@
           equals(Uri.parse("http://pub.dartlang.org/thing.js")));
     });
 
+    // JavaScriptCore traces are just like V8, except that it doesn't have a
+    // header and it starts with a tab rather than spaces.
+    test('parses a JavaScriptCore stack trace correctly', () {
+      var trace = new Trace.parse(
+          '\tat Foo._bar (http://pub.dartlang.org/stuff.js:42:21)\n'
+          '\tat http://pub.dartlang.org/stuff.js:0:2\n'
+          '\tat zip.<anonymous>.zap '
+              '(http://pub.dartlang.org/thing.js:1:100)');
+
+      expect(trace.frames[0].uri,
+          equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
+      expect(trace.frames[1].uri,
+          equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
+      expect(trace.frames[2].uri,
+          equals(Uri.parse("http://pub.dartlang.org/thing.js")));
+    });
+
     test('parses a Firefox/Safari stack trace correctly', () {
       var trace = new Trace.parse(
           'Foo._bar@http://pub.dartlang.org/stuff.js:42\n'