Skip to content

Commit fc30c5c

Browse files
committed
internal: refactor incorrect case diagnostics
1 parent 2ad7892 commit fc30c5c

File tree

6 files changed

+49
-79
lines changed

6 files changed

+49
-79
lines changed

crates/hir/src/diagnostics.rs

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ macro_rules! diagnostics {
3434
diagnostics![
3535
BreakOutsideOfLoop,
3636
InactiveCode,
37+
IncorrectCase,
3738
MacroError,
3839
MismatchedArgCount,
3940
MissingFields,
@@ -195,31 +196,3 @@ impl Diagnostic for InternalBailedOut {
195196
}
196197

197198
pub use hir_ty::diagnostics::IncorrectCase;
198-
199-
impl Diagnostic for IncorrectCase {
200-
fn code(&self) -> DiagnosticCode {
201-
DiagnosticCode("incorrect-ident-case")
202-
}
203-
204-
fn message(&self) -> String {
205-
format!(
206-
"{} `{}` should have {} name, e.g. `{}`",
207-
self.ident_type,
208-
self.ident_text,
209-
self.expected_case.to_string(),
210-
self.suggested_text
211-
)
212-
}
213-
214-
fn display_source(&self) -> InFile<SyntaxNodePtr> {
215-
InFile::new(self.file, self.ident.clone().into())
216-
}
217-
218-
fn as_any(&self) -> &(dyn Any + Send + 'static) {
219-
self
220-
}
221-
222-
fn is_experimental(&self) -> bool {
223-
true
224-
}
225-
}

crates/hir/src/lib.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ use crate::{
8686
pub use crate::{
8787
attrs::{HasAttrs, Namespace},
8888
diagnostics::{
89-
AnyDiagnostic, BreakOutsideOfLoop, InactiveCode, InternalBailedOut, MacroError,
90-
MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkOrSomeInTailExpr,
89+
AnyDiagnostic, BreakOutsideOfLoop, InactiveCode, IncorrectCase, InternalBailedOut,
90+
MacroError, MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkOrSomeInTailExpr,
9191
MissingUnsafe, NoSuchField, RemoveThisSemicolon, ReplaceFilterMapNextWithFindMap,
9292
UnimplementedBuiltinMacro, UnresolvedExternCrate, UnresolvedImport, UnresolvedMacroCall,
9393
UnresolvedModule, UnresolvedProcMacro,
@@ -340,7 +340,7 @@ impl ModuleDef {
340340
}
341341
}
342342

343-
pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {
343+
pub fn diagnostics(self, db: &dyn HirDatabase) -> Vec<AnyDiagnostic> {
344344
let id = match self {
345345
ModuleDef::Adt(it) => match it {
346346
Adt::Struct(it) => it.id.into(),
@@ -353,17 +353,19 @@ impl ModuleDef {
353353
ModuleDef::Module(it) => it.id.into(),
354354
ModuleDef::Const(it) => it.id.into(),
355355
ModuleDef::Static(it) => it.id.into(),
356-
_ => return,
356+
_ => return Vec::new(),
357357
};
358358

359359
let module = match self.module(db) {
360360
Some(it) => it,
361-
None => return,
361+
None => return Vec::new(),
362362
};
363363

364+
let mut acc = Vec::new();
364365
for diag in hir_ty::diagnostics::validate_module_item(db, module.id.krate(), id) {
365-
sink.push(diag)
366+
acc.push(diag.into())
366367
}
368+
acc
367369
}
368370
}
369371

@@ -624,7 +626,7 @@ impl Module {
624626
acc.extend(m.diagnostics(db, sink, internal_diagnostics))
625627
}
626628
}
627-
_ => decl.diagnostics(db, sink),
629+
_ => acc.extend(decl.diagnostics(db)),
628630
}
629631
}
630632

@@ -1234,7 +1236,7 @@ impl Function {
12341236
}
12351237

12361238
for diag in hir_ty::diagnostics::validate_module_item(db, krate, self.id.into()) {
1237-
sink.push(diag)
1239+
acc.push(diag.into())
12381240
}
12391241
acc
12401242
}

crates/hir_ty/src/diagnostics.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,6 @@ impl fmt::Display for IdentType {
8484
}
8585
}
8686

87-
// Diagnostic: incorrect-ident-case
88-
//
89-
// This diagnostic is triggered if an item name doesn't follow https://doc.rust-lang.org/1.0.0/style/style/naming/README.html[Rust naming convention].
9087
#[derive(Debug)]
9188
pub struct IncorrectCase {
9289
pub file: HirFileId,

crates/ide/src/diagnostics.rs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
77
mod break_outside_of_loop;
88
mod inactive_code;
9+
mod incorrect_case;
910
mod macro_error;
1011
mod mismatched_arg_count;
1112
mod missing_fields;
@@ -135,7 +136,6 @@ pub struct DiagnosticsConfig {
135136
struct DiagnosticsContext<'a> {
136137
config: &'a DiagnosticsConfig,
137138
sema: Semantics<'a, RootDatabase>,
138-
#[allow(unused)]
139139
resolve: &'a AssistResolveStrategy,
140140
}
141141

@@ -165,9 +165,6 @@ pub(crate) fn diagnostics(
165165
}
166166
let res = RefCell::new(res);
167167
let sink_builder = DiagnosticSinkBuilder::new()
168-
.on::<hir::diagnostics::IncorrectCase, _>(|d| {
169-
res.borrow_mut().push(warning_with_fix(d, &sema, resolve));
170-
})
171168
.on::<UnlinkedFile, _>(|d| {
172169
// Limit diagnostic to the first few characters in the file. This matches how VS Code
173170
// renders it with the full span, but on other editors, and is less invasive.
@@ -216,6 +213,7 @@ pub(crate) fn diagnostics(
216213
#[rustfmt::skip]
217214
let d = match diag {
218215
AnyDiagnostic::BreakOutsideOfLoop(d) => break_outside_of_loop::break_outside_of_loop(&ctx, &d),
216+
AnyDiagnostic::IncorrectCase(d) => incorrect_case::incorrect_case(&ctx, &d),
219217
AnyDiagnostic::MacroError(d) => macro_error::macro_error(&ctx, &d),
220218
AnyDiagnostic::MismatchedArgCount(d) => mismatched_arg_count::mismatched_arg_count(&ctx, &d),
221219
AnyDiagnostic::MissingFields(d) => missing_fields::missing_fields(&ctx, &d),
@@ -250,16 +248,6 @@ pub(crate) fn diagnostics(
250248
res
251249
}
252250

253-
fn warning_with_fix<D: DiagnosticWithFixes>(
254-
d: &D,
255-
sema: &Semantics<RootDatabase>,
256-
resolve: &AssistResolveStrategy,
257-
) -> Diagnostic {
258-
Diagnostic::hint(sema.diagnostics_display_range(d.display_source()).range, d.message())
259-
.with_fixes(d.fixes(sema, resolve))
260-
.with_code(Some(d.code()))
261-
}
262-
263251
fn check_unnecessary_braces_in_use_statement(
264252
acc: &mut Vec<Diagnostic>,
265253
file_id: FileId,

crates/ide/src/diagnostics/fixes.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//! Provides a way to attach fixes to the diagnostics.
22
//! The same module also has all curret custom fixes for the diagnostics implemented.
3-
mod change_case;
43
54
use hir::{diagnostics::Diagnostic, Semantics};
65
use ide_assists::AssistResolveStrategy;

crates/ide/src/diagnostics/fixes/change_case.rs renamed to crates/ide/src/diagnostics/incorrect_case.rs

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,46 @@
1-
use hir::{db::AstDatabase, diagnostics::IncorrectCase, InFile, Semantics};
2-
use ide_assists::{Assist, AssistResolveStrategy};
3-
use ide_db::{base_db::FilePosition, RootDatabase};
1+
use hir::{db::AstDatabase, InFile};
2+
use ide_assists::Assist;
3+
use ide_db::base_db::FilePosition;
44
use syntax::AstNode;
55

66
use crate::{
7-
diagnostics::{unresolved_fix, DiagnosticWithFixes},
7+
diagnostics::{unresolved_fix, Diagnostic, DiagnosticsContext},
88
references::rename::rename_with_semantics,
9+
Severity,
910
};
1011

11-
impl DiagnosticWithFixes for IncorrectCase {
12-
fn fixes(
13-
&self,
14-
sema: &Semantics<RootDatabase>,
15-
resolve: &AssistResolveStrategy,
16-
) -> Option<Vec<Assist>> {
17-
let root = sema.db.parse_or_expand(self.file)?;
18-
let name_node = self.ident.to_node(&root);
19-
20-
let name_node = InFile::new(self.file, name_node.syntax());
21-
let frange = name_node.original_file_range(sema.db);
22-
let file_position = FilePosition { file_id: frange.file_id, offset: frange.range.start() };
23-
24-
let label = format!("Rename to {}", self.suggested_text);
25-
let mut res = unresolved_fix("change_case", &label, frange.range);
26-
if resolve.should_resolve(&res.id) {
27-
let source_change = rename_with_semantics(sema, file_position, &self.suggested_text);
28-
res.source_change = Some(source_change.ok().unwrap_or_default());
29-
}
30-
31-
Some(vec![res])
12+
// Diagnostic: incorrect-ident-case
13+
//
14+
// This diagnostic is triggered if an item name doesn't follow https://doc.rust-lang.org/1.0.0/style/style/naming/README.html[Rust naming convention].
15+
pub(super) fn incorrect_case(ctx: &DiagnosticsContext<'_>, d: &hir::IncorrectCase) -> Diagnostic {
16+
Diagnostic::new(
17+
"incorrect-ident-case",
18+
format!(
19+
"{} `{}` should have {} name, e.g. `{}`",
20+
d.ident_type, d.ident_text, d.expected_case, d.suggested_text
21+
),
22+
ctx.sema.diagnostics_display_range(InFile::new(d.file, d.ident.clone().into())).range,
23+
)
24+
.severity(Severity::WeakWarning)
25+
.with_fixes(fixes(ctx, d))
26+
}
27+
28+
fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::IncorrectCase) -> Option<Vec<Assist>> {
29+
let root = ctx.sema.db.parse_or_expand(d.file)?;
30+
let name_node = d.ident.to_node(&root);
31+
32+
let name_node = InFile::new(d.file, name_node.syntax());
33+
let frange = name_node.original_file_range(ctx.sema.db);
34+
let file_position = FilePosition { file_id: frange.file_id, offset: frange.range.start() };
35+
36+
let label = format!("Rename to {}", d.suggested_text);
37+
let mut res = unresolved_fix("change_case", &label, frange.range);
38+
if ctx.resolve.should_resolve(&res.id) {
39+
let source_change = rename_with_semantics(&ctx.sema, file_position, &d.suggested_text);
40+
res.source_change = Some(source_change.ok().unwrap_or_default());
3241
}
42+
43+
Some(vec![res])
3344
}
3445

3546
#[cfg(test)]

0 commit comments

Comments
 (0)