aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/diagnostics.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/diagnostics.rs')
-rw-r--r--crates/ra_ide_api/src/diagnostics.rs87
1 files changed, 57 insertions, 30 deletions
diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs
index 156f28ca3..5a78e94d8 100644
--- a/crates/ra_ide_api/src/diagnostics.rs
+++ b/crates/ra_ide_api/src/diagnostics.rs
@@ -1,10 +1,11 @@
1use std::cell::RefCell;
2
1use itertools::Itertools; 3use itertools::Itertools;
2use hir::{Problem, source_binder}; 4use hir::{source_binder, diagnostics::{Diagnostic as _, DiagnosticSink}};
3use ra_db::SourceDatabase; 5use ra_db::SourceDatabase;
4use ra_syntax::{ 6use ra_syntax::{
5 Location, SourceFile, SyntaxKind, TextRange, SyntaxNode, 7 Location, SourceFile, SyntaxKind, TextRange, SyntaxNode,
6 ast::{self, AstNode}, 8 ast::{self, AstNode},
7
8}; 9};
9use ra_text_edit::{TextEdit, TextEditBuilder}; 10use ra_text_edit::{TextEdit, TextEditBuilder};
10 11
@@ -26,11 +27,31 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
26 check_unnecessary_braces_in_use_statement(&mut res, file_id, node); 27 check_unnecessary_braces_in_use_statement(&mut res, file_id, node);
27 check_struct_shorthand_initialization(&mut res, file_id, node); 28 check_struct_shorthand_initialization(&mut res, file_id, node);
28 } 29 }
29 30 let res = RefCell::new(res);
31 let mut sink = DiagnosticSink::new(|d| {
32 res.borrow_mut().push(Diagnostic {
33 message: d.message(),
34 range: d.highlight_range(),
35 severity: Severity::Error,
36 fix: None,
37 })
38 })
39 .on::<hir::diagnostics::UnresolvedModule, _>(|d| {
40 let source_root = db.file_source_root(d.file().original_file(db));
41 let create_file = FileSystemEdit::CreateFile { source_root, path: d.candidate.clone() };
42 let fix = SourceChange::file_system_edit("create module", create_file);
43 res.borrow_mut().push(Diagnostic {
44 range: d.highlight_range(),
45 message: d.message(),
46 severity: Severity::Error,
47 fix: Some(fix),
48 })
49 });
30 if let Some(m) = source_binder::module_from_file_id(db, file_id) { 50 if let Some(m) = source_binder::module_from_file_id(db, file_id) {
31 check_module(&mut res, db, file_id, m); 51 m.diagnostics(db, &mut sink);
32 }; 52 };
33 res 53 drop(sink);
54 res.into_inner()
34} 55}
35 56
36fn syntax_errors(acc: &mut Vec<Diagnostic>, source_file: &SourceFile) { 57fn syntax_errors(acc: &mut Vec<Diagnostic>, source_file: &SourceFile) {
@@ -128,34 +149,12 @@ fn check_struct_shorthand_initialization(
128 Some(()) 149 Some(())
129} 150}
130 151
131fn check_module(
132 acc: &mut Vec<Diagnostic>,
133 db: &RootDatabase,
134 file_id: FileId,
135 module: hir::Module,
136) {
137 let source_root = db.file_source_root(file_id);
138 for (name_node, problem) in module.problems(db) {
139 let diag = match problem {
140 Problem::UnresolvedModule { candidate } => {
141 let create_file =
142 FileSystemEdit::CreateFile { source_root, path: candidate.clone() };
143 let fix = SourceChange::file_system_edit("create module", create_file);
144 Diagnostic {
145 range: name_node.range(),
146 message: "unresolved module".to_string(),
147 severity: Severity::Error,
148 fix: Some(fix),
149 }
150 }
151 };
152 acc.push(diag)
153 }
154}
155
156#[cfg(test)] 152#[cfg(test)]
157mod tests { 153mod tests {
158 use test_utils::assert_eq_text; 154 use test_utils::assert_eq_text;
155 use insta::assert_debug_snapshot_matches;
156
157 use crate::mock_analysis::single_file;
159 158
160 use super::*; 159 use super::*;
161 160
@@ -185,6 +184,34 @@ mod tests {
185 } 184 }
186 185
187 #[test] 186 #[test]
187 fn test_unresolved_module_diagnostic() {
188 let (analysis, file_id) = single_file("mod foo;");
189 let diagnostics = analysis.diagnostics(file_id).unwrap();
190 assert_debug_snapshot_matches!(diagnostics, @r####"[
191 Diagnostic {
192 message: "unresolved module",
193 range: [0; 8),
194 fix: Some(
195 SourceChange {
196 label: "create module",
197 source_file_edits: [],
198 file_system_edits: [
199 CreateFile {
200 source_root: SourceRootId(
201 0
202 ),
203 path: "foo.rs"
204 }
205 ],
206 cursor_position: None
207 }
208 ),
209 severity: Error
210 }
211]"####);
212 }
213
214 #[test]
188 fn test_check_unnecessary_braces_in_use_statement() { 215 fn test_check_unnecessary_braces_in_use_statement() {
189 check_not_applicable( 216 check_not_applicable(
190 " 217 "