Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion lib/Parser/Parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8508,6 +8508,10 @@ ParseNodePtr Parser::ParseExpr(int oplMin,
}
}
}
else if (nop == knopAwait && m_token.tk == tkColon)
{
Error(ERRAwaitAsLabelInAsync);
}
else
{
// Disallow spread after a unary operator.
Expand Down Expand Up @@ -9631,6 +9635,7 @@ ParseNodePtr Parser::ParseStatement()
uint fnop;
bool expressionStmt = false;
bool isAsyncMethod = false;
bool labelledStatement = false;
tokens tok;
#if EXCEPTION_RECOVERY
ParseNodeTryCatch * pParentTryCatch = nullptr;
Expand Down Expand Up @@ -9683,6 +9688,10 @@ ParseNodePtr Parser::ParseStatement()
switch (tok)
{
case tkEOF:
if (labelledStatement)
{
Error(ERRLabelFollowedByEOF);
}
if (buildAST)
{
pnode = nullptr;
Expand All @@ -9704,6 +9713,25 @@ ParseNodePtr Parser::ParseStatement()
{
pnode = ParseFncDeclCheckScope<buildAST>(fFncDeclaration | (isAsyncMethod ? fFncAsync : fFncNoFlgs));
}

Assert(pnode != nullptr);
ParseNodeFnc* pNodeFnc = (ParseNodeFnc*)pnode;
if (labelledStatement)
{
if (IsStrictMode())
{
Error(ERRFunctionAfterLabelInStrict);
}
else if (pNodeFnc->IsAsync())
{
Error(ERRLabelBeforeAsyncFncDeclaration);
}
else if (pNodeFnc->IsGenerator())
{
Error(ERRLabelBeforeGeneratorDeclaration);
}
}

if (isAsyncMethod)
{
pnode->AsParseNodeFnc()->cbMin = iecpMin;
Expand All @@ -9713,7 +9741,11 @@ ParseNodePtr Parser::ParseStatement()
}

case tkCLASS:
if (m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
if (labelledStatement)
{
Error(ERRLabelBeforeClassDeclaration);
}
else if (m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
{
pnode = ParseClassDecl<buildAST>(TRUE, nullptr, nullptr, nullptr);
}
Expand All @@ -9726,6 +9758,10 @@ ParseNodePtr Parser::ParseStatement()
case tkID:
if (m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.let)
{
if (labelledStatement)
{
Error(ERRLabelBeforeLexicalDeclaration);
}
// We see "let" at the start of a statement. This could either be a declaration or an identifier
// reference. The next token determines which.
RestorePoint parsedLet;
Expand Down Expand Up @@ -9759,6 +9795,10 @@ ParseNodePtr Parser::ParseStatement()

case tkCONST:
case tkLET:
if (labelledStatement)
{
Error(ERRLabelBeforeLexicalDeclaration);
}
ichMin = this->GetScanner()->IchMinTok();

this->GetScanner()->Scan();
Expand Down Expand Up @@ -10628,6 +10668,7 @@ ParseNodePtr Parser::ParseStatement()
pLabelId->next = pLabelIdList;
pLabelIdList = pLabelId;
this->GetScanner()->Scan();
labelledStatement = true;
goto LRestart;
}

Expand Down
7 changes: 7 additions & 0 deletions lib/Parser/perrors.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,10 @@ LSC_ERROR_MSG(1087, ERRInvalidExportName, "Unable to resolve module export name"
LSC_ERROR_MSG(1088, ERRLetIDInLexicalDecl, "'let' is not an allowed identifier in lexical declarations")

LSC_ERROR_MSG(1089, ERRInvalidLHSInFor, "Invalid left-hand side in for loop")
LSC_ERROR_MSG(1090, ERRLabelBeforeLexicalDeclaration, "Labels not allowed before lexical declaration")
LSC_ERROR_MSG(1091, ERRLabelBeforeGeneratorDeclaration, "Labels not allowed before generator declaration")
LSC_ERROR_MSG(1092, ERRLabelBeforeAsyncFncDeclaration, "Labels not allowed before async function declaration")
LSC_ERROR_MSG(1093, ERRLabelBeforeClassDeclaration, "Labels not allowed before class declaration")
LSC_ERROR_MSG(1094, ERRLabelFollowedByEOF, "Unexpected end of script after a label.")
LSC_ERROR_MSG(1095, ERRFunctionAfterLabelInStrict, "Function declarations not allowed after a label in strict mode.")
LSC_ERROR_MSG(1096, ERRAwaitAsLabelInAsync, "Use of 'await' as label in async function is not allowed.")
Loading