@@ -984,6 +984,7 @@ ParseNodeProg * Parser::CreateProgNode(bool isModuleSource, ULONG lineNumber)
984984 }
985985
986986 pnodeProg->cbMin = this ->GetScanner ()->IecpMinTok ();
987+ pnodeProg->cbStringMin = pnodeProg->cbMin ;
987988 pnodeProg->lineNumber = lineNumber;
988989 pnodeProg->homeObjLocation = Js::Constants::NoRegister;
989990 return pnodeProg;
@@ -3346,8 +3347,7 @@ ParseNodePtr Parser::ParseTerm(BOOL fAllowCall,
33463347 pnode = ParseFncDeclNoCheckScope<buildAST>(flags, pNameHint, false , true , fUnaryOrParen );
33473348 if (isAsyncExpr)
33483349 {
3349- pnode->AsParseNodeFnc ()->cbMin = iecpMin;
3350- pnode->ichMin = ichMin;
3350+ pnode->AsParseNodeFnc ()->cbStringMin = iecpMin;
33513351 }
33523352 fCanAssign = FALSE ;
33533353 break ;
@@ -4218,7 +4218,7 @@ template<bool buildAST> void Parser::ParseComputedName(ParseNodePtr* ppnodeName,
42184218 { get foo(){ ... }, set bar(arg) { ... } }
42194219***************************************************************************/
42204220template <bool buildAST>
4221- ParseNodeBin * Parser::ParseMemberGetSet (OpCode nop, LPCOLESTR* ppNameHint)
4221+ ParseNodeBin * Parser::ParseMemberGetSet (OpCode nop, LPCOLESTR* ppNameHint, size_t iecpMin, charcount_t ichMin )
42224222{
42234223 ParseNodePtr pnodeName = nullptr ;
42244224 Assert (nop == knopGetMember || nop == knopSetMember);
@@ -4316,15 +4316,17 @@ ParseNodeBin * Parser::ParseMemberGetSet(OpCode nop, LPCOLESTR* ppNameHint)
43164316 ParseNodeFnc * pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(flags, *ppNameHint,
43174317 /* needsPIDOnRCurlyScan*/ false , /* resetParsingSuperRestrictionState*/ false );
43184318
4319+ pnodeFnc->cbStringMin = iecpMin;
4320+
43194321 if (isComputedName)
43204322 {
43214323 pnodeFnc->SetHasComputedName ();
43224324 }
43234325 pnodeFnc->SetHasHomeObj ();
4326+ pnodeFnc->SetIsAccessor ();
43244327
43254328 if (buildAST)
43264329 {
4327- pnodeFnc->SetIsAccessor ();
43284330 return CreateBinNode (nop, pnodeName, pnodeFnc);
43294331 }
43304332 else
@@ -4372,8 +4374,8 @@ ParseNodePtr Parser::ParseMemberList(LPCOLESTR pNameHint, uint32* pNameHintLengt
43724374 }
43734375#endif
43744376 bool isAsyncMethod = false ;
4375- charcount_t ichMin = 0 ;
4376- size_t iecpMin = 0 ;
4377+ charcount_t ichMin = this -> GetScanner ()-> IchMinTok () ;
4378+ size_t iecpMin = this -> GetScanner ()-> IecpMinTok () ;
43774379 if (m_token.tk == tkID && m_token.GetIdentifier (this ->GetHashTbl ()) == wellKnownPropertyPids.async && m_scriptContext->GetConfig ()->IsES7AsyncAndAwaitEnabled ())
43784380 {
43794381 RestorePoint parsedAsync;
@@ -4659,13 +4661,14 @@ ParseNodePtr Parser::ParseMemberList(LPCOLESTR pNameHint, uint32* pNameHintLengt
46594661
46604662 if (isAsyncMethod || isGenerator)
46614663 {
4662- pnodeFnc->cbMin = iecpMin;
4663- pnodeFnc->ichMin = ichMin;
4664+ pnodeFnc->cbStringMin = iecpMin;
46644665 }
46654666
46664667 if (isComputedName)
46674668 {
46684669 pnodeFnc->SetHasComputedName ();
4670+ pnodeFnc->cbStringMin = iecpMin;
4671+
46694672 }
46704673 pnodeFnc->SetHasHomeObj ();
46714674
@@ -4698,7 +4701,7 @@ ParseNodePtr Parser::ParseMemberList(LPCOLESTR pNameHint, uint32* pNameHintLengt
46984701 LPCOLESTR pNameGetOrSet = nullptr ;
46994702 OpCode op = pidHint == wellKnownPropertyPids.get ? knopGetMember : knopSetMember;
47004703
4701- pnodeArg = ParseMemberGetSet<buildAST>(op, &pNameGetOrSet);
4704+ pnodeArg = ParseMemberGetSet<buildAST>(op, &pNameGetOrSet, iecpMin, ichMin );
47024705
47034706 if (CONFIG_FLAG (UseFullName) && buildAST && pnodeArg->pnode2 ->nop == knopFncDecl)
47044707 {
@@ -4980,6 +4983,7 @@ ParseNodeFnc * Parser::ParseFncDeclInternal(ushort flags, LPCOLESTR pNameHint, c
49804983
49814984 pnodeFnc->nestedFuncEscapes = false ;
49824985 pnodeFnc->cbMin = this ->GetScanner ()->IecpMinTok ();
4986+ pnodeFnc->cbStringMin = pnodeFnc->cbMin ;
49834987 pnodeFnc->functionId = (*m_nextFunctionId)++;
49844988
49854989
@@ -5869,8 +5873,11 @@ void Parser::ParseTopLevelDeferredFunc(ParseNodeFnc * pnodeFnc, ParseNodeFnc * p
58695873
58705874 Assert (pnodeFnc->ichMin == stub->ichMin
58715875 || (stub->fncFlags & kFunctionIsAsync ) == kFunctionIsAsync
5872- || ((stub->fncFlags & kFunctionIsGenerator ) == kFunctionIsGenerator && (stub->fncFlags & kFunctionIsMethod ) == kFunctionIsMethod ));
5873-
5876+ || ((stub->fncFlags & kFunctionIsMethod ) == kFunctionIsMethod && (
5877+ (stub->fncFlags & kFunctionIsAccessor ) == kFunctionIsAccessor
5878+ || (stub->fncFlags & kFunctionIsGenerator ) == kFunctionIsGenerator
5879+ || (stub->fncFlags & kFunctionHasComputedName ) == kFunctionHasComputedName
5880+ )));
58745881 if (stub->fncFlags & kFunctionCallsEval )
58755882 {
58765883 this ->MarkEvalCaller ();
@@ -6777,6 +6784,7 @@ ParseNodeFnc * Parser::GenerateEmptyConstructor(bool extends)
67776784 pnodeFnc->ichMin = this ->GetScanner ()->IchMinTok ();
67786785 pnodeFnc->cbLim = this ->GetScanner ()->IecpLimTok ();
67796786 pnodeFnc->cbMin = this ->GetScanner ()->IecpMinTok ();
6787+ pnodeFnc->cbStringMin = pnodeFnc->cbMin ;
67806788 pnodeFnc->lineNumber = this ->GetScanner ()->LineCur ();
67816789
67826790 pnodeFnc->functionId = (*m_nextFunctionId);
@@ -7579,8 +7587,8 @@ ParseNodeClass * Parser::ParseClassDecl(BOOL isDeclaration, LPCOLESTR pNameHint,
75797587 }
75807588
75817589 ushort fncDeclFlags = fFncNoName | fFncMethod | fFncClassMember ;
7582- charcount_t ichMin = 0 ;
7583- size_t iecpMin = 0 ;
7590+ charcount_t ichMin = this -> GetScanner ()-> IchMinTok () ;
7591+ size_t iecpMin = this -> GetScanner ()-> IecpMinTok () ;
75847592 ParseNodePtr pnodeMemberName = nullptr ;
75857593 IdentPtr pidHint = nullptr ;
75867594 IdentPtr memberPid = nullptr ;
@@ -7774,6 +7782,11 @@ ParseNodeClass * Parser::ParseClassDecl(BOOL isDeclaration, LPCOLESTR pNameHint,
77747782 pnodeFnc->cbMin = iecpMin;
77757783 pnodeFnc->ichMin = ichMin;
77767784 }
7785+
7786+ if (isAsyncMethod || isGenerator || isComputedName)
7787+ {
7788+ pnodeFnc->cbStringMin = iecpMin;
7789+ }
77777790 }
77787791 pnodeFnc->SetIsStaticMember (isStatic);
77797792 if (isComputedName)
@@ -7843,6 +7856,7 @@ ParseNodeClass * Parser::ParseClassDecl(BOOL isDeclaration, LPCOLESTR pNameHint,
78437856 if (buildAST)
78447857 {
78457858 pnodeConstructor->cbMin = cbMinConstructor;
7859+ pnodeConstructor->cbStringMin = cbMinConstructor;
78467860 pnodeConstructor->cbLim = cbLimConstructor;
78477861 pnodeConstructor->ichMin = pnodeClass->ichMin ;
78487862 pnodeConstructor->ichLim = pnodeClass->ichLim ;
@@ -8884,8 +8898,7 @@ ParseNodePtr Parser::ParseExpr(int oplMin,
88848898 pnode = ParseFncDeclNoCheckScope<buildAST>(flags, nullptr , /* needsPIDOnRCurlyScan = */ false , /* resetParsingSuperRestrictionState = */ false , /* fUnaryOrParen = */ false , fAllowIn );
88858899 if (isAsyncMethod)
88868900 {
8887- pnode->AsParseNodeFnc ()->cbMin = iecpMin;
8888- pnode->ichMin = ichMin;
8901+ pnode->AsParseNodeFnc ()->cbStringMin = iecpMin;
88898902 }
88908903
88918904 // ArrowFunction/AsyncArrowFunction is part of AssignmentExpression, which should terminate the expression unless followed by a comma
@@ -9740,8 +9753,7 @@ ParseNodePtr Parser::ParseStatement()
97409753 }
97419754 if (isAsyncMethod)
97429755 {
9743- pnode->AsParseNodeFnc ()->cbMin = iecpMin;
9744- pnode->ichMin = ichMin;
9756+ pnode->AsParseNodeFnc ()->cbStringMin = iecpMin;
97459757 }
97469758 break ;
97479759 }
@@ -11440,8 +11452,6 @@ ParseNodeProg * Parser::Parse(LPCUTF8 pszSrc, size_t offset, size_t length, char
1144011452 {
1144111453 // Defer parse for a single function should just parse that one function - there are no other statements.
1144211454 ushort flags = fFncNoFlgs ;
11443- size_t iecpMin = 0 ;
11444- charcount_t ichMin = 0 ;
1144511455 bool isAsync = false ;
1144611456 bool isGenerator = false ;
1144711457 bool isMethod = false ;
@@ -11468,55 +11478,52 @@ ParseNodeProg * Parser::Parse(LPCUTF8 pszSrc, size_t offset, size_t length, char
1146811478 m_grfscr &= ~fscrDeferredFncIsMethod;
1146911479 isMethod = true ;
1147011480 flags |= fFncNoName | fFncMethod ;
11471- }
1147211481
11473- // These are the cases which can confirm async function:
11474- // async function() {} -> async function
11475- // async () => {} -> async lambda with parens around the formal parameter
11476- // async arg => {} -> async lambda with single identifier parameter
11477- // async name() {} -> async method
11478- // async [computed_name]() {} -> async method with a computed name
11479- if (m_token.tk == tkID && m_token.GetIdentifier (this ->GetHashTbl ()) == wellKnownPropertyPids.async && m_scriptContext->GetConfig ()->IsES7AsyncAndAwaitEnabled ())
11480- {
11481- ichMin = this ->GetScanner ()->IchMinTok ();
11482- iecpMin = this ->GetScanner ()->IecpMinTok ();
11483-
11484- // Keep state so we can rewind if it turns out that this isn't an async function:
11485- // async() {} -> method named async
11486- // async => {} -> lambda with single parameter named async
11487- RestorePoint termStart;
11488- this ->GetScanner ()->Capture (&termStart);
11489-
11490- this ->GetScanner ()->Scan ();
11491-
11492- if (m_token.tk == tkDArrow || (m_token.tk == tkLParen && isMethod) || this ->GetScanner ()->FHadNewLine ())
11482+ if (m_grfscr & fscrDeferredFncIsGenerator)
1149311483 {
11494- this ->GetScanner ()->SeekTo (termStart);
11484+ m_grfscr &= ~fscrDeferredFncIsGenerator;
11485+ isGenerator = true ;
11486+ flags |= fFncGenerator ;
1149511487 }
11496- else
11488+
11489+ if (m_token.tk == tkStar && m_scriptContext->GetConfig ()->IsES6GeneratorsEnabled ())
1149711490 {
11498- flags |= fFncAsync ;
11499- isAsync = true ;
11491+ Assert (isGenerator && !isMethod) ;
11492+ this -> GetScanner ()-> Scan () ;
1150011493 }
1150111494 }
1150211495
11503- if (m_token. tk == tkStar && m_scriptContext-> GetConfig ()-> IsES6GeneratorsEnabled () )
11496+ if (m_grfscr & fscrDeferredFncIsAsync )
1150411497 {
11505- ichMin = this ->GetScanner ()->IchMinTok ();
11506- iecpMin = this ->GetScanner ()->IecpMinTok ();
11507-
11508- flags |= fFncGenerator ;
11509- isGenerator = true ;
11510-
11511- this ->GetScanner ()->Scan ();
11498+ m_grfscr &= ~fscrDeferredFncIsAsync;
11499+ isAsync = true ;
11500+ flags |= fFncAsync ;
1151211501 }
1151311502
11514- // Eat the computed name expression
11515- if (m_token.tk == tkLBrack && isMethod)
11503+
11504+ #if DBG
11505+ if (isMethod && m_token.tk == tkID)
1151611506 {
11507+ RestorePoint atPid;
11508+ IdentPtr pidHint = m_token.GetIdentifier (this ->GetHashTbl ());
11509+ this ->GetScanner ()->Capture (&atPid);
1151711510 this ->GetScanner ()->Scan ();
11518- ParseExpr<false >();
11511+ if ((pidHint == wellKnownPropertyPids.get || pidHint == wellKnownPropertyPids.set ) && NextTokenIsPropertyNameStart ())
11512+ {
11513+ // Getter/setter
11514+ // Skip the get/set keyword and continue normally
11515+ AssertMsg (false , " We should not be re-parsing the get/set part of member accessor functions" );
11516+ }
11517+ else
11518+ {
11519+ // Not a getter/setter; rewind and treat the token as a name.
11520+ this ->GetScanner ()->SeekTo (atPid);
11521+ }
1151911522 }
11523+ #endif
11524+
11525+ // Ensure this isn't a computed name
11526+ AssertMsg (!(m_token.tk == tkLBrack && isMethod), " Can't defer parse a computed name expression, we should have started after this" );
1152011527
1152111528 if (!isMethod && (m_token.tk == tkID || m_token.tk == tkLParen))
1152211529 {
@@ -11528,12 +11535,7 @@ ParseNodeProg * Parser::Parse(LPCUTF8 pszSrc, size_t offset, size_t length, char
1152811535 pnodeProg->pnodeBody = nullptr ;
1152911536 AddToNodeList (&pnodeProg->pnodeBody , &lastNodeRef, pnodeFnc);
1153011537
11531- // Include the async keyword or star character in the function extents
11532- if (isAsync || isGenerator)
11533- {
11534- pnodeFnc->AsParseNodeFnc ()->cbMin = iecpMin;
11535- pnodeFnc->ichMin = ichMin;
11536- }
11538+ // No need to update the cbStringMin property since no ParseableFunctionInfo will be created from this defer-parsed pnodeFnc
1153711539 }
1153811540 else
1153911541 {
0 commit comments