| Index: stack_trace/lib/src/chain.dart | 
| diff --git a/stack_trace/lib/src/chain.dart b/stack_trace/lib/src/chain.dart | 
| deleted file mode 100644 | 
| index acd17e9d59ea516498fc50ed89b0ecea07290658..0000000000000000000000000000000000000000 | 
| --- a/stack_trace/lib/src/chain.dart | 
| +++ /dev/null | 
| @@ -1,196 +0,0 @@ | 
| -// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file | 
| -// for details. All rights reserved. Use of this source code is governed by a | 
| -// BSD-style license that can be found in the LICENSE file. | 
| - | 
| -library stack_trace.chain; | 
| - | 
| -import 'dart:async'; | 
| -import 'dart:collection'; | 
| -import 'dart:math' as math; | 
| - | 
| -import 'frame.dart'; | 
| -import 'stack_zone_specification.dart'; | 
| -import 'trace.dart'; | 
| -import 'utils.dart'; | 
| - | 
| -/// A function that handles errors in the zone wrapped by [Chain.capture]. | 
| -typedef void ChainHandler(error, Chain chain); | 
| - | 
| -/// The line used in the string representation of stack chains to represent | 
| -/// the gap between traces. | 
| -const _gap = '===== asynchronous gap ===========================\n'; | 
| - | 
| -/// A chain of stack traces. | 
| -/// | 
| -/// A stack chain is a collection of one or more stack traces that collectively | 
| -/// represent the path from [main] through nested function calls to a particular | 
| -/// code location, usually where an error was thrown. Multiple stack traces are | 
| -/// necessary when using asynchronous functions, since the program's stack is | 
| -/// reset before each asynchronous callback is run. | 
| -/// | 
| -/// Stack chains can be automatically tracked using [Chain.capture]. This sets | 
| -/// up a new [Zone] in which the current stack chain is tracked and can be | 
| -/// accessed using [new Chain.current]. Any errors that would be top-leveled in | 
| -/// the zone can be handled, along with their associated chains, with the | 
| -/// `onError` callback. For example: | 
| -/// | 
| -///     Chain.capture(() { | 
| -///       // ... | 
| -///     }, onError: (error, stackChain) { | 
| -///       print("Caught error $error\n" | 
| -///             "$stackChain"); | 
| -///     }); | 
| -class Chain implements StackTrace { | 
| - | 
| -  /// The stack traces that make up this chain. | 
| -  /// | 
| -  /// Like the frames in a stack trace, the traces are ordered from most local | 
| -  /// to least local. The first one is the trace where the actual exception was | 
| -  /// raised, the second one is where that callback was scheduled, and so on. | 
| -  final List<Trace> traces; | 
| - | 
| -  /// The [StackZoneSpecification] for the current zone. | 
| -  static StackZoneSpecification get _currentSpec => | 
| -    Zone.current[#stack_trace.stack_zone.spec]; | 
| - | 
| -  /// Runs [callback] in a [Zone] in which the current stack chain is tracked | 
| -  /// and automatically associated with (most) errors. | 
| -  /// | 
| -  /// If [onError] is passed, any error in the zone that would otherwise go | 
| -  /// unhandled is passed to it, along with the [Chain] associated with that | 
| -  /// error. Note that if [callback] produces multiple unhandled errors, | 
| -  /// [onError] may be called more than once. If [onError] isn't passed, the | 
| -  /// parent Zone's `unhandledErrorHandler` will be called with the error and | 
| -  /// its chain. | 
| -  /// | 
| -  /// Note that even if [onError] isn't passed, this zone will still be an error | 
| -  /// zone. This means that any errors that would cross the zone boundary are | 
| -  /// considered unhandled. | 
| -  /// | 
| -  /// If [callback] returns a value, it will be returned by [capture] as well. | 
| -  static capture(callback(), {ChainHandler onError}) { | 
| -    var spec = new StackZoneSpecification(onError); | 
| -    return runZoned(() { | 
| -      try { | 
| -        return callback(); | 
| -      } catch (error, stackTrace) { | 
| -        // TODO(nweiz): Don't special-case this when issue 19566 is fixed. | 
| -        return Zone.current.handleUncaughtError(error, stackTrace); | 
| -      } | 
| -    }, zoneSpecification: spec.toSpec(), zoneValues: { | 
| -      #stack_trace.stack_zone.spec: spec | 
| -    }); | 
| -  } | 
| - | 
| -  /// Returns [futureOrStream] unmodified. | 
| -  /// | 
| -  /// Prior to Dart 1.7, this was necessary to ensure that stack traces for | 
| -  /// exceptions reported with [Completer.completeError] and | 
| -  /// [StreamController.addError] were tracked correctly. | 
| -  @Deprecated("Chain.track is not necessary in Dart 1.7+.") | 
| -  static track(futureOrStream) => futureOrStream; | 
| - | 
| -  /// Returns the current stack chain. | 
| -  /// | 
| -  /// By default, the first frame of the first trace will be the line where | 
| -  /// [Chain.current] is called. If [level] is passed, the first trace will | 
| -  /// start that many frames up instead. | 
| -  /// | 
| -  /// If this is called outside of a [capture] zone, it just returns a | 
| -  /// single-trace chain. | 
| -  factory Chain.current([int level=0]) { | 
| -    if (_currentSpec != null) return _currentSpec.currentChain(level + 1); | 
| -    return new Chain([new Trace.current(level + 1)]); | 
| -  } | 
| - | 
| -  /// Returns the stack chain associated with [trace]. | 
| -  /// | 
| -  /// The first stack trace in the returned chain will always be [trace] | 
| -  /// (converted to a [Trace] if necessary). If there is no chain associated | 
| -  /// with [trace] or if this is called outside of a [capture] zone, this just | 
| -  /// returns a single-trace chain containing [trace]. | 
| -  /// | 
| -  /// If [trace] is already a [Chain], it will be returned as-is. | 
| -  factory Chain.forTrace(StackTrace trace) { | 
| -    if (trace is Chain) return trace; | 
| -    if (_currentSpec == null) return new Chain([new Trace.from(trace)]); | 
| -    return _currentSpec.chainFor(trace); | 
| -  } | 
| - | 
| -  /// Parses a string representation of a stack chain. | 
| -  /// | 
| -  /// Specifically, this parses the output of [Chain.toString]. | 
| -  factory Chain.parse(String chain) { | 
| -    if (chain.isEmpty) return new Chain([]); | 
| -    return new Chain( | 
| -        chain.split(_gap).map((trace) => new Trace.parseFriendly(trace))); | 
| -  } | 
| - | 
| -  /// Returns a new [Chain] comprised of [traces]. | 
| -  Chain(Iterable<Trace> traces) | 
| -      : traces = new UnmodifiableListView<Trace>(traces.toList()); | 
| - | 
| -  /// Returns a terser version of [this]. | 
| -  /// | 
| -  /// This calls [Trace.terse] on every trace in [traces], and discards any | 
| -  /// trace that contain only internal frames. | 
| -  Chain get terse => foldFrames((_) => false, terse: true); | 
| - | 
| -  /// Returns a new [Chain] based on [this] where multiple stack frames matching | 
| -  /// [predicate] are folded together. | 
| -  /// | 
| -  /// This means that whenever there are multiple frames in a row that match | 
| -  /// [predicate], only the last one is kept. In addition, traces that are | 
| -  /// composed entirely of frames matching [predicate] are omitted. | 
| -  /// | 
| -  /// This is useful for limiting the amount of library code that appears in a | 
| -  /// stack trace by only showing user code and code that's called by user code. | 
| -  /// | 
| -  /// If [terse] is true, this will also fold together frames from the core | 
| -  /// library or from this package, and simplify core library frames as in | 
| -  /// [Trace.terse]. | 
| -  Chain foldFrames(bool predicate(Frame frame), {bool terse: false}) { | 
| -    var foldedTraces = traces.map( | 
| -        (trace) => trace.foldFrames(predicate, terse: terse)); | 
| -    var nonEmptyTraces = foldedTraces.where((trace) { | 
| -      // Ignore traces that contain only folded frames. | 
| -      if (trace.frames.length > 1) return true; | 
| - | 
| -      // In terse mode, the trace may have removed an outer folded frame, | 
| -      // leaving a single non-folded frame. We can detect a folded frame because | 
| -      // it has no line information. | 
| -      if (!terse) return false; | 
| -      return trace.frames.single.line != null; | 
| -    }); | 
| - | 
| -    // If all the traces contain only internal processing, preserve the last | 
| -    // (top-most) one so that the chain isn't empty. | 
| -    if (nonEmptyTraces.isEmpty && foldedTraces.isNotEmpty) { | 
| -      return new Chain([foldedTraces.last]); | 
| -    } | 
| - | 
| -    return new Chain(nonEmptyTraces); | 
| -  } | 
| - | 
| -  /// Converts [this] to a [Trace]. | 
| -  /// | 
| -  /// The trace version of a chain is just the concatenation of all the traces | 
| -  /// in the chain. | 
| -  Trace toTrace() => new Trace(flatten(traces.map((trace) => trace.frames))); | 
| - | 
| -  String toString() { | 
| -    // Figure out the longest path so we know how much to pad. | 
| -    var longest = traces.map((trace) { | 
| -      return trace.frames.map((frame) => frame.location.length) | 
| -          .fold(0, math.max); | 
| -    }).fold(0, math.max); | 
| - | 
| -    // Don't call out to [Trace.toString] here because that doesn't ensure that | 
| -    // padding is consistent across all traces. | 
| -    return traces.map((trace) { | 
| -      return trace.frames.map((frame) { | 
| -        return '${padRight(frame.location, longest)}  ${frame.member}\n'; | 
| -      }).join(); | 
| -    }).join(_gap); | 
| -  } | 
| -} | 
|  |