aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2018-12-30 20:43:58 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2018-12-30 20:43:58 +0000
commitacc61cc28461b72e8a03869b0ad60c144b4b3b20 (patch)
tree72d9523c52aca48aac9dd8c5524bb044f547002b /crates
parentf9b58454a43274d3b1d4d0e74cdef597b75f9a97 (diff)
parent872950bc188ba104ecd1f532427dea6dc52533bd (diff)
Merge #375
375: Move renames into ra_analysis and rename the correct range r=DJMcNab a=DJMcNab Fixes #230. Supersedes #235. TODO: add some tests for this Co-authored-by: DJMcNab <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_analysis/src/imp.rs26
-rw-r--r--crates/ra_analysis/src/lib.rs7
-rw-r--r--crates/ra_analysis/tests/tests.rs93
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs21
4 files changed, 131 insertions, 16 deletions
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs
index bff2e00c9..5ed374c79 100644
--- a/crates/ra_analysis/src/imp.rs
+++ b/crates/ra_analysis/src/imp.rs
@@ -288,7 +288,11 @@ impl AnalysisImpl {
288 Some(it) => it, 288 Some(it) => it,
289 }; 289 };
290 290
291 let mut ret = vec![(position.file_id, binding.syntax().range())]; 291 let mut ret = binding
292 .name()
293 .into_iter()
294 .map(|name| (position.file_id, name.syntax().range()))
295 .collect::<Vec<_>>();
292 ret.extend( 296 ret.extend(
293 descr 297 descr
294 .scopes(&*self.db) 298 .scopes(&*self.db)
@@ -505,7 +509,25 @@ impl AnalysisImpl {
505 let infer = function.infer(&*self.db)?; 509 let infer = function.infer(&*self.db)?;
506 Ok(infer.type_of_node(node).map(|t| t.to_string())) 510 Ok(infer.type_of_node(node).map(|t| t.to_string()))
507 } 511 }
508 512 pub fn rename(
513 &self,
514 position: FilePosition,
515 new_name: &str,
516 ) -> Cancelable<Vec<SourceFileEdit>> {
517 let res = self
518 .find_all_refs(position)?
519 .iter()
520 .map(|(file_id, text_range)| SourceFileEdit {
521 file_id: *file_id,
522 edit: {
523 let mut builder = ra_text_edit::TextEditBuilder::new();
524 builder.replace(*text_range, new_name.into());
525 builder.finish()
526 },
527 })
528 .collect::<Vec<_>>();
529 Ok(res)
530 }
509 fn index_resolve(&self, name_ref: ast::NameRef) -> Cancelable<Vec<(FileId, FileSymbol)>> { 531 fn index_resolve(&self, name_ref: ast::NameRef) -> Cancelable<Vec<(FileId, FileSymbol)>> {
510 let name = name_ref.text(); 532 let name = name_ref.text();
511 let mut query = Query::new(name.to_string()); 533 let mut query = Query::new(name.to_string());
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs
index 9f5e9f358..e56168510 100644
--- a/crates/ra_analysis/src/lib.rs
+++ b/crates/ra_analysis/src/lib.rs
@@ -367,6 +367,13 @@ impl Analysis {
367 pub fn type_of(&self, frange: FileRange) -> Cancelable<Option<String>> { 367 pub fn type_of(&self, frange: FileRange) -> Cancelable<Option<String>> {
368 self.imp.type_of(frange) 368 self.imp.type_of(frange)
369 } 369 }
370 pub fn rename(
371 &self,
372 position: FilePosition,
373 new_name: &str,
374 ) -> Cancelable<Vec<SourceFileEdit>> {
375 self.imp.rename(position, new_name)
376 }
370} 377}
371 378
372pub struct LibraryData { 379pub struct LibraryData {
diff --git a/crates/ra_analysis/tests/tests.rs b/crates/ra_analysis/tests/tests.rs
index 210fa2a13..a314fbc40 100644
--- a/crates/ra_analysis/tests/tests.rs
+++ b/crates/ra_analysis/tests/tests.rs
@@ -1,5 +1,5 @@
1use ra_syntax::TextRange; 1use ra_syntax::TextRange;
2use test_utils::assert_eq_dbg; 2use test_utils::{assert_eq_dbg, assert_eq_text};
3 3
4use ra_analysis::{ 4use ra_analysis::{
5 mock_analysis::{analysis_and_position, single_file, single_file_with_position, MockAnalysis}, 5 mock_analysis::{analysis_and_position, single_file, single_file_with_position, MockAnalysis},
@@ -453,3 +453,94 @@ fn test_find_all_refs_for_fn_param() {
453 let refs = get_all_refs(code); 453 let refs = get_all_refs(code);
454 assert_eq!(refs.len(), 2); 454 assert_eq!(refs.len(), 2);
455} 455}
456#[test]
457fn test_rename_for_local() {
458 test_rename(
459 r#"
460 fn main() {
461 let mut i = 1;
462 let j = 1;
463 i = i<|> + j;
464
465 {
466 i = 0;
467 }
468
469 i = 5;
470 }"#,
471 "k",
472 r#"
473 fn main() {
474 let mut k = 1;
475 let j = 1;
476 k = k + j;
477
478 {
479 k = 0;
480 }
481
482 k = 5;
483 }"#,
484 );
485}
486
487#[test]
488fn test_rename_for_param_inside() {
489 test_rename(
490 r#"
491 fn foo(i : u32) -> u32 {
492 i<|>
493 }"#,
494 "j",
495 r#"
496 fn foo(j : u32) -> u32 {
497 j
498 }"#,
499 );
500}
501
502#[test]
503fn test_rename_refs_for_fn_param() {
504 test_rename(
505 r#"
506 fn foo(i<|> : u32) -> u32 {
507 i
508 }"#,
509 "new_name",
510 r#"
511 fn foo(new_name : u32) -> u32 {
512 new_name
513 }"#,
514 );
515}
516
517#[test]
518fn test_rename_for_mut_param() {
519 test_rename(
520 r#"
521 fn foo(mut i<|> : u32) -> u32 {
522 i
523 }"#,
524 "new_name",
525 r#"
526 fn foo(mut new_name : u32) -> u32 {
527 new_name
528 }"#,
529 );
530}
531fn test_rename(text: &str, new_name: &str, expected: &str) {
532 let (analysis, position) = single_file_with_position(text);
533 let edits = analysis.rename(position, new_name).unwrap();
534 let mut text_edit_bulder = ra_text_edit::TextEditBuilder::new();
535 let mut file_id: Option<FileId> = None;
536 for edit in edits {
537 file_id = Some(edit.file_id);
538 for atom in edit.edit.as_atoms() {
539 text_edit_bulder.replace(atom.delete, atom.insert.clone());
540 }
541 }
542 let result = text_edit_bulder
543 .finish()
544 .apply(&*analysis.file_text(file_id.unwrap()));
545 assert_eq_text!(expected, &*result);
546}
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index a2c12a4c1..3b7a14a5c 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -557,24 +557,19 @@ pub fn handle_rename(world: ServerWorld, params: RenameParams) -> Result<Option<
557 .into()); 557 .into());
558 } 558 }
559 559
560 let refs = world 560 let renames = world
561 .analysis() 561 .analysis()
562 .find_all_refs(FilePosition { file_id, offset })?; 562 .rename(FilePosition { file_id, offset }, &*params.new_name)?;
563 if refs.is_empty() { 563 if renames.is_empty() {
564 return Ok(None); 564 return Ok(None);
565 } 565 }
566 566
567 let mut changes = HashMap::new(); 567 let mut changes = HashMap::new();
568 for r in refs { 568 for edit in renames {
569 if let Ok(loc) = to_location(r.0, r.1, &world, &line_index) { 569 changes
570 changes 570 .entry(file_id.try_conv_with(&world)?)
571 .entry(loc.uri) 571 .or_insert_with(Vec::new)
572 .or_insert_with(Vec::new) 572 .extend(edit.edit.conv_with(&line_index));
573 .push(TextEdit {
574 range: loc.range,
575 new_text: params.new_name.clone(),
576 });
577 }
578 } 573 }
579 574
580 Ok(Some(WorkspaceEdit { 575 Ok(Some(WorkspaceEdit {