Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library dart2js.util; | 5 part of dart2js.helpers; |
| 6 | |
| 7 import "dart:collection"; | |
| 8 import 'util_implementation.dart'; | |
| 9 import 'characters.dart'; | |
| 10 | |
| 11 export 'setlet.dart'; | |
| 12 | |
| 13 part 'link.dart'; | |
| 14 part 'expensive_map.dart'; | |
| 15 part 'expensive_set.dart'; | |
| 16 | |
| 17 /** | |
| 18 * Tagging interface for classes from which source spans can be generated. | |
| 19 */ | |
| 20 // TODO(johnniwinther): Find a better name. | |
| 21 // TODO(ahe): How about "Bolt"? | |
| 22 abstract class Spannable {} | |
| 23 | |
| 24 class _SpannableSentinel implements Spannable { | |
| 25 final String name; | |
| 26 | |
| 27 const _SpannableSentinel(this.name); | |
| 28 | |
| 29 String toString() => name; | |
| 30 } | |
| 31 | |
| 32 /// Sentinel spannable used to mark that diagnostics should point to the | |
| 33 /// current element. Note that the diagnostic reporting will fail if the current | |
| 34 /// element is `null`. | |
| 35 const Spannable CURRENT_ELEMENT_SPANNABLE = | |
| 36 const _SpannableSentinel("Current element"); | |
| 37 | |
| 38 /// Sentinel spannable used to mark that there might be no location for the | |
| 39 /// diagnostic. Use this only when it is not an error not to have a current | |
| 40 /// element. | |
| 41 const Spannable NO_LOCATION_SPANNABLE = | |
| 42 const _SpannableSentinel("No location"); | |
| 43 | |
| 44 class SpannableAssertionFailure { | |
| 45 final Spannable node; | |
| 46 final String message; | |
| 47 SpannableAssertionFailure(this.node, this.message); | |
| 48 | |
| 49 String toString() => 'Assertion failure' | |
| 50 '${message != null ? ': $message' : ''}'; | |
| 51 } | |
| 52 | 6 |
| 53 /** | 7 /** |
| 54 * Helper method for printing stack traces for debugging. | 8 * Helper method for printing stack traces for debugging. |
| 55 * | 9 * |
| 56 * [message] is printed as the header of the stack trace. | 10 * [message] is printed as the header of the stack trace. |
| 57 * | 11 * |
| 58 * If [condition] is provided, the stack trace is only printed if [condition] | 12 * If [condition] is provided, the stack trace is only printed if [condition] |
| 59 * returns [:true:] on the stack trace text. This can be used to filter the | 13 * returns [:true:] on the stack trace text. This can be used to filter the |
| 60 * printed stack traces based on their content. For instance only print stack | 14 * printed stack traces based on their content. For instance only print stack |
| 61 * traces that contain specific paths. | 15 * traces that contain specific paths. |
| 62 */ | 16 */ |
| 63 void trace(String message, [bool condition(String stackTrace)]) { | 17 void trace(String message, [bool condition(String stackTrace)]) { |
| 64 try { | 18 try { |
| 65 throw ''; | 19 throw ''; |
| 66 } catch (e, s) { | 20 } catch (e, s) { |
| 67 String stackTrace = prettifyStackTrace( | 21 String stackTrace = prettifyStackTrace( |
| 68 s, rangeStart: 1, filePrefix: stackTraceFilePrefix); | 22 s, rangeStart: 1, filePrefix: stackTraceFilePrefix); |
| 69 if (condition != null) { | 23 if (condition != null) { |
| 70 if (!condition(stackTrace)) return; | 24 if (!condition(stackTrace)) return; |
| 71 } | 25 } |
| 72 print('$message\n$stackTrace'); | 26 print('$message\n$stackTrace'); |
| 73 } | 27 } |
| 74 } | 28 } |
| 75 | 29 |
| 76 /** | 30 void traceAndReport(Compiler compiler, Spannable node, |
| 77 * File name prefix used to shorten the file name in stack traces printed by | 31 String message, [bool condition(String stackTrace)]) { |
| 78 * [trace]. | 32 |
| 79 */ | 33 trace(message, (String stackTrace) { |
| 80 String stackTraceFilePrefix = null; | 34 bool result = condition != null ? condition(stackTrace) : true; |
| 35 if (result) { | |
| 36 reportHere(compiler, node, message); | |
| 37 } | |
| 38 return result; | |
| 39 }); | |
| 40 } | |
| 81 | 41 |
| 82 /// Helper class for the processing of stack traces in [prettifyStackTrace]. | 42 /// Helper class for the processing of stack traces in [prettifyStackTrace]. |
| 83 class _StackTraceLine { | 43 class _StackTraceLine { |
| 84 final int index; | 44 final int index; |
| 85 final String file; | 45 final String file; |
| 86 final String lineNo; | 46 final String lineNo; |
| 87 final String columnNo; | 47 final String columnNo; |
| 88 final String method; | 48 final String method; |
| 89 | 49 |
| 90 _StackTraceLine(this.index, this.file, this.lineNo, | 50 _StackTraceLine(this.index, this.file, this.lineNo, |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 218 } | 178 } |
| 219 for (int index = text.length ; index < intendedLength ; index ++) { | 179 for (int index = text.length ; index < intendedLength ; index ++) { |
| 220 int dotsIndex = index % dotsLength; | 180 int dotsIndex = index % dotsLength; |
| 221 sb.write(dots.substring(dotsIndex, dotsIndex + 1)); | 181 sb.write(dots.substring(dotsIndex, dotsIndex + 1)); |
| 222 } | 182 } |
| 223 if (padLeft) { | 183 if (padLeft) { |
| 224 sb.write(text); | 184 sb.write(text); |
| 225 } | 185 } |
| 226 return sb.toString(); | 186 return sb.toString(); |
| 227 } | 187 } |
| 228 | |
| 229 /// Writes the characters of [string] on [buffer]. The characters | |
|
karlklose
2014/03/25 14:22:18
This was unused?
Johnni Winther
2014/03/26 07:35:05
No. Git/svn saw this file as a copy of util.dart f
| |
| 230 /// are escaped as suitable for JavaScript and JSON. [buffer] is | |
| 231 /// anything which supports [:write:] and [:writeCharCode:], for example, | |
| 232 /// [StringBuffer]. Note that JS supports \xnn and \unnnn whereas JSON only | |
| 233 /// supports the \unnnn notation. Therefore we use the \unnnn notation. | |
| 234 void writeJsonEscapedCharsOn(String string, buffer) { | |
| 235 void addCodeUnitEscaped(var buffer, int code) { | |
| 236 assert(code < 0x10000); | |
| 237 buffer.write(r'\u'); | |
| 238 if (code < 0x1000) { | |
| 239 buffer.write('0'); | |
| 240 if (code < 0x100) { | |
| 241 buffer.write('0'); | |
| 242 if (code < 0x10) { | |
| 243 buffer.write('0'); | |
| 244 } | |
| 245 } | |
| 246 } | |
| 247 buffer.write(code.toRadixString(16)); | |
| 248 } | |
| 249 | |
| 250 void writeEscapedOn(String string, var buffer) { | |
| 251 for (int i = 0; i < string.length; i++) { | |
| 252 int code = string.codeUnitAt(i); | |
| 253 if (code == $DQ) { | |
| 254 buffer.write(r'\"'); | |
| 255 } else if (code == $TAB) { | |
| 256 buffer.write(r'\t'); | |
| 257 } else if (code == $LF) { | |
| 258 buffer.write(r'\n'); | |
| 259 } else if (code == $CR) { | |
| 260 buffer.write(r'\r'); | |
| 261 } else if (code == $DEL) { | |
| 262 addCodeUnitEscaped(buffer, $DEL); | |
| 263 } else if (code == $LS) { | |
| 264 // This Unicode line terminator and $PS are invalid in JS string | |
| 265 // literals. | |
| 266 addCodeUnitEscaped(buffer, $LS); // 0x2028. | |
| 267 } else if (code == $PS) { | |
| 268 addCodeUnitEscaped(buffer, $PS); // 0x2029. | |
| 269 } else if (code == $BACKSLASH) { | |
| 270 buffer.write(r'\\'); | |
| 271 } else { | |
| 272 if (code < 0x20) { | |
| 273 addCodeUnitEscaped(buffer, code); | |
| 274 // We emit DEL (ASCII 0x7f) as an escape because it would be confusing | |
| 275 // to have it unescaped in a string literal. We also escape | |
| 276 // everything above 0x7f because that means we don't have to worry | |
| 277 // about whether the web server serves it up as Latin1 or UTF-8. | |
| 278 } else if (code < 0x7f) { | |
| 279 buffer.writeCharCode(code); | |
| 280 } else { | |
| 281 // This will output surrogate pairs in the form \udxxx\udyyy, rather | |
| 282 // than the more logical \u{zzzzzz}. This should work in JavaScript | |
| 283 // (especially old UCS-2 based implementations) and is the only | |
| 284 // format that is allowed in JSON. | |
| 285 addCodeUnitEscaped(buffer, code); | |
| 286 } | |
| 287 } | |
| 288 } | |
| 289 } | |
| 290 | |
| 291 for (int i = 0; i < string.length; i++) { | |
| 292 int code = string.codeUnitAt(i); | |
| 293 if (code < 0x20 || code == $DEL || code == $DQ || code == $LS || | |
| 294 code == $PS || code == $BACKSLASH || code >= 0x80) { | |
| 295 writeEscapedOn(string, buffer); | |
| 296 return; | |
| 297 } | |
| 298 } | |
| 299 buffer.write(string); | |
| 300 } | |
| 301 | |
| 302 int computeHashCode(part1, [part2, part3, part4, part5]) { | |
| 303 return (part1.hashCode | |
| 304 ^ part2.hashCode | |
| 305 ^ part3.hashCode | |
| 306 ^ part4.hashCode | |
| 307 ^ part5.hashCode) & 0x3fffffff; | |
| 308 } | |
| OLD | NEW |