| // Copyright (c) 2012, 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 'package:source_span/source_span.dart'; |
| |
| import 'preprocessor_options.dart'; |
| |
| enum MessageLevel { info, warning, severe } |
| |
| // TODO(terry): Remove the global messages, use some object that tracks |
| // compilation state. |
| |
| /// The global [Messages] for tracking info/warnings/messages. |
| late Messages messages; |
| |
| // Color constants used for generating messages. |
| const _greenColor = '\u001b[32m'; |
| const _redColor = '\u001b[31m'; |
| const _magentaColor = '\u001b[35m'; |
| const _noColor = '\u001b[0m'; |
| |
| /// Map between error levels and their display color. |
| const Map<MessageLevel, String> _errorColors = { |
| MessageLevel.severe: _redColor, |
| MessageLevel.warning: _magentaColor, |
| MessageLevel.info: _greenColor, |
| }; |
| |
| /// Map between error levels and their friendly name. |
| const Map<MessageLevel, String> _errorLabel = { |
| MessageLevel.severe: 'error', |
| MessageLevel.warning: 'warning', |
| MessageLevel.info: 'info', |
| }; |
| |
| /// A single message from the compiler. |
| class Message { |
| final MessageLevel level; |
| final String message; |
| final SourceSpan? span; |
| final bool useColors; |
| |
| Message(this.level, this.message, {this.span, this.useColors = false}); |
| |
| @override |
| String toString() { |
| var output = StringBuffer(); |
| var colors = useColors && _errorColors.containsKey(level); |
| var levelColor = colors ? _errorColors[level] : null; |
| if (colors) output.write(levelColor); |
| output |
| ..write(_errorLabel[level]) |
| ..write(' '); |
| if (colors) output.write(_noColor); |
| |
| if (span == null) { |
| output.write(message); |
| } else { |
| output.write('on '); |
| output.write(span!.message(message, color: levelColor)); |
| } |
| |
| return output.toString(); |
| } |
| } |
| |
| /// This class tracks and prints information, warnings, and errors emitted by |
| /// the compiler. |
| class Messages { |
| /// Called on every error. Set to blank function to supress printing. |
| final void Function(Message obj) printHandler; |
| |
| final PreprocessorOptions options; |
| |
| final List<Message> messages = <Message>[]; |
| |
| Messages({PreprocessorOptions? options, this.printHandler = print}) |
| : options = options ?? PreprocessorOptions(); |
| |
| /// Report a compile-time CSS error. |
| void error(String message, SourceSpan? span) { |
| var msg = Message(MessageLevel.severe, message, |
| span: span, useColors: options.useColors); |
| |
| messages.add(msg); |
| |
| printHandler(msg); |
| } |
| |
| /// Report a compile-time CSS warning. |
| void warning(String message, SourceSpan? span) { |
| if (options.warningsAsErrors) { |
| error(message, span); |
| } else { |
| var msg = Message(MessageLevel.warning, message, |
| span: span, useColors: options.useColors); |
| |
| messages.add(msg); |
| } |
| } |
| |
| /// Report and informational message about what the compiler is doing. |
| void info(String message, SourceSpan span) { |
| var msg = Message(MessageLevel.info, message, |
| span: span, useColors: options.useColors); |
| |
| messages.add(msg); |
| |
| if (options.verbose) printHandler(msg); |
| } |
| |
| /// Merge [newMessages] to this message lsit. |
| void mergeMessages(Messages newMessages) { |
| messages.addAll(newMessages.messages); |
| newMessages.messages |
| .where((message) => |
| message.level == MessageLevel.severe || options.verbose) |
| .forEach(printHandler); |
| } |
| } |