| // Copyright (c) 2014, 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. |
| |
| import 'span.dart'; |
| |
| /// A class for exceptions that have source span information attached. |
| class SourceSpanException implements Exception { |
| // This is a getter so that subclasses can override it. |
| /// A message describing the exception. |
| String get message => _message; |
| final String _message; |
| |
| // This is a getter so that subclasses can override it. |
| /// The span associated with this exception. |
| /// |
| /// This may be `null` if the source location can't be determined. |
| SourceSpan? get span => _span; |
| final SourceSpan? _span; |
| |
| SourceSpanException(this._message, this._span); |
| |
| /// Returns a string representation of `this`. |
| /// |
| /// [color] may either be a [String], a [bool], or `null`. If it's a string, |
| /// it indicates an ANSI terminal color escape that should be used to |
| /// highlight the span's text. If it's `true`, it indicates that the text |
| /// should be highlighted using the default color. If it's `false` or `null`, |
| /// it indicates that the text shouldn't be highlighted. |
| @override |
| String toString({color}) { |
| if (span == null) return message; |
| return 'Error on ${span!.message(message, color: color)}'; |
| } |
| } |
| |
| /// A [SourceSpanException] that's also a [FormatException]. |
| class SourceSpanFormatException extends SourceSpanException |
| implements FormatException { |
| @override |
| final dynamic source; |
| |
| @override |
| int? get offset => span?.start.offset; |
| |
| SourceSpanFormatException(String message, SourceSpan? span, [this.source]) |
| : super(message, span); |
| } |
| |
| /// A [SourceSpanException] that also highlights some secondary spans to provide |
| /// the user with extra context. |
| /// |
| /// Each span has a label ([primaryLabel] for the primary, and the values of the |
| /// [secondarySpans] map for the secondary spans) that's used to indicate to the |
| /// user what that particular span represents. |
| class MultiSourceSpanException extends SourceSpanException { |
| /// A label to attach to [span] that provides additional information and helps |
| /// distinguish it from [secondarySpans]. |
| final String primaryLabel; |
| |
| /// A map whose keys are secondary spans that should be highlighted. |
| /// |
| /// Each span's value is a label to attach to that span that provides |
| /// additional information and helps distinguish it from [secondarySpans]. |
| final Map<SourceSpan, String> secondarySpans; |
| |
| MultiSourceSpanException(String message, SourceSpan? span, this.primaryLabel, |
| Map<SourceSpan, String> secondarySpans) |
| : secondarySpans = Map.unmodifiable(secondarySpans), |
| super(message, span); |
| |
| /// Returns a string representation of `this`. |
| /// |
| /// [color] may either be a [String], a [bool], or `null`. If it's a string, |
| /// it indicates an ANSI terminal color escape that should be used to |
| /// highlight the primary span's text. If it's `true`, it indicates that the |
| /// text should be highlighted using the default color. If it's `false` or |
| /// `null`, it indicates that the text shouldn't be highlighted. |
| /// |
| /// If [color] is `true` or a string, [secondaryColor] is used to highlight |
| /// [secondarySpans]. |
| @override |
| String toString({color, String? secondaryColor}) { |
| if (span == null) return message; |
| |
| var useColor = false; |
| String? primaryColor; |
| if (color is String) { |
| useColor = true; |
| primaryColor = color; |
| } else if (color == true) { |
| useColor = true; |
| } |
| |
| final formatted = span!.messageMultiple( |
| message, primaryLabel, secondarySpans, |
| color: useColor, |
| primaryColor: primaryColor, |
| secondaryColor: secondaryColor); |
| return 'Error on $formatted'; |
| } |
| } |
| |
| /// A [MultiSourceSpanException] that's also a [FormatException]. |
| class MultiSourceSpanFormatException extends MultiSourceSpanException |
| implements FormatException { |
| @override |
| final dynamic source; |
| |
| @override |
| int? get offset => span?.start.offset; |
| |
| MultiSourceSpanFormatException(String message, SourceSpan? span, |
| String primaryLabel, Map<SourceSpan, String> secondarySpans, |
| [this.source]) |
| : super(message, span, primaryLabel, secondarySpans); |
| } |