Skip to content

Commit

Permalink
[MERGE #2219 @pleath] Port fix for bad binding of async arrow functio…
Browse files Browse the repository at this point in the history
…n parameters

Merge pull request #2219 from pleath:1612_1.3

Apply the same parse-time-binding logic to async arrow function parameter lists as to normal arrow function parameter lists. (They take different paths in the parser prior to the discovery of the arrow.)
  • Loading branch information
pleath committed Dec 16, 2016
2 parents 1537208 + c663ea8 commit 55f6bd5
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 10 deletions.
43 changes: 35 additions & 8 deletions lib/Parser/Parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2868,22 +2868,24 @@ ParseNodePtr Parser::ParseTerm(BOOL fAllowCall,
ichMin = m_pscan->IchMinTok();
iecpMin = m_pscan->IecpMinTok();

if (pid == wellKnownPropertyPids.async &&
m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
{
isAsyncExpr = true;
}

m_pscan->Scan();

// We search for an Async expression (a function declaration or an async lambda expression)
if (pid == wellKnownPropertyPids.async &&
!m_pscan->FHadNewLine() &&
m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
if (isAsyncExpr && !m_pscan->FHadNewLine())
{
if (m_token.tk == tkFUNCTION)
{
isAsyncExpr = true;
goto LFunction;
}
else if (m_token.tk == tkID)
{
isLambdaExpr = true;
isAsyncExpr = true;
goto LFunction;
}
}
Expand Down Expand Up @@ -3234,7 +3236,7 @@ LFunction :
break;
}

pnode = ParsePostfixOperators<buildAST>(pnode, fAllowCall, fInNew, &fCanAssign, &term, pfIsDotOrIndex);
pnode = ParsePostfixOperators<buildAST>(pnode, fAllowCall, fInNew, isAsyncExpr, &fCanAssign, &term, pfIsDotOrIndex);

// Pass back identifier if requested
if (pToken && term.tk == tkID)
Expand Down Expand Up @@ -3329,6 +3331,7 @@ ParseNodePtr Parser::ParsePostfixOperators(
ParseNodePtr pnode,
BOOL fAllowCall,
BOOL fInNew,
BOOL isAsyncExpr,
BOOL *pfCanAssign,
_Inout_ IdentToken* pToken,
_Out_opt_ bool* pfIsDotOrIndex /*= nullptr */)
Expand Down Expand Up @@ -3368,6 +3371,7 @@ ParseNodePtr Parser::ParsePostfixOperators(
pToken->tk = tkNone; // This is no longer an identifier
}
fInNew = FALSE;
ChkCurTok(tkRParen, ERRnoRparen);
}
else
{
Expand All @@ -3377,6 +3381,17 @@ ParseNodePtr Parser::ParsePostfixOperators(
return pnode;
}

uint saveNextBlockId = m_nextBlockId;
uint saveCurrBlockId = GetCurrentBlock()->sxBlock.blockId;

if (isAsyncExpr)
{
// Advance the block ID here in case this parenthetical expression turns out to be a lambda parameter list.
// That way the pid ref stacks will be created in their correct final form, and we can simply fix
// up function ID's.
GetCurrentBlock()->sxBlock.blockId = m_nextBlockId++;
}

ParseNodePtr pnodeArgs = ParseArgList<buildAST>(&callOfConstants, &spreadArgCount, &count);
// We used to un-defer a deferred function body here if it was called as part of the expression that declared it.
// We now detect this case up front in ParseFncDecl, which is cheaper and simpler.
Expand Down Expand Up @@ -3411,8 +3426,20 @@ ParseNodePtr Parser::ParsePostfixOperators(
}
pToken->tk = tkNone; // This is no longer an identifier
}

ChkCurTok(tkRParen, ERRnoRparen);

if (isAsyncExpr)
{
GetCurrentBlock()->sxBlock.blockId = saveCurrBlockId;
if (m_token.tk == tkDArrow)
{
// We're going to rewind and reinterpret the expression as a parameter list.
// Put back the original next-block-ID so the existing pid ref stacks will be correct.
m_nextBlockId = saveNextBlockId;
}
}
}
ChkCurTok(tkRParen, ERRnoRparen);
if (pfCanAssign)
{
*pfCanAssign = FALSE;
Expand Down Expand Up @@ -12183,7 +12210,7 @@ ParseNodePtr Parser::ParseDestructuredVarDecl(tokens declarationType, bool isDec
BOOL fCanAssign;
IdentToken token;
// Look for postfix operator
pnodeElem = ParsePostfixOperators<buildAST>(pnodeElem, TRUE, FALSE, &fCanAssign, &token);
pnodeElem = ParsePostfixOperators<buildAST>(pnodeElem, TRUE, FALSE, FALSE, &fCanAssign, &token);
}
}
else if (m_token.tk == tkSUPER || m_token.tk == tkID)
Expand Down
1 change: 1 addition & 0 deletions lib/Parser/Parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,7 @@ class Parser
ParseNodePtr pnode,
BOOL fAllowCall,
BOOL fInNew,
BOOL isAsyncExpr,
BOOL *pfCanAssign,
_Inout_ IdentToken* pToken,
_Out_opt_ bool* pfIsDotOrIndex = nullptr);
Expand Down
2 changes: 2 additions & 0 deletions test/es6/lambda-params-shadow.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class B extends A {
super();
((B) => { super.increment() })();
(A=> { super.increment() })();
let C = async (B) => { B };
let D = async A => { A };
}
}
let b = new B();
Expand Down
4 changes: 2 additions & 2 deletions test/es6/rlexe.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
<test>
<default>
<files>lambda-params-shadow.js</files>
<compile-flags>-off:deferparse -args summary -endargs</compile-flags>
<compile-flags>-off:deferparse -es7asyncawait</compile-flags>
</default>
</test>
<test>
<default>
<files>lambda-params-shadow.js</files>
<compile-flags>-force:deferparse -args summary -endargs</compile-flags>
<compile-flags>-force:deferparse -es7asyncawait</compile-flags>
</default>
</test>
<test>
Expand Down

0 comments on commit 55f6bd5

Please sign in to comment.