this repo has no description

Implement extract function for statements also

authored by gearsco.de and committed by

Louis Pilfold 8f842821 b6398fd8

+95 -5
+50 -5
compiler-core/src/language_server/code_action.rs
··· 8496 8496 } 8497 8497 8498 8498 fn extract_statements(&mut self, statements: Vec<&TypedStatement>, function_end: u32) { 8499 - todo!("Implement for statements") 8499 + let Some(first) = statements.first() else { 8500 + return; 8501 + }; 8502 + let Some(last) = statements.last() else { 8503 + return; 8504 + }; 8505 + 8506 + let location = SrcSpan::new(first.location().start, last.location().end); 8507 + 8508 + let referenced_variables = referenced_variables_for_statements(&statements); 8509 + 8510 + let code = code_at(self.module, location); 8511 + 8512 + let arguments = referenced_variables.iter().map(|(name, _)| name).join(", "); 8513 + let call = format!("function({arguments})"); 8514 + self.edits.replace(location, call); 8515 + 8516 + let mut printer = Printer::new(&self.module.ast.names); 8517 + 8518 + let parameters = referenced_variables 8519 + .iter() 8520 + .map(|(name, type_)| eco_format!("{name}: {}", printer.print_type(type_))) 8521 + .join(", "); 8522 + let return_type = printer.print_type(&last.type_()); 8523 + 8524 + let function = format!( 8525 + "\n\nfn function({parameters}) -> {return_type} {{ 8526 + {code} 8527 + }}" 8528 + ); 8529 + 8530 + self.edits.insert(function_end, function); 8500 8531 } 8501 8532 } 8502 8533 ··· 8551 8582 } 8552 8583 8553 8584 fn referenced_variables(expression: &TypedExpr) -> Vec<(EcoString, Arc<Type>)> { 8554 - let mut references = ReferencedVariables { 8555 - variables: Vec::new(), 8556 - defined_variables: HashSet::new(), 8557 - }; 8585 + let mut references = ReferencedVariables::new(); 8558 8586 references.visit_typed_expr(expression); 8559 8587 references.variables 8560 8588 } 8561 8589 8590 + fn referenced_variables_for_statements( 8591 + statements: &[&TypedStatement], 8592 + ) -> Vec<(EcoString, Arc<Type>)> { 8593 + let mut references = ReferencedVariables::new(); 8594 + for statement in statements { 8595 + references.visit_typed_statement(*statement); 8596 + } 8597 + references.variables 8598 + } 8599 + 8562 8600 struct ReferencedVariables { 8563 8601 variables: Vec<(EcoString, Arc<Type>)>, 8564 8602 defined_variables: HashSet<EcoString>, 8565 8603 } 8566 8604 8567 8605 impl ReferencedVariables { 8606 + fn new() -> Self { 8607 + Self { 8608 + variables: Vec::new(), 8609 + defined_variables: HashSet::new(), 8610 + } 8611 + } 8612 + 8568 8613 fn register(&mut self, name: &EcoString, type_: &Arc<Type>) { 8569 8614 if self.defined_variables.contains(name) { 8570 8615 return;
+16
compiler-core/src/language_server/tests/action.rs
··· 10248 10248 .select_until(find_position_of("}\n").under_char('\n')) 10249 10249 ); 10250 10250 } 10251 + 10252 + #[test] 10253 + fn extract_function_from_statements() { 10254 + assert_code_action!( 10255 + EXTRACT_FUNCTION, 10256 + " 10257 + pub fn do_things(a, b) { 10258 + let a = 10 + a 10259 + let b = 10 + b 10260 + let result = a * b 10261 + result + 3 10262 + } 10263 + ", 10264 + find_position_of("let").select_until(find_position_of("* b\n").under_char('\n')) 10265 + ); 10266 + }
+29
compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__action__extract_function_from_statements.snap
··· 1 + --- 2 + source: compiler-core/src/language_server/tests/action.rs 3 + expression: "\npub fn do_things(a, b) {\n let a = 10 + a\n let b = 10 + b\n let result = a * b\n result + 3\n}\n" 4 + --- 5 + ----- BEFORE ACTION 6 + 7 + pub fn do_things(a, b) { 8 + let a = 10 + a 9 + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔ 10 + let b = 10 + b 11 + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ 12 + let result = a * 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 a = 10 + a 27 + let b = 10 + b 28 + let result = a * b 29 + }