aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/diagnostics/unresolved_module.rs
blob: 977b464140e58e5720f9059a752ccc7b6baca543 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use hir::db::AstDatabase;
use ide_assists::Assist;
use ide_db::{base_db::AnchoredPathBuf, source_change::FileSystemEdit};
use syntax::AstNode;

use crate::diagnostics::{fix, Diagnostic, DiagnosticsContext};

// Diagnostic: unresolved-module
//
// This diagnostic is triggered if rust-analyzer is unable to discover referred module.
pub(super) fn unresolved_module(
    ctx: &DiagnosticsContext<'_>,
    d: &hir::UnresolvedModule,
) -> Diagnostic {
    Diagnostic::new(
        "unresolved-module",
        "unresolved module",
        ctx.sema.diagnostics_display_range(d.decl.clone().map(|it| it.into())).range,
    )
    .with_fixes(fixes(ctx, d))
}

fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedModule) -> Option<Vec<Assist>> {
    let root = ctx.sema.db.parse_or_expand(d.decl.file_id)?;
    let unresolved_module = d.decl.value.to_node(&root);
    Some(vec![fix(
        "create_module",
        "Create module",
        FileSystemEdit::CreateFile {
            dst: AnchoredPathBuf {
                anchor: d.decl.file_id.original_file(ctx.sema.db),
                path: d.candidate.clone(),
            },
            initial_contents: "".to_string(),
        }
        .into(),
        unresolved_module.syntax().text_range(),
    )])
}

#[cfg(test)]
mod tests {
    use expect_test::expect;

    use crate::diagnostics::tests::{check_diagnostics, check_expect};

    #[test]
    fn unresolved_module() {
        check_diagnostics(
            r#"
//- /lib.rs
mod foo;
  mod bar;
//^^^^^^^^ unresolved module
mod baz {}
//- /foo.rs
"#,
        );
    }

    #[test]
    fn test_unresolved_module_diagnostic() {
        check_expect(
            r#"mod foo;"#,
            expect![[r#"
                [
                    Diagnostic {
                        code: DiagnosticCode(
                            "unresolved-module",
                        ),
                        message: "unresolved module",
                        range: 0..8,
                        severity: Error,
                        unused: false,
                        experimental: false,
                        fixes: Some(
                            [
                                Assist {
                                    id: AssistId(
                                        "create_module",
                                        QuickFix,
                                    ),
                                    label: "Create module",
                                    group: None,
                                    target: 0..8,
                                    source_change: Some(
                                        SourceChange {
                                            source_file_edits: {},
                                            file_system_edits: [
                                                CreateFile {
                                                    dst: AnchoredPathBuf {
                                                        anchor: FileId(
                                                            0,
                                                        ),
                                                        path: "foo.rs",
                                                    },
                                                    initial_contents: "",
                                                },
                                            ],
                                            is_snippet: false,
                                        },
                                    ),
                                },
                            ],
                        ),
                    },
                ]
            "#]],
        );
    }
}