aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src')
-rw-r--r--crates/ra_ide_api/src/diagnostics.rs79
1 files changed, 30 insertions, 49 deletions
diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs
index 5b1a90c82..bf77c9ab1 100644
--- a/crates/ra_ide_api/src/diagnostics.rs
+++ b/crates/ra_ide_api/src/diagnostics.rs
@@ -1,3 +1,5 @@
1use std::cell::RefCell;
2
1use itertools::Itertools; 3use itertools::Itertools;
2use hir::{source_binder, diagnostics::{Diagnostic as _, DiagnosticSink}}; 4use hir::{source_binder, diagnostics::{Diagnostic as _, DiagnosticSink}};
3use ra_db::SourceDatabase; 5use ra_db::SourceDatabase;
@@ -25,11 +27,36 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
25 check_unnecessary_braces_in_use_statement(&mut res, file_id, node); 27 check_unnecessary_braces_in_use_statement(&mut res, file_id, node);
26 check_struct_shorthand_initialization(&mut res, file_id, node); 28 check_struct_shorthand_initialization(&mut res, file_id, node);
27 } 29 }
28 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.syntax_node().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 {
43 label: "create module".to_string(),
44 source_file_edits: Vec::new(),
45 file_system_edits: vec![create_file],
46 cursor_position: None,
47 };
48 res.borrow_mut().push(Diagnostic {
49 range: d.syntax_node().range(),
50 message: d.message(),
51 severity: Severity::Error,
52 fix: Some(fix),
53 })
54 });
29 if let Some(m) = source_binder::module_from_file_id(db, file_id) { 55 if let Some(m) = source_binder::module_from_file_id(db, file_id) {
30 check_module(&mut res, db, m); 56 m.diagnostics(db, &mut sink);
31 }; 57 };
32 res 58 drop(sink);
59 res.into_inner()
33} 60}
34 61
35fn syntax_errors(acc: &mut Vec<Diagnostic>, source_file: &SourceFile) { 62fn syntax_errors(acc: &mut Vec<Diagnostic>, source_file: &SourceFile) {
@@ -127,52 +154,6 @@ fn check_struct_shorthand_initialization(
127 Some(()) 154 Some(())
128} 155}
129 156
130fn check_module(acc: &mut Vec<Diagnostic>, db: &RootDatabase, module: hir::Module) {
131 let mut diagnostics = DiagnosticSink::default();
132 module.diagnostics(db, &mut diagnostics);
133 for decl in module.declarations(db) {
134 match decl {
135 hir::ModuleDef::Function(f) => f.diagnostics(db, &mut diagnostics),
136 _ => (),
137 }
138 }
139
140 for impl_block in module.impl_blocks(db) {
141 for item in impl_block.items(db) {
142 match item {
143 hir::ImplItem::Method(f) => f.diagnostics(db, &mut diagnostics),
144 _ => (),
145 }
146 }
147 }
148
149 for d in diagnostics.into_diagnostics().iter() {
150 if let Some(d) = d.downcast_ref::<hir::diagnostics::UnresolvedModule>() {
151 let source_root = db.file_source_root(d.file().original_file(db));
152 let create_file = FileSystemEdit::CreateFile { source_root, path: d.candidate.clone() };
153 let fix = SourceChange {
154 label: "create module".to_string(),
155 source_file_edits: Vec::new(),
156 file_system_edits: vec![create_file],
157 cursor_position: None,
158 };
159 acc.push(Diagnostic {
160 range: d.syntax_node().range(),
161 message: d.message(),
162 severity: Severity::Error,
163 fix: Some(fix),
164 })
165 } else {
166 acc.push(Diagnostic {
167 message: d.message(),
168 range: d.syntax_node().range(),
169 severity: Severity::Error,
170 fix: None,
171 })
172 }
173 }
174}
175
176#[cfg(test)] 157#[cfg(test)]
177mod tests { 158mod tests {
178 use test_utils::assert_eq_text; 159 use test_utils::assert_eq_text;