| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import 'package:path/path.dart' as path; | 5 import 'package:path/path.dart' as path; |
| 6 | 6 |
| 7 import 'trace.dart'; | 7 import 'trace.dart'; |
| 8 import 'unparsed_frame.dart'; | 8 import 'unparsed_frame.dart'; |
| 9 | 9 |
| 10 // #1 Foo._bar (file:///home/nweiz/code/stuff.dart:42:21) | 10 // #1 Foo._bar (file:///home/nweiz/code/stuff.dart:42:21) |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 r'@' | 45 r'@' |
| 46 r')?' | 46 r')?' |
| 47 r'(.*?)' // The frame's URL. | 47 r'(.*?)' // The frame's URL. |
| 48 r':' | 48 r':' |
| 49 r'(\d*)' // The line number. Empty in Safari if it's unknown. | 49 r'(\d*)' // The line number. Empty in Safari if it's unknown. |
| 50 r'(?::(\d*))?' // The column number. Not present in older browsers and | 50 r'(?::(\d*))?' // The column number. Not present in older browsers and |
| 51 // empty in Safari if it's unknown. | 51 // empty in Safari if it's unknown. |
| 52 r'$'); | 52 r'$'); |
| 53 | 53 |
| 54 // foo/bar.dart 10:11 Foo._bar | 54 // foo/bar.dart 10:11 Foo._bar |
| 55 // foo/bar.dart 10:11 (anonymous function).dart.fn |
| 55 // http://dartlang.org/foo/bar.dart Foo._bar | 56 // http://dartlang.org/foo/bar.dart Foo._bar |
| 57 // data:... 10:11 Foo._bar |
| 56 final _friendlyFrame = new RegExp( | 58 final _friendlyFrame = new RegExp( |
| 57 r'^(\S+)(?: (\d+)(?::(\d+))?)?\s+([^\d]\S*)$'); | 59 r'^(\S+)(?: (\d+)(?::(\d+))?)?\s+([^\d].*)$'); |
| 58 | 60 |
| 59 /// A regular expression that matches asynchronous member names generated by the | 61 /// A regular expression that matches asynchronous member names generated by the |
| 60 /// VM. | 62 /// VM. |
| 61 final _asyncBody = new RegExp(r'<(<anonymous closure>|[^>]+)_async_body>'); | 63 final _asyncBody = new RegExp(r'<(<anonymous closure>|[^>]+)_async_body>'); |
| 62 | 64 |
| 63 final _initialDot = new RegExp(r"^\."); | 65 final _initialDot = new RegExp(r"^\."); |
| 64 | 66 |
| 65 /// A single stack frame. Each frame points to a precise location in Dart code. | 67 /// A single stack frame. Each frame points to a precise location in Dart code. |
| 66 class Frame { | 68 class Frame { |
| 67 /// The URI of the file in which the code is located. | 69 /// The URI of the file in which the code is located. |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 member); | 181 member); |
| 180 } | 182 } |
| 181 | 183 |
| 182 // V8 stack frames can be in two forms. | 184 // V8 stack frames can be in two forms. |
| 183 if (match[2] != null) { | 185 if (match[2] != null) { |
| 184 // The first form looks like " at FUNCTION (LOCATION)". V8 proper lists | 186 // The first form looks like " at FUNCTION (LOCATION)". V8 proper lists |
| 185 // anonymous functions within eval as "<anonymous>", while IE10 lists them | 187 // anonymous functions within eval as "<anonymous>", while IE10 lists them |
| 186 // as "Anonymous function". | 188 // as "Anonymous function". |
| 187 return parseLocation(match[2], | 189 return parseLocation(match[2], |
| 188 match[1].replaceAll("<anonymous>", "<fn>") | 190 match[1].replaceAll("<anonymous>", "<fn>") |
| 189 .replaceAll("Anonymous function", "<fn>")); | 191 .replaceAll("Anonymous function", "<fn>") |
| 192 .replaceAll("(anonymous function)", "<fn>")); |
| 190 } else { | 193 } else { |
| 191 // The second form looks like " at LOCATION", and is used for anonymous | 194 // The second form looks like " at LOCATION", and is used for anonymous |
| 192 // functions. | 195 // functions. |
| 193 return parseLocation(match[3], "<fn>"); | 196 return parseLocation(match[3], "<fn>"); |
| 194 } | 197 } |
| 195 }); | 198 }); |
| 196 | 199 |
| 197 /// Parses a string representation of a JavaScriptCore stack trace. | 200 /// Parses a string representation of a JavaScriptCore stack trace. |
| 198 factory Frame.parseJSCore(String frame) => new Frame.parseV8(frame); | 201 factory Frame.parseJSCore(String frame) => new Frame.parseV8(frame); |
| 199 | 202 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 /// Parses a string representation of a Safari stack frame. | 245 /// Parses a string representation of a Safari stack frame. |
| 243 factory Frame.parseSafari(String frame) => new Frame.parseFirefox(frame); | 246 factory Frame.parseSafari(String frame) => new Frame.parseFirefox(frame); |
| 244 | 247 |
| 245 /// Parses this package's string representation of a stack frame. | 248 /// Parses this package's string representation of a stack frame. |
| 246 factory Frame.parseFriendly(String frame) => _catchFormatException(frame, () { | 249 factory Frame.parseFriendly(String frame) => _catchFormatException(frame, () { |
| 247 var match = _friendlyFrame.firstMatch(frame); | 250 var match = _friendlyFrame.firstMatch(frame); |
| 248 if (match == null) { | 251 if (match == null) { |
| 249 throw new FormatException( | 252 throw new FormatException( |
| 250 "Couldn't parse package:stack_trace stack trace line '$frame'."); | 253 "Couldn't parse package:stack_trace stack trace line '$frame'."); |
| 251 } | 254 } |
| 252 | 255 // Fake truncated data urls generated by the friendly stack trace format |
| 253 var uri = Uri.parse(match[1]); | 256 // cause Uri.parse to throw an exception so we have to special case them. |
| 257 var uri = match[1] == 'data:...' |
| 258 ? new Uri.dataFromString('') |
| 259 : Uri.parse(match[1]); |
| 254 // If there's no scheme, this is a relative URI. We should interpret it as | 260 // If there's no scheme, this is a relative URI. We should interpret it as |
| 255 // relative to the current working directory. | 261 // relative to the current working directory. |
| 256 if (uri.scheme == '') { | 262 if (uri.scheme == '') { |
| 257 uri = path.toUri(path.absolute(path.fromUri(uri))); | 263 uri = path.toUri(path.absolute(path.fromUri(uri))); |
| 258 } | 264 } |
| 259 | 265 |
| 260 var line = match[2] == null ? null : int.parse(match[2]); | 266 var line = match[2] == null ? null : int.parse(match[2]); |
| 261 var column = match[3] == null ? null : int.parse(match[3]); | 267 var column = match[3] == null ? null : int.parse(match[3]); |
| 262 return new Frame(uri, line, column, match[4]); | 268 return new Frame(uri, line, column, match[4]); |
| 263 }); | 269 }); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 return body(); | 301 return body(); |
| 296 } on FormatException catch (_) { | 302 } on FormatException catch (_) { |
| 297 return new UnparsedFrame(text); | 303 return new UnparsedFrame(text); |
| 298 } | 304 } |
| 299 } | 305 } |
| 300 | 306 |
| 301 Frame(this.uri, this.line, this.column, this.member); | 307 Frame(this.uri, this.line, this.column, this.member); |
| 302 | 308 |
| 303 String toString() => '$location in $member'; | 309 String toString() => '$location in $member'; |
| 304 } | 310 } |
| OLD | NEW |