| 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 library trace; | 5 library trace; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 import 'dart:math' as math; | 8 import 'dart:math' as math; |
| 9 | 9 |
| 10 import 'chain.dart'; | 10 import 'chain.dart'; |
| 11 import 'frame.dart'; | 11 import 'frame.dart'; |
| 12 import 'lazy_trace.dart'; | 12 import 'lazy_trace.dart'; |
| 13 import 'unparsed_frame.dart'; |
| 13 import 'utils.dart'; | 14 import 'utils.dart'; |
| 14 import 'vm_trace.dart'; | 15 import 'vm_trace.dart'; |
| 15 | 16 |
| 16 final _terseRegExp = new RegExp(r"(-patch)?([/\\].*)?$"); | 17 final _terseRegExp = new RegExp(r"(-patch)?([/\\].*)?$"); |
| 17 | 18 |
| 18 /// A RegExp to match V8's stack traces. | 19 /// A RegExp to match V8's stack traces. |
| 19 /// | 20 /// |
| 20 /// V8's traces start with a line that's either just "Error" or else is a | 21 /// V8's traces start with a line that's either just "Error" or else is a |
| 21 /// description of the exception that occurred. That description can be multiple | 22 /// description of the exception that occurred. That description can be multiple |
| 22 /// lines, so we just look for any line other than the first that begins with | 23 /// lines, so we just look for any line other than the first that begins with |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 } | 109 } |
| 109 | 110 |
| 110 /// Parses a string representation of a stack trace. | 111 /// Parses a string representation of a stack trace. |
| 111 /// | 112 /// |
| 112 /// [trace] should be formatted in the same way as a Dart VM or browser stack | 113 /// [trace] should be formatted in the same way as a Dart VM or browser stack |
| 113 /// trace. | 114 /// trace. |
| 114 factory Trace.parse(String trace) { | 115 factory Trace.parse(String trace) { |
| 115 try { | 116 try { |
| 116 if (trace.isEmpty) return new Trace(<Frame>[]); | 117 if (trace.isEmpty) return new Trace(<Frame>[]); |
| 117 if (trace.contains(_v8Trace)) return new Trace.parseV8(trace); | 118 if (trace.contains(_v8Trace)) return new Trace.parseV8(trace); |
| 118 if (trace.startsWith("\tat ")) return new Trace.parseJSCore(trace); | 119 if (trace.contains("\tat ")) return new Trace.parseJSCore(trace); |
| 119 if (trace.contains(_firefoxSafariTrace)) { | 120 if (trace.contains(_firefoxSafariTrace)) { |
| 120 return new Trace.parseFirefox(trace); | 121 return new Trace.parseFirefox(trace); |
| 121 } | 122 } |
| 122 if (trace.contains(_friendlyTrace)) { | 123 if (trace.contains(_friendlyTrace)) { |
| 123 return new Trace.parseFriendly(trace); | 124 return new Trace.parseFriendly(trace); |
| 124 } | 125 } |
| 125 | 126 |
| 126 // Default to parsing the stack trace as a VM trace. This is also hit on | 127 // Default to parsing the stack trace as a VM trace. This is also hit on |
| 127 // IE and Safari, where the stack trace is just an empty string (issue | 128 // IE and Safari, where the stack trace is just an empty string (issue |
| 128 // 11257). | 129 // 11257). |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 // just get rid of them. | 256 // just get rid of them. |
| 256 // TODO(nweiz): Get rid of this logic some time after issue 22009 is | 257 // TODO(nweiz): Get rid of this logic some time after issue 22009 is |
| 257 // fixed. | 258 // fixed. |
| 258 if (!frame.member.contains('<async>')) return false; | 259 if (!frame.member.contains('<async>')) return false; |
| 259 return frame.line == null; | 260 return frame.line == null; |
| 260 }; | 261 }; |
| 261 } | 262 } |
| 262 | 263 |
| 263 var newFrames = []; | 264 var newFrames = []; |
| 264 for (var frame in frames.reversed) { | 265 for (var frame in frames.reversed) { |
| 265 if (!predicate(frame)) { | 266 if (frame is UnparsedFrame || !predicate(frame)) { |
| 266 newFrames.add(frame); | 267 newFrames.add(frame); |
| 267 } else if (newFrames.isEmpty || !predicate(newFrames.last)) { | 268 } else if (newFrames.isEmpty || !predicate(newFrames.last)) { |
| 268 newFrames.add(new Frame( | 269 newFrames.add(new Frame( |
| 269 frame.uri, frame.line, frame.column, frame.member)); | 270 frame.uri, frame.line, frame.column, frame.member)); |
| 270 } | 271 } |
| 271 } | 272 } |
| 272 | 273 |
| 273 if (terse) { | 274 if (terse) { |
| 274 newFrames = newFrames.map((frame) { | 275 newFrames = newFrames.map((frame) { |
| 275 if (!predicate(frame)) return frame; | 276 if (frame is UnparsedFrame || !predicate(frame)) return frame; |
| 276 var library = frame.library.replaceAll(_terseRegExp, ''); | 277 var library = frame.library.replaceAll(_terseRegExp, ''); |
| 277 return new Frame(Uri.parse(library), null, null, frame.member); | 278 return new Frame(Uri.parse(library), null, null, frame.member); |
| 278 }).toList(); | 279 }).toList(); |
| 279 if (newFrames.length > 1 && newFrames.first.isCore) newFrames.removeAt(0); | 280 if (newFrames.length > 1 && newFrames.first.isCore) newFrames.removeAt(0); |
| 280 } | 281 } |
| 281 | 282 |
| 282 return new Trace(newFrames.reversed); | 283 return new Trace(newFrames.reversed); |
| 283 } | 284 } |
| 284 | 285 |
| 285 /// Returns a human-readable string representation of [this]. | 286 /// Returns a human-readable string representation of [this]. |
| 286 String toString() { | 287 String toString() { |
| 287 // Figure out the longest path so we know how much to pad. | 288 // Figure out the longest path so we know how much to pad. |
| 288 var longest = frames.map((frame) => frame.location.length) | 289 var longest = frames.map((frame) => frame.location.length) |
| 289 .fold(0, math.max); | 290 .fold(0, math.max); |
| 290 | 291 |
| 291 // Print out the stack trace nicely formatted. | 292 // Print out the stack trace nicely formatted. |
| 292 return frames.map((frame) { | 293 return frames.map((frame) { |
| 294 if (frame is UnparsedFrame) return "$frame\n"; |
| 293 return '${padRight(frame.location, longest)} ${frame.member}\n'; | 295 return '${padRight(frame.location, longest)} ${frame.member}\n'; |
| 294 }).join(); | 296 }).join(); |
| 295 } | 297 } |
| 296 } | 298 } |
| OLD | NEW |