|
667 | 667 |
|
668 | 668 | // ## Parser utilities |
669 | 669 |
|
670 | | -varliteral=/^(?:'((?:\\.|[^'\\])*?)'|"((?:\\.|[^"\\])*?)")/; |
| 670 | +varliteral=/^(?:'((?:\\[^]|[^'\\])*?)'|"((?:\\[^]|[^"\\])*?)")/; |
671 | 671 | pp$9.strictDirective=function(start){ |
672 | 672 | if(this.options.ecmaVersion<5){returnfalse} |
673 | 673 | for(;;){ |
|
853 | 853 | // Statement) is allowed here. If context is not empty then only a Statement |
854 | 854 | // is allowed. However, `let [` is an explicit negative lookahead for |
855 | 855 | // ExpressionStatement, so special-case it first. |
856 | | -if(nextCh===91||nextCh===92){returntrue}// '[', '/' |
| 856 | +if(nextCh===91||nextCh===92){returntrue}// '[', '\' |
857 | 857 | if(context){returnfalse} |
858 | 858 |
|
859 | 859 | if(nextCh===123||nextCh>0xd7ff&&nextCh<0xdc00){returntrue}// '{', astral |
|
1046 | 1046 | returnthis.parseFor(node,init$1) |
1047 | 1047 | } |
1048 | 1048 | varstartsWithLet=this.isContextual("let"),isForOf=false; |
| 1049 | +varcontainsEsc=this.containsEsc; |
1049 | 1050 | varrefDestructuringErrors=newDestructuringErrors; |
1050 | | -varinit=this.parseExpression(awaitAt>-1 ? "await" : true,refDestructuringErrors); |
| 1051 | +varinitPos=this.start; |
| 1052 | +varinit=awaitAt>-1 |
| 1053 | + ? this.parseExprSubscripts(refDestructuringErrors,"await") |
| 1054 | + : this.parseExpression(true,refDestructuringErrors); |
1051 | 1055 | if(this.type===types$1._in||(isForOf=this.options.ecmaVersion>=6&&this.isContextual("of"))){ |
1052 | | -if(this.options.ecmaVersion>=9){ |
1053 | | -if(this.type===types$1._in){ |
1054 | | -if(awaitAt>-1){this.unexpected(awaitAt);} |
1055 | | -}else{node.await=awaitAt>-1;} |
| 1056 | +if(awaitAt>-1){// implies `ecmaVersion >= 9` (see declaration of awaitAt) |
| 1057 | +if(this.type===types$1._in){this.unexpected(awaitAt);} |
| 1058 | +node.await=true; |
| 1059 | +}elseif(isForOf&&this.options.ecmaVersion>=8){ |
| 1060 | +if(init.start===initPos&&!containsEsc&&init.type==="Identifier"&&init.name==="async"){this.unexpected();} |
| 1061 | +elseif(this.options.ecmaVersion>=9){node.await=false;} |
1056 | 1062 | } |
1057 | 1063 | if(startsWithLet&&isForOf){this.raise(init.start,"The left-hand side of a for-of loop may not start with 'let'.");} |
1058 | 1064 | this.toAssignable(init,false,refDestructuringErrors); |
|
2665 | 2671 | node.argument=this.parseMaybeUnary(null,true,update,forInit); |
2666 | 2672 | this.checkExpressionErrors(refDestructuringErrors,true); |
2667 | 2673 | if(update){this.checkLValSimple(node.argument);} |
2668 | | -elseif(this.strict&&node.operator==="delete"&& |
2669 | | -node.argument.type==="Identifier") |
| 2674 | +elseif(this.strict&&node.operator==="delete"&&isLocalVariableAccess(node.argument)) |
2670 | 2675 | {this.raiseRecoverable(node.start,"Deleting local variable in strict mode");} |
2671 | 2676 | elseif(node.operator==="delete"&&isPrivateFieldAccess(node.argument)) |
2672 | 2677 | {this.raiseRecoverable(node.start,"Private fields can not be deleted");} |
|
2701 | 2706 | } |
2702 | 2707 | }; |
2703 | 2708 |
|
| 2709 | +functionisLocalVariableAccess(node){ |
| 2710 | +return( |
| 2711 | +node.type==="Identifier"|| |
| 2712 | +node.type==="ParenthesizedExpression"&&isLocalVariableAccess(node.expression) |
| 2713 | +) |
| 2714 | +} |
| 2715 | + |
2704 | 2716 | functionisPrivateFieldAccess(node){ |
2705 | 2717 | return( |
2706 | 2718 | node.type==="MemberExpression"&&node.property.type==="PrivateIdentifier"|| |
2707 | | -node.type==="ChainExpression"&&isPrivateFieldAccess(node.expression) |
| 2719 | +node.type==="ChainExpression"&&isPrivateFieldAccess(node.expression)|| |
| 2720 | +node.type==="ParenthesizedExpression"&&isPrivateFieldAccess(node.expression) |
2708 | 2721 | ) |
2709 | 2722 | } |
2710 | 2723 |
|
|
3131 | 3144 | this.raiseRecoverable(this.start,"Bad escape sequence in untagged template literal"); |
3132 | 3145 | } |
3133 | 3146 | elem.value={ |
3134 | | -raw: this.value, |
| 3147 | +raw: this.value.replace(/\r\n?/g,"\n"), |
3135 | 3148 | cooked: null |
3136 | 3149 | }; |
3137 | 3150 | }else{ |
|
3806 | 3819 |
|
3807 | 3820 | varpp$1=Parser.prototype; |
3808 | 3821 |
|
| 3822 | +// Track disjunction structure to determine whether a duplicate |
| 3823 | +// capture group name is allowed because it is in a separate branch. |
| 3824 | +varBranchID=functionBranchID(parent,base){ |
| 3825 | +// Parent disjunction branch |
| 3826 | +this.parent=parent; |
| 3827 | +// Identifies this set of sibling branches |
| 3828 | +this.base=base||this; |
| 3829 | +}; |
| 3830 | + |
| 3831 | +BranchID.prototype.separatedFrom=functionseparatedFrom(alt){ |
| 3832 | +// A branch is separate from another branch if they or any of |
| 3833 | +// their parents are siblings in a given disjunction |
| 3834 | +for(varself=this;self;self=self.parent){ |
| 3835 | +for(varother=alt;other;other=other.parent){ |
| 3836 | +if(self.base===other.base&&self!==other){returntrue} |
| 3837 | +} |
| 3838 | +} |
| 3839 | +returnfalse |
| 3840 | +}; |
| 3841 | + |
| 3842 | +BranchID.prototype.sibling=functionsibling(){ |
| 3843 | +returnnewBranchID(this.parent,this.base) |
| 3844 | +}; |
| 3845 | + |
3809 | 3846 | varRegExpValidationState=functionRegExpValidationState(parser){ |
3810 | 3847 | this.parser=parser; |
3811 | 3848 | this.validFlags="gim"+(parser.options.ecmaVersion>=6 ? "uy" : "")+(parser.options.ecmaVersion>=9 ? "s" : "")+(parser.options.ecmaVersion>=13 ? "d" : "")+(parser.options.ecmaVersion>=15 ? "v" : ""); |
|
3822 | 3859 | this.lastAssertionIsQuantifiable=false; |
3823 | 3860 | this.numCapturingParens=0; |
3824 | 3861 | this.maxBackReference=0; |
3825 | | -this.groupNames=[]; |
| 3862 | +this.groupNames=Object.create(null); |
3826 | 3863 | this.backReferenceNames=[]; |
| 3864 | +this.branchID=null; |
3827 | 3865 | }; |
3828 | 3866 |
|
3829 | 3867 | RegExpValidationState.prototype.reset=functionreset(start,pattern,flags){ |
|
3955 | 3993 | } |
3956 | 3994 | }; |
3957 | 3995 |
|
| 3996 | +functionhasProp(obj){ |
| 3997 | +for(var_inobj){returntrue} |
| 3998 | +returnfalse |
| 3999 | +} |
| 4000 | + |
3958 | 4001 | /** |
3959 | 4002 | * Validate the pattern part of a given RegExpLiteral. |
3960 | 4003 | * |
|
3969 | 4012 | // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError* |
3970 | 4013 | // exception if _P_ did not conform to the grammar, if any elements of _P_ |
3971 | 4014 | // were not matched by the parse, or if any Early Error conditions exist. |
3972 | | -if(!state.switchN&&this.options.ecmaVersion>=9&&state.groupNames.length>0){ |
| 4015 | +if(!state.switchN&&this.options.ecmaVersion>=9&&hasProp(state.groupNames)){ |
3973 | 4016 | state.switchN=true; |
3974 | 4017 | this.regexp_pattern(state); |
3975 | 4018 | } |
|
3983 | 4026 | state.lastAssertionIsQuantifiable=false; |
3984 | 4027 | state.numCapturingParens=0; |
3985 | 4028 | state.maxBackReference=0; |
3986 | | -state.groupNames.length=0; |
| 4029 | +state.groupNames=Object.create(null); |
3987 | 4030 | state.backReferenceNames.length=0; |
| 4031 | +state.branchID=null; |
3988 | 4032 |
|
3989 | 4033 | this.regexp_disjunction(state); |
3990 | 4034 |
|
|
4003 | 4047 | for(vari=0,list=state.backReferenceNames;i<list.length;i+=1){ |
4004 | 4048 | varname=list[i]; |
4005 | 4049 |
|
4006 | | -if(state.groupNames.indexOf(name)===-1){ |
| 4050 | +if(!state.groupNames[name]){ |
4007 | 4051 | state.raise("Invalid named capture referenced"); |
4008 | 4052 | } |
4009 | 4053 | } |
4010 | 4054 | }; |
4011 | 4055 |
|
4012 | 4056 | // https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction |
4013 | 4057 | pp$1.regexp_disjunction=function(state){ |
| 4058 | +vartrackDisjunction=this.options.ecmaVersion>=16; |
| 4059 | +if(trackDisjunction){state.branchID=newBranchID(state.branchID,null);} |
4014 | 4060 | this.regexp_alternative(state); |
4015 | 4061 | while(state.eat(0x7C/* | */)){ |
| 4062 | +if(trackDisjunction){state.branchID=state.branchID.sibling();} |
4016 | 4063 | this.regexp_alternative(state); |
4017 | 4064 | } |
| 4065 | +if(trackDisjunction){state.branchID=state.branchID.parent;} |
4018 | 4066 |
|
4019 | 4067 | // Make the same message as V8. |
4020 | 4068 | if(this.regexp_eatQuantifier(state,true)){ |
|
4027 | 4075 |
|
4028 | 4076 | // https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative |
4029 | 4077 | pp$1.regexp_alternative=function(state){ |
4030 | | -while(state.pos<state.source.length&&this.regexp_eatTerm(state)) |
4031 | | -{} |
| 4078 | +while(state.pos<state.source.length&&this.regexp_eatTerm(state)){} |
4032 | 4079 | }; |
4033 | 4080 |
|
4034 | 4081 | // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term |
|
4266 | 4313 | // `?` GroupName |
4267 | 4314 | pp$1.regexp_groupSpecifier=function(state){ |
4268 | 4315 | if(state.eat(0x3F/* ? */)){ |
4269 | | -if(this.regexp_eatGroupName(state)){ |
4270 | | -if(state.groupNames.indexOf(state.lastStringValue)!==-1){ |
| 4316 | +if(!this.regexp_eatGroupName(state)){state.raise("Invalid group");} |
| 4317 | +vartrackDisjunction=this.options.ecmaVersion>=16; |
| 4318 | +varknown=state.groupNames[state.lastStringValue]; |
| 4319 | +if(known){ |
| 4320 | +if(trackDisjunction){ |
| 4321 | +for(vari=0,list=known;i<list.length;i+=1){ |
| 4322 | +varaltID=list[i]; |
| 4323 | + |
| 4324 | +if(!altID.separatedFrom(state.branchID)) |
| 4325 | +{state.raise("Duplicate capture group name");} |
| 4326 | +} |
| 4327 | +}else{ |
4271 | 4328 | state.raise("Duplicate capture group name"); |
4272 | 4329 | } |
4273 | | -state.groupNames.push(state.lastStringValue); |
4274 | | -return |
4275 | 4330 | } |
4276 | | -state.raise("Invalid group"); |
| 4331 | +if(trackDisjunction){ |
| 4332 | +(known||(state.groupNames[state.lastStringValue]=[])).push(state.branchID); |
| 4333 | +}else{ |
| 4334 | +state.groupNames[state.lastStringValue]=true; |
| 4335 | +} |
4277 | 4336 | } |
4278 | 4337 | }; |
4279 | 4338 |
|
|
5778 | 5837 | break |
5779 | 5838 |
|
5780 | 5839 | case"$": |
5781 | | -if(this.input[this.pos+1]!=="{"){ |
5782 | | -break |
5783 | | -} |
5784 | | - |
5785 | | -// falls through |
| 5840 | +if(this.input[this.pos+1]!=="{"){break} |
| 5841 | +// fall through |
5786 | 5842 | case"`": |
5787 | 5843 | returnthis.finishToken(types$1.invalidTemplate,this.input.slice(this.start,this.pos)) |
5788 | 5844 |
|
5789 | | -// no default |
| 5845 | +case"\r": |
| 5846 | +if(this.input[this.pos+1]==="\n"){++this.pos;} |
| 5847 | +// fall through |
| 5848 | +case"\n": case"\u2028": case"\u2029": |
| 5849 | +++this.curLine; |
| 5850 | +this.lineStart=this.pos+1; |
| 5851 | +break |
5790 | 5852 | } |
5791 | 5853 | } |
5792 | 5854 | this.raise(this.start,"Unterminated template"); |
|
5849 | 5911 | if(isNewLine(ch)){ |
5850 | 5912 | // Unicode new line characters after \ get removed from output in both |
5851 | 5913 | // template literals and strings |
| 5914 | +if(this.options.locations){this.lineStart=this.pos;++this.curLine;} |
5852 | 5915 | return"" |
5853 | 5916 | } |
5854 | 5917 | returnString.fromCharCode(ch) |
|
5927 | 5990 | // [walk]: util/walk.js |
5928 | 5991 |
|
5929 | 5992 |
|
5930 | | -varversion="8.11.3"; |
| 5993 | +varversion="8.12.1"; |
5931 | 5994 |
|
5932 | 5995 | Parser.acorn={ |
5933 | 5996 | Parser: Parser, |
|
0 commit comments