diff options
-rw-r--r-- | crates/ide/src/references/rename.rs | 49 | ||||
-rw-r--r-- | crates/ide_db/src/search.rs | 16 | ||||
-rw-r--r-- | crates/syntax/src/ast/expr_ext.rs | 12 | ||||
-rw-r--r-- | crates/syntax/src/ast/node_ext.rs | 10 |
4 files changed, 68 insertions, 19 deletions
diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs index 26ac2371a..b3ade20ef 100644 --- a/crates/ide/src/references/rename.rs +++ b/crates/ide/src/references/rename.rs | |||
@@ -106,7 +106,11 @@ fn find_module_at_offset( | |||
106 | Some(module) | 106 | Some(module) |
107 | } | 107 | } |
108 | 108 | ||
109 | fn source_edit_from_reference(reference: Reference, new_name: &str) -> SourceFileEdit { | 109 | fn source_edit_from_reference( |
110 | sema: &Semantics<RootDatabase>, | ||
111 | reference: Reference, | ||
112 | new_name: &str, | ||
113 | ) -> SourceFileEdit { | ||
110 | let mut replacement_text = String::new(); | 114 | let mut replacement_text = String::new(); |
111 | let file_id = reference.file_range.file_id; | 115 | let file_id = reference.file_range.file_id; |
112 | let range = match reference.kind { | 116 | let range = match reference.kind { |
@@ -122,6 +126,22 @@ fn source_edit_from_reference(reference: Reference, new_name: &str) -> SourceFil | |||
122 | replacement_text.push_str(new_name); | 126 | replacement_text.push_str(new_name); |
123 | TextRange::new(reference.file_range.range.end(), reference.file_range.range.end()) | 127 | TextRange::new(reference.file_range.range.end(), reference.file_range.range.end()) |
124 | } | 128 | } |
129 | ReferenceKind::RecordExprField => { | ||
130 | replacement_text.push_str(new_name); | ||
131 | let mut range = reference.file_range.range; | ||
132 | if let Some(field_expr) = syntax::algo::find_node_at_range::<ast::RecordExprField>( | ||
133 | sema.parse(file_id).syntax(), | ||
134 | reference.file_range.range, | ||
135 | ) { | ||
136 | // use shorthand initializer if we were to write foo: foo | ||
137 | if let Some(name) = field_expr.expr().and_then(|e| e.name_ref()) { | ||
138 | if &name.to_string() == new_name { | ||
139 | range = field_expr.syntax().text_range(); | ||
140 | } | ||
141 | } | ||
142 | } | ||
143 | range | ||
144 | } | ||
125 | _ => { | 145 | _ => { |
126 | replacement_text.push_str(new_name); | 146 | replacement_text.push_str(new_name); |
127 | reference.file_range.range | 147 | reference.file_range.range |
@@ -170,7 +190,7 @@ fn rename_mod( | |||
170 | let ref_edits = refs | 190 | let ref_edits = refs |
171 | .references | 191 | .references |
172 | .into_iter() | 192 | .into_iter() |
173 | .map(|reference| source_edit_from_reference(reference, new_name)); | 193 | .map(|reference| source_edit_from_reference(sema, reference, new_name)); |
174 | source_file_edits.extend(ref_edits); | 194 | source_file_edits.extend(ref_edits); |
175 | 195 | ||
176 | Ok(RangeInfo::new(range, SourceChange::from_edits(source_file_edits, file_system_edits))) | 196 | Ok(RangeInfo::new(range, SourceChange::from_edits(source_file_edits, file_system_edits))) |
@@ -211,7 +231,7 @@ fn rename_to_self( | |||
211 | 231 | ||
212 | let mut edits = usages | 232 | let mut edits = usages |
213 | .into_iter() | 233 | .into_iter() |
214 | .map(|reference| source_edit_from_reference(reference, "self")) | 234 | .map(|reference| source_edit_from_reference(sema, reference, "self")) |
215 | .collect::<Vec<_>>(); | 235 | .collect::<Vec<_>>(); |
216 | 236 | ||
217 | edits.push(SourceFileEdit { | 237 | edits.push(SourceFileEdit { |
@@ -300,7 +320,7 @@ fn rename_reference( | |||
300 | 320 | ||
301 | let edit = refs | 321 | let edit = refs |
302 | .into_iter() | 322 | .into_iter() |
303 | .map(|reference| source_edit_from_reference(reference, new_name)) | 323 | .map(|reference| source_edit_from_reference(sema, reference, new_name)) |
304 | .collect::<Vec<_>>(); | 324 | .collect::<Vec<_>>(); |
305 | 325 | ||
306 | if edit.is_empty() { | 326 | if edit.is_empty() { |
@@ -1097,4 +1117,25 @@ impl Foo { | |||
1097 | "#, | 1117 | "#, |
1098 | ); | 1118 | ); |
1099 | } | 1119 | } |
1120 | |||
1121 | #[test] | ||
1122 | fn test_initializer_use_field_init_shorthand() { | ||
1123 | check( | ||
1124 | "bar", | ||
1125 | r#" | ||
1126 | struct Foo { i<|>: i32 } | ||
1127 | |||
1128 | fn foo(bar: i32) -> Foo { | ||
1129 | Foo { i: bar } | ||
1130 | } | ||
1131 | "#, | ||
1132 | r#" | ||
1133 | struct Foo { bar: i32 } | ||
1134 | |||
1135 | fn foo(bar: i32) -> Foo { | ||
1136 | Foo { bar } | ||
1137 | } | ||
1138 | "#, | ||
1139 | ); | ||
1140 | } | ||
1100 | } | 1141 | } |
diff --git a/crates/ide_db/src/search.rs b/crates/ide_db/src/search.rs index a24335240..4248606c8 100644 --- a/crates/ide_db/src/search.rs +++ b/crates/ide_db/src/search.rs | |||
@@ -30,6 +30,7 @@ pub enum ReferenceKind { | |||
30 | FieldShorthandForField, | 30 | FieldShorthandForField, |
31 | FieldShorthandForLocal, | 31 | FieldShorthandForLocal, |
32 | StructLiteral, | 32 | StructLiteral, |
33 | RecordExprField, | ||
33 | Other, | 34 | Other, |
34 | } | 35 | } |
35 | 36 | ||
@@ -278,12 +279,15 @@ impl<'a> FindUsages<'a> { | |||
278 | ) -> bool { | 279 | ) -> bool { |
279 | match NameRefClass::classify(self.sema, &name_ref) { | 280 | match NameRefClass::classify(self.sema, &name_ref) { |
280 | Some(NameRefClass::Definition(def)) if &def == self.def => { | 281 | Some(NameRefClass::Definition(def)) if &def == self.def => { |
281 | let kind = if is_record_lit_name_ref(&name_ref) || is_call_expr_name_ref(&name_ref) | 282 | let kind = |
282 | { | 283 | if name_ref.syntax().parent().and_then(ast::RecordExprField::cast).is_some() { |
283 | ReferenceKind::StructLiteral | 284 | ReferenceKind::RecordExprField |
284 | } else { | 285 | } else if is_record_lit_name_ref(&name_ref) || is_call_expr_name_ref(&name_ref) |
285 | ReferenceKind::Other | 286 | { |
286 | }; | 287 | ReferenceKind::StructLiteral |
288 | } else { | ||
289 | ReferenceKind::Other | ||
290 | }; | ||
287 | 291 | ||
288 | let reference = Reference { | 292 | let reference = Reference { |
289 | file_range: self.sema.original_range(name_ref.syntax()), | 293 | file_range: self.sema.original_range(name_ref.syntax()), |
diff --git a/crates/syntax/src/ast/expr_ext.rs b/crates/syntax/src/ast/expr_ext.rs index 9253c97d0..e4a9b945c 100644 --- a/crates/syntax/src/ast/expr_ext.rs +++ b/crates/syntax/src/ast/expr_ext.rs | |||
@@ -22,6 +22,18 @@ impl ast::Expr { | |||
22 | _ => false, | 22 | _ => false, |
23 | } | 23 | } |
24 | } | 24 | } |
25 | |||
26 | pub fn name_ref(&self) -> Option<ast::NameRef> { | ||
27 | if let ast::Expr::PathExpr(expr) = self { | ||
28 | let path = expr.path()?; | ||
29 | let segment = path.segment()?; | ||
30 | let name_ref = segment.name_ref()?; | ||
31 | if path.qualifier().is_none() { | ||
32 | return Some(name_ref); | ||
33 | } | ||
34 | } | ||
35 | None | ||
36 | } | ||
25 | } | 37 | } |
26 | 38 | ||
27 | #[derive(Debug, Clone, PartialEq, Eq)] | 39 | #[derive(Debug, Clone, PartialEq, Eq)] |
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index ce35ac01a..b70b840b8 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs | |||
@@ -203,15 +203,7 @@ impl ast::RecordExprField { | |||
203 | if let Some(name_ref) = self.name_ref() { | 203 | if let Some(name_ref) = self.name_ref() { |
204 | return Some(name_ref); | 204 | return Some(name_ref); |
205 | } | 205 | } |
206 | if let Some(ast::Expr::PathExpr(expr)) = self.expr() { | 206 | self.expr()?.name_ref() |
207 | let path = expr.path()?; | ||
208 | let segment = path.segment()?; | ||
209 | let name_ref = segment.name_ref()?; | ||
210 | if path.qualifier().is_none() { | ||
211 | return Some(name_ref); | ||
212 | } | ||
213 | } | ||
214 | None | ||
215 | } | 207 | } |
216 | } | 208 | } |
217 | 209 | ||