OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 /** The one true [World]. */ |
| 6 World world; |
| 7 |
| 8 typedef void MessageHandler(String prefix, String message, SourceSpan span); |
| 9 typedef void PrintHandler(String message); |
| 10 |
| 11 /** |
| 12 * Should be called exactly once to setup singleton world. |
| 13 * Can use world.reset() to reinitialize. |
| 14 */ |
| 15 void initializeWorld(var files) { |
| 16 assert(world == null); |
| 17 world = new World(files); |
| 18 world.init(); |
| 19 } |
| 20 |
| 21 /** Can be thrown on any compiler error and includes source location. */ |
| 22 class CompilerException implements Exception { |
| 23 final String _message; |
| 24 final SourceSpan _location; |
| 25 |
| 26 CompilerException(this._message, this._location); |
| 27 |
| 28 String toString() { |
| 29 if (_location != null) { |
| 30 return 'CompilerException: ${_location.toMessageString(_message)}'; |
| 31 } else { |
| 32 return 'CompilerException: $_message'; |
| 33 } |
| 34 } |
| 35 } |
| 36 |
| 37 /** Represents a Dart template "world". */ |
| 38 class World { |
| 39 String template; |
| 40 |
| 41 var files; |
| 42 |
| 43 int errors = 0, warnings = 0; |
| 44 bool seenFatal = false; |
| 45 MessageHandler messageHandler; |
| 46 PrintHandler printHandler; |
| 47 |
| 48 World(this.files); |
| 49 |
| 50 void reset() { |
| 51 errors = warnings = 0; |
| 52 seenFatal = false; |
| 53 init(); |
| 54 } |
| 55 |
| 56 init() { |
| 57 } |
| 58 |
| 59 |
| 60 // ********************** Message support *********************** |
| 61 |
| 62 void _message(String color, String prefix, String message, |
| 63 SourceSpan span, SourceSpan span1, SourceSpan span2, bool throwing) { |
| 64 if (messageHandler != null) { |
| 65 // TODO(jimhug): Multiple spans cleaner... |
| 66 messageHandler(prefix, message, span); |
| 67 if (span1 != null) { |
| 68 messageHandler(prefix, message, span1); |
| 69 } |
| 70 if (span2 != null) { |
| 71 messageHandler(prefix, message, span2); |
| 72 } |
| 73 } else { |
| 74 final messageWithPrefix = options.useColors |
| 75 ? (color + prefix + _NO_COLOR + message) : (prefix + message); |
| 76 |
| 77 var text = messageWithPrefix; |
| 78 if (span != null) { |
| 79 text = span.toMessageString(messageWithPrefix); |
| 80 } |
| 81 |
| 82 String span1Text = span1 != null ? |
| 83 span1.toMessageString(messageWithPrefix) : ""; |
| 84 String span2Text = span2 != null ? |
| 85 span2.toMessageString(messageWithPrefix) : ""; |
| 86 |
| 87 if (printHandler == null) { |
| 88 print(text); |
| 89 if (span1 != null) { |
| 90 print(span1Text); |
| 91 } |
| 92 if (span2 != null) { |
| 93 print(span2Text); |
| 94 } |
| 95 } else { |
| 96 printHandler("${text}\r${span1Text}\r${span2Text}"); |
| 97 } |
| 98 } |
| 99 |
| 100 if (throwing) { |
| 101 throw new CompilerException(prefix + message, span); |
| 102 } |
| 103 } |
| 104 |
| 105 /** [message] is considered a static compile-time error by the Dart lang. */ |
| 106 void error(String message, |
| 107 [SourceSpan span, SourceSpan span1, SourceSpan span2]) { |
| 108 errors++; |
| 109 _message(_RED_COLOR, 'error: ', message, |
| 110 span, span1, span2, options.throwOnErrors); |
| 111 } |
| 112 |
| 113 /** [message] is considered a type warning by the Dart lang. */ |
| 114 void warning(String message, |
| 115 [SourceSpan span, SourceSpan span1, SourceSpan span2]) { |
| 116 if (options.warningsAsErrors) { |
| 117 error(message, span, span1, span2); |
| 118 return; |
| 119 } |
| 120 warnings++; |
| 121 if (options.showWarnings) { |
| 122 _message(_MAGENTA_COLOR, 'warning: ', message, |
| 123 span, span1, span2, options.throwOnWarnings); |
| 124 } |
| 125 } |
| 126 |
| 127 /** [message] at [location] is so bad we can't generate runnable code. */ |
| 128 void fatal(String message, |
| 129 [SourceSpan span, SourceSpan span1, SourceSpan span2]) { |
| 130 errors++; |
| 131 seenFatal = true; |
| 132 _message(_RED_COLOR, 'fatal: ', message, |
| 133 span, span1, span2, options.throwOnFatal || options.throwOnErrors); |
| 134 } |
| 135 |
| 136 /** [message] at [location] is about a bug in the compiler. */ |
| 137 void internalError(String message, |
| 138 [SourceSpan span, SourceSpan span1, SourceSpan span2]) { |
| 139 _message(_NO_COLOR, |
| 140 'We are sorry, but...', message, span, span1, span2, true); |
| 141 } |
| 142 |
| 143 /** |
| 144 * [message] at [location] will tell the user about what the compiler |
| 145 * is doing. |
| 146 */ |
| 147 void info(String message, |
| 148 [SourceSpan span, SourceSpan span1, SourceSpan span2]) { |
| 149 if (options.showInfo) { |
| 150 _message(_GREEN_COLOR, 'info: ', message, span, span1, span2, false); |
| 151 } |
| 152 } |
| 153 |
| 154 bool get hasErrors() => errors > 0; |
| 155 |
| 156 withTiming(String name, f()) { |
| 157 final sw = new Stopwatch(); |
| 158 sw.start(); |
| 159 var result = f(); |
| 160 sw.stop(); |
| 161 info('$name in ${sw.elapsedInMs()}msec'); |
| 162 return result; |
| 163 } |
| 164 } |
| 165 |
| 166 String _GREEN_COLOR = '\u001b[32m'; |
| 167 String _RED_COLOR = '\u001b[31m'; |
| 168 String _MAGENTA_COLOR = '\u001b[35m'; |
| 169 String _NO_COLOR = '\u001b[0m'; |
OLD | NEW |