+22
-5
compiler-core/src/language_server/code_action.rs
+22
-5
compiler-core/src/language_server/code_action.rs
···
8503
8503
action
8504
8504
}
8505
8505
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
+
8506
8521
fn extract_expression(
8507
8522
&mut self,
8508
8523
expression: &TypedExpr,
···
8511
8526
) {
8512
8527
let expression_code = code_at(self.module, expression.location());
8513
8528
8529
+
let name = self.function_name();
8514
8530
let arguments = parameters.iter().map(|(name, _)| name).join(", ");
8515
-
let call = format!("function({arguments})");
8531
+
let call = format!("{name}({arguments})");
8516
8532
self.edits.replace(expression.location(), call);
8517
8533
8518
8534
let mut printer = Printer::new(&self.module.ast.names);
···
8524
8540
let return_type = printer.print_type(&expression.type_());
8525
8541
8526
8542
let function = format!(
8527
-
"\n\nfn function({parameters}) -> {return_type} {{
8543
+
"\n\nfn {name}({parameters}) -> {return_type} {{
8528
8544
{expression_code}
8529
8545
}}"
8530
8546
);
···
8564
8580
}
8565
8581
};
8566
8582
8583
+
let name = self.function_name();
8567
8584
let arguments = parameters.iter().map(|(name, _)| name).join(", ");
8568
8585
8569
8586
let call = if returns_anything {
8570
-
format!("let {return_value} = function({arguments})")
8587
+
format!("let {return_value} = {name}({arguments})")
8571
8588
} else {
8572
-
format!("function({arguments})")
8589
+
format!("{name}({arguments})")
8573
8590
};
8574
8591
self.edits.replace(location, call);
8575
8592
···
8583
8600
let return_type = printer.print_type(&return_type);
8584
8601
8585
8602
let function = format!(
8586
-
"\n\nfn function({parameters}) -> {return_type} {{
8603
+
"\n\nfn {name}({parameters}) -> {return_type} {{
8587
8604
{code}
8588
8605
{return_value}
8589
8606
}}"
+45
compiler-core/src/language_server/tests/action.rs
+45
compiler-core/src/language_server/tests/action.rs
···
10437
10437
.select_until(find_position_of("TEXT"))
10438
10438
);
10439
10439
}
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
+
}
+45
compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__action__extract_function_when_multiple_names_already_in_scope.snap
+45
compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__action__extract_function_when_multiple_names_already_in_scope.snap
···
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
+
}
+39
compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__action__extract_function_when_name_already_in_scope.snap
+39
compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__action__extract_function_when_name_already_in_scope.snap
···
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
+
}