| 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.elapsedMilliseconds}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 |