|
667 | 667 |
|
668 | 668 | // ## Parser utilities
|
669 | 669 |
|
670 |
| - var literal = /^(?:'((?:\\.|[^'\\])*?)'|"((?:\\.|[^"\\])*?)")/; |
| 670 | + var literal = /^(?:'((?:\\[^]|[^'\\])*?)'|"((?:\\[^]|[^"\\])*?)")/; |
671 | 671 | pp$9.strictDirective = function(start) {
|
672 | 672 | if (this.options.ecmaVersion < 5) { return false }
|
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) { return true } // '[', '/' |
| 856 | + if (nextCh === 91 || nextCh === 92) { return true } // '[', '\' |
857 | 857 | if (context) { return false }
|
858 | 858 |
|
859 | 859 | if (nextCh === 123 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true } // '{', astral
|
|
1046 | 1046 | return this.parseFor(node, init$1)
|
1047 | 1047 | }
|
1048 | 1048 | var startsWithLet = this.isContextual("let"), isForOf = false;
|
| 1049 | + var containsEsc = this.containsEsc; |
1049 | 1050 | var refDestructuringErrors = new DestructuringErrors;
|
1050 |
| - var init = this.parseExpression(awaitAt > -1 ? "await" : true, refDestructuringErrors); |
| 1051 | + var initPos = this.start; |
| 1052 | + var init = 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 | + } else if (isForOf && this.options.ecmaVersion >= 8) { |
| 1060 | + if (init.start === initPos && !containsEsc && init.type === "Identifier" && init.name === "async") { this.unexpected(); } |
| 1061 | + else if (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 |
| - else if (this.strict && node.operator === "delete" && |
2669 |
| - node.argument.type === "Identifier") |
| 2674 | + else if (this.strict && node.operator === "delete" && isLocalVariableAccess(node.argument)) |
2670 | 2675 | { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); }
|
2671 | 2676 | else if (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 | + function isLocalVariableAccess(node) { |
| 2710 | + return ( |
| 2711 | + node.type === "Identifier" || |
| 2712 | + node.type === "ParenthesizedExpression" && isLocalVariableAccess(node.expression) |
| 2713 | + ) |
| 2714 | + } |
| 2715 | + |
2704 | 2716 | function isPrivateFieldAccess(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 | var pp$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 | + var BranchID = function BranchID(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 = function separatedFrom (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 (var self = this; self; self = self.parent) { |
| 3835 | + for (var other = alt; other; other = other.parent) { |
| 3836 | + if (self.base === other.base && self !== other) { return true } |
| 3837 | + } |
| 3838 | + } |
| 3839 | + return false |
| 3840 | + }; |
| 3841 | + |
| 3842 | + BranchID.prototype.sibling = function sibling () { |
| 3843 | + return new BranchID(this.parent, this.base) |
| 3844 | + }; |
| 3845 | + |
3809 | 3846 | var RegExpValidationState = function RegExpValidationState(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 = function reset (start, pattern, flags) {
|
|
3955 | 3993 | }
|
3956 | 3994 | };
|
3957 | 3995 |
|
| 3996 | + function hasProp(obj) { |
| 3997 | + for (var _ in obj) { return true } |
| 3998 | + return false |
| 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 (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) {
|
4004 | 4048 | var name = 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 | + var trackDisjunction = this.options.ecmaVersion >= 16; |
| 4059 | + if (trackDisjunction) { state.branchID = new BranchID(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 | + var trackDisjunction = this.options.ecmaVersion >= 16; |
| 4318 | + var known = state.groupNames[state.lastStringValue]; |
| 4319 | + if (known) { |
| 4320 | + if (trackDisjunction) { |
| 4321 | + for (var i = 0, list = known; i < list.length; i += 1) { |
| 4322 | + var altID = 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 | return this.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 | return String.fromCharCode(ch)
|
|
5927 | 5990 | // [walk]: util/walk.js
|
5928 | 5991 |
|
5929 | 5992 |
|
5930 |
| - var version = "8.11.3"; |
| 5993 | + var version = "8.12.1"; |
5931 | 5994 |
|
5932 | 5995 | Parser.acorn = {
|
5933 | 5996 | Parser: Parser,
|
|
0 commit comments