diff options
Diffstat (limited to 'crates/ide_diagnostics/src/lib.rs')
-rw-r--r-- | crates/ide_diagnostics/src/lib.rs | 112 |
1 files changed, 67 insertions, 45 deletions
diff --git a/crates/ide_diagnostics/src/lib.rs b/crates/ide_diagnostics/src/lib.rs index 2a16c73a8..88037be5a 100644 --- a/crates/ide_diagnostics/src/lib.rs +++ b/crates/ide_diagnostics/src/lib.rs | |||
@@ -1,28 +1,49 @@ | |||
1 | //! Collects diagnostics & fixits for a single file. | 1 | //! Diagnostics rendering and fixits. |
2 | //! | 2 | //! |
3 | //! The tricky bit here is that diagnostics are produced by hir in terms of | 3 | //! Most of the diagnostics originate from the dark depth of the compiler, and |
4 | //! macro-expanded files, but we need to present them to the users in terms of | 4 | //! are originally expressed in term of IR. When we emit the diagnostic, we are |
5 | //! original files. So we need to map the ranges. | 5 | //! usually not in the position to decide how to best "render" it in terms of |
6 | 6 | //! user-authored source code. We are especially not in the position to offer | |
7 | mod break_outside_of_loop; | 7 | //! fixits, as the compiler completely lacks the infrastructure to edit the |
8 | mod inactive_code; | 8 | //! source code. |
9 | mod incorrect_case; | 9 | //! |
10 | mod macro_error; | 10 | //! Instead, we "bubble up" raw, structured diagnostics until the `hir` crate, |
11 | mod mismatched_arg_count; | 11 | //! where we "cook" them so that each diagnostic is formulated in terms of `hir` |
12 | mod missing_fields; | 12 | //! types. Well, at least that's the aspiration, the "cooking" is somewhat |
13 | mod missing_match_arms; | 13 | //! ad-hoc at the moment. Anyways, we get a bunch of ide-friendly diagnostic |
14 | mod missing_ok_or_some_in_tail_expr; | 14 | //! structs from hir, and we want to render them to unified serializable |
15 | mod missing_unsafe; | 15 | //! representation (span, level, message) here. If we can, we also provide |
16 | mod no_such_field; | 16 | //! fixits. By the way, that's why we want to keep diagnostics structured |
17 | mod remove_this_semicolon; | 17 | //! internally -- so that we have all the info to make fixes. |
18 | mod replace_filter_map_next_with_find_map; | 18 | //! |
19 | mod unimplemented_builtin_macro; | 19 | //! We have one "handler" module per diagnostic code. Such a module contains |
20 | mod unlinked_file; | 20 | //! rendering, optional fixes and tests. It's OK if some low-level compiler |
21 | mod unresolved_extern_crate; | 21 | //! functionality ends up being tested via a diagnostic. |
22 | mod unresolved_import; | 22 | //! |
23 | mod unresolved_macro_call; | 23 | //! There are also a couple of ad-hoc diagnostics implemented directly here, we |
24 | mod unresolved_module; | 24 | //! don't yet have a great pattern for how to do them properly. |
25 | mod unresolved_proc_macro; | 25 | |
26 | mod handlers { | ||
27 | pub(crate) mod break_outside_of_loop; | ||
28 | pub(crate) mod inactive_code; | ||
29 | pub(crate) mod incorrect_case; | ||
30 | pub(crate) mod macro_error; | ||
31 | pub(crate) mod mismatched_arg_count; | ||
32 | pub(crate) mod missing_fields; | ||
33 | pub(crate) mod missing_match_arms; | ||
34 | pub(crate) mod missing_ok_or_some_in_tail_expr; | ||
35 | pub(crate) mod missing_unsafe; | ||
36 | pub(crate) mod no_such_field; | ||
37 | pub(crate) mod remove_this_semicolon; | ||
38 | pub(crate) mod replace_filter_map_next_with_find_map; | ||
39 | pub(crate) mod unimplemented_builtin_macro; | ||
40 | pub(crate) mod unlinked_file; | ||
41 | pub(crate) mod unresolved_extern_crate; | ||
42 | pub(crate) mod unresolved_import; | ||
43 | pub(crate) mod unresolved_macro_call; | ||
44 | pub(crate) mod unresolved_module; | ||
45 | pub(crate) mod unresolved_proc_macro; | ||
46 | } | ||
26 | 47 | ||
27 | mod field_shorthand; | 48 | mod field_shorthand; |
28 | 49 | ||
@@ -41,7 +62,8 @@ use syntax::{ | |||
41 | SyntaxNode, TextRange, | 62 | SyntaxNode, TextRange, |
42 | }; | 63 | }; |
43 | use text_edit::TextEdit; | 64 | use text_edit::TextEdit; |
44 | use unlinked_file::UnlinkedFile; | 65 | |
66 | use crate::handlers::unlinked_file::UnlinkedFile; | ||
45 | 67 | ||
46 | #[derive(Copy, Clone, Debug, PartialEq)] | 68 | #[derive(Copy, Clone, Debug, PartialEq)] |
47 | pub struct DiagnosticCode(pub &'static str); | 69 | pub struct DiagnosticCode(pub &'static str); |
@@ -148,32 +170,32 @@ pub fn diagnostics( | |||
148 | let ctx = DiagnosticsContext { config, sema, resolve }; | 170 | let ctx = DiagnosticsContext { config, sema, resolve }; |
149 | if module.is_none() { | 171 | if module.is_none() { |
150 | let d = UnlinkedFile { file: file_id }; | 172 | let d = UnlinkedFile { file: file_id }; |
151 | let d = unlinked_file::unlinked_file(&ctx, &d); | 173 | let d = handlers::unlinked_file::unlinked_file(&ctx, &d); |
152 | res.push(d) | 174 | res.push(d) |
153 | } | 175 | } |
154 | 176 | ||
155 | for diag in diags { | 177 | for diag in diags { |
156 | #[rustfmt::skip] | 178 | #[rustfmt::skip] |
157 | let d = match diag { | 179 | let d = match diag { |
158 | AnyDiagnostic::BreakOutsideOfLoop(d) => break_outside_of_loop::break_outside_of_loop(&ctx, &d), | 180 | AnyDiagnostic::BreakOutsideOfLoop(d) => handlers::break_outside_of_loop::break_outside_of_loop(&ctx, &d), |
159 | AnyDiagnostic::IncorrectCase(d) => incorrect_case::incorrect_case(&ctx, &d), | 181 | AnyDiagnostic::IncorrectCase(d) => handlers::incorrect_case::incorrect_case(&ctx, &d), |
160 | AnyDiagnostic::MacroError(d) => macro_error::macro_error(&ctx, &d), | 182 | AnyDiagnostic::MacroError(d) => handlers::macro_error::macro_error(&ctx, &d), |
161 | AnyDiagnostic::MismatchedArgCount(d) => mismatched_arg_count::mismatched_arg_count(&ctx, &d), | 183 | AnyDiagnostic::MismatchedArgCount(d) => handlers::mismatched_arg_count::mismatched_arg_count(&ctx, &d), |
162 | AnyDiagnostic::MissingFields(d) => missing_fields::missing_fields(&ctx, &d), | 184 | AnyDiagnostic::MissingFields(d) => handlers::missing_fields::missing_fields(&ctx, &d), |
163 | AnyDiagnostic::MissingMatchArms(d) => missing_match_arms::missing_match_arms(&ctx, &d), | 185 | AnyDiagnostic::MissingMatchArms(d) => handlers::missing_match_arms::missing_match_arms(&ctx, &d), |
164 | AnyDiagnostic::MissingOkOrSomeInTailExpr(d) => missing_ok_or_some_in_tail_expr::missing_ok_or_some_in_tail_expr(&ctx, &d), | 186 | AnyDiagnostic::MissingOkOrSomeInTailExpr(d) => handlers::missing_ok_or_some_in_tail_expr::missing_ok_or_some_in_tail_expr(&ctx, &d), |
165 | AnyDiagnostic::MissingUnsafe(d) => missing_unsafe::missing_unsafe(&ctx, &d), | 187 | AnyDiagnostic::MissingUnsafe(d) => handlers::missing_unsafe::missing_unsafe(&ctx, &d), |
166 | AnyDiagnostic::NoSuchField(d) => no_such_field::no_such_field(&ctx, &d), | 188 | AnyDiagnostic::NoSuchField(d) => handlers::no_such_field::no_such_field(&ctx, &d), |
167 | AnyDiagnostic::RemoveThisSemicolon(d) => remove_this_semicolon::remove_this_semicolon(&ctx, &d), | 189 | AnyDiagnostic::RemoveThisSemicolon(d) => handlers::remove_this_semicolon::remove_this_semicolon(&ctx, &d), |
168 | AnyDiagnostic::ReplaceFilterMapNextWithFindMap(d) => replace_filter_map_next_with_find_map::replace_filter_map_next_with_find_map(&ctx, &d), | 190 | AnyDiagnostic::ReplaceFilterMapNextWithFindMap(d) => handlers::replace_filter_map_next_with_find_map::replace_filter_map_next_with_find_map(&ctx, &d), |
169 | AnyDiagnostic::UnimplementedBuiltinMacro(d) => unimplemented_builtin_macro::unimplemented_builtin_macro(&ctx, &d), | 191 | AnyDiagnostic::UnimplementedBuiltinMacro(d) => handlers::unimplemented_builtin_macro::unimplemented_builtin_macro(&ctx, &d), |
170 | AnyDiagnostic::UnresolvedExternCrate(d) => unresolved_extern_crate::unresolved_extern_crate(&ctx, &d), | 192 | AnyDiagnostic::UnresolvedExternCrate(d) => handlers::unresolved_extern_crate::unresolved_extern_crate(&ctx, &d), |
171 | AnyDiagnostic::UnresolvedImport(d) => unresolved_import::unresolved_import(&ctx, &d), | 193 | AnyDiagnostic::UnresolvedImport(d) => handlers::unresolved_import::unresolved_import(&ctx, &d), |
172 | AnyDiagnostic::UnresolvedMacroCall(d) => unresolved_macro_call::unresolved_macro_call(&ctx, &d), | 194 | AnyDiagnostic::UnresolvedMacroCall(d) => handlers::unresolved_macro_call::unresolved_macro_call(&ctx, &d), |
173 | AnyDiagnostic::UnresolvedModule(d) => unresolved_module::unresolved_module(&ctx, &d), | 195 | AnyDiagnostic::UnresolvedModule(d) => handlers::unresolved_module::unresolved_module(&ctx, &d), |
174 | AnyDiagnostic::UnresolvedProcMacro(d) => unresolved_proc_macro::unresolved_proc_macro(&ctx, &d), | 196 | AnyDiagnostic::UnresolvedProcMacro(d) => handlers::unresolved_proc_macro::unresolved_proc_macro(&ctx, &d), |
175 | 197 | ||
176 | AnyDiagnostic::InactiveCode(d) => match inactive_code::inactive_code(&ctx, &d) { | 198 | AnyDiagnostic::InactiveCode(d) => match handlers::inactive_code::inactive_code(&ctx, &d) { |
177 | Some(it) => it, | 199 | Some(it) => it, |
178 | None => continue, | 200 | None => continue, |
179 | } | 201 | } |