blob: 837eefdfcd3cd6c91088a9dcfc3a541e093d5795 [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.
/** The one true [World]. */
World world;
typedef void MessageHandler(String prefix, String message, SourceSpan span);
typedef void PrintHandler(String message);
/**
* Should be called exactly once to setup singleton world.
* Can use world.reset() to reinitialize.
*/
void initializeWorld(var files) {
assert(world == null);
world = new World(files);
world.init();
}
/** Can be thrown on any compiler error and includes source location. */
class CompilerException implements Exception {
final String _message;
final SourceSpan _location;
CompilerException(this._message, this._location);
String toString() {
if (_location != null) {
return 'CompilerException: ${_location.toMessageString(_message)}';
} else {
return 'CompilerException: $_message';
}
}
}
/** Represents a Dart template "world". */
class World {
String template;
var files;
int errors = 0, warnings = 0;
bool seenFatal = false;
MessageHandler messageHandler;
PrintHandler printHandler;
World(this.files);
void reset() {
errors = warnings = 0;
seenFatal = false;
init();
}
init() {
}
// ********************** Message support ***********************
void _message(String color, String prefix, String message,
SourceSpan span, SourceSpan span1, SourceSpan span2, bool throwing) {
if (messageHandler != null) {
// TODO(jimhug): Multiple spans cleaner...
messageHandler(prefix, message, span);
if (span1 != null) {
messageHandler(prefix, message, span1);
}
if (span2 != null) {
messageHandler(prefix, message, span2);
}
} else {
final messageWithPrefix = options.useColors
? (color + prefix + _NO_COLOR + message) : (prefix + message);
var text = messageWithPrefix;
if (span != null) {
text = span.toMessageString(messageWithPrefix);
}
String span1Text = span1 != null ?
span1.toMessageString(messageWithPrefix) : "";
String span2Text = span2 != null ?
span2.toMessageString(messageWithPrefix) : "";
if (printHandler == null) {
print(text);
if (span1 != null) {
print(span1Text);
}
if (span2 != null) {
print(span2Text);
}
} else {
printHandler("${text}\r${span1Text}\r${span2Text}");
}
}
if (throwing) {
throw new CompilerException(prefix + message, span);
}
}
/** [message] is considered a static compile-time error by the Dart lang. */
void error(String message,
[SourceSpan span, SourceSpan span1, SourceSpan span2]) {
errors++;
_message(_RED_COLOR, 'error: ', message,
span, span1, span2, options.throwOnErrors);
}
/** [message] is considered a type warning by the Dart lang. */
void warning(String message,
[SourceSpan span, SourceSpan span1, SourceSpan span2]) {
if (options.warningsAsErrors) {
error(message, span, span1, span2);
return;
}
warnings++;
if (options.showWarnings) {
_message(_MAGENTA_COLOR, 'warning: ', message,
span, span1, span2, options.throwOnWarnings);
}
}
/** [message] at [location] is so bad we can't generate runnable code. */
void fatal(String message,
[SourceSpan span, SourceSpan span1, SourceSpan span2]) {
errors++;
seenFatal = true;
_message(_RED_COLOR, 'fatal: ', message,
span, span1, span2, options.throwOnFatal || options.throwOnErrors);
}
/** [message] at [location] is about a bug in the compiler. */
void internalError(String message,
{SourceSpan span, SourceSpan span1, SourceSpan span2}) {
_message(_NO_COLOR,
'We are sorry, but...', message, span, span1, span2, true);
}
/**
* [message] at [location] will tell the user about what the compiler
* is doing.
*/
void info(String message,
[SourceSpan span, SourceSpan span1, SourceSpan span2]) {
if (options.showInfo) {
_message(_GREEN_COLOR, 'info: ', message, span, span1, span2, false);
}
}
bool get hasErrors => errors > 0;
withTiming(String name, f()) {
final sw = new Stopwatch();
sw.start();
var result = f();
sw.stop();
info('$name in ${sw.elapsedMilliseconds}msec');
return result;
}
}
// Color constants used for generating messages.
String _GREEN_COLOR = '\u001b[32m';
String _RED_COLOR = '\u001b[31m';
String _MAGENTA_COLOR = '\u001b[35m';
String _NO_COLOR = '\u001b[0m';