use algo::find_covering_element;
use hir::Semantics;
-use ide_db::base_db::{FileId, FileRange};
+use ide_db::base_db::{AnchoredPathBuf, FileId, FileRange};
use ide_db::{
label::Label,
- source_change::{SourceChange, SourceFileEdit},
+ source_change::{FileSystemEdit, SourceChange, SourceFileEdit},
RootDatabase,
};
use syntax::{
file_id: FileId,
is_snippet: bool,
source_file_edits: Vec<SourceFileEdit>,
+ file_system_edits: Vec<FileSystemEdit>,
}
impl AssistBuilder {
file_id,
is_snippet: false,
source_file_edits: Vec::default(),
+ file_system_edits: Vec::default(),
}
}
algo::diff(&node, &new).into_text_edit(&mut self.edit);
}
}
+ pub(crate) fn create_file(&mut self, dst: AnchoredPathBuf, content: impl Into<String>) {
+ let file_system_edit = FileSystemEdit::CreateFile { dst: dst.clone() };
+ self.file_system_edits.push(file_system_edit);
+ self.edit_file(dst.anchor);
+ self.insert(TextSize::from(0), content)
+ }
fn finish(mut self) -> SourceChange {
self.commit();
SourceChange {
source_file_edits: mem::take(&mut self.source_file_edits),
- file_system_edits: Default::default(),
+ file_system_edits: mem::take(&mut self.file_system_edits),
is_snippet: self.is_snippet,
}
}
use hir::Semantics;
use ide_db::base_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt};
+use ide_db::source_change::FileSystemEdit;
use ide_db::RootDatabase;
use syntax::TextRange;
use test_utils::{assert_eq_text, extract_offset, extract_range};
let before = db.file_text(file_id).to_string();
let frange = FileRange { file_id, range: selection.into() };
- let mut assist = Assist::resolved(&db, &AssistConfig::default(), frange)
+ let assist = Assist::resolved(&db, &AssistConfig::default(), frange)
.into_iter()
.find(|assist| assist.assist.id.0 == assist_id)
.unwrap_or_else(|| {
});
let actual = {
- let change = assist.source_change.source_file_edits.pop().unwrap();
let mut actual = before;
- change.edit.apply(&mut actual);
+ for source_file_edit in assist.source_change.source_file_edits {
+ if source_file_edit.file_id == file_id {
+ source_file_edit.edit.apply(&mut actual)
+ }
+ }
actual
};
assert_eq_text!(&after, &actual);
(Some(assist), ExpectedResult::After(after)) => {
let mut source_change = assist.source_change;
assert!(!source_change.source_file_edits.is_empty());
- let skip_header = source_change.source_file_edits.len() == 1;
+ let skip_header = source_change.source_file_edits.len() == 1
+ && source_change.file_system_edits.len() == 0;
source_change.source_file_edits.sort_by_key(|it| it.file_id);
+ let mut created_file_ids = Vec::new();
let mut buf = String::new();
+ for file_system_edit in source_change.file_system_edits.clone() {
+ match file_system_edit {
+ FileSystemEdit::CreateFile { dst } => {
+ created_file_ids.push(dst.anchor);
+ }
+ _ => (),
+ }
+ }
+
for source_file_edit in source_change.source_file_edits {
- let mut text = db.file_text(source_file_edit.file_id).as_ref().to_owned();
- source_file_edit.edit.apply(&mut text);
- if !skip_header {
- let sr = db.file_source_root(source_file_edit.file_id);
- let sr = db.source_root(sr);
- let path = sr.path_for_file(&source_file_edit.file_id).unwrap();
- format_to!(buf, "//- {}\n", path)
+ if created_file_ids.contains(&source_file_edit.file_id) {
+ let target_dst = source_change
+ .file_system_edits
+ .iter()
+ .find_map(|f| match f {
+ FileSystemEdit::CreateFile { dst } => {
+ if dst.anchor == source_file_edit.file_id {
+ Some(&dst.path)
+ } else {
+ None
+ }
+ }
+ _ => None,
+ })
+ .unwrap();
+ format_to!(buf, "//- {}\n", target_dst);
+ let mut text = String::new();
+ source_file_edit.edit.apply(&mut text);
+ buf.push_str(&text);
+ } else {
+ let mut text = db.file_text(source_file_edit.file_id).as_ref().to_owned();
+ source_file_edit.edit.apply(&mut text);
+ if !skip_header {
+ let sr = db.file_source_root(source_file_edit.file_id);
+ let sr = db.source_root(sr);
+ let path = sr.path_for_file(&source_file_edit.file_id).unwrap();
+ format_to!(buf, "//- {}\n", path)
+ }
+ buf.push_str(&text);
}
- buf.push_str(&text);
}
assert_eq_text!(after, &buf);