mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
feat(semantic): check non-simple lhs expression of assignment expression (#994)
This commit is contained in:
parent
dc08a21207
commit
1661385c1a
4 changed files with 38 additions and 21 deletions
|
|
@ -807,6 +807,10 @@ pub enum AssignmentTarget<'a> {
|
|||
}
|
||||
|
||||
impl<'a> AssignmentTarget<'a> {
|
||||
pub fn is_simple(&self) -> bool {
|
||||
matches!(self, Self::SimpleAssignmentTarget(_))
|
||||
}
|
||||
|
||||
pub fn is_destructuring_pattern(&self) -> bool {
|
||||
matches!(self, Self::AssignmentTargetPattern(_))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use oxc_diagnostics::{
|
|||
use oxc_span::{Atom, GetSpan, ModuleKind, Span};
|
||||
use oxc_syntax::{
|
||||
module_record::ExportLocalName,
|
||||
operator::{BinaryOperator, LogicalOperator, UnaryOperator},
|
||||
operator::{AssignmentOperator, BinaryOperator, LogicalOperator, UnaryOperator},
|
||||
NumberBase,
|
||||
};
|
||||
use phf::{phf_set, Set};
|
||||
|
|
@ -65,12 +65,14 @@ impl EarlyErrorJavaScript {
|
|||
|
||||
AstKind::FormalParameters(params) => check_formal_parameters(params, node, ctx),
|
||||
AstKind::ArrayPattern(pat) => check_array_pattern(pat, ctx),
|
||||
AstKind::ObjectExpression(expr) => check_object_expression(expr, ctx),
|
||||
|
||||
AstKind::AssignmentExpression(expr) => check_assignment_expression(expr, ctx),
|
||||
AstKind::AwaitExpression(expr) => check_await_expression(expr, node, ctx),
|
||||
AstKind::BinaryExpression(expr) => check_binary_expression(expr, ctx),
|
||||
AstKind::LogicalExpression(expr) => check_logical_expression(expr, ctx),
|
||||
AstKind::MemberExpression(expr) => check_member_expression(expr, ctx),
|
||||
AstKind::ObjectExpression(expr) => check_object_expression(expr, ctx),
|
||||
AstKind::UnaryExpression(expr) => check_unary_expression(expr, node, ctx),
|
||||
AstKind::AwaitExpression(expr) => check_await_expression(expr, node, ctx),
|
||||
AstKind::YieldExpression(expr) => check_yield_expression(expr, node, ctx),
|
||||
_ => {}
|
||||
}
|
||||
|
|
@ -989,6 +991,22 @@ fn check_array_pattern(pattern: &ArrayPattern, ctx: &SemanticBuilder<'_>) {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_assignment_expression(assign_expr: &AssignmentExpression, ctx: &SemanticBuilder<'_>) {
|
||||
#[derive(Debug, Error, Diagnostic)]
|
||||
#[error("Invalid left-hand side in assignment")]
|
||||
#[diagnostic()]
|
||||
struct AssignmentIsNotSimple(#[label] Span);
|
||||
// AssignmentExpression :
|
||||
// LeftHandSideExpression AssignmentOperator AssignmentExpression
|
||||
// LeftHandSideExpression &&= AssignmentExpression
|
||||
// LeftHandSideExpression ||= AssignmentExpression
|
||||
// LeftHandSideExpression ??= AssignmentExpression
|
||||
// It is a Syntax Error if AssignmentTargetType of LeftHandSideExpression is not SIMPLE.
|
||||
if assign_expr.operator != AssignmentOperator::Assign && !assign_expr.left.is_simple() {
|
||||
ctx.error(AssignmentIsNotSimple(assign_expr.left.span()));
|
||||
}
|
||||
}
|
||||
|
||||
fn check_object_expression(obj_expr: &ObjectExpression, ctx: &SemanticBuilder<'_>) {
|
||||
// ObjectLiteral : { PropertyDefinitionList }
|
||||
// It is a Syntax Error if PropertyNameList of PropertyDefinitionList contains any duplicate entries for "__proto__"
|
||||
|
|
|
|||
|
|
@ -43,27 +43,17 @@ impl AssignmentOperator {
|
|||
matches!(self, Self::LogicalAnd | Self::LogicalOr | Self::LogicalNullish)
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub fn is_arithmetic(self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
Self::Addition
|
||||
| Self::Subtraction
|
||||
| Self::Multiplication
|
||||
| Self::Division
|
||||
| Self::Remainder
|
||||
| Self::Exponential
|
||||
matches!(self, Self::Addition | Self::Subtraction | Self::Multiplication
|
||||
| Self::Division | Self::Remainder | Self::Exponential
|
||||
)
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub fn is_bitwise(self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
Self::BitwiseOR
|
||||
| Self::BitwiseXOR
|
||||
| Self::BitwiseAnd
|
||||
| Self::ShiftLeft
|
||||
| Self::ShiftRight
|
||||
| Self::ShiftRightZeroFill
|
||||
matches!(self, Self::BitwiseOR | Self::BitwiseXOR | Self::BitwiseAnd
|
||||
| Self::ShiftLeft | Self::ShiftRight | Self::ShiftRightZeroFill
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
parser_babel Summary:
|
||||
AST Parsed : 2072/2078 (99.71%)
|
||||
Positive Passed: 2069/2078 (99.57%)
|
||||
Negative Passed: 1342/1507 (89.05%)
|
||||
Negative Passed: 1343/1507 (89.12%)
|
||||
Expect Syntax Error: "annex-b/disabled/1.1-html-comments-close/input.js"
|
||||
Expect Syntax Error: "annex-b/disabled/3.1-sloppy-labeled-functions/input.js"
|
||||
Expect Syntax Error: "annex-b/disabled/3.1-sloppy-labeled-functions-if-body/input.js"
|
||||
|
|
@ -24,7 +24,6 @@ Expect Syntax Error: "es2015/object/disallow-duplicate-method-params/input.js"
|
|||
Expect Syntax Error: "es2015/uncategorised/.191/input.js"
|
||||
Expect Syntax Error: "es2015/uncategorised/.335/input.js"
|
||||
Expect Syntax Error: "es2015/uncategorised/.343/input.js"
|
||||
Expect Syntax Error: "es2015/uncategorised/220/input.js"
|
||||
Expect Syntax Error: "es2015/uncategorised/297/input.js"
|
||||
Expect Syntax Error: "es2017/async-functions/await-binding-inside-arrow-params-inside-async-arrow-params/input.js"
|
||||
Expect Syntax Error: "es2017/trailing-function-commas/7/input.js"
|
||||
|
|
@ -3559,6 +3558,12 @@ Expect to Parse: "typescript/types/const-type-parameters-babel-7/input.ts"
|
|||
· ─────
|
||||
╰────
|
||||
|
||||
× Invalid left-hand side in assignment
|
||||
╭─[es2015/uncategorised/220/input.js:1:1]
|
||||
1 │ [v] += ary
|
||||
· ───
|
||||
╰────
|
||||
|
||||
× Cannot assign to this expression
|
||||
╭─[es2015/uncategorised/221/input.js:1:1]
|
||||
1 │ [2] = 42
|
||||
|
|
|
|||
Loading…
Reference in a new issue