blob: 3145cd284af378eb41803544b60a7244d01e8212 [file] [log] [blame]
// 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);
}
}