420857 - Part 2: Report the position of opening brace for missing brace error in block.

This commit is contained in:
Gaming4JC 2019-07-14 10:22:32 -04:00 committed by Roy Tam
commit fce1adbcd7
2 changed files with 75 additions and 15 deletions

View file

@ -66,29 +66,32 @@ using UsedNamePtr = UsedNameTracker::UsedNameMap::Ptr;
// Read a token. Report an error and return null() if that token doesn't match
// to the condition. Do not use MUST_MATCH_TOKEN_INTERNAL directly.
#define MUST_MATCH_TOKEN_INTERNAL(cond, modifier, errorNumber) \
#define MUST_MATCH_TOKEN_INTERNAL(cond, modifier, errorReport) \
JS_BEGIN_MACRO \
TokenKind token; \
if (!tokenStream.getToken(&token, modifier)) \
return null(); \
if (!(cond)) { \
error(errorNumber); \
errorReport; \
return null(); \
} \
JS_END_MACRO
#define MUST_MATCH_TOKEN_MOD(tt, modifier, errorNumber) \
MUST_MATCH_TOKEN_INTERNAL(token == tt, modifier, errorNumber)
MUST_MATCH_TOKEN_INTERNAL(token == tt, modifier, error(errorNumber))
#define MUST_MATCH_TOKEN(tt, errorNumber) \
MUST_MATCH_TOKEN_MOD(tt, TokenStream::None, errorNumber)
#define MUST_MATCH_TOKEN_FUNC_MOD(func, modifier, errorNumber) \
MUST_MATCH_TOKEN_INTERNAL((func)(token), modifier, errorNumber)
MUST_MATCH_TOKEN_INTERNAL((func)(token), modifier, error(errorNumber))
#define MUST_MATCH_TOKEN_FUNC(func, errorNumber) \
MUST_MATCH_TOKEN_FUNC_MOD(func, TokenStream::None, errorNumber)
#define MUST_MATCH_TOKEN_MOD_WITH_REPORT(tt, modifier, errorReport) \
MUST_MATCH_TOKEN_INTERNAL(token == tt, modifier, errorReport)
template <class T, class U>
static inline void
PropagateTransitiveParseFlags(const T* inner, U* outer)
@ -3703,13 +3706,9 @@ Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling,
}
if (bodyType == StatementListBody) {
bool matched;
if (!tokenStream.matchToken(&matched, TOK_RC, TokenStream::Operand))
return false;
if (!matched) {
reportMissingClosing(JSMSG_CURLY_AFTER_BODY, JSMSG_CURLY_OPENED, openedPos);
return false;
}
MUST_MATCH_TOKEN_MOD_WITH_REPORT(TOK_RC, TokenStream::Operand,
reportMissingClosing(JSMSG_CURLY_AFTER_BODY,
JSMSG_CURLY_OPENED, openedPos));
funbox->setEnd(pos().end);
} else {
#if !JS_HAS_EXPR_CLOSURES
@ -4481,6 +4480,7 @@ typename ParseHandler::Node
Parser<ParseHandler>::blockStatement(YieldHandling yieldHandling, unsigned errorNumber)
{
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_LC));
uint32_t openedPos = pos().begin;
ParseContext::Statement stmt(pc, StatementKind::Block);
ParseContext::Scope scope(this);
@ -4491,7 +4491,9 @@ Parser<ParseHandler>::blockStatement(YieldHandling yieldHandling, unsigned error
if (!list)
return null();
MUST_MATCH_TOKEN_MOD(TOK_RC, TokenStream::Operand, errorNumber);
MUST_MATCH_TOKEN_MOD_WITH_REPORT(TOK_RC, TokenStream::Operand,
reportMissingClosing(errorNumber, JSMSG_CURLY_OPENED,
openedPos));
return finishLexicalScope(scope, list);
}
@ -6743,6 +6745,8 @@ Parser<ParseHandler>::tryStatement(YieldHandling yieldHandling)
{
MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_TRY);
uint32_t openedPos = pos().begin;
ParseContext::Statement stmt(pc, StatementKind::Try);
ParseContext::Scope scope(this);
if (!scope.init(pc))
@ -6756,7 +6760,9 @@ Parser<ParseHandler>::tryStatement(YieldHandling yieldHandling)
if (!innerBlock)
return null();
MUST_MATCH_TOKEN_MOD(TOK_RC, TokenStream::Operand, JSMSG_CURLY_AFTER_TRY);
MUST_MATCH_TOKEN_MOD_WITH_REPORT(TOK_RC, TokenStream::Operand,
reportMissingClosing(JSMSG_CURLY_AFTER_TRY,
JSMSG_CURLY_OPENED, openedPos));
}
bool hasUnconditionalCatch = false;
@ -6872,6 +6878,8 @@ Parser<ParseHandler>::tryStatement(YieldHandling yieldHandling)
if (tt == TOK_FINALLY) {
MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_FINALLY);
uint32_t openedPos = pos().begin;
ParseContext::Statement stmt(pc, StatementKind::Finally);
ParseContext::Scope scope(this);
if (!scope.init(pc))
@ -6885,7 +6893,9 @@ Parser<ParseHandler>::tryStatement(YieldHandling yieldHandling)
if (!finallyBlock)
return null();
MUST_MATCH_TOKEN_MOD(TOK_RC, TokenStream::Operand, JSMSG_CURLY_AFTER_FINALLY);
MUST_MATCH_TOKEN_MOD_WITH_REPORT(TOK_RC, TokenStream::Operand,
reportMissingClosing(JSMSG_CURLY_AFTER_FINALLY,
JSMSG_CURLY_OPENED, openedPos));
} else {
tokenStream.ungetToken();
}
@ -6902,6 +6912,8 @@ typename ParseHandler::Node
Parser<ParseHandler>::catchBlockStatement(YieldHandling yieldHandling,
ParseContext::Scope& catchParamScope)
{
uint32_t openedPos = pos().begin;
ParseContext::Statement stmt(pc, StatementKind::Block);
// ES 13.15.7 CatchClauseEvaluation
@ -6921,7 +6933,9 @@ Parser<ParseHandler>::catchBlockStatement(YieldHandling yieldHandling,
if (!list)
return null();
MUST_MATCH_TOKEN_MOD(TOK_RC, TokenStream::Operand, JSMSG_CURLY_AFTER_CATCH);
MUST_MATCH_TOKEN_MOD_WITH_REPORT(TOK_RC, TokenStream::Operand,
reportMissingClosing(JSMSG_CURLY_AFTER_CATCH,
JSMSG_CURLY_OPENED, openedPos));
// The catch parameter names are not bound in the body scope, so remove
// them before generating bindings.

View file

@ -28,3 +28,49 @@ function test2() {
function test3() {
}
`, [4, 17]);
// Block statement.
test(`
{
if (true) {
}
`, [2, 0]);
test(`
if (true) {
if (true) {
}
`, [2, 10]);
test(`
for (;;) {
if (true) {
}
`, [2, 9]);
test(`
while (true) {
if (true) {
}
`, [2, 13]);
test(`
do {
do {
} while(true);
`, [2, 3]);
// try-catch-finally.
test(`
try {
if (true) {
}
`, [2, 4]);
test(`
try {
} catch (e) {
if (true) {
}
`, [3, 12]);
test(`
try {
} finally {
if (true) {
}
`, [3, 10]);