From 7d95d38ecb9b197721e2533ba98afbc2f91610d0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 29 Aug 2018 18:35:28 +0300 Subject: fix join lines selection --- crates/libanalysis/tests/tests.rs | 30 +++++++++------- crates/libeditor/src/code_actions.rs | 1 - crates/libeditor/src/edit.rs | 12 ++++--- crates/libeditor/src/typing.rs | 69 ++++++++++++++++-------------------- 4 files changed, 54 insertions(+), 58 deletions(-) (limited to 'crates') diff --git a/crates/libanalysis/tests/tests.rs b/crates/libanalysis/tests/tests.rs index e05aa8895..5893efaf6 100644 --- a/crates/libanalysis/tests/tests.rs +++ b/crates/libanalysis/tests/tests.rs @@ -41,23 +41,21 @@ fn test_resolve_module() { world.change_file(FileId(1), Some("mod foo;".to_string())); world.change_file(FileId(2), Some("".to_string())); - let snap = world.snapshot(FileMap(&[ + let snap = world.analysis(FileMap(&[ (1, "/lib.rs"), (2, "/foo.rs"), ])); - let symbols = snap.approximately_resolve_symbol(FileId(1), 4.into()) - .unwrap(); + let symbols = snap.approximately_resolve_symbol(FileId(1), 4.into()); assert_eq_dbg( r#"[(FileId(2), FileSymbol { name: "foo", node_range: [0; 0), kind: MODULE })]"#, &symbols, ); - let snap = world.snapshot(FileMap(&[ + let snap = world.analysis(FileMap(&[ (1, "/lib.rs"), (2, "/foo/mod.rs") ])); - let symbols = snap.approximately_resolve_symbol(FileId(1), 4.into()) - .unwrap(); + let symbols = snap.approximately_resolve_symbol(FileId(1), 4.into()); assert_eq_dbg( r#"[(FileId(2), FileSymbol { name: "foo", node_range: [0; 0), kind: MODULE })]"#, &symbols, @@ -69,11 +67,17 @@ fn test_unresolved_module_diagnostic() { let mut world = WorldState::new(); world.change_file(FileId(1), Some("mod foo;".to_string())); - let snap = world.snapshot(FileMap(&[(1, "/lib.rs")])); - let diagnostics = snap.diagnostics(FileId(1)).unwrap(); + let snap = world.analysis(FileMap(&[(1, "/lib.rs")])); + let diagnostics = snap.diagnostics(FileId(1)); assert_eq_dbg( - r#"[(Diagnostic { range: [4; 7), msg: "unresolved module" }, - Some(QuickFix { fs_ops: [CreateFile { anchor: FileId(1), path: "../foo.rs" }] }))]"#, + r#"[Diagnostic { + message: "unresolved module", + range: [4; 7), + fix: Some(SourceChange { + label: "create module", + source_file_edits: [], + file_system_edits: [CreateFile { anchor: FileId(1), path: "../foo.rs" }], + cursor_position: None }) }]"#, &diagnostics, ); } @@ -83,8 +87,8 @@ fn test_unresolved_module_diagnostic_no_diag_for_inline_mode() { let mut world = WorldState::new(); world.change_file(FileId(1), Some("mod foo {}".to_string())); - let snap = world.snapshot(FileMap(&[(1, "/lib.rs")])); - let diagnostics = snap.diagnostics(FileId(1)).unwrap(); + let snap = world.analysis(FileMap(&[(1, "/lib.rs")])); + let diagnostics = snap.diagnostics(FileId(1)); assert_eq_dbg( r#"[]"#, &diagnostics, @@ -97,7 +101,7 @@ fn test_resolve_parent_module() { world.change_file(FileId(1), Some("mod foo;".to_string())); world.change_file(FileId(2), Some("".to_string())); - let snap = world.snapshot(FileMap(&[ + let snap = world.analysis(FileMap(&[ (1, "/lib.rs"), (2, "/foo.rs"), ])); diff --git a/crates/libeditor/src/code_actions.rs b/crates/libeditor/src/code_actions.rs index dadbd63ab..522b605ed 100644 --- a/crates/libeditor/src/code_actions.rs +++ b/crates/libeditor/src/code_actions.rs @@ -13,7 +13,6 @@ use libsyntax2::{ use {EditBuilder, Edit, find_node_at_offset}; -// TODO: rename to FileEdit #[derive(Debug)] pub struct LocalEdit { pub edit: Edit, diff --git a/crates/libeditor/src/edit.rs b/crates/libeditor/src/edit.rs index dcf1ee81e..09cf2bd00 100644 --- a/crates/libeditor/src/edit.rs +++ b/crates/libeditor/src/edit.rs @@ -1,5 +1,8 @@ use {TextRange, TextUnit}; -use libsyntax2::AtomEdit; +use libsyntax2::{ + AtomEdit, + text_utils::contains_offset_nonstrict, +}; #[derive(Debug, Clone)] pub struct Edit { @@ -15,19 +18,15 @@ impl EditBuilder { pub fn new() -> EditBuilder { EditBuilder { atoms: Vec::new() } } - pub fn replace(&mut self, range: TextRange, replace_with: String) { self.atoms.push(AtomEdit::replace(range, replace_with)) } - pub fn delete(&mut self, range: TextRange) { self.atoms.push(AtomEdit::delete(range)) } - pub fn insert(&mut self, offset: TextUnit, text: String) { self.atoms.push(AtomEdit::insert(offset, text)) } - pub fn finish(self) -> Edit { let mut atoms = self.atoms; atoms.sort_by_key(|a| a.delete.start()); @@ -36,6 +35,9 @@ impl EditBuilder { } Edit { atoms } } + pub fn invalidates_offset(&self, offset: TextUnit) -> bool { + self.atoms.iter().any(|atom| contains_offset_nonstrict(atom.delete, offset)) + } } impl Edit { diff --git a/crates/libeditor/src/typing.rs b/crates/libeditor/src/typing.rs index f888f3240..826b16181 100644 --- a/crates/libeditor/src/typing.rs +++ b/crates/libeditor/src/typing.rs @@ -45,10 +45,11 @@ pub fn join_lines(file: &File, range: TextRange) -> LocalEdit { for (pos, _) in text[range].bytes().enumerate().filter(|&(_, b)| b == b'\n') { let pos: TextUnit = (pos as u32).into(); let off = node.range().start() + range.start() + pos; - remove_newline(&mut edit, node, text.as_str(), off); + if !edit.invalidates_offset(off) { + remove_newline(&mut edit, node, text.as_str(), off); + } } } - eprintln!("{:?}", edit); LocalEdit { edit: edit.finish(), @@ -239,17 +240,17 @@ fn foo() { }"); } - #[test] - fn test_join_lines_selection() { - fn do_check(before: &str, after: &str) { - let (sel, before) = extract_range(before); - let file = File::parse(&before); - let result = join_lines(&file, sel); - let actual = result.edit.apply(&before); - assert_eq_text!(after, &actual); - } + fn check_join_lines_sel(before: &str, after: &str) { + let (sel, before) = extract_range(before); + let file = File::parse(&before); + let result = join_lines(&file, sel); + let actual = result.edit.apply(&before); + assert_eq_text!(after, &actual); + } - do_check(r" + #[test] + fn test_join_lines_selection_fn_args() { + check_join_lines_sel(r" fn foo() { <|>foo(1, 2, @@ -261,15 +262,22 @@ fn foo() { foo(1, 2, 3) } "); + } - do_check(r" + #[test] + fn test_join_lines_selection_struct() { + check_join_lines_sel(r" struct Foo <|>{ f: u32, }<|> ", r" struct Foo { f: u32 } "); - do_check(r" + } + + #[test] + fn test_join_lines_selection_dot_chain() { + check_join_lines_sel(r" fn foo() { join(<|>type_params.type_params() .filter_map(|it| it.name()) @@ -278,39 +286,22 @@ fn foo() { fn foo() { join(type_params.type_params().filter_map(|it| it.name()).map(|it| it.text())) }"); + } - do_check(r" -pub fn handle_find_matching_brace( - world: ServerWorld, - params: req::FindMatchingBraceParams, -) -> Result> { - let file_id = params.text_document.try_conv_with(&world)?; - let file = world.analysis().file_syntax(file_id); - let line_index = world.analysis().file_line_index(file_id); - let res = params.offsets - .into_iter() - .map_conv_with(&line_index) + #[test] + fn test_join_lines_selection_lambda_block_body() { + check_join_lines_sel(r" +pub fn handle_find_matching_brace() { + params.offsets .map(|offset| <|>{ world.analysis().matching_brace(&file, offset).unwrap_or(offset) }<|>) - .map_conv_with(&line_index) .collect(); - Ok(res) }", r" -pub fn handle_find_matching_brace( - world: ServerWorld, - params: req::FindMatchingBraceParams, -) -> Result> { - let file_id = params.text_document.try_conv_with(&world)?; - let file = world.analysis().file_syntax(file_id); - let line_index = world.analysis().file_line_index(file_id); - let res = params.offsets - .into_iter() - .map_conv_with(&line_index) +pub fn handle_find_matching_brace() { + params.offsets .map(|offset| world.analysis().matching_brace(&file, offset).unwrap_or(offset)) - .map_conv_with(&line_index) .collect(); - Ok(res) }"); } -- cgit v1.2.3