fix(semantic): implicit return UpdateExpression in ArrowFunctionExpression does not as read reference (#5161)

close: #5158
close: #5156
This commit is contained in:
Dunqing 2024-08-26 03:30:16 +00:00
parent 04c5ca2ceb
commit 293413fe71
2 changed files with 67 additions and 1 deletions

View file

@ -2013,7 +2013,19 @@ impl<'a> SemanticBuilder<'a> {
for node in self.nodes.iter_parents(self.current_node_id).skip(1) {
return match node.kind() {
AstKind::ParenthesizedExpression(_) => continue,
AstKind::ExpressionStatement(_) => false,
AstKind::ExpressionStatement(_) => {
if self.current_scope_flags().is_arrow() {
if let Some(node) = self.nodes.iter_parents(node.id()).nth(2) {
// (x) => x++
// ^^^ implicit return, we need to treat `x` as a read reference
if matches!(node.kind(), AstKind::ArrowFunctionExpression(arrow) if arrow.expression)
{
return true;
}
}
}
false
}
_ => true,
};
}

View file

@ -372,3 +372,57 @@ fn test_ts_interface_heritage() {
.has_number_of_references(1)
.test();
}
#[test]
fn test_arrow_implicit_return() {
SemanticTester::js("let i = 0; const x = () => i")
.has_root_symbol("i")
.has_number_of_reads(1)
.has_number_of_writes(0)
.test();
SemanticTester::js("let i = 0; const x = () => ++i")
.has_root_symbol("i")
.has_number_of_reads(1)
.has_number_of_writes(1)
.test();
SemanticTester::js("let i = 0; const x = () => { ++i }")
.has_root_symbol("i")
.has_number_of_reads(0)
.has_number_of_writes(1)
.test();
SemanticTester::js("let i = 0; const x = () => (0, ++i)")
.has_root_symbol("i")
.has_number_of_reads(1)
.has_number_of_writes(1)
.test();
SemanticTester::js("let i = 0; const x = () => (++i, 0)")
.has_root_symbol("i")
.has_number_of_reads(1)
.has_number_of_writes(1)
.test();
SemanticTester::js("let i = 1; const foo = () => () => { i++ }")
.has_root_symbol("i")
.has_number_of_reads(0)
.has_number_of_writes(1)
.test();
}
#[test]
fn test_arrow_explicit_return() {
SemanticTester::js("let i = 0; const x = () => { return i }")
.has_root_symbol("i")
.has_number_of_reads(1)
.has_number_of_writes(0)
.test();
SemanticTester::js("let i = 0; const x = () => { return ++i }")
.has_root_symbol("i")
.has_number_of_reads(1)
.has_number_of_writes(1)
.test();
}