| 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 stack_trace.chain; | 5 library stack_trace.chain; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 import 'dart:math' as math; | 9 import 'dart:math' as math; |
| 10 | 10 |
| 11 import 'frame.dart'; | 11 import 'frame.dart'; |
| 12 import 'stack_zone_specification.dart'; | 12 import 'stack_zone_specification.dart'; |
| 13 import 'trace.dart'; | 13 import 'trace.dart'; |
| 14 import 'utils.dart'; | 14 import 'utils.dart'; |
| 15 | 15 |
| 16 /// A function that handles errors in the zone wrapped by [Chain.capture]. | 16 /// A function that handles errors in the zone wrapped by [Chain.capture]. |
| 17 typedef void ChainHandler(error, Chain chain); | 17 typedef void ChainHandler(error, Chain chain); |
| 18 | 18 |
| 19 /// The line used in the string representation of stack chains to represent | |
| 20 /// the gap between traces. | |
| 21 const _gap = '===== asynchronous gap ===========================\n'; | |
| 22 | |
| 23 /// A chain of stack traces. | 19 /// A chain of stack traces. |
| 24 /// | 20 /// |
| 25 /// A stack chain is a collection of one or more stack traces that collectively | 21 /// A stack chain is a collection of one or more stack traces that collectively |
| 26 /// represent the path from [main] through nested function calls to a particular | 22 /// represent the path from [main] through nested function calls to a particular |
| 27 /// code location, usually where an error was thrown. Multiple stack traces are | 23 /// code location, usually where an error was thrown. Multiple stack traces are |
| 28 /// necessary when using asynchronous functions, since the program's stack is | 24 /// necessary when using asynchronous functions, since the program's stack is |
| 29 /// reset before each asynchronous callback is run. | 25 /// reset before each asynchronous callback is run. |
| 30 /// | 26 /// |
| 31 /// Stack chains can be automatically tracked using [Chain.capture]. This sets | 27 /// Stack chains can be automatically tracked using [Chain.capture]. This sets |
| 32 /// up a new [Zone] in which the current stack chain is tracked and can be | 28 /// up a new [Zone] in which the current stack chain is tracked and can be |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 /// | 108 /// |
| 113 /// If [trace] is already a [Chain], it will be returned as-is. | 109 /// If [trace] is already a [Chain], it will be returned as-is. |
| 114 factory Chain.forTrace(StackTrace trace) { | 110 factory Chain.forTrace(StackTrace trace) { |
| 115 if (trace is Chain) return trace; | 111 if (trace is Chain) return trace; |
| 116 if (_currentSpec == null) return new Chain([new Trace.from(trace)]); | 112 if (_currentSpec == null) return new Chain([new Trace.from(trace)]); |
| 117 return _currentSpec.chainFor(trace); | 113 return _currentSpec.chainFor(trace); |
| 118 } | 114 } |
| 119 | 115 |
| 120 /// Parses a string representation of a stack chain. | 116 /// Parses a string representation of a stack chain. |
| 121 /// | 117 /// |
| 122 /// Specifically, this parses the output of [Chain.toString]. | 118 /// If [chain] is the output of a call to [Chain.toString], it will be parsed |
| 119 /// as a full stack chain. Otherwise, it will be parsed as in [Trace.parse] |
| 120 /// and returned as a single-trace chain. |
| 123 factory Chain.parse(String chain) { | 121 factory Chain.parse(String chain) { |
| 124 if (chain.isEmpty) return new Chain([]); | 122 if (chain.isEmpty) return new Chain([]); |
| 123 if (!chain.contains(chainGap)) return new Chain([new Trace.parse(chain)]); |
| 124 |
| 125 return new Chain( | 125 return new Chain( |
| 126 chain.split(_gap).map((trace) => new Trace.parseFriendly(trace))); | 126 chain.split(chainGap).map((trace) => new Trace.parseFriendly(trace))); |
| 127 } | 127 } |
| 128 | 128 |
| 129 /// Returns a new [Chain] comprised of [traces]. | 129 /// Returns a new [Chain] comprised of [traces]. |
| 130 Chain(Iterable<Trace> traces) | 130 Chain(Iterable<Trace> traces) |
| 131 : traces = new UnmodifiableListView<Trace>(traces.toList()); | 131 : traces = new UnmodifiableListView<Trace>(traces.toList()); |
| 132 | 132 |
| 133 /// Returns a terser version of [this]. | 133 /// Returns a terser version of [this]. |
| 134 /// | 134 /// |
| 135 /// This calls [Trace.terse] on every trace in [traces], and discards any | 135 /// This calls [Trace.terse] on every trace in [traces], and discards any |
| 136 /// trace that contain only internal frames. | 136 /// trace that contain only internal frames. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 return trace.frames.map((frame) => frame.location.length) | 184 return trace.frames.map((frame) => frame.location.length) |
| 185 .fold(0, math.max); | 185 .fold(0, math.max); |
| 186 }).fold(0, math.max); | 186 }).fold(0, math.max); |
| 187 | 187 |
| 188 // Don't call out to [Trace.toString] here because that doesn't ensure that | 188 // Don't call out to [Trace.toString] here because that doesn't ensure that |
| 189 // padding is consistent across all traces. | 189 // padding is consistent across all traces. |
| 190 return traces.map((trace) { | 190 return traces.map((trace) { |
| 191 return trace.frames.map((frame) { | 191 return trace.frames.map((frame) { |
| 192 return '${padRight(frame.location, longest)} ${frame.member}\n'; | 192 return '${padRight(frame.location, longest)} ${frame.member}\n'; |
| 193 }).join(); | 193 }).join(); |
| 194 }).join(_gap); | 194 }).join(chainGap); |
| 195 } | 195 } |
| 196 } | 196 } |
| OLD | NEW |