fix(semantic): incorrect reference flag for MemberExpression assign (#2433)

fix: #2432
This commit is contained in:
Dunqing 2024-02-19 10:33:51 +08:00 committed by GitHub
parent daaea40d0e
commit 5bd2ce6ecf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 23 additions and 10 deletions

View file

@ -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![

View file

@ -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),
];

View file

@ -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

View file

@ -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()),