aboutsummaryrefslogtreecommitdiff
path: root/crates/ide
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide')
-rw-r--r--crates/ide/src/references/rename.rs105
1 files changed, 59 insertions, 46 deletions
diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs
index 449cfa4ae..b8725693a 100644
--- a/crates/ide/src/references/rename.rs
+++ b/crates/ide/src/references/rename.rs
@@ -126,6 +126,7 @@ fn source_edit_from_reference(
126 TextRange::new(reference.file_range.range.end(), reference.file_range.range.end()) 126 TextRange::new(reference.file_range.range.end(), reference.file_range.range.end())
127 } 127 }
128 ReferenceKind::RecordFieldExprOrPat => { 128 ReferenceKind::RecordFieldExprOrPat => {
129 mark::hit!(test_rename_field_expr_pat);
129 replacement_text.push_str(new_name); 130 replacement_text.push_str(new_name);
130 edit_text_range_for_record_field_expr_or_pat(sema, reference.file_range, new_name) 131 edit_text_range_for_record_field_expr_or_pat(sema, reference.file_range, new_name)
131 } 132 }
@@ -145,29 +146,27 @@ fn edit_text_range_for_record_field_expr_or_pat(
145 file_range: FileRange, 146 file_range: FileRange,
146 new_name: &str, 147 new_name: &str,
147) -> TextRange { 148) -> TextRange {
148 let mut range = file_range.range;
149 let source_file = sema.parse(file_range.file_id); 149 let source_file = sema.parse(file_range.file_id);
150 let file_syntax = source_file.syntax(); 150 let file_syntax = source_file.syntax();
151 if let Some(field_expr) = 151 let original_range = file_range.range;
152 syntax::algo::find_node_at_range::<ast::RecordExprField>(file_syntax, range) 152
153 { 153 syntax::algo::find_node_at_range::<ast::RecordExprField>(file_syntax, original_range)
154 match field_expr.expr().and_then(|e| e.name_ref()) { 154 .and_then(|field_expr| match field_expr.expr().and_then(|e| e.name_ref()) {
155 Some(name) if &name.to_string() == new_name => range = field_expr.syntax().text_range(), 155 Some(name) if &name.to_string() == new_name => Some(field_expr.syntax().text_range()),
156 _ => (), 156 _ => None,
157 } 157 })
158 } else if let Some(field_pat) = 158 .or_else(|| {
159 syntax::algo::find_node_at_range::<ast::RecordPatField>(file_syntax, range) 159 syntax::algo::find_node_at_range::<ast::RecordPatField>(file_syntax, original_range)
160 { 160 .and_then(|field_pat| match field_pat.pat() {
161 match field_pat.pat() { 161 Some(ast::Pat::IdentPat(pat))
162 Some(ast::Pat::IdentPat(pat)) 162 if pat.name().map(|n| n.to_string()).as_deref() == Some(new_name) =>
163 if pat.name().map(|n| n.to_string()).as_deref() == Some(new_name) => 163 {
164 { 164 Some(field_pat.syntax().text_range())
165 range = field_pat.syntax().text_range() 165 }
166 } 166 _ => None,
167 _ => (), 167 })
168 } 168 })
169 } 169 .unwrap_or(original_range)
170 range
171} 170}
172 171
173fn rename_mod( 172fn rename_mod(
@@ -1140,6 +1139,7 @@ impl Foo {
1140 1139
1141 #[test] 1140 #[test]
1142 fn test_initializer_use_field_init_shorthand() { 1141 fn test_initializer_use_field_init_shorthand() {
1142 mark::check!(test_rename_field_expr_pat);
1143 check( 1143 check(
1144 "bar", 1144 "bar",
1145 r#" 1145 r#"
@@ -1160,27 +1160,23 @@ fn foo(bar: i32) -> Foo {
1160 } 1160 }
1161 1161
1162 #[test] 1162 #[test]
1163 fn test_rename_binding_in_destructure_pat_shorthand() { 1163 fn test_struct_field_destructure_into_shorthand() {
1164 check( 1164 check(
1165 "bar", 1165 "baz",
1166 r#" 1166 r#"
1167struct Foo { 1167struct Foo { i<|>: i32 }
1168 i: i32,
1169}
1170 1168
1171fn foo(foo: Foo) { 1169fn foo(foo: Foo) {
1172 let Foo { i } = foo; 1170 let Foo { i: baz } = foo;
1173 let _ = i<|>; 1171 let _ = baz;
1174} 1172}
1175"#, 1173"#,
1176 r#" 1174 r#"
1177struct Foo { 1175struct Foo { baz: i32 }
1178 i: i32,
1179}
1180 1176
1181fn foo(foo: Foo) { 1177fn foo(foo: Foo) {
1182 let Foo { i: bar } = foo; 1178 let Foo { baz } = foo;
1183 let _ = bar; 1179 let _ = baz;
1184} 1180}
1185"#, 1181"#,
1186 ); 1182 );
@@ -1188,6 +1184,16 @@ fn foo(foo: Foo) {
1188 1184
1189 #[test] 1185 #[test]
1190 fn test_rename_binding_in_destructure_pat() { 1186 fn test_rename_binding_in_destructure_pat() {
1187 let expected_fixture = r#"
1188struct Foo {
1189 i: i32,
1190}
1191
1192fn foo(foo: Foo) {
1193 let Foo { i: bar } = foo;
1194 let _ = bar;
1195}
1196"#;
1191 check( 1197 check(
1192 "bar", 1198 "bar",
1193 r#" 1199 r#"
@@ -1200,39 +1206,46 @@ fn foo(foo: Foo) {
1200 let _ = b<|>; 1206 let _ = b<|>;
1201} 1207}
1202"#, 1208"#,
1209 expected_fixture,
1210 );
1211 check(
1212 "bar",
1203 r#" 1213 r#"
1204struct Foo { 1214struct Foo {
1205 i: i32, 1215 i: i32,
1206} 1216}
1207 1217
1208fn foo(foo: Foo) { 1218fn foo(foo: Foo) {
1209 let Foo { i: bar } = foo; 1219 let Foo { i } = foo;
1210 let _ = bar; 1220 let _ = i<|>;
1211} 1221}
1212"#, 1222"#,
1223 expected_fixture,
1213 ); 1224 );
1214 } 1225 }
1215 1226
1216 #[test] 1227 #[test]
1217 fn test_struct_field_destructure_into_shorthand() { 1228 fn test_rename_binding_in_destructure_param_pat() {
1218 check( 1229 check(
1219 "baz", 1230 "bar",
1220 r#" 1231 r#"
1221struct Foo { i<|>: i32 } 1232struct Foo {
1233 i: i32
1234}
1222 1235
1223fn foo(foo: Foo) { 1236fn foo(Foo { i }: foo) -> i32 {
1224 let Foo { i: baz } = foo; 1237 i<|>
1225 let _ = baz;
1226} 1238}
1227"#, 1239"#,
1228 r#" 1240 r#"
1229struct Foo { baz: i32 } 1241struct Foo {
1242 i: i32
1243}
1230 1244
1231fn foo(foo: Foo) { 1245fn foo(Foo { i: bar }: foo) -> i32 {
1232 let Foo { baz } = foo; 1246 bar
1233 let _ = baz;
1234} 1247}
1235"#, 1248"#,
1236 ); 1249 )
1237 } 1250 }
1238} 1251}