1317375 - Implement "Template Literals Revision / Lifting Template Literal Restriction" ECMAScript proposal

This commit is contained in:
Gaming4JC 2019-06-08 16:51:29 -04:00 committed by Roy Tam
commit ee1e2aba19
14 changed files with 386 additions and 69 deletions

View file

@ -1917,55 +1917,6 @@ TokenStream::getTokenInternal(TokenKind* ttp, Modifier modifier)
return false;
}
bool
TokenStream::matchBracedUnicode(bool* matched, uint32_t* cp)
{
int32_t c;
if (!peekChar(&c))
return false;
if (c != '{') {
*matched = false;
return true;
}
consumeKnownChar('{');
uint32_t start = userbuf.offset();
bool first = true;
uint32_t code = 0;
do {
int32_t c = getCharIgnoreEOL();
if (c == EOF) {
error(JSMSG_MALFORMED_ESCAPE, "Unicode");
return false;
}
if (c == '}') {
if (first) {
error(JSMSG_MALFORMED_ESCAPE, "Unicode");
return false;
}
break;
}
if (!JS7_ISHEX(c)) {
error(JSMSG_MALFORMED_ESCAPE, "Unicode");
return false;
}
code = (code << 4) | JS7_UNHEX(c);
if (code > unicode::NonBMPMax) {
errorAt(start, JSMSG_UNICODE_OVERFLOW, "escape sequence");
return false;
}
first = false;
} while (true);
*matched = true;
*cp = code;
return true;
}
bool
TokenStream::getStringOrTemplateToken(int untilChar, Token** tp)
{
@ -1988,6 +1939,10 @@ TokenStream::getStringOrTemplateToken(int untilChar, Token** tp)
}
if (c == '\\') {
// When parsing templates, we don't immediately report errors for
// invalid escapes; these are handled by the parser.
// In those cases we don't append to tokenbuf, since it won't be
// read.
switch (c = getChar()) {
case 'b': c = '\b'; break;
case 'f': c = '\f'; break;
@ -2003,11 +1958,73 @@ TokenStream::getStringOrTemplateToken(int untilChar, Token** tp)
// Unicode character specification.
case 'u': {
bool matched;
uint32_t code;
if (!matchBracedUnicode(&matched, &code))
uint32_t code = 0;
int32_t c2;
if (!peekChar(&c2))
return false;
if (matched) {
uint32_t start = userbuf.offset() - 2;
if (c2 == '{') {
consumeKnownChar('{');
bool first = true;
bool valid = true;
do {
int32_t c = getCharIgnoreEOL();
if (c == EOF) {
if (parsingTemplate) {
setInvalidTemplateEscape(start, InvalidEscapeType::Unicode);
valid = false;
break;
}
reportInvalidEscapeError(start, InvalidEscapeType::Unicode);
return false;
}
if (c == '}') {
if (first) {
if (parsingTemplate) {
setInvalidTemplateEscape(start, InvalidEscapeType::Unicode);
valid = false;
break;
}
reportInvalidEscapeError(start, InvalidEscapeType::Unicode);
return false;
}
break;
}
if (!JS7_ISHEX(c)) {
if (parsingTemplate) {
// We put the character back so that we read
// it on the next pass, which matters if it
// was '`' or '\'.
ungetCharIgnoreEOL(c);
setInvalidTemplateEscape(start, InvalidEscapeType::Unicode);
valid = false;
break;
}
reportInvalidEscapeError(start, InvalidEscapeType::Unicode);
return false;
}
code = (code << 4) | JS7_UNHEX(c);
if (code > unicode::NonBMPMax) {
if (parsingTemplate) {
setInvalidTemplateEscape(start + 3, InvalidEscapeType::UnicodeOverflow);
valid = false;
break;
}
reportInvalidEscapeError(start + 3, InvalidEscapeType::UnicodeOverflow);
return false;
}
first = false;
} while (true);
if (!valid)
continue;
MOZ_ASSERT(code <= unicode::NonBMPMax);
if (code < unicode::NonBMPMin) {
@ -2030,7 +2047,11 @@ TokenStream::getStringOrTemplateToken(int untilChar, Token** tp)
c = (c << 4) + JS7_UNHEX(cp[3]);
skipChars(4);
} else {
error(JSMSG_MALFORMED_ESCAPE, "Unicode");
if (parsingTemplate) {
setInvalidTemplateEscape(start, InvalidEscapeType::Unicode);
continue;
}
reportInvalidEscapeError(start, InvalidEscapeType::Unicode);
return false;
}
break;
@ -2043,7 +2064,12 @@ TokenStream::getStringOrTemplateToken(int untilChar, Token** tp)
c = (JS7_UNHEX(cp[0]) << 4) + JS7_UNHEX(cp[1]);
skipChars(2);
} else {
error(JSMSG_MALFORMED_ESCAPE, "hexadecimal");
uint32_t start = userbuf.offset() - 2;
if (parsingTemplate) {
setInvalidTemplateEscape(start, InvalidEscapeType::Hexadecimal);
continue;
}
reportInvalidEscapeError(start, InvalidEscapeType::Hexadecimal);
return false;
}
break;
@ -2060,8 +2086,8 @@ TokenStream::getStringOrTemplateToken(int untilChar, Token** tp)
// Strict mode code allows only \0, then a non-digit.
if (val != 0 || JS7_ISDEC(c)) {
if (parsingTemplate) {
error(JSMSG_DEPRECATED_OCTAL);
return false;
setInvalidTemplateEscape(userbuf.offset() - 2, InvalidEscapeType::Octal);
continue;
}
if (!reportStrictModeError(JSMSG_DEPRECATED_OCTAL))
return false;