| // 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. |
| |
| library csslib.src.messages; |
| |
| import 'package:logging/logging.dart' show Level; |
| import 'package:source_span/source_span.dart'; |
| |
| import 'options.dart'; |
| |
| // TODO(terry): Remove the global messages, use some object that tracks |
| // compilation state. |
| |
| /** The global [Messages] for tracking info/warnings/messages. */ |
| Messages messages; |
| |
| // Color constants used for generating messages. |
| final String GREEN_COLOR = '\u001b[32m'; |
| final String RED_COLOR = '\u001b[31m'; |
| final String MAGENTA_COLOR = '\u001b[35m'; |
| final String NO_COLOR = '\u001b[0m'; |
| |
| /** Map between error levels and their display color. */ |
| final Map<Level, String> _ERROR_COLORS = (() { |
| var colorsMap = new Map<Level, String>(); |
| colorsMap[Level.SEVERE] = RED_COLOR; |
| colorsMap[Level.WARNING] = MAGENTA_COLOR; |
| colorsMap[Level.INFO] = GREEN_COLOR; |
| return colorsMap; |
| })(); |
| |
| /** Map between error levels and their friendly name. */ |
| final Map<Level, String> _ERROR_LABEL = (() { |
| var labels = new Map<Level, String>(); |
| labels[Level.SEVERE] = 'error'; |
| labels[Level.WARNING] = 'warning'; |
| labels[Level.INFO] = 'info'; |
| return labels; |
| })(); |
| |
| /** A single message from the compiler. */ |
| class Message { |
| final Level level; |
| final String message; |
| final SourceSpan span; |
| final bool useColors; |
| |
| Message(this.level, this.message, {SourceSpan span, bool useColors: false}) |
| : this.span = span, |
| this.useColors = useColors; |
| |
| String toString() { |
| var output = new StringBuffer(); |
| bool colors = useColors && _ERROR_COLORS.containsKey(level); |
| var levelColor = colors ? _ERROR_COLORS[level] : null; |
| if (colors) output.write(levelColor); |
| output..write(_ERROR_LABEL[level])..write(' '); |
| if (colors) output.write(NO_COLOR); |
| |
| if (span == null) { |
| output.write(message); |
| } else { |
| output.write('on '); |
| output.write(span.message(message, color: levelColor)); |
| } |
| |
| return output.toString(); |
| } |
| } |
| |
| typedef void PrintHandler(Message obj); |
| |
| /** |
| * 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 PrintHandler printHandler; |
| |
| final PreprocessorOptions options; |
| |
| final List<Message> messages = <Message>[]; |
| |
| Messages({PreprocessorOptions options, this.printHandler: print}) |
| : options = options != null ? options : new PreprocessorOptions(); |
| |
| /** Report a compile-time CSS error. */ |
| void error(String message, SourceSpan span) { |
| var msg = new Message(Level.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 = new Message(Level.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 = new Message(Level.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 == Level.SEVERE || options.verbose) |
| .forEach(printHandler); |
| } |
| } |