diff options
Diffstat (limited to 'crates/ra_ide/src/references')
-rw-r--r-- | crates/ra_ide/src/references/rename.rs | 1210 |
1 files changed, 614 insertions, 596 deletions
diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs index 28c6349b1..8735ec53c 100644 --- a/crates/ra_ide/src/references/rename.rs +++ b/crates/ra_ide/src/references/rename.rs | |||
@@ -1,11 +1,14 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir::{ModuleSource, Semantics}; | 3 | use hir::{Module, ModuleDef, ModuleSource, Semantics}; |
4 | use ra_db::{RelativePath, RelativePathBuf, SourceDatabaseExt}; | 4 | use ra_db::SourceDatabaseExt; |
5 | use ra_ide_db::RootDatabase; | 5 | use ra_ide_db::{ |
6 | defs::{classify_name, classify_name_ref, Definition, NameClass, NameRefClass}, | ||
7 | RootDatabase, | ||
8 | }; | ||
6 | use ra_syntax::{ | 9 | use ra_syntax::{ |
7 | algo::find_node_at_offset, ast, ast::TypeAscriptionOwner, lex_single_valid_syntax_kind, | 10 | algo::find_node_at_offset, ast, ast::NameOwner, ast::TypeAscriptionOwner, |
8 | AstNode, SyntaxKind, SyntaxNode, SyntaxToken, | 11 | lex_single_valid_syntax_kind, match_ast, AstNode, SyntaxKind, SyntaxNode, SyntaxToken, |
9 | }; | 12 | }; |
10 | use ra_text_edit::TextEdit; | 13 | use ra_text_edit::TextEdit; |
11 | use std::convert::TryInto; | 14 | use std::convert::TryInto; |
@@ -21,35 +24,53 @@ pub(crate) fn rename( | |||
21 | position: FilePosition, | 24 | position: FilePosition, |
22 | new_name: &str, | 25 | new_name: &str, |
23 | ) -> Option<RangeInfo<SourceChange>> { | 26 | ) -> Option<RangeInfo<SourceChange>> { |
27 | let sema = Semantics::new(db); | ||
28 | |||
24 | match lex_single_valid_syntax_kind(new_name)? { | 29 | match lex_single_valid_syntax_kind(new_name)? { |
25 | SyntaxKind::IDENT | SyntaxKind::UNDERSCORE => (), | 30 | SyntaxKind::IDENT | SyntaxKind::UNDERSCORE => (), |
26 | SyntaxKind::SELF_KW => return rename_to_self(db, position), | 31 | SyntaxKind::SELF_KW => return rename_to_self(&sema, position), |
27 | _ => return None, | 32 | _ => return None, |
28 | } | 33 | } |
29 | 34 | ||
30 | let sema = Semantics::new(db); | ||
31 | let source_file = sema.parse(position.file_id); | 35 | let source_file = sema.parse(position.file_id); |
32 | let syntax = source_file.syntax(); | 36 | let syntax = source_file.syntax(); |
33 | if let Some((ast_name, ast_module)) = find_name_and_module_at_offset(syntax, position) { | 37 | if let Some(module) = find_module_at_offset(&sema, position, syntax) { |
34 | let range = ast_name.syntax().text_range(); | 38 | rename_mod(&sema, position, module, new_name) |
35 | rename_mod(&sema, &ast_name, &ast_module, position, new_name) | ||
36 | .map(|info| RangeInfo::new(range, info)) | ||
37 | } else if let Some(self_token) = | 39 | } else if let Some(self_token) = |
38 | syntax.token_at_offset(position.offset).find(|t| t.kind() == SyntaxKind::SELF_KW) | 40 | syntax.token_at_offset(position.offset).find(|t| t.kind() == SyntaxKind::SELF_KW) |
39 | { | 41 | { |
40 | rename_self_to_param(db, position, self_token, new_name) | 42 | rename_self_to_param(&sema, position, self_token, new_name) |
41 | } else { | 43 | } else { |
42 | rename_reference(sema.db, position, new_name) | 44 | rename_reference(&sema, position, new_name) |
43 | } | 45 | } |
44 | } | 46 | } |
45 | 47 | ||
46 | fn find_name_and_module_at_offset( | 48 | fn find_module_at_offset( |
47 | syntax: &SyntaxNode, | 49 | sema: &Semantics<RootDatabase>, |
48 | position: FilePosition, | 50 | position: FilePosition, |
49 | ) -> Option<(ast::Name, ast::Module)> { | 51 | syntax: &SyntaxNode, |
50 | let ast_name = find_node_at_offset::<ast::Name>(syntax, position.offset)?; | 52 | ) -> Option<Module> { |
51 | let ast_module = ast::Module::cast(ast_name.syntax().parent()?)?; | 53 | let ident = syntax.token_at_offset(position.offset).find(|t| t.kind() == SyntaxKind::IDENT)?; |
52 | Some((ast_name, ast_module)) | 54 | |
55 | let module = match_ast! { | ||
56 | match (ident.parent()) { | ||
57 | ast::NameRef(name_ref) => { | ||
58 | match classify_name_ref(sema, &name_ref)? { | ||
59 | NameRefClass::Definition(Definition::ModuleDef(ModuleDef::Module(module))) => module, | ||
60 | _ => return None, | ||
61 | } | ||
62 | }, | ||
63 | ast::Name(name) => { | ||
64 | match classify_name(&sema, &name)? { | ||
65 | NameClass::Definition(Definition::ModuleDef(ModuleDef::Module(module))) => module, | ||
66 | _ => return None, | ||
67 | } | ||
68 | }, | ||
69 | _ => return None, | ||
70 | } | ||
71 | }; | ||
72 | |||
73 | Some(module) | ||
53 | } | 74 | } |
54 | 75 | ||
55 | fn source_edit_from_reference(reference: Reference, new_name: &str) -> SourceFileEdit { | 76 | fn source_edit_from_reference(reference: Reference, new_name: &str) -> SourceFileEdit { |
@@ -78,61 +99,53 @@ fn source_edit_from_reference(reference: Reference, new_name: &str) -> SourceFil | |||
78 | 99 | ||
79 | fn rename_mod( | 100 | fn rename_mod( |
80 | sema: &Semantics<RootDatabase>, | 101 | sema: &Semantics<RootDatabase>, |
81 | ast_name: &ast::Name, | ||
82 | ast_module: &ast::Module, | ||
83 | position: FilePosition, | 102 | position: FilePosition, |
103 | module: Module, | ||
84 | new_name: &str, | 104 | new_name: &str, |
85 | ) -> Option<SourceChange> { | 105 | ) -> Option<RangeInfo<SourceChange>> { |
86 | let mut source_file_edits = Vec::new(); | 106 | let mut source_file_edits = Vec::new(); |
87 | let mut file_system_edits = Vec::new(); | 107 | let mut file_system_edits = Vec::new(); |
88 | if let Some(module) = sema.to_def(ast_module) { | 108 | |
89 | let src = module.definition_source(sema.db); | 109 | let src = module.definition_source(sema.db); |
90 | let file_id = src.file_id.original_file(sema.db); | 110 | let file_id = src.file_id.original_file(sema.db); |
91 | match src.value { | 111 | match src.value { |
92 | ModuleSource::SourceFile(..) => { | 112 | ModuleSource::SourceFile(..) => { |
93 | let mod_path: RelativePathBuf = sema.db.file_relative_path(file_id); | 113 | // mod is defined in path/to/dir/mod.rs |
94 | // mod is defined in path/to/dir/mod.rs | 114 | let dst = if module.is_mod_rs(sema.db) { |
95 | let dst_path = if mod_path.file_stem() == Some("mod") { | 115 | format!("../{}/mod.rs", new_name) |
96 | mod_path | 116 | } else { |
97 | .parent() | 117 | format!("{}.rs", new_name) |
98 | .and_then(|p| p.parent()) | 118 | }; |
99 | .or_else(|| Some(RelativePath::new(""))) | 119 | let move_file = FileSystemEdit::MoveFile { src: file_id, anchor: file_id, dst }; |
100 | .map(|p| p.join(new_name).join("mod.rs")) | 120 | file_system_edits.push(move_file); |
101 | } else { | ||
102 | Some(mod_path.with_file_name(new_name).with_extension("rs")) | ||
103 | }; | ||
104 | if let Some(path) = dst_path { | ||
105 | let move_file = FileSystemEdit::MoveFile { | ||
106 | src: file_id, | ||
107 | dst_source_root: sema.db.file_source_root(position.file_id), | ||
108 | dst_path: path, | ||
109 | }; | ||
110 | file_system_edits.push(move_file); | ||
111 | } | ||
112 | } | ||
113 | ModuleSource::Module(..) => {} | ||
114 | } | 121 | } |
122 | ModuleSource::Module(..) => {} | ||
115 | } | 123 | } |
116 | 124 | ||
117 | let edit = SourceFileEdit { | 125 | if let Some(src) = module.declaration_source(sema.db) { |
118 | file_id: position.file_id, | 126 | let file_id = src.file_id.original_file(sema.db); |
119 | edit: TextEdit::replace(ast_name.syntax().text_range(), new_name.into()), | 127 | let name = src.value.name()?; |
120 | }; | 128 | let edit = SourceFileEdit { |
121 | source_file_edits.push(edit); | 129 | file_id, |
122 | 130 | edit: TextEdit::replace(name.syntax().text_range(), new_name.into()), | |
123 | if let Some(RangeInfo { range: _, info: refs }) = find_all_refs(sema.db, position, None) { | 131 | }; |
124 | let ref_edits = refs | 132 | source_file_edits.push(edit); |
125 | .references | ||
126 | .into_iter() | ||
127 | .map(|reference| source_edit_from_reference(reference, new_name)); | ||
128 | source_file_edits.extend(ref_edits); | ||
129 | } | 133 | } |
130 | 134 | ||
131 | Some(SourceChange::from_edits(source_file_edits, file_system_edits)) | 135 | let RangeInfo { range, info: refs } = find_all_refs(sema, position, None)?; |
136 | let ref_edits = refs | ||
137 | .references | ||
138 | .into_iter() | ||
139 | .map(|reference| source_edit_from_reference(reference, new_name)); | ||
140 | source_file_edits.extend(ref_edits); | ||
141 | |||
142 | Some(RangeInfo::new(range, SourceChange::from_edits(source_file_edits, file_system_edits))) | ||
132 | } | 143 | } |
133 | 144 | ||
134 | fn rename_to_self(db: &RootDatabase, position: FilePosition) -> Option<RangeInfo<SourceChange>> { | 145 | fn rename_to_self( |
135 | let sema = Semantics::new(db); | 146 | sema: &Semantics<RootDatabase>, |
147 | position: FilePosition, | ||
148 | ) -> Option<RangeInfo<SourceChange>> { | ||
136 | let source_file = sema.parse(position.file_id); | 149 | let source_file = sema.parse(position.file_id); |
137 | let syn = source_file.syntax(); | 150 | let syn = source_file.syntax(); |
138 | 151 | ||
@@ -147,7 +160,7 @@ fn rename_to_self(db: &RootDatabase, position: FilePosition) -> Option<RangeInfo | |||
147 | _ => return None, // not renaming other types | 160 | _ => return None, // not renaming other types |
148 | }; | 161 | }; |
149 | 162 | ||
150 | let RangeInfo { range, info: refs } = find_all_refs(db, position, None)?; | 163 | let RangeInfo { range, info: refs } = find_all_refs(sema, position, None)?; |
151 | 164 | ||
152 | let param_range = first_param.syntax().text_range(); | 165 | let param_range = first_param.syntax().text_range(); |
153 | let (param_ref, usages): (Vec<Reference>, Vec<Reference>) = refs | 166 | let (param_ref, usages): (Vec<Reference>, Vec<Reference>) = refs |
@@ -171,7 +184,7 @@ fn rename_to_self(db: &RootDatabase, position: FilePosition) -> Option<RangeInfo | |||
171 | ), | 184 | ), |
172 | }); | 185 | }); |
173 | 186 | ||
174 | Some(RangeInfo::new(range, SourceChange::source_file_edits(edits))) | 187 | Some(RangeInfo::new(range, SourceChange::from(edits))) |
175 | } | 188 | } |
176 | 189 | ||
177 | fn text_edit_from_self_param( | 190 | fn text_edit_from_self_param( |
@@ -199,16 +212,15 @@ fn text_edit_from_self_param( | |||
199 | } | 212 | } |
200 | 213 | ||
201 | fn rename_self_to_param( | 214 | fn rename_self_to_param( |
202 | db: &RootDatabase, | 215 | sema: &Semantics<RootDatabase>, |
203 | position: FilePosition, | 216 | position: FilePosition, |
204 | self_token: SyntaxToken, | 217 | self_token: SyntaxToken, |
205 | new_name: &str, | 218 | new_name: &str, |
206 | ) -> Option<RangeInfo<SourceChange>> { | 219 | ) -> Option<RangeInfo<SourceChange>> { |
207 | let sema = Semantics::new(db); | ||
208 | let source_file = sema.parse(position.file_id); | 220 | let source_file = sema.parse(position.file_id); |
209 | let syn = source_file.syntax(); | 221 | let syn = source_file.syntax(); |
210 | 222 | ||
211 | let text = db.file_text(position.file_id); | 223 | let text = sema.db.file_text(position.file_id); |
212 | let fn_def = find_node_at_offset::<ast::FnDef>(syn, position.offset)?; | 224 | let fn_def = find_node_at_offset::<ast::FnDef>(syn, position.offset)?; |
213 | let search_range = fn_def.syntax().text_range(); | 225 | let search_range = fn_def.syntax().text_range(); |
214 | 226 | ||
@@ -234,15 +246,15 @@ fn rename_self_to_param( | |||
234 | let range = ast::SelfParam::cast(self_token.parent()) | 246 | let range = ast::SelfParam::cast(self_token.parent()) |
235 | .map_or(self_token.text_range(), |p| p.syntax().text_range()); | 247 | .map_or(self_token.text_range(), |p| p.syntax().text_range()); |
236 | 248 | ||
237 | Some(RangeInfo::new(range, SourceChange::source_file_edits(edits))) | 249 | Some(RangeInfo::new(range, SourceChange::from(edits))) |
238 | } | 250 | } |
239 | 251 | ||
240 | fn rename_reference( | 252 | fn rename_reference( |
241 | db: &RootDatabase, | 253 | sema: &Semantics<RootDatabase>, |
242 | position: FilePosition, | 254 | position: FilePosition, |
243 | new_name: &str, | 255 | new_name: &str, |
244 | ) -> Option<RangeInfo<SourceChange>> { | 256 | ) -> Option<RangeInfo<SourceChange>> { |
245 | let RangeInfo { range, info: refs } = find_all_refs(db, position, None)?; | 257 | let RangeInfo { range, info: refs } = find_all_refs(sema, position, None)?; |
246 | 258 | ||
247 | let edit = refs | 259 | let edit = refs |
248 | .into_iter() | 260 | .into_iter() |
@@ -253,57 +265,56 @@ fn rename_reference( | |||
253 | return None; | 265 | return None; |
254 | } | 266 | } |
255 | 267 | ||
256 | Some(RangeInfo::new(range, SourceChange::source_file_edits(edit))) | 268 | Some(RangeInfo::new(range, SourceChange::from(edit))) |
257 | } | 269 | } |
258 | 270 | ||
259 | #[cfg(test)] | 271 | #[cfg(test)] |
260 | mod tests { | 272 | mod tests { |
261 | use insta::assert_debug_snapshot; | 273 | use expect::{expect, Expect}; |
262 | use ra_text_edit::TextEditBuilder; | 274 | use ra_text_edit::TextEditBuilder; |
275 | use stdx::trim_indent; | ||
263 | use test_utils::{assert_eq_text, mark}; | 276 | use test_utils::{assert_eq_text, mark}; |
264 | 277 | ||
265 | use crate::{ | 278 | use crate::{mock_analysis::analysis_and_position, FileId}; |
266 | mock_analysis::analysis_and_position, mock_analysis::single_file_with_position, FileId, | 279 | |
267 | }; | 280 | fn check(new_name: &str, ra_fixture_before: &str, ra_fixture_after: &str) { |
281 | let ra_fixture_after = &trim_indent(ra_fixture_after); | ||
282 | let (analysis, position) = analysis_and_position(ra_fixture_before); | ||
283 | let source_change = analysis.rename(position, new_name).unwrap(); | ||
284 | let mut text_edit_builder = TextEditBuilder::default(); | ||
285 | let mut file_id: Option<FileId> = None; | ||
286 | if let Some(change) = source_change { | ||
287 | for edit in change.info.source_file_edits { | ||
288 | file_id = Some(edit.file_id); | ||
289 | for indel in edit.edit.into_iter() { | ||
290 | text_edit_builder.replace(indel.delete, indel.insert); | ||
291 | } | ||
292 | } | ||
293 | } | ||
294 | let mut result = analysis.file_text(file_id.unwrap()).unwrap().to_string(); | ||
295 | text_edit_builder.finish().apply(&mut result); | ||
296 | assert_eq_text!(ra_fixture_after, &*result); | ||
297 | } | ||
298 | |||
299 | fn check_expect(new_name: &str, ra_fixture: &str, expect: Expect) { | ||
300 | let (analysis, position) = analysis_and_position(ra_fixture); | ||
301 | let source_change = analysis.rename(position, new_name).unwrap().unwrap(); | ||
302 | expect.assert_debug_eq(&source_change) | ||
303 | } | ||
268 | 304 | ||
269 | #[test] | 305 | #[test] |
270 | fn test_rename_to_underscore() { | 306 | fn test_rename_to_underscore() { |
271 | test_rename( | 307 | check("_", r#"fn main() { let i<|> = 1; }"#, r#"fn main() { let _ = 1; }"#); |
272 | r#" | ||
273 | fn main() { | ||
274 | let i<|> = 1; | ||
275 | }"#, | ||
276 | "_", | ||
277 | r#" | ||
278 | fn main() { | ||
279 | let _ = 1; | ||
280 | }"#, | ||
281 | ); | ||
282 | } | 308 | } |
283 | 309 | ||
284 | #[test] | 310 | #[test] |
285 | fn test_rename_to_raw_identifier() { | 311 | fn test_rename_to_raw_identifier() { |
286 | test_rename( | 312 | check("r#fn", r#"fn main() { let i<|> = 1; }"#, r#"fn main() { let r#fn = 1; }"#); |
287 | r#" | ||
288 | fn main() { | ||
289 | let i<|> = 1; | ||
290 | }"#, | ||
291 | "r#fn", | ||
292 | r#" | ||
293 | fn main() { | ||
294 | let r#fn = 1; | ||
295 | }"#, | ||
296 | ); | ||
297 | } | 313 | } |
298 | 314 | ||
299 | #[test] | 315 | #[test] |
300 | fn test_rename_to_invalid_identifier() { | 316 | fn test_rename_to_invalid_identifier() { |
301 | let (analysis, position) = single_file_with_position( | 317 | let (analysis, position) = analysis_and_position(r#"fn main() { let i<|> = 1; }"#); |
302 | " | ||
303 | fn main() { | ||
304 | let i<|> = 1; | ||
305 | }", | ||
306 | ); | ||
307 | let new_name = "invalid!"; | 318 | let new_name = "invalid!"; |
308 | let source_change = analysis.rename(position, new_name).unwrap(); | 319 | let source_change = analysis.rename(position, new_name).unwrap(); |
309 | assert!(source_change.is_none()); | 320 | assert!(source_change.is_none()); |
@@ -311,682 +322,689 @@ mod tests { | |||
311 | 322 | ||
312 | #[test] | 323 | #[test] |
313 | fn test_rename_for_local() { | 324 | fn test_rename_for_local() { |
314 | test_rename( | 325 | check( |
326 | "k", | ||
315 | r#" | 327 | r#" |
316 | fn main() { | 328 | fn main() { |
317 | let mut i = 1; | 329 | let mut i = 1; |
318 | let j = 1; | 330 | let j = 1; |
319 | i = i<|> + j; | 331 | i = i<|> + j; |
320 | 332 | ||
321 | { | 333 | { i = 0; } |
322 | i = 0; | ||
323 | } | ||
324 | 334 | ||
325 | i = 5; | 335 | i = 5; |
326 | }"#, | 336 | } |
327 | "k", | 337 | "#, |
328 | r#" | 338 | r#" |
329 | fn main() { | 339 | fn main() { |
330 | let mut k = 1; | 340 | let mut k = 1; |
331 | let j = 1; | 341 | let j = 1; |
332 | k = k + j; | 342 | k = k + j; |
333 | 343 | ||
334 | { | 344 | { k = 0; } |
335 | k = 0; | ||
336 | } | ||
337 | 345 | ||
338 | k = 5; | 346 | k = 5; |
339 | }"#, | 347 | } |
348 | "#, | ||
340 | ); | 349 | ); |
341 | } | 350 | } |
342 | 351 | ||
343 | #[test] | 352 | #[test] |
344 | fn test_rename_for_macro_args() { | 353 | fn test_rename_for_macro_args() { |
345 | test_rename( | 354 | check( |
346 | r#" | ||
347 | macro_rules! foo {($i:ident) => {$i} } | ||
348 | fn main() { | ||
349 | let a<|> = "test"; | ||
350 | foo!(a); | ||
351 | }"#, | ||
352 | "b", | 355 | "b", |
353 | r#" | 356 | r#" |
354 | macro_rules! foo {($i:ident) => {$i} } | 357 | macro_rules! foo {($i:ident) => {$i} } |
355 | fn main() { | 358 | fn main() { |
356 | let b = "test"; | 359 | let a<|> = "test"; |
357 | foo!(b); | 360 | foo!(a); |
358 | }"#, | 361 | } |
362 | "#, | ||
363 | r#" | ||
364 | macro_rules! foo {($i:ident) => {$i} } | ||
365 | fn main() { | ||
366 | let b = "test"; | ||
367 | foo!(b); | ||
368 | } | ||
369 | "#, | ||
359 | ); | 370 | ); |
360 | } | 371 | } |
361 | 372 | ||
362 | #[test] | 373 | #[test] |
363 | fn test_rename_for_macro_args_rev() { | 374 | fn test_rename_for_macro_args_rev() { |
364 | test_rename( | 375 | check( |
365 | r#" | ||
366 | macro_rules! foo {($i:ident) => {$i} } | ||
367 | fn main() { | ||
368 | let a = "test"; | ||
369 | foo!(a<|>); | ||
370 | }"#, | ||
371 | "b", | 376 | "b", |
372 | r#" | 377 | r#" |
373 | macro_rules! foo {($i:ident) => {$i} } | 378 | macro_rules! foo {($i:ident) => {$i} } |
374 | fn main() { | 379 | fn main() { |
375 | let b = "test"; | 380 | let a = "test"; |
376 | foo!(b); | 381 | foo!(a<|>); |
377 | }"#, | 382 | } |
383 | "#, | ||
384 | r#" | ||
385 | macro_rules! foo {($i:ident) => {$i} } | ||
386 | fn main() { | ||
387 | let b = "test"; | ||
388 | foo!(b); | ||
389 | } | ||
390 | "#, | ||
378 | ); | 391 | ); |
379 | } | 392 | } |
380 | 393 | ||
381 | #[test] | 394 | #[test] |
382 | fn test_rename_for_macro_define_fn() { | 395 | fn test_rename_for_macro_define_fn() { |
383 | test_rename( | 396 | check( |
384 | r#" | ||
385 | macro_rules! define_fn {($id:ident) => { fn $id{} }} | ||
386 | define_fn!(foo); | ||
387 | fn main() { | ||
388 | fo<|>o(); | ||
389 | }"#, | ||
390 | "bar", | 397 | "bar", |
391 | r#" | 398 | r#" |
392 | macro_rules! define_fn {($id:ident) => { fn $id{} }} | 399 | macro_rules! define_fn {($id:ident) => { fn $id{} }} |
393 | define_fn!(bar); | 400 | define_fn!(foo); |
394 | fn main() { | 401 | fn main() { |
395 | bar(); | 402 | fo<|>o(); |
396 | }"#, | 403 | } |
404 | "#, | ||
405 | r#" | ||
406 | macro_rules! define_fn {($id:ident) => { fn $id{} }} | ||
407 | define_fn!(bar); | ||
408 | fn main() { | ||
409 | bar(); | ||
410 | } | ||
411 | "#, | ||
397 | ); | 412 | ); |
398 | } | 413 | } |
399 | 414 | ||
400 | #[test] | 415 | #[test] |
401 | fn test_rename_for_macro_define_fn_rev() { | 416 | fn test_rename_for_macro_define_fn_rev() { |
402 | test_rename( | 417 | check( |
403 | r#" | ||
404 | macro_rules! define_fn {($id:ident) => { fn $id{} }} | ||
405 | define_fn!(fo<|>o); | ||
406 | fn main() { | ||
407 | foo(); | ||
408 | }"#, | ||
409 | "bar", | 418 | "bar", |
410 | r#" | 419 | r#" |
411 | macro_rules! define_fn {($id:ident) => { fn $id{} }} | 420 | macro_rules! define_fn {($id:ident) => { fn $id{} }} |
412 | define_fn!(bar); | 421 | define_fn!(fo<|>o); |
413 | fn main() { | 422 | fn main() { |
414 | bar(); | 423 | foo(); |
415 | }"#, | 424 | } |
425 | "#, | ||
426 | r#" | ||
427 | macro_rules! define_fn {($id:ident) => { fn $id{} }} | ||
428 | define_fn!(bar); | ||
429 | fn main() { | ||
430 | bar(); | ||
431 | } | ||
432 | "#, | ||
416 | ); | 433 | ); |
417 | } | 434 | } |
418 | 435 | ||
419 | #[test] | 436 | #[test] |
420 | fn test_rename_for_param_inside() { | 437 | fn test_rename_for_param_inside() { |
421 | test_rename( | 438 | check("j", r#"fn foo(i : u32) -> u32 { i<|> }"#, r#"fn foo(j : u32) -> u32 { j }"#); |
422 | r#" | ||
423 | fn foo(i : u32) -> u32 { | ||
424 | i<|> | ||
425 | }"#, | ||
426 | "j", | ||
427 | r#" | ||
428 | fn foo(j : u32) -> u32 { | ||
429 | j | ||
430 | }"#, | ||
431 | ); | ||
432 | } | 439 | } |
433 | 440 | ||
434 | #[test] | 441 | #[test] |
435 | fn test_rename_refs_for_fn_param() { | 442 | fn test_rename_refs_for_fn_param() { |
436 | test_rename( | 443 | check("j", r#"fn foo(i<|> : u32) -> u32 { i }"#, r#"fn foo(j : u32) -> u32 { j }"#); |
437 | r#" | ||
438 | fn foo(i<|> : u32) -> u32 { | ||
439 | i | ||
440 | }"#, | ||
441 | "new_name", | ||
442 | r#" | ||
443 | fn foo(new_name : u32) -> u32 { | ||
444 | new_name | ||
445 | }"#, | ||
446 | ); | ||
447 | } | 444 | } |
448 | 445 | ||
449 | #[test] | 446 | #[test] |
450 | fn test_rename_for_mut_param() { | 447 | fn test_rename_for_mut_param() { |
451 | test_rename( | 448 | check("j", r#"fn foo(mut i<|> : u32) -> u32 { i }"#, r#"fn foo(mut j : u32) -> u32 { j }"#); |
452 | r#" | ||
453 | fn foo(mut i<|> : u32) -> u32 { | ||
454 | i | ||
455 | }"#, | ||
456 | "new_name", | ||
457 | r#" | ||
458 | fn foo(mut new_name : u32) -> u32 { | ||
459 | new_name | ||
460 | }"#, | ||
461 | ); | ||
462 | } | 449 | } |
463 | 450 | ||
464 | #[test] | 451 | #[test] |
465 | fn test_rename_struct_field() { | 452 | fn test_rename_struct_field() { |
466 | test_rename( | 453 | check( |
454 | "j", | ||
467 | r#" | 455 | r#" |
468 | struct Foo { | 456 | struct Foo { i<|>: i32 } |
469 | i<|>: i32, | ||
470 | } | ||
471 | 457 | ||
472 | impl Foo { | 458 | impl Foo { |
473 | fn new(i: i32) -> Self { | 459 | fn new(i: i32) -> Self { |
474 | Self { i: i } | 460 | Self { i: i } |
475 | } | ||
476 | } | 461 | } |
477 | "#, | 462 | } |
478 | "j", | 463 | "#, |
479 | r#" | 464 | r#" |
480 | struct Foo { | 465 | struct Foo { j: i32 } |
481 | j: i32, | ||
482 | } | ||
483 | 466 | ||
484 | impl Foo { | 467 | impl Foo { |
485 | fn new(i: i32) -> Self { | 468 | fn new(i: i32) -> Self { |
486 | Self { j: i } | 469 | Self { j: i } |
487 | } | ||
488 | } | 470 | } |
489 | "#, | 471 | } |
472 | "#, | ||
490 | ); | 473 | ); |
491 | } | 474 | } |
492 | 475 | ||
493 | #[test] | 476 | #[test] |
494 | fn test_rename_struct_field_for_shorthand() { | 477 | fn test_rename_struct_field_for_shorthand() { |
495 | mark::check!(test_rename_struct_field_for_shorthand); | 478 | mark::check!(test_rename_struct_field_for_shorthand); |
496 | test_rename( | 479 | check( |
480 | "j", | ||
497 | r#" | 481 | r#" |
498 | struct Foo { | 482 | struct Foo { i<|>: i32 } |
499 | i<|>: i32, | ||
500 | } | ||
501 | 483 | ||
502 | impl Foo { | 484 | impl Foo { |
503 | fn new(i: i32) -> Self { | 485 | fn new(i: i32) -> Self { |
504 | Self { i } | 486 | Self { i } |
505 | } | ||
506 | } | 487 | } |
507 | "#, | 488 | } |
508 | "j", | 489 | "#, |
509 | r#" | 490 | r#" |
510 | struct Foo { | 491 | struct Foo { j: i32 } |
511 | j: i32, | ||
512 | } | ||
513 | 492 | ||
514 | impl Foo { | 493 | impl Foo { |
515 | fn new(i: i32) -> Self { | 494 | fn new(i: i32) -> Self { |
516 | Self { j: i } | 495 | Self { j: i } |
517 | } | ||
518 | } | 496 | } |
519 | "#, | 497 | } |
498 | "#, | ||
520 | ); | 499 | ); |
521 | } | 500 | } |
522 | 501 | ||
523 | #[test] | 502 | #[test] |
524 | fn test_rename_local_for_field_shorthand() { | 503 | fn test_rename_local_for_field_shorthand() { |
525 | mark::check!(test_rename_local_for_field_shorthand); | 504 | mark::check!(test_rename_local_for_field_shorthand); |
526 | test_rename( | 505 | check( |
506 | "j", | ||
527 | r#" | 507 | r#" |
528 | struct Foo { | 508 | struct Foo { i: i32 } |
529 | i: i32, | ||
530 | } | ||
531 | 509 | ||
532 | impl Foo { | 510 | impl Foo { |
533 | fn new(i<|>: i32) -> Self { | 511 | fn new(i<|>: i32) -> Self { |
534 | Self { i } | 512 | Self { i } |
535 | } | ||
536 | } | 513 | } |
537 | "#, | 514 | } |
538 | "j", | 515 | "#, |
539 | r#" | 516 | r#" |
540 | struct Foo { | 517 | struct Foo { i: i32 } |
541 | i: i32, | ||
542 | } | ||
543 | 518 | ||
544 | impl Foo { | 519 | impl Foo { |
545 | fn new(j: i32) -> Self { | 520 | fn new(j: i32) -> Self { |
546 | Self { i: j } | 521 | Self { i: j } |
547 | } | ||
548 | } | 522 | } |
549 | "#, | 523 | } |
524 | "#, | ||
550 | ); | 525 | ); |
551 | } | 526 | } |
552 | 527 | ||
553 | #[test] | 528 | #[test] |
554 | fn test_field_shorthand_correct_struct() { | 529 | fn test_field_shorthand_correct_struct() { |
555 | test_rename( | 530 | check( |
556 | r#" | ||
557 | struct Foo { | ||
558 | i<|>: i32, | ||
559 | } | ||
560 | |||
561 | struct Bar { | ||
562 | i: i32, | ||
563 | } | ||
564 | |||
565 | impl Bar { | ||
566 | fn new(i: i32) -> Self { | ||
567 | Self { i } | ||
568 | } | ||
569 | } | ||
570 | "#, | ||
571 | "j", | 531 | "j", |
572 | r#" | 532 | r#" |
573 | struct Foo { | 533 | struct Foo { i<|>: i32 } |
574 | j: i32, | 534 | struct Bar { i: i32 } |
575 | } | ||
576 | 535 | ||
577 | struct Bar { | 536 | impl Bar { |
578 | i: i32, | 537 | fn new(i: i32) -> Self { |
538 | Self { i } | ||
579 | } | 539 | } |
540 | } | ||
541 | "#, | ||
542 | r#" | ||
543 | struct Foo { j: i32 } | ||
544 | struct Bar { i: i32 } | ||
580 | 545 | ||
581 | impl Bar { | 546 | impl Bar { |
582 | fn new(i: i32) -> Self { | 547 | fn new(i: i32) -> Self { |
583 | Self { i } | 548 | Self { i } |
584 | } | ||
585 | } | 549 | } |
586 | "#, | 550 | } |
551 | "#, | ||
587 | ); | 552 | ); |
588 | } | 553 | } |
589 | 554 | ||
590 | #[test] | 555 | #[test] |
591 | fn test_shadow_local_for_struct_shorthand() { | 556 | fn test_shadow_local_for_struct_shorthand() { |
592 | test_rename( | 557 | check( |
558 | "j", | ||
593 | r#" | 559 | r#" |
594 | struct Foo { | 560 | struct Foo { i: i32 } |
595 | i: i32, | ||
596 | } | ||
597 | 561 | ||
598 | fn baz(i<|>: i32) -> Self { | 562 | fn baz(i<|>: i32) -> Self { |
599 | let x = Foo { i }; | 563 | let x = Foo { i }; |
600 | { | 564 | { |
601 | let i = 0; | 565 | let i = 0; |
602 | Foo { i } | 566 | Foo { i } |
603 | } | ||
604 | } | 567 | } |
605 | "#, | 568 | } |
606 | "j", | 569 | "#, |
607 | r#" | 570 | r#" |
608 | struct Foo { | 571 | struct Foo { i: i32 } |
609 | i: i32, | ||
610 | } | ||
611 | 572 | ||
612 | fn baz(j: i32) -> Self { | 573 | fn baz(j: i32) -> Self { |
613 | let x = Foo { i: j }; | 574 | let x = Foo { i: j }; |
614 | { | 575 | { |
615 | let i = 0; | 576 | let i = 0; |
616 | Foo { i } | 577 | Foo { i } |
617 | } | ||
618 | } | 578 | } |
619 | "#, | 579 | } |
580 | "#, | ||
620 | ); | 581 | ); |
621 | } | 582 | } |
622 | 583 | ||
623 | #[test] | 584 | #[test] |
624 | fn test_rename_mod() { | 585 | fn test_rename_mod() { |
625 | let (analysis, position) = analysis_and_position( | 586 | check_expect( |
626 | " | 587 | "foo2", |
627 | //- /lib.rs | 588 | r#" |
628 | mod bar; | 589 | //- /lib.rs |
629 | 590 | mod bar; | |
630 | //- /bar.rs | 591 | |
631 | mod foo<|>; | 592 | //- /bar.rs |
632 | 593 | mod foo<|>; | |
633 | //- /bar/foo.rs | 594 | |
634 | // emtpy | 595 | //- /bar/foo.rs |
635 | ", | 596 | // empty |
597 | "#, | ||
598 | expect![[r#" | ||
599 | RangeInfo { | ||
600 | range: 4..7, | ||
601 | info: SourceChange { | ||
602 | source_file_edits: [ | ||
603 | SourceFileEdit { | ||
604 | file_id: FileId( | ||
605 | 2, | ||
606 | ), | ||
607 | edit: TextEdit { | ||
608 | indels: [ | ||
609 | Indel { | ||
610 | insert: "foo2", | ||
611 | delete: 4..7, | ||
612 | }, | ||
613 | ], | ||
614 | }, | ||
615 | }, | ||
616 | ], | ||
617 | file_system_edits: [ | ||
618 | MoveFile { | ||
619 | src: FileId( | ||
620 | 3, | ||
621 | ), | ||
622 | anchor: FileId( | ||
623 | 3, | ||
624 | ), | ||
625 | dst: "foo2.rs", | ||
626 | }, | ||
627 | ], | ||
628 | is_snippet: false, | ||
629 | }, | ||
630 | } | ||
631 | "#]], | ||
636 | ); | 632 | ); |
637 | let new_name = "foo2"; | 633 | } |
638 | let source_change = analysis.rename(position, new_name).unwrap(); | 634 | |
639 | assert_debug_snapshot!(&source_change, | 635 | #[test] |
640 | @r###" | 636 | fn test_rename_mod_in_use_tree() { |
641 | Some( | 637 | check_expect( |
642 | RangeInfo { | 638 | "quux", |
643 | range: 4..7, | 639 | r#" |
644 | info: SourceChange { | 640 | //- /main.rs |
645 | source_file_edits: [ | 641 | pub mod foo; |
646 | SourceFileEdit { | 642 | pub mod bar; |
647 | file_id: FileId( | 643 | fn main() {} |
648 | 2, | 644 | |
649 | ), | 645 | //- /foo.rs |
650 | edit: TextEdit { | 646 | pub struct FooContent; |
651 | indels: [ | 647 | |
652 | Indel { | 648 | //- /bar.rs |
653 | insert: "foo2", | 649 | use crate::foo<|>::FooContent; |
654 | delete: 4..7, | 650 | "#, |
655 | }, | 651 | expect![[r#" |
656 | ], | 652 | RangeInfo { |
653 | range: 11..14, | ||
654 | info: SourceChange { | ||
655 | source_file_edits: [ | ||
656 | SourceFileEdit { | ||
657 | file_id: FileId( | ||
658 | 1, | ||
659 | ), | ||
660 | edit: TextEdit { | ||
661 | indels: [ | ||
662 | Indel { | ||
663 | insert: "quux", | ||
664 | delete: 8..11, | ||
665 | }, | ||
666 | ], | ||
667 | }, | ||
657 | }, | 668 | }, |
658 | }, | 669 | SourceFileEdit { |
659 | ], | 670 | file_id: FileId( |
660 | file_system_edits: [ | 671 | 3, |
661 | MoveFile { | 672 | ), |
662 | src: FileId( | 673 | edit: TextEdit { |
663 | 3, | 674 | indels: [ |
664 | ), | 675 | Indel { |
665 | dst_source_root: SourceRootId( | 676 | insert: "quux", |
666 | 0, | 677 | delete: 11..14, |
667 | ), | 678 | }, |
668 | dst_path: "bar/foo2.rs", | 679 | ], |
669 | }, | 680 | }, |
670 | ], | 681 | }, |
671 | is_snippet: false, | 682 | ], |
672 | }, | 683 | file_system_edits: [ |
673 | }, | 684 | MoveFile { |
674 | ) | 685 | src: FileId( |
675 | "###); | 686 | 2, |
687 | ), | ||
688 | anchor: FileId( | ||
689 | 2, | ||
690 | ), | ||
691 | dst: "quux.rs", | ||
692 | }, | ||
693 | ], | ||
694 | is_snippet: false, | ||
695 | }, | ||
696 | } | ||
697 | "#]], | ||
698 | ); | ||
676 | } | 699 | } |
677 | 700 | ||
678 | #[test] | 701 | #[test] |
679 | fn test_rename_mod_in_dir() { | 702 | fn test_rename_mod_in_dir() { |
680 | let (analysis, position) = analysis_and_position( | 703 | check_expect( |
681 | " | 704 | "foo2", |
682 | //- /lib.rs | 705 | r#" |
683 | mod fo<|>o; | 706 | //- /lib.rs |
684 | //- /foo/mod.rs | 707 | mod fo<|>o; |
685 | // emtpy | 708 | //- /foo/mod.rs |
686 | ", | 709 | // emtpy |
687 | ); | 710 | "#, |
688 | let new_name = "foo2"; | 711 | expect![[r#" |
689 | let source_change = analysis.rename(position, new_name).unwrap(); | 712 | RangeInfo { |
690 | assert_debug_snapshot!(&source_change, | 713 | range: 4..7, |
691 | @r###" | 714 | info: SourceChange { |
692 | Some( | 715 | source_file_edits: [ |
693 | RangeInfo { | 716 | SourceFileEdit { |
694 | range: 4..7, | 717 | file_id: FileId( |
695 | info: SourceChange { | 718 | 1, |
696 | source_file_edits: [ | 719 | ), |
697 | SourceFileEdit { | 720 | edit: TextEdit { |
698 | file_id: FileId( | 721 | indels: [ |
699 | 1, | 722 | Indel { |
700 | ), | 723 | insert: "foo2", |
701 | edit: TextEdit { | 724 | delete: 4..7, |
702 | indels: [ | 725 | }, |
703 | Indel { | 726 | ], |
704 | insert: "foo2", | 727 | }, |
705 | delete: 4..7, | ||
706 | }, | ||
707 | ], | ||
708 | }, | 728 | }, |
709 | }, | 729 | ], |
710 | ], | 730 | file_system_edits: [ |
711 | file_system_edits: [ | 731 | MoveFile { |
712 | MoveFile { | 732 | src: FileId( |
713 | src: FileId( | 733 | 2, |
714 | 2, | 734 | ), |
715 | ), | 735 | anchor: FileId( |
716 | dst_source_root: SourceRootId( | 736 | 2, |
717 | 0, | 737 | ), |
718 | ), | 738 | dst: "../foo2/mod.rs", |
719 | dst_path: "foo2/mod.rs", | 739 | }, |
720 | }, | 740 | ], |
721 | ], | 741 | is_snippet: false, |
722 | is_snippet: false, | 742 | }, |
723 | }, | 743 | } |
724 | }, | 744 | "#]], |
725 | ) | 745 | ); |
726 | "### | ||
727 | ); | ||
728 | } | 746 | } |
729 | 747 | ||
730 | #[test] | 748 | #[test] |
731 | fn test_module_rename_in_path() { | 749 | fn test_rename_unusually_nested_mod() { |
732 | test_rename( | 750 | check_expect( |
751 | "bar", | ||
733 | r#" | 752 | r#" |
734 | mod <|>foo { | 753 | //- /lib.rs |
735 | pub fn bar() {} | 754 | mod outer { mod fo<|>o; } |
755 | |||
756 | //- /outer/foo.rs | ||
757 | // emtpy | ||
758 | "#, | ||
759 | expect![[r#" | ||
760 | RangeInfo { | ||
761 | range: 16..19, | ||
762 | info: SourceChange { | ||
763 | source_file_edits: [ | ||
764 | SourceFileEdit { | ||
765 | file_id: FileId( | ||
766 | 1, | ||
767 | ), | ||
768 | edit: TextEdit { | ||
769 | indels: [ | ||
770 | Indel { | ||
771 | insert: "bar", | ||
772 | delete: 16..19, | ||
773 | }, | ||
774 | ], | ||
775 | }, | ||
776 | }, | ||
777 | ], | ||
778 | file_system_edits: [ | ||
779 | MoveFile { | ||
780 | src: FileId( | ||
781 | 2, | ||
782 | ), | ||
783 | anchor: FileId( | ||
784 | 2, | ||
785 | ), | ||
786 | dst: "bar.rs", | ||
787 | }, | ||
788 | ], | ||
789 | is_snippet: false, | ||
790 | }, | ||
791 | } | ||
792 | "#]], | ||
793 | ); | ||
736 | } | 794 | } |
737 | 795 | ||
738 | fn main() { | 796 | #[test] |
739 | foo::bar(); | 797 | fn test_module_rename_in_path() { |
740 | }"#, | 798 | check( |
741 | "baz", | 799 | "baz", |
742 | r#" | 800 | r#" |
743 | mod baz { | 801 | mod <|>foo { pub fn bar() {} } |
744 | pub fn bar() {} | ||
745 | } | ||
746 | 802 | ||
747 | fn main() { | 803 | fn main() { foo::bar(); } |
748 | baz::bar(); | 804 | "#, |
749 | }"#, | 805 | r#" |
806 | mod baz { pub fn bar() {} } | ||
807 | |||
808 | fn main() { baz::bar(); } | ||
809 | "#, | ||
750 | ); | 810 | ); |
751 | } | 811 | } |
752 | 812 | ||
753 | #[test] | 813 | #[test] |
754 | fn test_rename_mod_filename_and_path() { | 814 | fn test_rename_mod_filename_and_path() { |
755 | let (analysis, position) = analysis_and_position( | 815 | check_expect( |
756 | " | 816 | "foo2", |
757 | //- /lib.rs | 817 | r#" |
758 | mod bar; | 818 | //- /lib.rs |
759 | fn f() { | 819 | mod bar; |
760 | bar::foo::fun() | 820 | fn f() { |
761 | } | 821 | bar::foo::fun() |
762 | 822 | } | |
763 | //- /bar.rs | ||
764 | pub mod foo<|>; | ||
765 | 823 | ||
766 | //- /bar/foo.rs | 824 | //- /bar.rs |
767 | // pub fn fun() {} | 825 | pub mod foo<|>; |
768 | ", | 826 | |
769 | ); | 827 | //- /bar/foo.rs |
770 | let new_name = "foo2"; | 828 | // pub fn fun() {} |
771 | let source_change = analysis.rename(position, new_name).unwrap(); | 829 | "#, |
772 | assert_debug_snapshot!(&source_change, | 830 | expect![[r#" |
773 | @r###" | 831 | RangeInfo { |
774 | Some( | 832 | range: 8..11, |
775 | RangeInfo { | 833 | info: SourceChange { |
776 | range: 8..11, | 834 | source_file_edits: [ |
777 | info: SourceChange { | 835 | SourceFileEdit { |
778 | source_file_edits: [ | 836 | file_id: FileId( |
779 | SourceFileEdit { | 837 | 2, |
780 | file_id: FileId( | 838 | ), |
781 | 2, | 839 | edit: TextEdit { |
782 | ), | 840 | indels: [ |
783 | edit: TextEdit { | 841 | Indel { |
784 | indels: [ | 842 | insert: "foo2", |
785 | Indel { | 843 | delete: 8..11, |
786 | insert: "foo2", | 844 | }, |
787 | delete: 8..11, | 845 | ], |
788 | }, | 846 | }, |
789 | ], | ||
790 | }, | 847 | }, |
791 | }, | 848 | SourceFileEdit { |
792 | SourceFileEdit { | 849 | file_id: FileId( |
793 | file_id: FileId( | 850 | 1, |
794 | 1, | 851 | ), |
795 | ), | 852 | edit: TextEdit { |
796 | edit: TextEdit { | 853 | indels: [ |
797 | indels: [ | 854 | Indel { |
798 | Indel { | 855 | insert: "foo2", |
799 | insert: "foo2", | 856 | delete: 27..30, |
800 | delete: 27..30, | 857 | }, |
801 | }, | 858 | ], |
802 | ], | 859 | }, |
803 | }, | 860 | }, |
804 | }, | 861 | ], |
805 | ], | 862 | file_system_edits: [ |
806 | file_system_edits: [ | 863 | MoveFile { |
807 | MoveFile { | 864 | src: FileId( |
808 | src: FileId( | 865 | 3, |
809 | 3, | 866 | ), |
810 | ), | 867 | anchor: FileId( |
811 | dst_source_root: SourceRootId( | 868 | 3, |
812 | 0, | 869 | ), |
813 | ), | 870 | dst: "foo2.rs", |
814 | dst_path: "bar/foo2.rs", | 871 | }, |
815 | }, | 872 | ], |
816 | ], | 873 | is_snippet: false, |
817 | is_snippet: false, | 874 | }, |
818 | }, | 875 | } |
819 | }, | 876 | "#]], |
820 | ) | 877 | ); |
821 | "###); | ||
822 | } | 878 | } |
823 | 879 | ||
824 | #[test] | 880 | #[test] |
825 | fn test_enum_variant_from_module_1() { | 881 | fn test_enum_variant_from_module_1() { |
826 | test_rename( | 882 | check( |
883 | "Baz", | ||
827 | r#" | 884 | r#" |
828 | mod foo { | 885 | mod foo { |
829 | pub enum Foo { | 886 | pub enum Foo { Bar<|> } |
830 | Bar<|>, | 887 | } |
831 | } | ||
832 | } | ||
833 | 888 | ||
834 | fn func(f: foo::Foo) { | 889 | fn func(f: foo::Foo) { |
835 | match f { | 890 | match f { |
836 | foo::Foo::Bar => {} | 891 | foo::Foo::Bar => {} |
837 | } | ||
838 | } | 892 | } |
839 | "#, | 893 | } |
840 | "Baz", | 894 | "#, |
841 | r#" | 895 | r#" |
842 | mod foo { | 896 | mod foo { |
843 | pub enum Foo { | 897 | pub enum Foo { Baz } |
844 | Baz, | 898 | } |
845 | } | ||
846 | } | ||
847 | 899 | ||
848 | fn func(f: foo::Foo) { | 900 | fn func(f: foo::Foo) { |
849 | match f { | 901 | match f { |
850 | foo::Foo::Baz => {} | 902 | foo::Foo::Baz => {} |
851 | } | ||
852 | } | 903 | } |
853 | "#, | 904 | } |
905 | "#, | ||
854 | ); | 906 | ); |
855 | } | 907 | } |
856 | 908 | ||
857 | #[test] | 909 | #[test] |
858 | fn test_enum_variant_from_module_2() { | 910 | fn test_enum_variant_from_module_2() { |
859 | test_rename( | 911 | check( |
912 | "baz", | ||
860 | r#" | 913 | r#" |
861 | mod foo { | 914 | mod foo { |
862 | pub struct Foo { | 915 | pub struct Foo { pub bar<|>: uint } |
863 | pub bar<|>: uint, | 916 | } |
864 | } | ||
865 | } | ||
866 | 917 | ||
867 | fn foo(f: foo::Foo) { | 918 | fn foo(f: foo::Foo) { |
868 | let _ = f.bar; | 919 | let _ = f.bar; |
869 | } | 920 | } |
870 | "#, | 921 | "#, |
871 | "baz", | ||
872 | r#" | 922 | r#" |
873 | mod foo { | 923 | mod foo { |
874 | pub struct Foo { | 924 | pub struct Foo { pub baz: uint } |
875 | pub baz: uint, | 925 | } |
876 | } | ||
877 | } | ||
878 | 926 | ||
879 | fn foo(f: foo::Foo) { | 927 | fn foo(f: foo::Foo) { |
880 | let _ = f.baz; | 928 | let _ = f.baz; |
881 | } | 929 | } |
882 | "#, | 930 | "#, |
883 | ); | 931 | ); |
884 | } | 932 | } |
885 | 933 | ||
886 | #[test] | 934 | #[test] |
887 | fn test_parameter_to_self() { | 935 | fn test_parameter_to_self() { |
888 | test_rename( | 936 | check( |
937 | "self", | ||
889 | r#" | 938 | r#" |
890 | struct Foo { | 939 | struct Foo { i: i32 } |
891 | i: i32, | ||
892 | } | ||
893 | 940 | ||
894 | impl Foo { | 941 | impl Foo { |
895 | fn f(foo<|>: &mut Foo) -> i32 { | 942 | fn f(foo<|>: &mut Foo) -> i32 { |
896 | foo.i | 943 | foo.i |
897 | } | ||
898 | } | 944 | } |
899 | "#, | 945 | } |
900 | "self", | 946 | "#, |
901 | r#" | 947 | r#" |
902 | struct Foo { | 948 | struct Foo { i: i32 } |
903 | i: i32, | ||
904 | } | ||
905 | 949 | ||
906 | impl Foo { | 950 | impl Foo { |
907 | fn f(&mut self) -> i32 { | 951 | fn f(&mut self) -> i32 { |
908 | self.i | 952 | self.i |
909 | } | ||
910 | } | 953 | } |
911 | "#, | 954 | } |
955 | "#, | ||
912 | ); | 956 | ); |
913 | } | 957 | } |
914 | 958 | ||
915 | #[test] | 959 | #[test] |
916 | fn test_self_to_parameter() { | 960 | fn test_self_to_parameter() { |
917 | test_rename( | 961 | check( |
962 | "foo", | ||
918 | r#" | 963 | r#" |
919 | struct Foo { | 964 | struct Foo { i: i32 } |
920 | i: i32, | ||
921 | } | ||
922 | 965 | ||
923 | impl Foo { | 966 | impl Foo { |
924 | fn f(&mut <|>self) -> i32 { | 967 | fn f(&mut <|>self) -> i32 { |
925 | self.i | 968 | self.i |
926 | } | ||
927 | } | 969 | } |
928 | "#, | 970 | } |
929 | "foo", | 971 | "#, |
930 | r#" | 972 | r#" |
931 | struct Foo { | 973 | struct Foo { i: i32 } |
932 | i: i32, | ||
933 | } | ||
934 | 974 | ||
935 | impl Foo { | 975 | impl Foo { |
936 | fn f(foo: &mut Foo) -> i32 { | 976 | fn f(foo: &mut Foo) -> i32 { |
937 | foo.i | 977 | foo.i |
938 | } | ||
939 | } | 978 | } |
940 | "#, | 979 | } |
980 | "#, | ||
941 | ); | 981 | ); |
942 | } | 982 | } |
943 | 983 | ||
944 | #[test] | 984 | #[test] |
945 | fn test_self_in_path_to_parameter() { | 985 | fn test_self_in_path_to_parameter() { |
946 | test_rename( | 986 | check( |
987 | "foo", | ||
947 | r#" | 988 | r#" |
948 | struct Foo { | 989 | struct Foo { i: i32 } |
949 | i: i32, | ||
950 | } | ||
951 | 990 | ||
952 | impl Foo { | 991 | impl Foo { |
953 | fn f(&self) -> i32 { | 992 | fn f(&self) -> i32 { |
954 | let self_var = 1; | 993 | let self_var = 1; |
955 | self<|>.i | 994 | self<|>.i |
956 | } | ||
957 | } | 995 | } |
958 | "#, | 996 | } |
959 | "foo", | 997 | "#, |
960 | r#" | 998 | r#" |
961 | struct Foo { | 999 | struct Foo { i: i32 } |
962 | i: i32, | ||
963 | } | ||
964 | 1000 | ||
965 | impl Foo { | 1001 | impl Foo { |
966 | fn f(foo: &Foo) -> i32 { | 1002 | fn f(foo: &Foo) -> i32 { |
967 | let self_var = 1; | 1003 | let self_var = 1; |
968 | foo.i | 1004 | foo.i |
969 | } | ||
970 | } | 1005 | } |
971 | "#, | 1006 | } |
1007 | "#, | ||
972 | ); | 1008 | ); |
973 | } | 1009 | } |
974 | |||
975 | fn test_rename(text: &str, new_name: &str, expected: &str) { | ||
976 | let (analysis, position) = single_file_with_position(text); | ||
977 | let source_change = analysis.rename(position, new_name).unwrap(); | ||
978 | let mut text_edit_builder = TextEditBuilder::default(); | ||
979 | let mut file_id: Option<FileId> = None; | ||
980 | if let Some(change) = source_change { | ||
981 | for edit in change.info.source_file_edits { | ||
982 | file_id = Some(edit.file_id); | ||
983 | for indel in edit.edit.into_iter() { | ||
984 | text_edit_builder.replace(indel.delete, indel.insert); | ||
985 | } | ||
986 | } | ||
987 | } | ||
988 | let mut result = analysis.file_text(file_id.unwrap()).unwrap().to_string(); | ||
989 | text_edit_builder.finish().apply(&mut result); | ||
990 | assert_eq_text!(expected, &*result); | ||
991 | } | ||
992 | } | 1010 | } |