Index: sdk/lib/_internal/compiler/implementation/util/util.dart |
diff --git a/sdk/lib/_internal/compiler/implementation/util/util.dart b/sdk/lib/_internal/compiler/implementation/util/util.dart |
index 44fc305ef997ea0ce5304b27f1454f77785fd7ce..64194ea4d4c79f0db3550227497397912ccf5ab8 100644 |
--- a/sdk/lib/_internal/compiler/implementation/util/util.dart |
+++ b/sdk/lib/_internal/compiler/implementation/util/util.dart |
@@ -24,66 +24,52 @@ class SpannableAssertionFailure { |
String toString() => 'Compiler crashed: $message.'; |
} |
-/// Writes the characters of [string] on [buffer]. The characters |
+/// Writes the characters of [iterator] on [buffer]. The characters |
/// are escaped as suitable for JavaScript and JSON. [buffer] is |
/// anything which supports [:add:] and [:addCharCode:], for example, |
-/// [StringBuffer]. Note that JS supports \xnn and \unnnn whereas JSON only |
-/// supports the \unnnn notation. Therefore we use the \unnnn notation. |
- |
-void writeJsonEscapedCharsOn(String string, buffer) { |
- void addCodeUnitEscaped(CodeBuffer buffer, int code) { |
- assert(code < 0x10000); |
- buffer.add(r'\u'); |
- if (code < 0x1000) { |
- buffer.add('0'); |
- if (code < 0x100) { |
- buffer.add('0'); |
- if (code < 0x10) { |
- buffer.add('0'); |
- } |
+/// [StringBuffer]. |
+void writeJsonEscapedCharsOn(Iterator<int> iterator, buffer, onError(code)) { |
+ while (iterator.hasNext) { |
+ int code = iterator.next(); |
+ if (identical(code, $SQ)) { |
+ buffer.add(r"\'"); |
+ } else if (identical(code, $LF)) { |
+ buffer.add(r'\n'); |
+ } else if (identical(code, $CR)) { |
+ buffer.add(r'\r'); |
+ } else if (identical(code, $LS)) { |
+ // This Unicode line terminator and $PS are invalid in JS string |
+ // literals. |
+ buffer.add(r'\u2028'); |
+ } else if (identical(code, $PS)) { |
+ buffer.add(r'\u2029'); |
+ } else if (identical(code, $BACKSLASH)) { |
+ buffer.add(r'\\'); |
+ } else { |
+ if (code > 0xffff) { |
+ if (onError != null) onError(code); |
+ throw 'Unhandled non-BMP character: ${code.toRadixString(16)}'; |
} |
- } |
- buffer.add(code.toRadixString(16)); |
- } |
- |
- void writeEscaped(String string, buffer) { |
- for (int i = 0; i < string.length; i++) { |
- int code = string.codeUnitAt(i); |
- if (identical(code, $DQ)) { |
- buffer.add(r'\"'); |
- } else if (identical(code, $TAB)) { |
- buffer.add(r'\t'); |
- } else if (identical(code, $LF)) { |
- buffer.add(r'\n'); |
- } else if (identical(code, $CR)) { |
- buffer.add(r'\r'); |
- } else if (identical(code, $DEL)) { |
- addCodeUnitEscaped(buffer, $DEL); |
- } else if (identical(code, $LS)) { |
- // This Unicode line terminator and $PS are invalid in JS string |
- // literals. |
- addCodeUnitEscaped(buffer, $LS); // 0x2028. |
- } else if (identical(code, $PS)) { |
- addCodeUnitEscaped(buffer, $PS); // 0x2029. |
- } else if (identical(code, $BACKSLASH)) { |
- buffer.add(r'\\'); |
- } else { |
- if (code < 0x20) { |
- addCodeUnitEscaped(buffer, code); |
+ // TODO(lrn): Consider whether all codes above 0x7f really need to |
+ // be escaped. We build a Dart string here, so it should be a literal |
+ // stage that converts it to, e.g., UTF-8 for a JS interpreter. |
+ if (code < 0x20) { |
+ buffer.add(r'\x'); |
+ if (code < 0x10) buffer.add('0'); |
+ buffer.add(code.toRadixString(16)); |
+ } else if (code >= 0x80) { |
+ if (code < 0x100) { |
+ buffer.add(r'\x'); |
} else { |
- buffer.addCharCode(code); |
+ buffer.add(r'\u'); |
+ if (code < 0x1000) { |
+ buffer.add('0'); |
+ } |
} |
+ buffer.add(code.toRadixString(16)); |
+ } else { |
+ buffer.addCharCode(code); |
} |
} |
} |
- |
- for (int i = 0; i < string.length; i++) { |
- int code = string.codeUnitAt(i); |
- if (code < 0x20 || code == $DEL || code == $DQ || code == $LS || |
- code == $PS || code == $BACKSLASH) { |
- writeEscaped(string, buffer); |
- return; |
- } |
- } |
- buffer.add(string); |
} |