Skip to content

Commit fede1a3

Browse files
committed
Add promote_mod_file assist
1 parent d270679 commit fede1a3

File tree

4 files changed

+167
-10
lines changed

4 files changed

+167
-10
lines changed

crates/ide_assists/src/assist_context.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,10 @@ impl AssistBuilder {
294294
let file_system_edit = FileSystemEdit::CreateFile { dst, initial_contents: content.into() };
295295
self.source_change.push_file_system_edit(file_system_edit);
296296
}
297+
pub(crate) fn move_file(&mut self, src: FileId, dst: AnchoredPathBuf) {
298+
let file_system_edit = FileSystemEdit::MoveFile { src, dst };
299+
self.source_change.push_file_system_edit(file_system_edit);
300+
}
297301

298302
fn finish(mut self) -> SourceChange {
299303
self.commit();
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
use ide_db::{
2+
assists::{AssistId, AssistKind},
3+
base_db::AnchoredPathBuf,
4+
};
5+
use syntax::{
6+
ast::{self},
7+
AstNode, TextRange,
8+
};
9+
10+
use crate::assist_context::{AssistContext, Assists};
11+
12+
pub(crate) fn promote_mod_file(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
13+
let source_file = ctx.find_node_at_offset::<ast::SourceFile>()?;
14+
let module = ctx.sema.to_module_def(ctx.frange.file_id)?;
15+
if module.is_mod_rs(ctx.db()) {
16+
return None;
17+
}
18+
let target = TextRange::new(
19+
source_file.syntax().text_range().start(),
20+
source_file.syntax().text_range().end(),
21+
);
22+
let path = format!("./{}/mod.rs", module.name(ctx.db())?.to_string());
23+
let dst = AnchoredPathBuf { anchor: ctx.frange.file_id, path };
24+
acc.add(
25+
AssistId("promote_mod_file", AssistKind::Refactor),
26+
"Promote Module to directory",
27+
target,
28+
|builder| {
29+
builder.move_file(ctx.frange.file_id, dst);
30+
},
31+
)
32+
}
33+
34+
#[cfg(test)]
35+
mod tests {
36+
use crate::tests::{check_assist, check_assist_not_applicable};
37+
38+
use super::*;
39+
40+
#[test]
41+
fn trivial() {
42+
check_assist(
43+
promote_mod_file,
44+
r#"
45+
//- /main.rs
46+
mod a;
47+
//- /a.rs
48+
$0fn t() {}
49+
"#,
50+
r#"
51+
//- /a/mod.rs
52+
fn t() {}
53+
"#,
54+
);
55+
}
56+
57+
#[test]
58+
fn cursor_can_be_putted_anywhere() {
59+
check_assist(
60+
promote_mod_file,
61+
r#"
62+
//- /main.rs
63+
mod a;
64+
//- /a.rs
65+
fn t() {}$0
66+
"#,
67+
r#"
68+
//- /a/mod.rs
69+
fn t() {}
70+
"#,
71+
);
72+
check_assist(
73+
promote_mod_file,
74+
r#"
75+
//- /main.rs
76+
mod a;
77+
//- /a.rs
78+
fn t()$0 {}
79+
"#,
80+
r#"
81+
//- /a/mod.rs
82+
fn t() {}
83+
"#,
84+
);
85+
check_assist(
86+
promote_mod_file,
87+
r#"
88+
//- /main.rs
89+
mod a;
90+
//- /a.rs
91+
fn t($0) {}
92+
"#,
93+
r#"
94+
//- /a/mod.rs
95+
fn t() {}
96+
"#,
97+
);
98+
}
99+
100+
#[test]
101+
fn cannot_promote_mod_rs() {
102+
check_assist_not_applicable(
103+
promote_mod_file,
104+
r#"//- /main.rs
105+
mod a;
106+
//- /a/mod.rs
107+
$0fn t() {}
108+
"#,
109+
);
110+
}
111+
112+
#[test]
113+
fn cannot_promote_main_and_lib_rs() {
114+
check_assist_not_applicable(
115+
promote_mod_file,
116+
r#"//- /main.rs
117+
$0fn t() {}
118+
"#,
119+
);
120+
check_assist_not_applicable(
121+
promote_mod_file,
122+
r#"//- /lib.rs
123+
$0fn t() {}
124+
"#,
125+
);
126+
}
127+
128+
#[test]
129+
fn works_in_mod() {
130+
// note: /a/b.rs remains untouched
131+
check_assist(
132+
promote_mod_file,
133+
r#"//- /main.rs
134+
mod a;
135+
//- /a.rs
136+
mod b;
137+
$0fn t() {}
138+
//- /a/b.rs
139+
fn t1() {}
140+
"#,
141+
r#"
142+
//- /a/mod.rs
143+
mod b;
144+
fn t() {}
145+
"#,
146+
);
147+
}
148+
}

crates/ide_assists/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ mod handlers {
9696
mod move_bounds;
9797
mod move_guard;
9898
mod move_module_to_file;
99+
mod promote_mod_file;
99100
mod pull_assignment_up;
100101
mod qualify_path;
101102
mod raw_string;
@@ -167,6 +168,7 @@ mod handlers {
167168
move_guard::move_arm_cond_to_match_guard,
168169
move_guard::move_guard_to_arm_body,
169170
move_module_to_file::move_module_to_file,
171+
promote_mod_file::promote_mod_file,
170172
pull_assignment_up::pull_assignment_up,
171173
qualify_path::qualify_path,
172174
raw_string::add_hash,

crates/ide_assists/src/tests.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label:
142142
(Some(assist), ExpectedResult::After(after)) => {
143143
let source_change =
144144
assist.source_change.expect("Assist did not contain any source changes");
145-
assert!(!source_change.source_file_edits.is_empty());
146145
let skip_header = source_change.source_file_edits.len() == 1
147146
&& source_change.file_system_edits.len() == 0;
148147

@@ -160,15 +159,19 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label:
160159
}
161160

162161
for file_system_edit in source_change.file_system_edits {
163-
if let FileSystemEdit::CreateFile { dst, initial_contents } = file_system_edit {
164-
let sr = db.file_source_root(dst.anchor);
165-
let sr = db.source_root(sr);
166-
let mut base = sr.path_for_file(&dst.anchor).unwrap().clone();
167-
base.pop();
168-
let created_file_path = format!("{}{}", base.to_string(), &dst.path[1..]);
169-
format_to!(buf, "//- {}\n", created_file_path);
170-
buf.push_str(&initial_contents);
171-
}
162+
let (dst, contents) = match file_system_edit {
163+
FileSystemEdit::CreateFile { dst, initial_contents } => (dst, initial_contents),
164+
FileSystemEdit::MoveFile { src, dst } => {
165+
(dst, db.file_text(src).as_ref().to_owned())
166+
}
167+
};
168+
let sr = db.file_source_root(dst.anchor);
169+
let sr = db.source_root(sr);
170+
let mut base = sr.path_for_file(&dst.anchor).unwrap().clone();
171+
base.pop();
172+
let created_file_path = format!("{}{}", base.to_string(), &dst.path[1..]);
173+
format_to!(buf, "//- {}\n", created_file_path);
174+
buf.push_str(&contents);
172175
}
173176

174177
assert_eq_text!(after, &buf);

0 commit comments

Comments
 (0)