mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-02 13:58:40 +09:00
1317375 - Implement "Template Literals Revision / Lifting Template Literal Restriction" ECMAScript proposal
This commit is contained in:
parent
8350dfc515
commit
ee1e2aba19
14 changed files with 386 additions and 69 deletions
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue