diff --git a/lib/Parser/Parse.cpp b/lib/Parser/Parse.cpp index 5db98640ef8..683a8fdf433 100644 --- a/lib/Parser/Parse.cpp +++ b/lib/Parser/Parse.cpp @@ -2863,6 +2863,7 @@ ParseNodePtr Parser::ParseTerm(BOOL fAllowCall, _Inout_opt_ charcount_t *plastRParen /*= nullptr*/) { ParseNodePtr pnode = nullptr; + PidRefStack *savedTopAsyncRef = nullptr; charcount_t ichMin = 0; size_t iecpMin = 0; size_t iuMin; @@ -2915,6 +2916,13 @@ ParseNodePtr Parser::ParseTerm(BOOL fAllowCall, isLambdaExpr = true; goto LFunction; } + else if (m_token.tk == tkLParen) + { + // This is potentially an async arrow function. Save the state of the async references + // in case it needs to be restored. (Note that the case of a single parameter with no ()'s + // is detected upstream and need not be handled here.) + savedTopAsyncRef = pid->GetTopRef(); + } } // Don't push a reference if this is a single lambda parameter, because we'll reparse with @@ -3269,6 +3277,18 @@ LFunction : pnode = ParsePostfixOperators(pnode, fAllowCall, fInNew, isAsyncExpr, &fCanAssign, &term, pfIsDotOrIndex); + if (savedTopAsyncRef != nullptr && + this->m_token.tk == tkDArrow) + { + // This is an async arrow function; we're going to back up and reparse it. + // Make sure we don't leave behind a bogus reference to the 'async' identifier. + for (IdentPtr pid = wellKnownPropertyPids.async; pid->GetTopRef() != savedTopAsyncRef;) + { + Assert(pid->GetTopRef() != nullptr); + pid->RemovePrevPidRef(nullptr); + } + } + // Pass back identifier if requested if (pToken && term.tk == tkID) { diff --git a/test/es6/lambda-params-shadow.js b/test/es6/lambda-params-shadow.js index 1e45ab40bf3..69c07a584e5 100644 --- a/test/es6/lambda-params-shadow.js +++ b/test/es6/lambda-params-shadow.js @@ -18,7 +18,14 @@ class B extends A { } } let b = new B(); -if (count !== 3) { +class async extends A { + constructor() { + super(); + let Q = async A => { A }; + } +} +let a = new async(); +if (count !== 4) { WScript.Echo('fail'); }