aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_diagnostics/src/lib.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-06-14 17:32:39 +0100
committerAleksey Kladov <[email protected]>2021-06-14 17:45:39 +0100
commit4768e5fb23c058eba90f0a1dcd6e9d5c0ecdee1b (patch)
tree814f6a8ace5d131b9f704b3f81e8287b36943b79 /crates/ide_diagnostics/src/lib.rs
parent94f7b63522cb7464a853c74a8431587db6434b12 (diff)
internal: document diagnostics crate
Diffstat (limited to 'crates/ide_diagnostics/src/lib.rs')
-rw-r--r--crates/ide_diagnostics/src/lib.rs112
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
7mod break_outside_of_loop; 7//! fixits, as the compiler completely lacks the infrastructure to edit the
8mod inactive_code; 8//! source code.
9mod incorrect_case; 9//!
10mod macro_error; 10//! Instead, we "bubble up" raw, structured diagnostics until the `hir` crate,
11mod mismatched_arg_count; 11//! where we "cook" them so that each diagnostic is formulated in terms of `hir`
12mod missing_fields; 12//! types. Well, at least that's the aspiration, the "cooking" is somewhat
13mod missing_match_arms; 13//! ad-hoc at the moment. Anyways, we get a bunch of ide-friendly diagnostic
14mod missing_ok_or_some_in_tail_expr; 14//! structs from hir, and we want to render them to unified serializable
15mod missing_unsafe; 15//! representation (span, level, message) here. If we can, we also provide
16mod no_such_field; 16//! fixits. By the way, that's why we want to keep diagnostics structured
17mod remove_this_semicolon; 17//! internally -- so that we have all the info to make fixes.
18mod replace_filter_map_next_with_find_map; 18//!
19mod unimplemented_builtin_macro; 19//! We have one "handler" module per diagnostic code. Such a module contains
20mod unlinked_file; 20//! rendering, optional fixes and tests. It's OK if some low-level compiler
21mod unresolved_extern_crate; 21//! functionality ends up being tested via a diagnostic.
22mod unresolved_import; 22//!
23mod unresolved_macro_call; 23//! There are also a couple of ad-hoc diagnostics implemented directly here, we
24mod unresolved_module; 24//! don't yet have a great pattern for how to do them properly.
25mod unresolved_proc_macro; 25
26mod 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
27mod field_shorthand; 48mod field_shorthand;
28 49
@@ -41,7 +62,8 @@ use syntax::{
41 SyntaxNode, TextRange, 62 SyntaxNode, TextRange,
42}; 63};
43use text_edit::TextEdit; 64use text_edit::TextEdit;
44use unlinked_file::UnlinkedFile; 65
66use crate::handlers::unlinked_file::UnlinkedFile;
45 67
46#[derive(Copy, Clone, Debug, PartialEq)] 68#[derive(Copy, Clone, Debug, PartialEq)]
47pub struct DiagnosticCode(pub &'static str); 69pub 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 }