Skip to content

Commit b8e634c

Browse files
GearsDatapackslpil
authored andcommitted
Prevent duplicate naming
1 parent c1073bc commit b8e634c

4 files changed

+151
-5
lines changed

compiler-core/src/language_server/code_action.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8503,6 +8503,21 @@ impl<'a> ExtractFunction<'a> {
85038503
action
85048504
}
85058505

8506+
fn function_name(&self) -> EcoString {
8507+
if !self.module.ast.type_info.values.contains_key("function") {
8508+
return "function".into();
8509+
}
8510+
8511+
let mut number = 2;
8512+
loop {
8513+
let name = eco_format!("function_{number}");
8514+
if !self.module.ast.type_info.values.contains_key(&name) {
8515+
return name;
8516+
}
8517+
number += 1;
8518+
}
8519+
}
8520+
85068521
fn extract_expression(
85078522
&mut self,
85088523
expression: &TypedExpr,
@@ -8511,8 +8526,9 @@ impl<'a> ExtractFunction<'a> {
85118526
) {
85128527
let expression_code = code_at(self.module, expression.location());
85138528

8529+
let name = self.function_name();
85148530
let arguments = parameters.iter().map(|(name, _)| name).join(", ");
8515-
let call = format!("function({arguments})");
8531+
let call = format!("{name}({arguments})");
85168532
self.edits.replace(expression.location(), call);
85178533

85188534
let mut printer = Printer::new(&self.module.ast.names);
@@ -8524,7 +8540,7 @@ impl<'a> ExtractFunction<'a> {
85248540
let return_type = printer.print_type(&expression.type_());
85258541

85268542
let function = format!(
8527-
"\n\nfn function({parameters}) -> {return_type} {{
8543+
"\n\nfn {name}({parameters}) -> {return_type} {{
85288544
{expression_code}
85298545
}}"
85308546
);
@@ -8564,12 +8580,13 @@ impl<'a> ExtractFunction<'a> {
85648580
}
85658581
};
85668582

8583+
let name = self.function_name();
85678584
let arguments = parameters.iter().map(|(name, _)| name).join(", ");
85688585

85698586
let call = if returns_anything {
8570-
format!("let {return_value} = function({arguments})")
8587+
format!("let {return_value} = {name}({arguments})")
85718588
} else {
8572-
format!("function({arguments})")
8589+
format!("{name}({arguments})")
85738590
};
85748591
self.edits.replace(location, call);
85758592

@@ -8583,7 +8600,7 @@ impl<'a> ExtractFunction<'a> {
85838600
let return_type = printer.print_type(&return_type);
85848601

85858602
let function = format!(
8586-
"\n\nfn function({parameters}) -> {return_type} {{
8603+
"\n\nfn {name}({parameters}) -> {return_type} {{
85878604
{code}
85888605
{return_value}
85898606
}}"

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

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10437,3 +10437,48 @@ pub fn main() {
1043710437
.select_until(find_position_of("TEXT"))
1043810438
);
1043910439
}
10440+
10441+
#[test]
10442+
fn extract_function_when_name_already_in_scope() {
10443+
assert_code_action!(
10444+
EXTRACT_FUNCTION,
10445+
r#"
10446+
fn function() { todo }
10447+
10448+
pub fn do_things(a, b) {
10449+
let result = {
10450+
let a = 10 + a
10451+
let b = 10 + b
10452+
a * b
10453+
}
10454+
result + 3
10455+
}
10456+
"#,
10457+
find_position_of("= {")
10458+
.select_until(find_position_of("}\n").nth_occurrence(2).under_char('\n'))
10459+
);
10460+
}
10461+
10462+
#[test]
10463+
fn extract_function_when_multiple_names_already_in_scope() {
10464+
assert_code_action!(
10465+
EXTRACT_FUNCTION,
10466+
r#"
10467+
fn function() { todo }
10468+
fn function_2() { todo }
10469+
fn function_3() { todo }
10470+
fn function_4() { todo }
10471+
10472+
pub fn do_things(a, b) {
10473+
let result = {
10474+
let a = 10 + a
10475+
let b = 10 + b
10476+
a * b
10477+
}
10478+
result + 3
10479+
}
10480+
"#,
10481+
find_position_of("= {")
10482+
.select_until(find_position_of("}\n").nth_occurrence(5).under_char('\n'))
10483+
);
10484+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
source: compiler-core/src/language_server/tests/action.rs
3+
expression: "\nfn function() { todo }\nfn function_2() { todo }\nfn function_3() { todo }\nfn function_4() { todo }\n\npub fn do_things(a, b) {\n let result = {\n let a = 10 + a\n let b = 10 + b\n a * b\n }\n result + 3\n}\n"
4+
---
5+
----- BEFORE ACTION
6+
7+
fn function() { todo }
8+
fn function_2() { todo }
9+
fn function_3() { todo }
10+
fn function_4() { todo }
11+
12+
pub fn do_things(a, b) {
13+
let result = {
14+
▔▔▔
15+
let a = 10 + a
16+
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
17+
let b = 10 + b
18+
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
19+
a * b
20+
▔▔▔▔▔▔▔▔▔
21+
}
22+
▔▔▔
23+
result + 3
24+
}
25+
26+
27+
----- AFTER ACTION
28+
29+
fn function() { todo }
30+
fn function_2() { todo }
31+
fn function_3() { todo }
32+
fn function_4() { todo }
33+
34+
pub fn do_things(a, b) {
35+
let result = function_5(a, b)
36+
result + 3
37+
}
38+
39+
fn function_5(a: Int, b: Int) -> Int {
40+
{
41+
let a = 10 + a
42+
let b = 10 + b
43+
a * b
44+
}
45+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
source: compiler-core/src/language_server/tests/action.rs
3+
expression: "\nfn function() { todo }\n\npub fn do_things(a, b) {\n let result = {\n let a = 10 + a\n let b = 10 + b\n a * b\n }\n result + 3\n}\n"
4+
---
5+
----- BEFORE ACTION
6+
7+
fn function() { todo }
8+
9+
pub fn do_things(a, b) {
10+
let result = {
11+
▔▔▔
12+
let a = 10 + a
13+
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
14+
let b = 10 + b
15+
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
16+
a * b
17+
▔▔▔▔▔▔▔▔▔
18+
}
19+
▔▔▔
20+
result + 3
21+
}
22+
23+
24+
----- AFTER ACTION
25+
26+
fn function() { todo }
27+
28+
pub fn do_things(a, b) {
29+
let result = function_2(a, b)
30+
result + 3
31+
}
32+
33+
fn function_2(a: Int, b: Int) -> Int {
34+
{
35+
let a = 10 + a
36+
let b = 10 + b
37+
a * b
38+
}
39+
}

0 commit comments

Comments
 (0)