diff options
-rw-r--r-- | crates/ra_ide/src/references/rename.rs | 52 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 2 |
2 files changed, 51 insertions, 3 deletions
diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs index ea6b354c2..b804d5f6d 100644 --- a/crates/ra_ide/src/references/rename.rs +++ b/crates/ra_ide/src/references/rename.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use hir::ModuleSource; | 3 | use hir::ModuleSource; |
4 | use ra_db::{RelativePath, RelativePathBuf, SourceDatabase, SourceDatabaseExt}; | 4 | use ra_db::{RelativePath, RelativePathBuf, SourceDatabase, SourceDatabaseExt}; |
5 | use ra_syntax::{algo::find_node_at_offset, ast, AstNode, SyntaxNode}; | 5 | use ra_syntax::{algo::find_node_at_offset, ast, tokenize, AstNode, SyntaxKind, SyntaxNode}; |
6 | use ra_text_edit::TextEdit; | 6 | use ra_text_edit::TextEdit; |
7 | 7 | ||
8 | use crate::{ | 8 | use crate::{ |
@@ -17,6 +17,13 @@ pub(crate) fn rename( | |||
17 | position: FilePosition, | 17 | position: FilePosition, |
18 | new_name: &str, | 18 | new_name: &str, |
19 | ) -> Option<RangeInfo<SourceChange>> { | 19 | ) -> Option<RangeInfo<SourceChange>> { |
20 | let tokens = tokenize(new_name); | ||
21 | if tokens.len() != 1 | ||
22 | || (tokens[0].kind != SyntaxKind::IDENT && tokens[0].kind != SyntaxKind::UNDERSCORE) | ||
23 | { | ||
24 | return None; | ||
25 | } | ||
26 | |||
20 | let parse = db.parse(position.file_id); | 27 | let parse = db.parse(position.file_id); |
21 | if let Some((ast_name, ast_module)) = | 28 | if let Some((ast_name, ast_module)) = |
22 | find_name_and_module_at_offset(parse.tree().syntax(), position) | 29 | find_name_and_module_at_offset(parse.tree().syntax(), position) |
@@ -124,6 +131,49 @@ mod tests { | |||
124 | }; | 131 | }; |
125 | 132 | ||
126 | #[test] | 133 | #[test] |
134 | fn test_rename_to_underscore() { | ||
135 | test_rename( | ||
136 | r#" | ||
137 | fn main() { | ||
138 | let i<|> = 1; | ||
139 | }"#, | ||
140 | "_", | ||
141 | r#" | ||
142 | fn main() { | ||
143 | let _ = 1; | ||
144 | }"#, | ||
145 | ); | ||
146 | } | ||
147 | |||
148 | #[test] | ||
149 | fn test_rename_to_raw_identifier() { | ||
150 | test_rename( | ||
151 | r#" | ||
152 | fn main() { | ||
153 | let i<|> = 1; | ||
154 | }"#, | ||
155 | "r#fn", | ||
156 | r#" | ||
157 | fn main() { | ||
158 | let r#fn = 1; | ||
159 | }"#, | ||
160 | ); | ||
161 | } | ||
162 | |||
163 | #[test] | ||
164 | fn test_rename_to_invalid_identifier() { | ||
165 | let (analysis, position) = single_file_with_position( | ||
166 | " | ||
167 | fn main() { | ||
168 | let i<|> = 1; | ||
169 | }", | ||
170 | ); | ||
171 | let new_name = "invalid!"; | ||
172 | let source_change = analysis.rename(position, new_name).unwrap(); | ||
173 | assert!(source_change.is_none()); | ||
174 | } | ||
175 | |||
176 | #[test] | ||
127 | fn test_rename_for_local() { | 177 | fn test_rename_for_local() { |
128 | test_rename( | 178 | test_rename( |
129 | r#" | 179 | r#" |
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index c81fa7f67..ca47ff5e1 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -480,8 +480,6 @@ pub fn handle_prepare_rename( | |||
480 | let _p = profile("handle_prepare_rename"); | 480 | let _p = profile("handle_prepare_rename"); |
481 | let position = params.try_conv_with(&world)?; | 481 | let position = params.try_conv_with(&world)?; |
482 | 482 | ||
483 | // We support renaming references like handle_rename does. | ||
484 | // In the future we may want to reject the renaming of things like keywords here too. | ||
485 | let optional_change = world.analysis().rename(position, "dummy")?; | 483 | let optional_change = world.analysis().rename(position, "dummy")?; |
486 | let range = match optional_change { | 484 | let range = match optional_change { |
487 | None => return Ok(None), | 485 | None => return Ok(None), |