mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
fix(semantic): incorrect reference flag for MemberExpression assign (#2433)
fix: #2432
This commit is contained in:
parent
daaea40d0e
commit
5bd2ce6ecf
4 changed files with 23 additions and 10 deletions
|
|
@ -72,6 +72,7 @@ fn test() {
|
|||
("class X {} X = 1;", None),
|
||||
("try {} catch (x) { x = 1; }", None),
|
||||
("const a = 1; { let a = 2; { a += 1; } }", None),
|
||||
("const foo = 1;let bar;bar[foo ?? foo] = 42;", None),
|
||||
];
|
||||
|
||||
let fail = vec![
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ fn test() {
|
|||
("top = 0;", None),
|
||||
// ("onload = 0;", None), // env: { browser: true }
|
||||
("require = 0;", None),
|
||||
("window[parseInt('42', 10)] = 99;", None),
|
||||
// ("a = 1", None), // globals: { a: true } },
|
||||
// ("/*global a:true*/ a = 1", None),
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1731,12 +1731,15 @@ impl<'a> SemanticBuilder<'a> {
|
|||
self.current_reference_flag |= ReferenceFlag::Write;
|
||||
}
|
||||
AstKind::AssignmentExpression(expr) => {
|
||||
if self.is_not_expression_statement_parent()
|
||||
|| expr.operator != AssignmentOperator::Assign
|
||||
if expr.operator != AssignmentOperator::Assign
|
||||
|| self.is_not_expression_statement_parent()
|
||||
{
|
||||
self.current_reference_flag |= ReferenceFlag::Read;
|
||||
}
|
||||
}
|
||||
AstKind::MemberExpression(_) => {
|
||||
self.current_reference_flag = ReferenceFlag::Read;
|
||||
}
|
||||
AstKind::AssignmentTarget(_) => {
|
||||
self.current_reference_flag |= ReferenceFlag::Write;
|
||||
}
|
||||
|
|
@ -1798,8 +1801,8 @@ impl<'a> SemanticBuilder<'a> {
|
|||
self.current_reference_flag -= ReferenceFlag::Write;
|
||||
}
|
||||
AstKind::AssignmentExpression(expr) => {
|
||||
if self.is_not_expression_statement_parent()
|
||||
|| expr.operator != AssignmentOperator::Assign
|
||||
if expr.operator != AssignmentOperator::Assign
|
||||
|| self.is_not_expression_statement_parent()
|
||||
{
|
||||
self.current_reference_flag -= ReferenceFlag::Read;
|
||||
}
|
||||
|
|
@ -1834,12 +1837,7 @@ impl<'a> SemanticBuilder<'a> {
|
|||
fn resolve_reference_usages(&self) -> ReferenceFlag {
|
||||
if self.in_type_definition {
|
||||
ReferenceFlag::Type
|
||||
} else if self.current_reference_flag.is_write()
|
||||
&& !matches!(
|
||||
self.nodes.parent_kind(self.current_node_id),
|
||||
Some(AstKind::MemberExpression(_))
|
||||
)
|
||||
{
|
||||
} else if self.current_reference_flag.is_write() {
|
||||
self.current_reference_flag
|
||||
} else {
|
||||
ReferenceFlag::Read
|
||||
|
|
|
|||
|
|
@ -327,6 +327,19 @@ mod tests {
|
|||
"let a; function foo(a) { return a }; foo(a = 1)",
|
||||
ReferenceFlag::read_write(),
|
||||
),
|
||||
// member expression
|
||||
(SourceType::default(), "let a; a.b = 1", ReferenceFlag::read()),
|
||||
(SourceType::default(), "let a; let b; b[a += 1] = 1", ReferenceFlag::read_write()),
|
||||
(
|
||||
SourceType::default(),
|
||||
"let a; let b; let c; b[c[a = c['a']] = 'c'] = 'b'",
|
||||
ReferenceFlag::read_write(),
|
||||
),
|
||||
(
|
||||
SourceType::default(),
|
||||
"let a; let b; let c; a[c[b = c['a']] = 'c'] = 'b'",
|
||||
ReferenceFlag::read(),
|
||||
),
|
||||
// typescript
|
||||
(typescript, "let a: number = 1; (a as any) = true", ReferenceFlag::write()),
|
||||
(typescript, "let a: number = 1; a = true as any", ReferenceFlag::write()),
|
||||
|
|
|
|||
Loading…
Reference in a new issue