OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS d.file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS d.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 '../exceptions.dart'; | 5 import '../exceptions.dart'; |
6 | 6 |
7 /// An exception thrown when a transformer dependency cycle is detected. | 7 /// An exception thrown when a transformer dependency cycle is detected. |
8 /// | 8 /// |
9 /// A cycle exception is usually produced within a deeply-nested series of | 9 /// A cycle exception is usually produced within a deeply-nested series of |
10 /// calls. The API is designed to make it easy for each of these calls to add to | 10 /// calls. The API is designed to make it easy for each of these calls to add to |
11 /// the message so that the full reasoning for the cycle is made visible to the | 11 /// the message so that the full reasoning for the cycle is made visible to the |
12 /// user. | 12 /// user. |
13 /// | 13 /// |
14 /// Each call's individual message is called a "step". A [CycleException] is | 14 /// Each call's individual message is called a "step". A [CycleException] is |
15 /// represented internally as a linked list of steps. | 15 /// represented internally as a linked list of steps. |
16 class CycleException implements ApplicationException { | 16 class CycleException implements ApplicationException { |
17 /// The step for this exception. | 17 /// The step for this exception. |
18 final String _step; | 18 final String _step; |
19 | 19 |
20 /// The next exception in the linked list. | 20 /// The next exception in the linked list. |
21 /// | 21 /// |
22 /// [_next]'s steps come after [_step]. | 22 /// [_next]'s steps come after [_step]. |
23 final CycleException _next; | 23 final CycleException _next; |
24 | 24 |
25 /// A list of all steps in the cycle. | 25 /// A list of all steps in the cycle. |
26 List<String> get steps { | 26 List<String> get steps { |
27 if (_step == null) return []; | 27 if (_step == null) return []; |
28 | 28 |
29 var exception = this; | 29 var exception = this; |
30 var steps = []; | 30 var steps = <String>[]; |
31 while (exception != null) { | 31 while (exception != null) { |
32 steps.add(exception._step); | 32 steps.add(exception._step); |
33 exception = exception._next; | 33 exception = exception._next; |
34 } | 34 } |
35 return steps; | 35 return steps; |
36 } | 36 } |
37 | 37 |
38 String get message { | 38 String get message { |
39 var steps = this.steps; | 39 var steps = this.steps; |
40 if (steps.isEmpty) return "Transformer cycle detected."; | 40 if (steps.isEmpty) return "Transformer cycle detected."; |
41 return "Transformer cycle detected:\n" + | 41 return "Transformer cycle detected:\n" + |
42 steps.map((step) => " $step").join("\n"); | 42 steps.map((step) => " $step").join("\n"); |
43 } | 43 } |
44 | 44 |
45 /// Creates a new [CycleException] with zero or one steps. | 45 /// Creates a new [CycleException] with zero or one steps. |
46 CycleException([this._step]) | 46 CycleException([this._step]) |
47 : _next = null; | 47 : _next = null; |
48 | 48 |
49 CycleException._(this._step, this._next); | 49 CycleException._(this._step, this._next); |
50 | 50 |
51 /// Returns a copy of [this] with [step] added to the beginning of [steps]. | 51 /// Returns a copy of [this] with [step] added to the beginning of [steps]. |
52 CycleException prependStep(String step) { | 52 CycleException prependStep(String step) { |
53 if (_step == null) return new CycleException(step); | 53 if (_step == null) return new CycleException(step); |
54 return new CycleException._(step, this); | 54 return new CycleException._(step, this); |
55 } | 55 } |
56 | 56 |
57 String toString() => message; | 57 String toString() => message; |
58 } | 58 } |
OLD | NEW |