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 [iterator] on [buffer]. The characters | 27 /// Writes the characters of [string] 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]. | 30 /// [StringBuffer]. Note that JS supports \xnn and \unnnn whereas JSON only |
31 void writeJsonEscapedCharsOn(Iterator<int> iterator, buffer, onError(code)) { | 31 /// supports the \unnnn notation. Therefore we use the \unnnn notation. |
32 while (iterator.hasNext) { | 32 |
floitsch
2012/11/21 16:16:50
remove new line.
| |
33 int code = iterator.next(); | 33 void writeJsonEscapedCharsOn(String string, buffer) { |
floitsch
2012/11/21 16:16:50
var buffer
erikcorry
2012/11/22 12:42:15
Done.
| |
34 if (identical(code, $SQ)) { | 34 void addCodeUnitEscaped(buffer, int code) { |
35 buffer.add(r"\'"); | 35 assert(code < 0x10000); |
36 } else if (identical(code, $LF)) { | 36 buffer.add(r'\u'); |
37 buffer.add(r'\n'); | 37 if (code < 0x1000) { |
38 } else if (identical(code, $CR)) { | 38 buffer.add('0'); |
39 buffer.add(r'\r'); | 39 if (code < 0x100) { |
40 } else if (identical(code, $LS)) { | 40 buffer.add('0'); |
41 // This Unicode line terminator and $PS are invalid in JS string | 41 if (code < 0x10) { |
42 // literals. | 42 buffer.add('0'); |
43 buffer.add(r'\u2028'); | 43 } |
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 } | 44 } |
53 // TODO(lrn): Consider whether all codes above 0x7f really need to | 45 } |
54 // be escaped. We build a Dart string here, so it should be a literal | 46 buffer.add(code.toRadixString(16)); |
55 // stage that converts it to, e.g., UTF-8 for a JS interpreter. | 47 } |
56 if (code < 0x20) { | 48 |
57 buffer.add(r'\x'); | 49 void writeEscaped(String string, buffer) { |
floitsch
2012/11/21 16:16:50
writeEscapedOn (or change name above)
erikcorry
2012/11/22 12:42:15
Done.
| |
58 if (code < 0x10) buffer.add('0'); | 50 for (int i = 0; i < string.length; i++) { |
59 buffer.add(code.toRadixString(16)); | 51 int code = string.charCodeAt(i); |
60 } else if (code >= 0x80) { | 52 if (identical(code, $DQ)) { |
floitsch
2012/11/21 16:16:50
nyc: remove identicals.
numbers should never be co
erikcorry
2012/11/22 12:42:15
Done.
| |
61 if (code < 0x100) { | 53 buffer.add(r'\"'); |
62 buffer.add(r'\x'); | 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 { | |
71 if (code < 0x20) { | |
72 addCodeUnitEscaped(buffer, code); | |
73 // We emit DEL (ASCII 0x7f) as an escape because it would be confusing | |
74 // to have it unescaped in a string literal. We also escape | |
75 // everything above 0x7f because that means we don't have to worry | |
76 // about whether the web server serves it up as Latin1 or UTF-8. | |
77 } else if (code < 0x7f) { | |
78 buffer.addCharCode(code); | |
63 } else { | 79 } else { |
64 buffer.add(r'\u'); | 80 // This will output surrogate pairs in the form \udxxx\udyyy, rather |
65 if (code < 0x1000) { | 81 // than the more logical \u{zzzzzz}. This should work in JavaScript |
66 buffer.add('0'); | 82 // (especially old UCS-2 based implementations) and is the only |
67 } | 83 // format that is allowed in JSON. |
84 addCodeUnitEscaped(buffer, code); | |
68 } | 85 } |
69 buffer.add(code.toRadixString(16)); | |
70 } else { | |
71 buffer.addCharCode(code); | |
72 } | 86 } |
73 } | 87 } |
74 } | 88 } |
89 | |
90 for (int i = 0; i < string.length; i++) { | |
91 int code = string.charCodeAt(i); | |
92 if (code < 0x20 || code == $DEL || code == $DQ || code == $LS || | |
93 code == $PS || code == $BACKSLASH || code >= 0x80) { | |
94 writeEscaped(string, buffer); | |
95 return; | |
96 } | |
97 } | |
98 buffer.add(string); | |
75 } | 99 } |
OLD | NEW |