Skip to content

Commit 2dd3748

Browse files
GearsDatapackslpil
authored andcommitted
Don't make parameters of variables defined within the scope of the extracted function
1 parent 8f84282 commit 2dd3748

4 files changed

+113
-10
lines changed

compiler-core/src/language_server/code_action.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8505,7 +8505,7 @@ impl<'a> ExtractFunction<'a> {
85058505

85068506
let location = SrcSpan::new(first.location().start, last.location().end);
85078507

8508-
let referenced_variables = referenced_variables_for_statements(&statements);
8508+
let referenced_variables = referenced_variables_for_statements(&statements, location);
85098509

85108510
let code = code_at(self.module, location);
85118511

@@ -8582,15 +8582,16 @@ impl<'ast> ast::visit::Visit<'ast> for ExtractFunction<'ast> {
85828582
}
85838583

85848584
fn referenced_variables(expression: &TypedExpr) -> Vec<(EcoString, Arc<Type>)> {
8585-
let mut references = ReferencedVariables::new();
8585+
let mut references = ReferencedVariables::new(expression.location());
85868586
references.visit_typed_expr(expression);
85878587
references.variables
85888588
}
85898589

85908590
fn referenced_variables_for_statements(
85918591
statements: &[&TypedStatement],
8592+
location: SrcSpan,
85928593
) -> Vec<(EcoString, Arc<Type>)> {
8593-
let mut references = ReferencedVariables::new();
8594+
let mut references = ReferencedVariables::new(location);
85948595
for statement in statements {
85958596
references.visit_typed_statement(*statement);
85968597
}
@@ -8599,19 +8600,19 @@ fn referenced_variables_for_statements(
85998600

86008601
struct ReferencedVariables {
86018602
variables: Vec<(EcoString, Arc<Type>)>,
8602-
defined_variables: HashSet<EcoString>,
8603+
location: SrcSpan,
86038604
}
86048605

86058606
impl ReferencedVariables {
8606-
fn new() -> Self {
8607+
fn new(location: SrcSpan) -> Self {
86078608
Self {
86088609
variables: Vec::new(),
8609-
defined_variables: HashSet::new(),
8610+
location,
86108611
}
86118612
}
86128613

8613-
fn register(&mut self, name: &EcoString, type_: &Arc<Type>) {
8614-
if self.defined_variables.contains(name) {
8614+
fn register(&mut self, name: &EcoString, type_: &Arc<Type>, definition_location: SrcSpan) {
8615+
if self.location.contains_span(definition_location) {
86158616
return;
86168617
}
86178618

@@ -8633,8 +8634,8 @@ impl<'ast> ast::visit::Visit<'ast> for ReferencedVariables {
86338634
name: &'ast EcoString,
86348635
) {
86358636
match &constructor.variant {
8636-
type_::ValueConstructorVariant::LocalVariable { .. } => {
8637-
self.register(name, &constructor.type_);
8637+
type_::ValueConstructorVariant::LocalVariable { location, .. } => {
8638+
self.register(name, &constructor.type_, *location);
86388639
}
86398640
type_::ValueConstructorVariant::ModuleConstant { .. }
86408641
| type_::ValueConstructorVariant::LocalConstant { .. }

compiler-core/src/language_server/tests/action.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10264,3 +10264,38 @@ pub fn do_things(a, b) {
1026410264
find_position_of("let").select_until(find_position_of("* b\n").under_char('\n'))
1026510265
);
1026610266
}
10267+
10268+
#[test]
10269+
fn extract_function_which_use_variables_defined_in_the_extracted_span() {
10270+
assert_code_action!(
10271+
EXTRACT_FUNCTION,
10272+
"
10273+
pub fn do_things(a, b) {
10274+
let new_a = 10 + a
10275+
let new_b = 10 + b
10276+
let result = new_a * new_b
10277+
result + 3
10278+
}
10279+
",
10280+
find_position_of("let").select_until(find_position_of("* new_b\n").under_char('\n'))
10281+
);
10282+
}
10283+
10284+
#[test]
10285+
fn extract_function_which_use_variables_shadowed_in_an_inner_scope() {
10286+
assert_code_action!(
10287+
EXTRACT_FUNCTION,
10288+
"
10289+
pub fn do_things(a, b) {
10290+
let first_part = {
10291+
let a = a + 10
10292+
let b = b + 10
10293+
a * b
10294+
}
10295+
let result = first_part + a * b
10296+
result + 3
10297+
}
10298+
",
10299+
find_position_of("let").select_until(find_position_of("+ a * b\n").under_char('\n'))
10300+
);
10301+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
source: compiler-core/src/language_server/tests/action.rs
3+
expression: "\npub fn do_things(a, b) {\n let new_a = 10 + a\n let new_b = 10 + b\n let result = new_a * new_b\n result + 3\n}\n"
4+
---
5+
----- BEFORE ACTION
6+
7+
pub fn do_things(a, b) {
8+
let new_a = 10 + a
9+
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
10+
let new_b = 10 + b
11+
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
12+
let result = new_a * new_b
13+
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
14+
result + 3
15+
}
16+
17+
18+
----- AFTER ACTION
19+
20+
pub fn do_things(a, b) {
21+
function(a, b)
22+
result + 3
23+
}
24+
25+
fn function(a: Int, b: Int) -> Int {
26+
let new_a = 10 + a
27+
let new_b = 10 + b
28+
let result = new_a * new_b
29+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
source: compiler-core/src/language_server/tests/action.rs
3+
expression: "\npub fn do_things(a, b) {\n let first_part = {\n let a = a + 10\n let b = b + 10\n a * b\n }\n let result = first_part + a * b\n result + 3\n}\n"
4+
---
5+
----- BEFORE ACTION
6+
7+
pub fn do_things(a, b) {
8+
let first_part = {
9+
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
10+
let a = a + 10
11+
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
12+
let b = b + 10
13+
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
14+
a * b
15+
▔▔▔▔▔▔▔▔▔
16+
}
17+
▔▔▔
18+
let result = first_part + a * b
19+
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
20+
result + 3
21+
}
22+
23+
24+
----- AFTER ACTION
25+
26+
pub fn do_things(a, b) {
27+
function(a, b)
28+
result + 3
29+
}
30+
31+
fn function(a: Int, b: Int) -> Int {
32+
let first_part = {
33+
let a = a + 10
34+
let b = b + 10
35+
a * b
36+
}
37+
let result = first_part + a * b
38+
}

0 commit comments

Comments
 (0)