]> git.lizzy.rs Git - rust.git/blob - crates/ide/src/ssr.rs
Merge #11579
[rust.git] / crates / ide / src / ssr.rs
1 //! This module provides an SSR assist. It is not desirable to include this
2 //! assist in ide_assists because that would require the ide_assists crate
3 //! depend on the ide_ssr crate.
4
5 use ide_assists::{Assist, AssistId, AssistKind, AssistResolveStrategy, GroupLabel};
6 use ide_db::{base_db::FileRange, label::Label, source_change::SourceChange, RootDatabase};
7
8 pub(crate) fn ssr_assists(
9     db: &RootDatabase,
10     resolve: &AssistResolveStrategy,
11     frange: FileRange,
12 ) -> Vec<Assist> {
13     let mut ssr_assists = Vec::with_capacity(2);
14
15     let (match_finder, comment_range) = match ide_ssr::ssr_from_comment(db, frange) {
16         Some(ssr_data) => ssr_data,
17         None => return ssr_assists,
18     };
19     let id = AssistId("ssr", AssistKind::RefactorRewrite);
20
21     let (source_change_for_file, source_change_for_workspace) = if resolve.should_resolve(&id) {
22         let edits = match_finder.edits();
23
24         let source_change_for_file = {
25             let text_edit_for_file = edits.get(&frange.file_id).cloned().unwrap_or_default();
26             SourceChange::from_text_edit(frange.file_id, text_edit_for_file)
27         };
28
29         let source_change_for_workspace = SourceChange::from(match_finder.edits());
30
31         (Some(source_change_for_file), Some(source_change_for_workspace))
32     } else {
33         (None, None)
34     };
35
36     let assists = vec![
37         ("Apply SSR in file", source_change_for_file),
38         ("Apply SSR in workspace", source_change_for_workspace),
39     ];
40
41     for (label, source_change) in assists.into_iter() {
42         let assist = Assist {
43             id,
44             label: Label::new(label.to_string()),
45             group: Some(GroupLabel("Apply SSR".into())),
46             target: comment_range,
47             source_change,
48         };
49
50         ssr_assists.push(assist);
51     }
52
53     ssr_assists
54 }
55
56 #[cfg(test)]
57 mod tests {
58     use std::sync::Arc;
59
60     use expect_test::expect;
61     use ide_assists::{Assist, AssistResolveStrategy};
62     use ide_db::{
63         base_db::{fixture::WithFixture, salsa::Durability, FileRange},
64         symbol_index::SymbolsDatabase,
65         RootDatabase,
66     };
67     use rustc_hash::FxHashSet;
68
69     use super::ssr_assists;
70
71     fn get_assists(ra_fixture: &str, resolve: AssistResolveStrategy) -> Vec<Assist> {
72         let (mut db, file_id, range_or_offset) = RootDatabase::with_range_or_offset(ra_fixture);
73         let mut local_roots = FxHashSet::default();
74         local_roots.insert(ide_db::base_db::fixture::WORKSPACE);
75         db.set_local_roots_with_durability(Arc::new(local_roots), Durability::HIGH);
76         ssr_assists(&db, &resolve, FileRange { file_id, range: range_or_offset.into() })
77     }
78
79     #[test]
80     fn not_applicable_comment_not_ssr() {
81         let ra_fixture = r#"
82             //- /lib.rs
83
84             // This is foo $0
85             fn foo() {}
86             "#;
87         let assists = get_assists(ra_fixture, AssistResolveStrategy::All);
88
89         assert_eq!(0, assists.len());
90     }
91
92     #[test]
93     fn resolve_edits_true() {
94         let assists = get_assists(
95             r#"
96             //- /lib.rs
97             mod bar;
98
99             // 2 ==>> 3$0
100             fn foo() { 2 }
101
102             //- /bar.rs
103             fn bar() { 2 }
104             "#,
105             AssistResolveStrategy::All,
106         );
107
108         assert_eq!(2, assists.len());
109         let mut assists = assists.into_iter();
110
111         let apply_in_file_assist = assists.next().unwrap();
112         expect![[r#"
113             Assist {
114                 id: AssistId(
115                     "ssr",
116                     RefactorRewrite,
117                 ),
118                 label: "Apply SSR in file",
119                 group: Some(
120                     GroupLabel(
121                         "Apply SSR",
122                     ),
123                 ),
124                 target: 10..21,
125                 source_change: Some(
126                     SourceChange {
127                         source_file_edits: {
128                             FileId(
129                                 0,
130                             ): TextEdit {
131                                 indels: [
132                                     Indel {
133                                         insert: "3",
134                                         delete: 33..34,
135                                     },
136                                 ],
137                             },
138                         },
139                         file_system_edits: [],
140                         is_snippet: false,
141                     },
142                 ),
143             }
144         "#]]
145         .assert_debug_eq(&apply_in_file_assist);
146
147         let apply_in_workspace_assist = assists.next().unwrap();
148         expect![[r#"
149             Assist {
150                 id: AssistId(
151                     "ssr",
152                     RefactorRewrite,
153                 ),
154                 label: "Apply SSR in workspace",
155                 group: Some(
156                     GroupLabel(
157                         "Apply SSR",
158                     ),
159                 ),
160                 target: 10..21,
161                 source_change: Some(
162                     SourceChange {
163                         source_file_edits: {
164                             FileId(
165                                 0,
166                             ): TextEdit {
167                                 indels: [
168                                     Indel {
169                                         insert: "3",
170                                         delete: 33..34,
171                                     },
172                                 ],
173                             },
174                             FileId(
175                                 1,
176                             ): TextEdit {
177                                 indels: [
178                                     Indel {
179                                         insert: "3",
180                                         delete: 11..12,
181                                     },
182                                 ],
183                             },
184                         },
185                         file_system_edits: [],
186                         is_snippet: false,
187                     },
188                 ),
189             }
190         "#]]
191         .assert_debug_eq(&apply_in_workspace_assist);
192     }
193
194     #[test]
195     fn resolve_edits_false() {
196         let assists = get_assists(
197             r#"
198             //- /lib.rs
199             mod bar;
200
201             // 2 ==>> 3$0
202             fn foo() { 2 }
203
204             //- /bar.rs
205             fn bar() { 2 }
206             "#,
207             AssistResolveStrategy::None,
208         );
209
210         assert_eq!(2, assists.len());
211         let mut assists = assists.into_iter();
212
213         let apply_in_file_assist = assists.next().unwrap();
214         expect![[r#"
215             Assist {
216                 id: AssistId(
217                     "ssr",
218                     RefactorRewrite,
219                 ),
220                 label: "Apply SSR in file",
221                 group: Some(
222                     GroupLabel(
223                         "Apply SSR",
224                     ),
225                 ),
226                 target: 10..21,
227                 source_change: None,
228             }
229         "#]]
230         .assert_debug_eq(&apply_in_file_assist);
231
232         let apply_in_workspace_assist = assists.next().unwrap();
233         expect![[r#"
234             Assist {
235                 id: AssistId(
236                     "ssr",
237                     RefactorRewrite,
238                 ),
239                 label: "Apply SSR in workspace",
240                 group: Some(
241                     GroupLabel(
242                         "Apply SSR",
243                     ),
244                 ),
245                 target: 10..21,
246                 source_change: None,
247             }
248         "#]]
249         .assert_debug_eq(&apply_in_workspace_assist);
250     }
251 }