aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/diagnostics
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-06-13 12:41:19 +0100
committerAleksey Kladov <[email protected]>2021-06-13 12:55:45 +0100
commitefa069d28818dd074afd2c7cee776907b63ca012 (patch)
tree39f3ff2d5154bb62df5e4611f7054e1f7e96eb2f /crates/ide/src/diagnostics
parent546be18e3a91e4844b0dacc76c9f055397b6d89e (diff)
internal: start new diagnostics API
At the moment, this moves only a single diagnostic, but the idea is reafactor the rest to use the same pattern. We are going to have a single file per diagnostic. This file will define diagnostics code, rendering range and fixes, if any. It'll also have all of the tests. This is similar to how we deal with assists. After we refactor all diagnostics to follow this pattern, we'll probably move them to a new `ide_diagnostics` crate. Not that we intentionally want to test all diagnostics on this layer, despite the fact that they are generally emitted in the guts on the compiler. Diagnostics care to much about the end presentation details/fixes to be worth-while "unit" testing. So, we'll unit-test only the primary output of compilation process (types and name res tables), and will use integrated UI tests for diagnostics.
Diffstat (limited to 'crates/ide/src/diagnostics')
-rw-r--r--crates/ide/src/diagnostics/fixes.rs1
-rw-r--r--crates/ide/src/diagnostics/unresolved_module.rs (renamed from crates/ide/src/diagnostics/fixes/unresolved_module.rs)74
2 files changed, 47 insertions, 28 deletions
diff --git a/crates/ide/src/diagnostics/fixes.rs b/crates/ide/src/diagnostics/fixes.rs
index 258ac6974..8640d7231 100644
--- a/crates/ide/src/diagnostics/fixes.rs
+++ b/crates/ide/src/diagnostics/fixes.rs
@@ -5,7 +5,6 @@ mod create_field;
5mod fill_missing_fields; 5mod fill_missing_fields;
6mod remove_semicolon; 6mod remove_semicolon;
7mod replace_with_find_map; 7mod replace_with_find_map;
8mod unresolved_module;
9mod wrap_tail_expr; 8mod wrap_tail_expr;
10 9
11use hir::{diagnostics::Diagnostic, Semantics}; 10use hir::{diagnostics::Diagnostic, Semantics};
diff --git a/crates/ide/src/diagnostics/fixes/unresolved_module.rs b/crates/ide/src/diagnostics/unresolved_module.rs
index b3d0283bb..abf53a57c 100644
--- a/crates/ide/src/diagnostics/fixes/unresolved_module.rs
+++ b/crates/ide/src/diagnostics/unresolved_module.rs
@@ -1,39 +1,59 @@
1use hir::{db::AstDatabase, diagnostics::UnresolvedModule, Semantics}; 1use hir::db::AstDatabase;
2use ide_assists::{Assist, AssistResolveStrategy}; 2use ide_assists::Assist;
3use ide_db::{base_db::AnchoredPathBuf, source_change::FileSystemEdit, RootDatabase}; 3use ide_db::{base_db::AnchoredPathBuf, source_change::FileSystemEdit};
4use syntax::AstNode; 4use syntax::AstNode;
5 5
6use crate::diagnostics::{fix, DiagnosticWithFixes}; 6use crate::diagnostics::{fix, Diagnostic, DiagnosticsContext};
7 7
8impl DiagnosticWithFixes for UnresolvedModule { 8// Diagnostic: unresolved-module
9 fn fixes( 9//
10 &self, 10// This diagnostic is triggered if rust-analyzer is unable to discover referred module.
11 sema: &Semantics<RootDatabase>, 11pub(super) fn render(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedModule) -> Diagnostic {
12 _resolve: &AssistResolveStrategy, 12 Diagnostic::new(
13 ) -> Option<Vec<Assist>> { 13 "unresolved-module",
14 let root = sema.db.parse_or_expand(self.file)?; 14 "unresolved module",
15 let unresolved_module = self.decl.to_node(&root); 15 ctx.sema.diagnostics_display_range(d.decl.clone().map(|it| it.into())).range,
16 Some(vec![fix( 16 )
17 "create_module", 17 .with_fixes(fixes(ctx, d))
18 "Create module", 18}
19 FileSystemEdit::CreateFile { 19
20 dst: AnchoredPathBuf { 20fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedModule) -> Option<Vec<Assist>> {
21 anchor: self.file.original_file(sema.db), 21 let root = ctx.sema.db.parse_or_expand(d.decl.file_id)?;
22 path: self.candidate.clone(), 22 let unresolved_module = d.decl.value.to_node(&root);
23 }, 23 Some(vec![fix(
24 initial_contents: "".to_string(), 24 "create_module",
25 } 25 "Create module",
26 .into(), 26 FileSystemEdit::CreateFile {
27 unresolved_module.syntax().text_range(), 27 dst: AnchoredPathBuf {
28 )]) 28 anchor: d.decl.file_id.original_file(ctx.sema.db),
29 } 29 path: d.candidate.clone(),
30 },
31 initial_contents: "".to_string(),
32 }
33 .into(),
34 unresolved_module.syntax().text_range(),
35 )])
30} 36}
31 37
32#[cfg(test)] 38#[cfg(test)]
33mod tests { 39mod tests {
34 use expect_test::expect; 40 use expect_test::expect;
35 41
36 use crate::diagnostics::tests::check_expect; 42 use crate::diagnostics::tests::{check_diagnostics, check_expect};
43
44 #[test]
45 fn unresolved_module() {
46 check_diagnostics(
47 r#"
48//- /lib.rs
49mod foo;
50 mod bar;
51//^^^^^^^^ unresolved module
52mod baz {}
53//- /foo.rs
54"#,
55 );
56 }
37 57
38 #[test] 58 #[test]
39 fn test_unresolved_module_diagnostic() { 59 fn test_unresolved_module_diagnostic() {