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 |