Harmonize found string escaping with expectation escaping

Change how found strings are escaped when building syntax error
messages:

  * Do not escape non-ASCII characters (U+0100-U+FFFF). They are
    typically more readable in their raw form.

  * Escape DEL (U+007F). It is a control character.

  * Escape NUL (U+0000) as "\0", not "\x00".

  * Do not use less known shortcut escape sequences ("\b", "\f"), only the
    well-known ones ("\0", "\t", "\n", "\r").

These changes mirror expectation escaping changes done in
4fe682794d.

Part of work on #428.
redux
David Majda 8 years ago
parent 6b60896216
commit 75cedcb7d8

@ -1075,31 +1075,18 @@ function generateJS(ast, options) {
' }',
'',
' function buildMessage(expected, found) {',
' function stringEscape(s) {',
' function escape(s) {',
' function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); }',
'',
/*
* ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a
* string literal except for the closing quote character, backslash,
* carriage return, line separator, paragraph separator, and line feed.
* Any character may appear in the form of an escape sequence.
*
* For portability, we also escape all control and non-ASCII characters.
* Note that "\0" and "\v" escape sequences are not used because JSHint
* does not like the first and IE the second.
*/
' return s',
' .replace(/\\\\/g, \'\\\\\\\\\')', // backslash
' .replace(/"/g, \'\\\\"\')', // closing double quote
' .replace(/\\x08/g, \'\\\\b\')', // backspace
' .replace(/\\0/g, \'\\\\0\')', // null
' .replace(/\\t/g, \'\\\\t\')', // horizontal tab
' .replace(/\\n/g, \'\\\\n\')', // line feed
' .replace(/\\f/g, \'\\\\f\')', // form feed
' .replace(/\\r/g, \'\\\\r\')', // carriage return
' .replace(/[\\x00-\\x07\\x0B\\x0E\\x0F]/g, function(ch) { return \'\\\\x0\' + hex(ch); })',
' .replace(/[\\x10-\\x1F\\x80-\\xFF]/g, function(ch) { return \'\\\\x\' + hex(ch); })',
' .replace(/[\\u0100-\\u0FFF]/g, function(ch) { return \'\\\\u0\' + hex(ch); })',
' .replace(/[\\u1000-\\uFFFF]/g, function(ch) { return \'\\\\u\' + hex(ch); });',
' .replace(/[\\x01-\\x08\\x0B\\x0C\\x0E\\x0F]/g, function(ch) { return \'\\\\x0\' + hex(ch); })',
' .replace(/[\\x10-\\x1F\\x7F-\\x9F]/g, function(ch) { return \'\\\\x\' + hex(ch); });',
' }',
'',
' var expectedDescs = new Array(expected.length),',
@ -1115,7 +1102,7 @@ function generateJS(ast, options) {
' + expectedDescs[expected.length - 1]',
' : expectedDescs[0];',
'',
' foundDesc = found ? "\\"" + stringEscape(found) + "\\"" : "end of input";',
' foundDesc = found ? "\\"" + escape(found) + "\\"" : "end of input";',
'',
' return "Expected " + expectedDesc + " but " + foundDesc + " found.";',
' }',

@ -532,21 +532,18 @@
}
function buildMessage(expected, found) {
function stringEscape(s) {
function escape(s) {
function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); }
return s
.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"')
.replace(/\x08/g, '\\b')
.replace(/\0/g, '\\0')
.replace(/\t/g, '\\t')
.replace(/\n/g, '\\n')
.replace(/\f/g, '\\f')
.replace(/\r/g, '\\r')
.replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
.replace(/[\x10-\x1F\x80-\xFF]/g, function(ch) { return '\\x' + hex(ch); })
.replace(/[\u0100-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); })
.replace(/[\u1000-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); });
.replace(/[\x01-\x08\x0B\x0C\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
.replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); });
}
var expectedDescs = new Array(expected.length),
@ -562,7 +559,7 @@
+ expectedDescs[expected.length - 1]
: expectedDescs[0];
foundDesc = found ? "\"" + stringEscape(found) + "\"" : "end of input";
foundDesc = found ? "\"" + escape(found) + "\"" : "end of input";
return "Expected " + expectedDesc + " but " + foundDesc + " found.";
}

Loading…
Cancel
Save