fix: disallow all parenthesized pattern except parsing LHS (#12327)
* fix: disallow all parenthesized pattern except parsing LHS * fix: forStatement requires LHS * simplify toAssignable * add more test cases * fix: pass through isLHS on object property and assignment expression * fix: record parenthesized identifier error for LHS * remove duplicated skipped tests * fix: do not record errors on ancestry arrow head * Update packages/babel-parser/src/util/expression-scope.js Co-authored-by: Brian Ng <bng412@gmail.com> Co-authored-by: Brian Ng <bng412@gmail.com>
This commit is contained in:
@@ -20,6 +20,7 @@ some expression scopes and thrown later when we know what the ambigous pattern i
|
||||
- AwaitBindingIdentifier
|
||||
- AwaitExpressionFormalParameter
|
||||
- YieldInParameter
|
||||
- InvalidParenthesizedAssignment when parenthesized is an identifier
|
||||
|
||||
There are four different expression scope
|
||||
- Expression
|
||||
@@ -130,6 +131,41 @@ export default class ExpressionScopeHandler {
|
||||
/* eslint-disable @babel/development-internal/dry-error-messages */
|
||||
this.raise(pos, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Record parenthesized identifier errors
|
||||
*
|
||||
* A parenthesized identifier in LHS can be ambiguous because the assignment
|
||||
* can be transformed to an assignable later, but not vice versa:
|
||||
* For example, in `([(a) = []] = []) => {}`, we think `(a) = []` is an LHS in `[(a) = []]`,
|
||||
* an LHS within `[(a) = []] = []`. However the LHS chain is then transformed by toAssignable,
|
||||
* and we should throw assignment `(a)`, which is only valid in LHS. Hence we record the
|
||||
* location of parenthesized `(a)` to current scope if it is one of MaybeArrowParameterDeclaration
|
||||
* and MaybeAsyncArrowParameterDeclaration
|
||||
*
|
||||
* Unlike `recordParameterInitializerError`, we don't record to ancestry scope because we
|
||||
* validate arrow head parsing scope before exit, and then the LHS will be unambiguous:
|
||||
* For example, in `( x = ( [(a) = []] = [] ) ) => {}`, we should not record `(a)` in `( x = ... ) =>`
|
||||
* arrow scope because when we finish parsing `( [(a) = []] = [] )`, it is an unambiguous assignment
|
||||
* expression and can not be cast to pattern
|
||||
* @param {number} pos
|
||||
* @param {string} message
|
||||
* @returns {void}
|
||||
* @memberof ExpressionScopeHandler
|
||||
*/
|
||||
recordParenthesizedIdentifierError(pos: number, message: string): void {
|
||||
const { stack } = this;
|
||||
const scope: ExpressionScope = stack[stack.length - 1];
|
||||
if (scope.isCertainlyParameterDeclaration()) {
|
||||
this.raise(pos, message);
|
||||
} else if (scope.canBeArrowParameterDeclaration()) {
|
||||
/*:: invariant(scope instanceof ArrowHeadParsingScope) */
|
||||
scope.recordDeclarationError(pos, message);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Record likely async arrow parameter errors
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user