aboutsummaryrefslogtreecommitdiff
path: root/crates/assists
diff options
context:
space:
mode:
Diffstat (limited to 'crates/assists')
-rw-r--r--crates/assists/src/assist_context.rs14
-rw-r--r--crates/assists/src/tests.rs60
2 files changed, 59 insertions, 15 deletions
diff --git a/crates/assists/src/assist_context.rs b/crates/assists/src/assist_context.rs
index 69499ea32..cd22cf17d 100644
--- a/crates/assists/src/assist_context.rs
+++ b/crates/assists/src/assist_context.rs
@@ -4,10 +4,10 @@ use std::mem;
4 4
5use algo::find_covering_element; 5use algo::find_covering_element;
6use hir::Semantics; 6use hir::Semantics;
7use ide_db::base_db::{FileId, FileRange}; 7use ide_db::base_db::{AnchoredPathBuf, FileId, FileRange};
8use ide_db::{ 8use ide_db::{
9 label::Label, 9 label::Label,
10 source_change::{SourceChange, SourceFileEdit}, 10 source_change::{FileSystemEdit, SourceChange, SourceFileEdit},
11 RootDatabase, 11 RootDatabase,
12}; 12};
13use syntax::{ 13use syntax::{
@@ -209,6 +209,7 @@ pub(crate) struct AssistBuilder {
209 file_id: FileId, 209 file_id: FileId,
210 is_snippet: bool, 210 is_snippet: bool,
211 source_file_edits: Vec<SourceFileEdit>, 211 source_file_edits: Vec<SourceFileEdit>,
212 file_system_edits: Vec<FileSystemEdit>,
212} 213}
213 214
214impl AssistBuilder { 215impl AssistBuilder {
@@ -218,6 +219,7 @@ impl AssistBuilder {
218 file_id, 219 file_id,
219 is_snippet: false, 220 is_snippet: false,
220 source_file_edits: Vec::default(), 221 source_file_edits: Vec::default(),
222 file_system_edits: Vec::default(),
221 } 223 }
222 } 224 }
223 225
@@ -282,12 +284,18 @@ impl AssistBuilder {
282 algo::diff(&node, &new).into_text_edit(&mut self.edit); 284 algo::diff(&node, &new).into_text_edit(&mut self.edit);
283 } 285 }
284 } 286 }
287 pub(crate) fn create_file(&mut self, dst: AnchoredPathBuf, content: impl Into<String>) {
288 let file_system_edit = FileSystemEdit::CreateFile { dst: dst.clone() };
289 self.file_system_edits.push(file_system_edit);
290 self.edit_file(dst.anchor);
291 self.insert(TextSize::from(0), content)
292 }
285 293
286 fn finish(mut self) -> SourceChange { 294 fn finish(mut self) -> SourceChange {
287 self.commit(); 295 self.commit();
288 SourceChange { 296 SourceChange {
289 source_file_edits: mem::take(&mut self.source_file_edits), 297 source_file_edits: mem::take(&mut self.source_file_edits),
290 file_system_edits: Default::default(), 298 file_system_edits: mem::take(&mut self.file_system_edits),
291 is_snippet: self.is_snippet, 299 is_snippet: self.is_snippet,
292 } 300 }
293 } 301 }
diff --git a/crates/assists/src/tests.rs b/crates/assists/src/tests.rs
index 709a34d03..9002040ce 100644
--- a/crates/assists/src/tests.rs
+++ b/crates/assists/src/tests.rs
@@ -2,6 +2,7 @@ mod generated;
2 2
3use hir::Semantics; 3use hir::Semantics;
4use ide_db::base_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt}; 4use ide_db::base_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt};
5use ide_db::source_change::FileSystemEdit;
5use ide_db::RootDatabase; 6use ide_db::RootDatabase;
6use syntax::TextRange; 7use syntax::TextRange;
7use test_utils::{assert_eq_text, extract_offset, extract_range}; 8use test_utils::{assert_eq_text, extract_offset, extract_range};
@@ -47,7 +48,7 @@ fn check_doc_test(assist_id: &str, before: &str, after: &str) {
47 let before = db.file_text(file_id).to_string(); 48 let before = db.file_text(file_id).to_string();
48 let frange = FileRange { file_id, range: selection.into() }; 49 let frange = FileRange { file_id, range: selection.into() };
49 50
50 let mut assist = Assist::resolved(&db, &AssistConfig::default(), frange) 51 let assist = Assist::resolved(&db, &AssistConfig::default(), frange)
51 .into_iter() 52 .into_iter()
52 .find(|assist| assist.assist.id.0 == assist_id) 53 .find(|assist| assist.assist.id.0 == assist_id)
53 .unwrap_or_else(|| { 54 .unwrap_or_else(|| {
@@ -63,9 +64,12 @@ fn check_doc_test(assist_id: &str, before: &str, after: &str) {
63 }); 64 });
64 65
65 let actual = { 66 let actual = {
66 let change = assist.source_change.source_file_edits.pop().unwrap();
67 let mut actual = before; 67 let mut actual = before;
68 change.edit.apply(&mut actual); 68 for source_file_edit in assist.source_change.source_file_edits {
69 if source_file_edit.file_id == file_id {
70 source_file_edit.edit.apply(&mut actual)
71 }
72 }
69 actual 73 actual
70 }; 74 };
71 assert_eq_text!(&after, &actual); 75 assert_eq_text!(&after, &actual);
@@ -99,20 +103,52 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label:
99 (Some(assist), ExpectedResult::After(after)) => { 103 (Some(assist), ExpectedResult::After(after)) => {
100 let mut source_change = assist.source_change; 104 let mut source_change = assist.source_change;
101 assert!(!source_change.source_file_edits.is_empty()); 105 assert!(!source_change.source_file_edits.is_empty());
102 let skip_header = source_change.source_file_edits.len() == 1; 106 let skip_header = source_change.source_file_edits.len() == 1
107 && source_change.file_system_edits.len() == 0;
103 source_change.source_file_edits.sort_by_key(|it| it.file_id); 108 source_change.source_file_edits.sort_by_key(|it| it.file_id);
104 109
110 let mut created_file_ids = Vec::new();
105 let mut buf = String::new(); 111 let mut buf = String::new();
112 for file_system_edit in source_change.file_system_edits.clone() {
113 match file_system_edit {
114 FileSystemEdit::CreateFile { dst } => {
115 created_file_ids.push(dst.anchor);
116 }
117 _ => (),
118 }
119 }
120
106 for source_file_edit in source_change.source_file_edits { 121 for source_file_edit in source_change.source_file_edits {
107 let mut text = db.file_text(source_file_edit.file_id).as_ref().to_owned(); 122 if created_file_ids.contains(&source_file_edit.file_id) {
108 source_file_edit.edit.apply(&mut text); 123 let target_dst = source_change
109 if !skip_header { 124 .file_system_edits
110 let sr = db.file_source_root(source_file_edit.file_id); 125 .iter()
111 let sr = db.source_root(sr); 126 .find_map(|f| match f {
112 let path = sr.path_for_file(&source_file_edit.file_id).unwrap(); 127 FileSystemEdit::CreateFile { dst } => {
113 format_to!(buf, "//- {}\n", path) 128 if dst.anchor == source_file_edit.file_id {
129 Some(&dst.path)
130 } else {
131 None
132 }
133 }
134 _ => None,
135 })
136 .unwrap();
137 format_to!(buf, "//- {}\n", target_dst);
138 let mut text = String::new();
139 source_file_edit.edit.apply(&mut text);
140 buf.push_str(&text);
141 } else {
142 let mut text = db.file_text(source_file_edit.file_id).as_ref().to_owned();
143 source_file_edit.edit.apply(&mut text);
144 if !skip_header {
145 let sr = db.file_source_root(source_file_edit.file_id);
146 let sr = db.source_root(sr);
147 let path = sr.path_for_file(&source_file_edit.file_id).unwrap();
148 format_to!(buf, "//- {}\n", path)
149 }
150 buf.push_str(&text);
114 } 151 }
115 buf.push_str(&text);
116 } 152 }
117 153
118 assert_eq_text!(after, &buf); 154 assert_eq_text!(after, &buf);