mirror of
https://github.com/RGBCube/serenity
synced 2025-10-24 09:52:34 +00:00
Instead of passing the continuously merged initial forbidden token set
(with the new additional forbidden tokens from each parsed secondary
expression) to the next call of parse_secondary_expression(), keep a
copy of the original set and use it as the base for parsing the next
secondary expression.
This bug prevented us from properly parsing the following expression:
```js
0 ?? 0 ? 0 : 0 || 0
```
...due to LogicalExpression with LogicalOp::NullishCoalescing returning
both DoubleAmpersand and DoublePipe in its forbidden token set.
The following correct AST is now generated:
Program
(Children)
ExpressionStatement
ConditionalExpression
(Test)
LogicalExpression
NumericLiteral 0
??
NumericLiteral 0
(Consequent)
NumericLiteral 0
(Alternate)
LogicalExpression
NumericLiteral 0
||
NumericLiteral 0
An alternate solution I explored was only merging the original forbidden
token set with the one of the last parsed secondary expression which is
then passed to match_secondary_expression(); however that led to an
incorrect AST (note the alternate expression):
Program
(Children)
ExpressionStatement
LogicalExpression
ConditionalExpression
(Test)
LogicalExpression
NumericLiteral 0
??
NumericLiteral 0
(Consequent)
NumericLiteral 0
(Alternate)
NumericLiteral 0
||
NumericLiteral 0
Truth be told, I don't know enough about the inner workings of the
parser to fully explain the difference. AFAICT this patch has no
unintended side effects in its current form though.
Fixes #18087.
|
||
|---|---|---|
| .. | ||
| builtins | ||
| classes | ||
| functions | ||
| iterators | ||
| loops | ||
| modules | ||
| operators | ||
| syntax | ||
| add-values-to-primitive.js | ||
| arguments-callee.js | ||
| arguments-object.js | ||
| automatic-semicolon-insertion.js | ||
| break-continue-syntax-errors.js | ||
| comments-basic.js | ||
| computed-property-sideeffects.js | ||
| computed-property-throws.js | ||
| const-declaration-missing-initializer.js | ||
| const-reassignment.js | ||
| custom-@@hasInstance.js | ||
| custom-@@toPrimitive.js | ||
| custom-@@toStringTag.js | ||
| debugger-statement.js | ||
| duplicated-variable-declarations.js | ||
| empty-statements.js | ||
| eval-aliasing.js | ||
| eval-basic.js | ||
| exception-in-catch-block.js | ||
| exception-ReferenceError.js | ||
| exponentiation-basic.js | ||
| gc-deeply-nested-object-graph.js | ||
| global-var-let-const.js | ||
| if-statement-function-declaration.js | ||
| indexed-access-prototype-indirection.js | ||
| indexed-access-string-object.js | ||
| invalid-lhs-in-assignment.js | ||
| labels.js | ||
| let-scoping.js | ||
| new-expression.js | ||
| non-writable-assignment.js | ||
| numeric-literals-basic.js | ||
| object-basic.js | ||
| object-expression-__proto__.js | ||
| object-expression-computed-property.js | ||
| object-expression-numeric-property.js | ||
| object-getter-setter-shorthand.js | ||
| object-method-shorthand.js | ||
| object-spread.js | ||
| ordinary-to-primitive.js | ||
| parseInt.js | ||
| parser-declaration-in-single-statement-context.js | ||
| parser-line-terminators.js | ||
| parser-unary-associativity.js | ||
| permanently-screwed-by-eval.js | ||
| program-non-strict.js | ||
| program-strict-mode.js | ||
| return.js | ||
| runtime-error-call-stack-size.js | ||
| statement-with-many-labels.js | ||
| strict-mode-blocks.js | ||
| strict-mode-errors.js | ||
| string-basic.js | ||
| string-concatenation.js | ||
| string-escapes.js | ||
| string-spread.js | ||
| switch-basic.js | ||
| switch-break.js | ||
| switch-default-before-case.js | ||
| tagged-template-literals.js | ||
| template-literals.js | ||
| test-common-tests.js | ||
| test-common.js | ||
| this-value-strict.js | ||
| this-value.js | ||
| throw-basic.js | ||
| to-number-basic.js | ||
| to-number-exception.js | ||
| try-catch-finally-nested.js | ||
| try-catch-finally-return.js | ||
| try-catch-finally.js | ||
| try-finally-break.js | ||
| try-finally-continue.js | ||
| unicode-identifier-escape.js | ||
| update-expression-on-member-expression.js | ||
| update-expressions-basic.js | ||
| use-strict-directive.js | ||
| using-declaration.js | ||
| using-for-loops.js | ||
| var-multiple-declarator.js | ||
| var-scoping.js | ||
| variable-undefined.js | ||
| with-basic.js | ||