@@ -6639,7 +6639,10 @@ void Parser::ParseFncName(ParseNodeFnc * pnodeFnc, ushort flags, IdentPtr* pFncN
66396639 {
66406640 if (pnodeFnc->IsGenerator())
66416641 {
6642- Error(ERRsyntax);
6642+ if (!m_scriptContext->GetConfig()->IsES2018AsyncIterationEnabled())
6643+ {
6644+ Error(ERRExperimental);
6645+ }
66436646 }
66446647 pnodeFnc->SetIsAsync();
66456648 }
@@ -10214,9 +10217,26 @@ ParseNodePtr Parser::ParseStatement()
1021410217 ParseNodeBlock * pnodeBlock = nullptr;
1021510218 ParseNodePtr *ppnodeScopeSave = nullptr;
1021610219 ParseNodePtr *ppnodeExprScopeSave = nullptr;
10220+ bool isForAwait = false;
1021710221
1021810222 ichMin = this->GetScanner()->IchMinTok();
10219- ChkNxtTok(tkLParen, ERRnoLparen);
10223+
10224+ this->GetScanner()->Scan();
10225+ if (m_token.tk == tkAWAIT || (m_token.tk == tkID && m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.await))
10226+ {
10227+ if (!this->GetScanner()->AwaitIsKeywordRegion())
10228+ {
10229+ Error(ERRBadAwait); // for await () in a non-async function
10230+ }
10231+ if (!m_scriptContext->GetConfig()->IsES2018AsyncIterationEnabled())
10232+ {
10233+ Error(ERRExperimental);
10234+ }
10235+ isForAwait = true;
10236+ this->GetScanner()->Scan();
10237+ }
10238+ ChkCurTok(tkLParen, ERRnoLparen);
10239+
1022010240 pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block);
1022110241 if (buildAST)
1022210242 {
@@ -10343,6 +10363,11 @@ ParseNodePtr Parser::ParseStatement()
1034310363 bool isForOf = (m_token.tk != tkIN);
1034410364 Assert(!isForOf || (m_token.tk == tkID && m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.of));
1034510365
10366+ if (isForAwait && !isForOf)
10367+ {
10368+ Error(ERRTokenAfter, _u("in"), _u("for await"));
10369+ }
10370+
1034610371 if ((buildAST && nullptr == pnodeT) || !fForInOrOfOkay)
1034710372 {
1034810373 if (isForOf)
@@ -10370,7 +10395,11 @@ ParseNodePtr Parser::ParseStatement()
1037010395 ParseNodeForInOrForOf * pnodeForInOrForOf = nullptr;
1037110396 if (buildAST)
1037210397 {
10373- if (isForOf)
10398+ if (isForAwait)
10399+ {
10400+ pnodeForInOrForOf = CreateNodeForOpT<knopForAwaitOf>(ichMin);
10401+ }
10402+ else if (isForOf)
1037410403 {
1037510404 pnodeForInOrForOf = CreateNodeForOpT<knopForOf>(ichMin);
1037610405 }
@@ -10385,7 +10414,7 @@ ParseNodePtr Parser::ParseStatement()
1038510414
1038610415 TrackAssignment<true>(pnodeT, nullptr);
1038710416 }
10388- PushStmt<buildAST>(&stmt, pnodeForInOrForOf, isForOf ? knopForOf : knopForIn, pLabelIdList);
10417+ PushStmt<buildAST>(&stmt, pnodeForInOrForOf, isForAwait ? knopForAwaitOf : ( isForOf ? knopForOf : knopForIn) , pLabelIdList);
1038910418 ParseNodePtr pnodeBody = ParseStatement<buildAST>();
1039010419
1039110420 if (buildAST)
@@ -10402,6 +10431,11 @@ ParseNodePtr Parser::ParseStatement()
1040210431 Error(ERRDestructInit);
1040310432 }
1040410433
10434+ if (isForAwait)
10435+ {
10436+ Error(ERRValidIfFollowedBy, _u("'for await'"), _u("'of'"));
10437+ }
10438+
1040510439 ChkCurTok(tkSColon, ERRnoSemic);
1040610440 ParseNodePtr pnodeCond = nullptr;
1040710441 if (m_token.tk != tkSColon)
@@ -11640,6 +11674,7 @@ void Parser::InitPids()
1164011674 wellKnownPropertyPids.get = this->GetHashTbl()->PidHashNameLen(g_ssym_get.sz, g_ssym_get.cch);
1164111675 wellKnownPropertyPids.set = this->GetHashTbl()->PidHashNameLen(g_ssym_set.sz, g_ssym_set.cch);
1164211676 wellKnownPropertyPids.let = this->GetHashTbl()->PidHashNameLen(g_ssym_let.sz, g_ssym_let.cch);
11677+ wellKnownPropertyPids.await = this->GetHashTbl()->PidHashNameLen(g_ssym_await.sz, g_ssym_await.cch);
1164311678 wellKnownPropertyPids.constructor = this->GetHashTbl()->PidHashNameLen(g_ssym_constructor.sz, g_ssym_constructor.cch);
1164411679 wellKnownPropertyPids.prototype = this->GetHashTbl()->PidHashNameLen(g_ssym_prototype.sz, g_ssym_prototype.cch);
1164511680 wellKnownPropertyPids.__proto__ = this->GetHashTbl()->PidHashNameLen(_u("__proto__"), sizeof("__proto__") - 1);
@@ -12677,6 +12712,9 @@ ParseNode* Parser::CopyPnode(ParseNode *pnode) {
1267712712 case knopForOf:
1267812713 Assert(false);
1267912714 break;
12715+ case knopForAwaitOf:
12716+ Assert(false);
12717+ break;
1268012718 //PTNODE(knopReturn , "return" ,None ,Uni ,fnopNone)
1268112719 case knopReturn: {
1268212720 ParseNode* copyNode = CreateNodeForOpT<knopReturn>(pnode->ichMin, pnode->ichLim);
@@ -13485,6 +13523,7 @@ void PrintScopesWIndent(ParseNode *pnode, int indentAmt) {
1348513523 case knopFor: scope = pnode->AsParseNodeFor()->pnodeBlock; firstOnly = true; break;
1348613524 case knopForIn: scope = pnode->AsParseNodeForInOrForOf()->pnodeBlock; firstOnly = true; break;
1348713525 case knopForOf: scope = pnode->AsParseNodeForInOrForOf()->pnodeBlock; firstOnly = true; break;
13526+ case knopForAwaitOf: scope = pnode->AsParseNodeForInOrForOf()->pnodeBlock; firstOnly = true; break;
1348813527 }
1348913528 if (scope) {
1349013529 Output::Print(_u("[%4d, %4d): "), scope->ichMin, scope->ichLim);
@@ -14118,6 +14157,14 @@ void PrintPnodeWIndent(ParseNode *pnode, int indentAmt) {
1411814157 PrintPnodeWIndent(pnode->AsParseNodeForInOrForOf()->pnodeObj, indentAmt + INDENT_SIZE);
1411914158 PrintPnodeWIndent(pnode->AsParseNodeForInOrForOf()->pnodeBody, indentAmt + INDENT_SIZE);
1412014159 break;
14160+ case knopForAwaitOf:
14161+ Indent(indentAmt);
14162+ Output::Print(_u("forAwaitOf\n"));
14163+ PrintScopesWIndent(pnode, indentAmt + INDENT_SIZE);
14164+ PrintPnodeWIndent(pnode->AsParseNodeForInOrForOf()->pnodeLval, indentAmt + INDENT_SIZE);
14165+ PrintPnodeWIndent(pnode->AsParseNodeForInOrForOf()->pnodeObj, indentAmt + INDENT_SIZE);
14166+ PrintPnodeWIndent(pnode->AsParseNodeForInOrForOf()->pnodeBody, indentAmt + INDENT_SIZE);
14167+ break;
1412114168 //PTNODE(knopReturn , "return" ,None ,Uni ,fnopNone)
1412214169 case knopReturn:
1412314170 Indent(indentAmt);
0 commit comments