| 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 utils; | 5 library utils; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:stack_trace/stack_trace.dart'; | 9 import 'package:stack_trace/stack_trace.dart'; |
| 10 | 10 |
| 11 /// A pair of values. | 11 /// A pair of values. |
| 12 class Pair<E, F> { | 12 class Pair<E, F> { |
| 13 E first; | 13 E first; |
| 14 F last; | 14 F last; |
| 15 | 15 |
| 16 Pair(this.first, this.last); | 16 Pair(this.first, this.last); |
| 17 | 17 |
| 18 String toString() => '($first, $last)'; | 18 String toString() => '($first, $last)'; |
| 19 | 19 |
| 20 bool operator==(other) { | 20 bool operator==(other) { |
| 21 if (other is! Pair) return false; | 21 if (other is! Pair) return false; |
| 22 return other.first == first && other.last == last; | 22 return other.first == first && other.last == last; |
| 23 } | 23 } |
| 24 | 24 |
| 25 int get hashCode => first.hashCode ^ last.hashCode; | 25 int get hashCode => first.hashCode ^ last.hashCode; |
| 26 } | 26 } |
| 27 | 27 |
| 28 /// A class that represents a value or an error. |
| 29 class FallibleValue<E> { |
| 30 /// Whether [this] has a [value], as opposed to an [error]. |
| 31 final bool hasValue; |
| 32 |
| 33 /// Whether [this] has an [error], as opposed to an[value]. |
| 34 bool get hasError => !hasValue; |
| 35 |
| 36 /// The value. |
| 37 /// |
| 38 /// This will be `null` if [this] has an [error]. |
| 39 final E _value; |
| 40 |
| 41 /// The value. |
| 42 /// |
| 43 /// This will throw a [StateError] if [this] has an [error]. |
| 44 E get value { |
| 45 if (hasValue) return _value; |
| 46 throw new StateError("FallibleValue has no value.\n" |
| 47 "$_error$_stackTraceSuffix"); |
| 48 } |
| 49 |
| 50 /// The error. |
| 51 /// |
| 52 /// This will be `null` if [this] has a [value]. |
| 53 final _error; |
| 54 |
| 55 /// The error. |
| 56 /// |
| 57 /// This will throw a [StateError] if [this] has a [value]. |
| 58 get error { |
| 59 if (hasError) return _error; |
| 60 throw new StateError("FallibleValue has no error."); |
| 61 } |
| 62 |
| 63 /// The stack trace for [_error]. |
| 64 /// |
| 65 /// This will be `null` if [this] has a [value], or if no stack trace was |
| 66 /// provided. |
| 67 final StackTrace _stackTrace; |
| 68 |
| 69 /// The stack trace for [error]. |
| 70 /// |
| 71 /// This will throw a [StateError] if [this] has a [value]. |
| 72 StackTrace get stackTrace { |
| 73 if (hasError) return _stackTrace; |
| 74 throw new StateError("FallibleValue has no error."); |
| 75 } |
| 76 |
| 77 FallibleValue.withValue(this._value) |
| 78 : hasValue = true; |
| 79 |
| 80 FallibleValue.withError(this._error, [this._stackTrace]) |
| 81 : hasValue = false; |
| 82 |
| 83 String toString() { |
| 84 if (hasValue) return "FallibleValue value: $value"; |
| 85 return "FallibleValue error: $error$_stackTraceSuffix"; |
| 86 } |
| 87 |
| 88 String get _stackTraceSuffix { |
| 89 if (stackTrace == null) return ""; |
| 90 return "\nStack trace:\n${new Chain.from(_stackTrace).terse}"; |
| 91 } |
| 92 } |
| 93 |
| 28 /// Configures [future] so that its result (success or exception) is passed on | 94 /// Configures [future] so that its result (success or exception) is passed on |
| 29 /// to [completer]. | 95 /// to [completer]. |
| 30 void chainToCompleter(Future future, Completer completer) { | 96 void chainToCompleter(Future future, Completer completer) { |
| 31 future.then(completer.complete, onError: completer.completeError); | 97 future.then(completer.complete, onError: completer.completeError); |
| 32 } | 98 } |
| 33 | 99 |
| 34 /// Like [Future.sync], but wraps the Future in [Chain.track] as well. | 100 /// Like [Future.sync], but wraps the Future in [Chain.track] as well. |
| 35 Future syncFuture(callback()) => Chain.track(new Future.sync(callback)); | 101 Future syncFuture(callback()) => Chain.track(new Future.sync(callback)); |
| 36 | 102 |
| 37 /// Prepends each line in [text] with [prefix]. If [firstPrefix] is passed, the | 103 /// Prepends each line in [text] with [prefix]. If [firstPrefix] is passed, the |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 /// Returns whether [pattern] matches all of [string]. | 290 /// Returns whether [pattern] matches all of [string]. |
| 225 bool fullMatch(String string, Pattern pattern) { | 291 bool fullMatch(String string, Pattern pattern) { |
| 226 var matches = pattern.allMatches(string); | 292 var matches = pattern.allMatches(string); |
| 227 if (matches.isEmpty) return false; | 293 if (matches.isEmpty) return false; |
| 228 return matches.first.start == 0 && matches.first.end == string.length; | 294 return matches.first.start == 0 && matches.first.end == string.length; |
| 229 } | 295 } |
| 230 | 296 |
| 231 /// Returns a string representation of [trace] that has the core and test frames | 297 /// Returns a string representation of [trace] that has the core and test frames |
| 232 /// folded together. | 298 /// folded together. |
| 233 String terseTraceString(StackTrace trace) { | 299 String terseTraceString(StackTrace trace) { |
| 234 return new Chain(new Chain.forTrace(trace).traces.map((trace) { | 300 return new Chain.forTrace(trace).terse.toString().trim(); |
| 235 return trace.foldFrames((frame) { | |
| 236 return frame.package == 'scheduled_test' || | |
| 237 frame.package == 'unittest' || | |
| 238 frame.package == 'stack_trace' || | |
| 239 frame.isCore; | |
| 240 }); | |
| 241 })).terse.toString().trim(); | |
| 242 } | 301 } |
| OLD | NEW |