| OLD | NEW | 
|---|
| 1 // Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 org_dartlang_compiler_util; | 5 library org_dartlang_compiler_util; | 
| 6 | 6 | 
| 7 import 'util_implementation.dart'; | 7 import 'util_implementation.dart'; | 
| 8 import 'characters.dart'; | 8 import 'characters.dart'; | 
| 9 | 9 | 
| 10 part 'link.dart'; | 10 part 'link.dart'; | 
| 11 | 11 | 
| 12 /** | 12 /** | 
| 13  * Tagging interface for classes from which source spans can be generated. | 13  * Tagging interface for classes from which source spans can be generated. | 
| 14  */ | 14  */ | 
| 15 // TODO(johnniwinther): Find a better name. | 15 // TODO(johnniwinther): Find a better name. | 
| 16 // TODO(ahe): How about "Bolt"? | 16 // TODO(ahe): How about "Bolt"? | 
| 17 abstract class Spannable {} | 17 abstract class Spannable {} | 
| 18 | 18 | 
| 19 class SpannableAssertionFailure { | 19 class SpannableAssertionFailure { | 
| 20   final Spannable node; | 20   final Spannable node; | 
| 21   final String message; | 21   final String message; | 
| 22   SpannableAssertionFailure(this.node, this.message); | 22   SpannableAssertionFailure(this.node, this.message); | 
| 23 | 23 | 
| 24   String toString() => 'Compiler crashed: $message.'; | 24   String toString() => 'Compiler crashed: $message.'; | 
| 25 } | 25 } | 
| 26 | 26 | 
| 27 /// Writes the characters of [string] on [buffer].  The characters | 27 /// Writes the characters of [iterator] on [buffer].  The characters | 
| 28 /// are escaped as suitable for JavaScript and JSON.  [buffer] is | 28 /// are escaped as suitable for JavaScript and JSON.  [buffer] is | 
| 29 /// anything which supports [:add:] and [:addCharCode:], for example, | 29 /// anything which supports [:add:] and [:addCharCode:], for example, | 
| 30 /// [StringBuffer].  Note that JS supports \xnn and \unnnn whereas JSON only | 30 /// [StringBuffer]. | 
| 31 /// supports the \unnnn notation.  Therefore we use the \unnnn notation. | 31 void writeJsonEscapedCharsOn(Iterator<int> iterator, buffer, onError(code)) { | 
| 32 | 32   while (iterator.hasNext) { | 
| 33 void writeJsonEscapedCharsOn(String string, buffer) { | 33     int code = iterator.next(); | 
| 34   void addCodeUnitEscaped(CodeBuffer buffer, int code) { | 34     if (identical(code, $SQ)) { | 
| 35     assert(code < 0x10000); | 35       buffer.add(r"\'"); | 
| 36     buffer.add(r'\u'); | 36     } else if (identical(code, $LF)) { | 
| 37     if (code < 0x1000) { | 37       buffer.add(r'\n'); | 
| 38       buffer.add('0'); | 38     } else if (identical(code, $CR)) { | 
| 39       if (code < 0x100) { | 39       buffer.add(r'\r'); | 
| 40         buffer.add('0'); | 40     } else if (identical(code, $LS)) { | 
| 41         if (code < 0x10) { | 41       // This Unicode line terminator and $PS are invalid in JS string | 
| 42           buffer.add('0'); | 42       // literals. | 
|  | 43       buffer.add(r'\u2028'); | 
|  | 44     } else if (identical(code, $PS)) { | 
|  | 45       buffer.add(r'\u2029'); | 
|  | 46     } else if (identical(code, $BACKSLASH)) { | 
|  | 47       buffer.add(r'\\'); | 
|  | 48     } else { | 
|  | 49       if (code > 0xffff) { | 
|  | 50         if (onError != null) onError(code); | 
|  | 51         throw 'Unhandled non-BMP character: ${code.toRadixString(16)}'; | 
|  | 52       } | 
|  | 53       // TODO(lrn): Consider whether all codes above 0x7f really need to | 
|  | 54       // be escaped. We build a Dart string here, so it should be a literal | 
|  | 55       // stage that converts it to, e.g., UTF-8 for a JS interpreter. | 
|  | 56       if (code < 0x20) { | 
|  | 57         buffer.add(r'\x'); | 
|  | 58         if (code < 0x10) buffer.add('0'); | 
|  | 59         buffer.add(code.toRadixString(16)); | 
|  | 60       } else if (code >= 0x80) { | 
|  | 61         if (code < 0x100) { | 
|  | 62           buffer.add(r'\x'); | 
|  | 63         } else { | 
|  | 64           buffer.add(r'\u'); | 
|  | 65           if (code < 0x1000) { | 
|  | 66             buffer.add('0'); | 
|  | 67           } | 
| 43         } | 68         } | 
| 44       } | 69         buffer.add(code.toRadixString(16)); | 
| 45     } |  | 
| 46     buffer.add(code.toRadixString(16)); |  | 
| 47   } |  | 
| 48 |  | 
| 49   void writeEscaped(String string, buffer) { |  | 
| 50     for (int i = 0; i < string.length; i++) { |  | 
| 51       int code = string.codeUnitAt(i); |  | 
| 52       if (identical(code, $DQ)) { |  | 
| 53         buffer.add(r'\"'); |  | 
| 54       } else if (identical(code, $TAB)) { |  | 
| 55         buffer.add(r'\t'); |  | 
| 56       } else if (identical(code, $LF)) { |  | 
| 57         buffer.add(r'\n'); |  | 
| 58       } else if (identical(code, $CR)) { |  | 
| 59         buffer.add(r'\r'); |  | 
| 60       } else if (identical(code, $DEL)) { |  | 
| 61         addCodeUnitEscaped(buffer, $DEL); |  | 
| 62       } else if (identical(code, $LS)) { |  | 
| 63         // This Unicode line terminator and $PS are invalid in JS string |  | 
| 64         // literals. |  | 
| 65         addCodeUnitEscaped(buffer, $LS);  // 0x2028. |  | 
| 66       } else if (identical(code, $PS)) { |  | 
| 67         addCodeUnitEscaped(buffer, $PS);  // 0x2029. |  | 
| 68       } else if (identical(code, $BACKSLASH)) { |  | 
| 69         buffer.add(r'\\'); |  | 
| 70       } else { | 70       } else { | 
| 71         if (code < 0x20) { | 71         buffer.addCharCode(code); | 
| 72           addCodeUnitEscaped(buffer, code); |  | 
| 73         } else { |  | 
| 74           buffer.addCharCode(code); |  | 
| 75         } |  | 
| 76       } | 72       } | 
| 77     } | 73     } | 
| 78   } | 74   } | 
| 79 |  | 
| 80   for (int i = 0; i < string.length; i++) { |  | 
| 81     int code = string.codeUnitAt(i); |  | 
| 82     if (code < 0x20 || code == $DEL || code == $DQ || code == $LS || |  | 
| 83         code == $PS || code == $BACKSLASH) { |  | 
| 84       writeEscaped(string, buffer); |  | 
| 85       return; |  | 
| 86     } |  | 
| 87   } |  | 
| 88   buffer.add(string); |  | 
| 89 } | 75 } | 
| OLD | NEW | 
|---|