Line data Source code
1 : // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 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. 4 : 5 : import 'span.dart'; 6 : 7 : /// A class for exceptions that have source span information attached. 8 : class SourceSpanException implements Exception { 9 : // This is a getter so that subclasses can override it. 10 : /// A message describing the exception. 11 0 : String get message => _message; 12 : final String _message; 13 : 14 : // This is a getter so that subclasses can override it. 15 : /// The span associated with this exception. 16 : /// 17 : /// This may be `null` if the source location can't be determined. 18 0 : SourceSpan? get span => _span; 19 : final SourceSpan? _span; 20 : 21 0 : SourceSpanException(this._message, this._span); 22 : 23 : /// Returns a string representation of `this`. 24 : /// 25 : /// [color] may either be a [String], a [bool], or `null`. If it's a string, 26 : /// it indicates an ANSI terminal color escape that should be used to 27 : /// highlight the span's text. If it's `true`, it indicates that the text 28 : /// should be highlighted using the default color. If it's `false` or `null`, 29 : /// it indicates that the text shouldn't be highlighted. 30 0 : @override 31 : String toString({color}) { 32 0 : if (span == null) return message; 33 0 : return 'Error on ${span!.message(message, color: color)}'; 34 : } 35 : } 36 : 37 : /// A [SourceSpanException] that's also a [FormatException]. 38 : class SourceSpanFormatException extends SourceSpanException 39 : implements FormatException { 40 : @override 41 : final dynamic source; 42 : 43 0 : @override 44 0 : int? get offset => span?.start.offset; 45 : 46 0 : SourceSpanFormatException(String message, SourceSpan? span, [this.source]) 47 0 : : super(message, span); 48 : } 49 : 50 : /// A [SourceSpanException] that also highlights some secondary spans to provide 51 : /// the user with extra context. 52 : /// 53 : /// Each span has a label ([primaryLabel] for the primary, and the values of the 54 : /// [secondarySpans] map for the secondary spans) that's used to indicate to the 55 : /// user what that particular span represents. 56 : class MultiSourceSpanException extends SourceSpanException { 57 : /// A label to attach to [span] that provides additional information and helps 58 : /// distinguish it from [secondarySpans]. 59 : final String primaryLabel; 60 : 61 : /// A map whose keys are secondary spans that should be highlighted. 62 : /// 63 : /// Each span's value is a label to attach to that span that provides 64 : /// additional information and helps distinguish it from [secondarySpans]. 65 : final Map<SourceSpan, String> secondarySpans; 66 : 67 0 : MultiSourceSpanException(String message, SourceSpan? span, this.primaryLabel, 68 : Map<SourceSpan, String> secondarySpans) 69 0 : : secondarySpans = Map.unmodifiable(secondarySpans), 70 0 : super(message, span); 71 : 72 : /// Returns a string representation of `this`. 73 : /// 74 : /// [color] may either be a [String], a [bool], or `null`. If it's a string, 75 : /// it indicates an ANSI terminal color escape that should be used to 76 : /// highlight the primary span's text. If it's `true`, it indicates that the 77 : /// text should be highlighted using the default color. If it's `false` or 78 : /// `null`, it indicates that the text shouldn't be highlighted. 79 : /// 80 : /// If [color] is `true` or a string, [secondaryColor] is used to highlight 81 : /// [secondarySpans]. 82 0 : @override 83 : String toString({color, String? secondaryColor}) { 84 0 : if (span == null) return message; 85 : 86 : var useColor = false; 87 : String? primaryColor; 88 0 : if (color is String) { 89 : useColor = true; 90 : primaryColor = color; 91 0 : } else if (color == true) { 92 : useColor = true; 93 : } 94 : 95 0 : final formatted = span!.messageMultiple( 96 0 : message, primaryLabel, secondarySpans, 97 : color: useColor, 98 : primaryColor: primaryColor, 99 : secondaryColor: secondaryColor); 100 0 : return 'Error on $formatted'; 101 : } 102 : } 103 : 104 : /// A [MultiSourceSpanException] that's also a [FormatException]. 105 : class MultiSourceSpanFormatException extends MultiSourceSpanException 106 : implements FormatException { 107 : @override 108 : final dynamic source; 109 : 110 0 : @override 111 0 : int? get offset => span?.start.offset; 112 : 113 0 : MultiSourceSpanFormatException(String message, SourceSpan? span, 114 : String primaryLabel, Map<SourceSpan, String> secondarySpans, 115 : [this.source]) 116 0 : : super(message, span, primaryLabel, secondarySpans); 117 : }