Skip to content

Commit daf0856

Browse files
authored
Merge pull request #20681 from A4-Tacks/indent-diag-reduanted-trait-assoc
Fix indent for trait_impl_redundant_assoc_item
2 parents 17e7f0c + e44f348 commit daf0856

2 files changed

Lines changed: 109 additions & 7 deletions

File tree

crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs

Lines changed: 90 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use ide_db::{
66
source_change::SourceChangeBuilder,
77
};
88
use syntax::ToSmolStr;
9+
use syntax::ast::edit::AstNodeEdit;
910

1011
use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext};
1112

@@ -23,33 +24,32 @@ pub(crate) fn trait_impl_redundant_assoc_item(
2324

2425
let default_range = d.impl_.syntax_node_ptr().text_range();
2526
let trait_name = d.trait_.name(db).display_no_db(ctx.edition).to_smolstr();
27+
let indent_level = d.trait_.source(db).map_or(0, |it| it.value.indent_level().0) + 1;
2628

2729
let (redundant_item_name, diagnostic_range, redundant_item_def) = match assoc_item {
2830
hir::AssocItem::Function(id) => {
2931
let function = id;
3032
(
3133
format!("`fn {redundant_assoc_item_name}`"),
3234
function.source(db).map(|it| it.syntax().text_range()).unwrap_or(default_range),
33-
format!("\n {};", function.display(db, ctx.display_target)),
35+
format!("\n{};", function.display(db, ctx.display_target)),
3436
)
3537
}
3638
hir::AssocItem::Const(id) => {
3739
let constant = id;
3840
(
3941
format!("`const {redundant_assoc_item_name}`"),
4042
constant.source(db).map(|it| it.syntax().text_range()).unwrap_or(default_range),
41-
format!("\n {};", constant.display(db, ctx.display_target)),
43+
format!("\n{};", constant.display(db, ctx.display_target)),
4244
)
4345
}
4446
hir::AssocItem::TypeAlias(id) => {
4547
let type_alias = id;
4648
(
4749
format!("`type {redundant_assoc_item_name}`"),
4850
type_alias.source(db).map(|it| it.syntax().text_range()).unwrap_or(default_range),
49-
format!(
50-
"\n type {};",
51-
type_alias.name(ctx.sema.db).display_no_db(ctx.edition).to_smolstr()
52-
),
51+
// FIXME cannot generate generic parameter and bounds
52+
format!("\ntype {};", type_alias.name(ctx.sema.db).display_no_db(ctx.edition)),
5353
)
5454
}
5555
};
@@ -65,7 +65,7 @@ pub(crate) fn trait_impl_redundant_assoc_item(
6565
.with_fixes(quickfix_for_redundant_assoc_item(
6666
ctx,
6767
d,
68-
redundant_item_def,
68+
stdx::indent_string(&redundant_item_def, indent_level),
6969
diagnostic_range,
7070
))
7171
}
@@ -191,6 +191,89 @@ impl Marker for Foo {
191191
)
192192
}
193193

194+
#[test]
195+
fn quickfix_indentations() {
196+
check_fix(
197+
r#"
198+
mod indent {
199+
trait Marker {
200+
fn boo();
201+
}
202+
struct Foo;
203+
impl Marker for Foo {
204+
fn$0 bar<T: Copy>(_a: i32, _b: T) -> String {}
205+
fn boo() {}
206+
}
207+
}
208+
"#,
209+
r#"
210+
mod indent {
211+
trait Marker {
212+
fn bar<T>(_a: i32, _b: T) -> String
213+
where
214+
T: Copy,;
215+
fn boo();
216+
}
217+
struct Foo;
218+
impl Marker for Foo {
219+
fn bar<T: Copy>(_a: i32, _b: T) -> String {}
220+
fn boo() {}
221+
}
222+
}
223+
"#,
224+
);
225+
226+
check_fix(
227+
r#"
228+
mod indent {
229+
trait Marker {
230+
fn foo () {}
231+
}
232+
struct Foo;
233+
impl Marker for Foo {
234+
const FLAG: bool$0 = false;
235+
}
236+
}
237+
"#,
238+
r#"
239+
mod indent {
240+
trait Marker {
241+
const FLAG: bool;
242+
fn foo () {}
243+
}
244+
struct Foo;
245+
impl Marker for Foo {
246+
const FLAG: bool = false;
247+
}
248+
}
249+
"#,
250+
);
251+
252+
check_fix(
253+
r#"
254+
mod indent {
255+
trait Marker {
256+
}
257+
struct Foo;
258+
impl Marker for Foo {
259+
type T = i32;$0
260+
}
261+
}
262+
"#,
263+
r#"
264+
mod indent {
265+
trait Marker {
266+
type T;
267+
}
268+
struct Foo;
269+
impl Marker for Foo {
270+
type T = i32;
271+
}
272+
}
273+
"#,
274+
);
275+
}
276+
194277
#[test]
195278
fn quickfix_dont_work() {
196279
check_no_fix(

crates/stdx/src/lib.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Missing batteries for standard libraries.
22
3+
use std::borrow::Cow;
34
use std::io as sio;
45
use std::process::Command;
56
use std::{cmp::Ordering, ops, time::Instant};
@@ -250,6 +251,24 @@ pub fn dedent_by(spaces: usize, text: &str) -> String {
250251
.collect()
251252
}
252253

254+
/// Indent non empty lines, including the first line
255+
#[must_use]
256+
pub fn indent_string(s: &str, indent_level: u8) -> String {
257+
if indent_level == 0 || s.is_empty() {
258+
return s.to_owned();
259+
}
260+
let indent_str = " ".repeat(indent_level as usize);
261+
s.split_inclusive("\n")
262+
.map(|line| {
263+
if line.trim_end().is_empty() {
264+
Cow::Borrowed(line)
265+
} else {
266+
format!("{indent_str}{line}").into()
267+
}
268+
})
269+
.collect()
270+
}
271+
253272
pub fn equal_range_by<T, F>(slice: &[T], mut key: F) -> ops::Range<usize>
254273
where
255274
F: FnMut(&T) -> Ordering,

0 commit comments

Comments
 (0)