From 7e8f17188efcecfdfd1afbbc894a53c65985f836 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Mar 2019 22:13:11 +0300 Subject: diagnostics --- crates/ra_ide_api/src/diagnostics.rs | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'crates/ra_ide_api/src') diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs index 156f28ca3..f662f7e2f 100644 --- a/crates/ra_ide_api/src/diagnostics.rs +++ b/crates/ra_ide_api/src/diagnostics.rs @@ -3,7 +3,7 @@ use hir::{Problem, source_binder}; use ra_db::SourceDatabase; use ra_syntax::{ Location, SourceFile, SyntaxKind, TextRange, SyntaxNode, - ast::{self, AstNode}, + ast::{self, AstNode, NameOwner}, }; use ra_text_edit::{TextEdit, TextEditBuilder}; @@ -134,6 +134,13 @@ fn check_module( file_id: FileId, module: hir::Module, ) { + for decl in module.declarations(db) { + match decl { + hir::ModuleDef::Function(f) => check_function(acc, db, f), + _ => (), + } + } + let source_root = db.file_source_root(file_id); for (name_node, problem) in module.problems(db) { let diag = match problem { @@ -153,6 +160,27 @@ fn check_module( } } +fn check_function(acc: &mut Vec, db: &RootDatabase, function: hir::Function) { + let (_file_id, fn_def) = function.source(db); + let source_file = fn_def.syntax().ancestors().find_map(ast::SourceFile::cast).unwrap(); + let source_map = function.body_source_map(db); + for d in function.diagnostics(db) { + match d { + hir::diagnostics::FunctionDiagnostic::NoSuchField { expr, field } => { + if let Some(field) = source_map.field_syntax(expr, field) { + let field = field.to_node(&source_file); + acc.push(Diagnostic { + message: "no such field".into(), + range: field.syntax().range(), + severity: Severity::Error, + fix: None, + }) + } + } + } + } +} + #[cfg(test)] mod tests { use test_utils::assert_eq_text; -- cgit v1.2.3 From fcca35969dd7c63a83ee34c4ce7d54cefdb72bbe Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 23 Mar 2019 16:28:47 +0300 Subject: allow dyn diagnostics --- crates/ra_ide_api/src/diagnostics.rs | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) (limited to 'crates/ra_ide_api/src') diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs index f662f7e2f..943fd2f53 100644 --- a/crates/ra_ide_api/src/diagnostics.rs +++ b/crates/ra_ide_api/src/diagnostics.rs @@ -3,7 +3,7 @@ use hir::{Problem, source_binder}; use ra_db::SourceDatabase; use ra_syntax::{ Location, SourceFile, SyntaxKind, TextRange, SyntaxNode, - ast::{self, AstNode, NameOwner}, + ast::{self, AstNode}, }; use ra_text_edit::{TextEdit, TextEditBuilder}; @@ -161,23 +161,13 @@ fn check_module( } fn check_function(acc: &mut Vec, db: &RootDatabase, function: hir::Function) { - let (_file_id, fn_def) = function.source(db); - let source_file = fn_def.syntax().ancestors().find_map(ast::SourceFile::cast).unwrap(); - let source_map = function.body_source_map(db); - for d in function.diagnostics(db) { - match d { - hir::diagnostics::FunctionDiagnostic::NoSuchField { expr, field } => { - if let Some(field) = source_map.field_syntax(expr, field) { - let field = field.to_node(&source_file); - acc.push(Diagnostic { - message: "no such field".into(), - range: field.syntax().range(), - severity: Severity::Error, - fix: None, - }) - } - } - } + for d in function.diagnostics(db).iter() { + acc.push(Diagnostic { + message: d.message(), + range: d.syntax_node().range(), + severity: Severity::Error, + fix: None, + }) } } -- cgit v1.2.3 From 3fb88e95aa5e122a521beec766d5b1264ca4de3b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 23 Mar 2019 18:35:14 +0300 Subject: switch modules to new diagnostics --- crates/ra_ide_api/src/diagnostics.rs | 66 ++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 36 deletions(-) (limited to 'crates/ra_ide_api/src') diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs index 943fd2f53..254342c0a 100644 --- a/crates/ra_ide_api/src/diagnostics.rs +++ b/crates/ra_ide_api/src/diagnostics.rs @@ -1,5 +1,5 @@ use itertools::Itertools; -use hir::{Problem, source_binder}; +use hir::{source_binder, diagnostics::Diagnostic as _}; use ra_db::SourceDatabase; use ra_syntax::{ Location, SourceFile, SyntaxKind, TextRange, SyntaxNode, @@ -28,7 +28,7 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec } if let Some(m) = source_binder::module_from_file_id(db, file_id) { - check_module(&mut res, db, file_id, m); + check_module(&mut res, db, m); }; res } @@ -128,46 +128,40 @@ fn check_struct_shorthand_initialization( Some(()) } -fn check_module( - acc: &mut Vec, - db: &RootDatabase, - file_id: FileId, - module: hir::Module, -) { +fn check_module(acc: &mut Vec, db: &RootDatabase, module: hir::Module) { + let mut diagnostics = hir::diagnostics::Diagnostics::default(); + module.diagnostics(db, &mut diagnostics); for decl in module.declarations(db) { match decl { - hir::ModuleDef::Function(f) => check_function(acc, db, f), + hir::ModuleDef::Function(f) => f.diagnostics(db, &mut diagnostics), _ => (), } } - let source_root = db.file_source_root(file_id); - for (name_node, problem) in module.problems(db) { - let diag = match problem { - Problem::UnresolvedModule { candidate } => { - let create_file = - FileSystemEdit::CreateFile { source_root, path: candidate.clone() }; - let fix = SourceChange::file_system_edit("create module", create_file); - Diagnostic { - range: name_node.range(), - message: "unresolved module".to_string(), - severity: Severity::Error, - fix: Some(fix), - } - } - }; - acc.push(diag) - } -} - -fn check_function(acc: &mut Vec, db: &RootDatabase, function: hir::Function) { - for d in function.diagnostics(db).iter() { - acc.push(Diagnostic { - message: d.message(), - range: d.syntax_node().range(), - severity: Severity::Error, - fix: None, - }) + for d in diagnostics.iter() { + if let Some(d) = d.downcast_ref::() { + let source_root = db.file_source_root(d.file().original_file(db)); + let create_file = FileSystemEdit::CreateFile { source_root, path: d.candidate.clone() }; + let fix = SourceChange { + label: "create module".to_string(), + source_file_edits: Vec::new(), + file_system_edits: vec![create_file], + cursor_position: None, + }; + acc.push(Diagnostic { + range: d.syntax_node().range(), + message: d.message(), + severity: Severity::Error, + fix: Some(fix), + }) + } else { + acc.push(Diagnostic { + message: d.message(), + range: d.syntax_node().range(), + severity: Severity::Error, + fix: None, + }) + } } } -- cgit v1.2.3 From 79df62bc742afa33dcf5bedefd60860ca296b9da Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 23 Mar 2019 20:41:59 +0300 Subject: cleanup --- crates/ra_ide_api/src/diagnostics.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'crates/ra_ide_api/src') diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs index 254342c0a..1395cede2 100644 --- a/crates/ra_ide_api/src/diagnostics.rs +++ b/crates/ra_ide_api/src/diagnostics.rs @@ -129,7 +129,7 @@ fn check_struct_shorthand_initialization( } fn check_module(acc: &mut Vec, db: &RootDatabase, module: hir::Module) { - let mut diagnostics = hir::diagnostics::Diagnostics::default(); + let mut diagnostics = hir::diagnostics::DiagnosticSink::default(); module.diagnostics(db, &mut diagnostics); for decl in module.declarations(db) { match decl { @@ -138,7 +138,7 @@ fn check_module(acc: &mut Vec, db: &RootDatabase, module: hir::Modul } } - for d in diagnostics.iter() { + for d in diagnostics.into_diagnostics().iter() { if let Some(d) = d.downcast_ref::() { let source_root = db.file_source_root(d.file().original_file(db)); let create_file = FileSystemEdit::CreateFile { source_root, path: d.candidate.clone() }; -- cgit v1.2.3 From 45fbab2b1ac02dab971d245c45c2404494cb3e03 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 23 Mar 2019 21:17:05 +0300 Subject: check impls as well --- crates/ra_ide_api/src/diagnostics.rs | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'crates/ra_ide_api/src') diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs index 1395cede2..e03dcaa8f 100644 --- a/crates/ra_ide_api/src/diagnostics.rs +++ b/crates/ra_ide_api/src/diagnostics.rs @@ -138,6 +138,15 @@ fn check_module(acc: &mut Vec, db: &RootDatabase, module: hir::Modul } } + for impl_block in module.impl_blocks(db) { + for item in impl_block.items(db) { + match item { + hir::ImplItem::Method(f) => f.diagnostics(db, &mut diagnostics), + _ => (), + } + } + } + for d in diagnostics.into_diagnostics().iter() { if let Some(d) = d.downcast_ref::() { let source_root = db.file_source_root(d.file().original_file(db)); -- cgit v1.2.3 From 7ee2887d1ec129afed80845c2361ce35f1a0c013 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 23 Mar 2019 21:20:49 +0300 Subject: fixes --- crates/ra_ide_api/src/diagnostics.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'crates/ra_ide_api/src') diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs index e03dcaa8f..5b1a90c82 100644 --- a/crates/ra_ide_api/src/diagnostics.rs +++ b/crates/ra_ide_api/src/diagnostics.rs @@ -1,10 +1,9 @@ use itertools::Itertools; -use hir::{source_binder, diagnostics::Diagnostic as _}; +use hir::{source_binder, diagnostics::{Diagnostic as _, DiagnosticSink}}; use ra_db::SourceDatabase; use ra_syntax::{ Location, SourceFile, SyntaxKind, TextRange, SyntaxNode, ast::{self, AstNode}, - }; use ra_text_edit::{TextEdit, TextEditBuilder}; @@ -129,7 +128,7 @@ fn check_struct_shorthand_initialization( } fn check_module(acc: &mut Vec, db: &RootDatabase, module: hir::Module) { - let mut diagnostics = hir::diagnostics::DiagnosticSink::default(); + let mut diagnostics = DiagnosticSink::default(); module.diagnostics(db, &mut diagnostics); for decl in module.declarations(db) { match decl { -- cgit v1.2.3 From c7ffd939f670a1cba5bf415759b43e63700761a7 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 24 Mar 2019 10:21:36 +0300 Subject: more enterprisey diagnostics setup --- crates/ra_ide_api/src/diagnostics.rs | 79 ++++++++++++++---------------------- 1 file changed, 30 insertions(+), 49 deletions(-) (limited to 'crates/ra_ide_api/src') 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 @@ +use std::cell::RefCell; + use itertools::Itertools; use hir::{source_binder, diagnostics::{Diagnostic as _, DiagnosticSink}}; use ra_db::SourceDatabase; @@ -25,11 +27,36 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec check_unnecessary_braces_in_use_statement(&mut res, file_id, node); check_struct_shorthand_initialization(&mut res, file_id, node); } - + let res = RefCell::new(res); + let mut sink = DiagnosticSink::new(|d| { + res.borrow_mut().push(Diagnostic { + message: d.message(), + range: d.syntax_node().range(), + severity: Severity::Error, + fix: None, + }) + }) + .on::(|d| { + let source_root = db.file_source_root(d.file().original_file(db)); + let create_file = FileSystemEdit::CreateFile { source_root, path: d.candidate.clone() }; + let fix = SourceChange { + label: "create module".to_string(), + source_file_edits: Vec::new(), + file_system_edits: vec![create_file], + cursor_position: None, + }; + res.borrow_mut().push(Diagnostic { + range: d.syntax_node().range(), + message: d.message(), + severity: Severity::Error, + fix: Some(fix), + }) + }); if let Some(m) = source_binder::module_from_file_id(db, file_id) { - check_module(&mut res, db, m); + m.diagnostics(db, &mut sink); }; - res + drop(sink); + res.into_inner() } fn syntax_errors(acc: &mut Vec, source_file: &SourceFile) { @@ -127,52 +154,6 @@ fn check_struct_shorthand_initialization( Some(()) } -fn check_module(acc: &mut Vec, db: &RootDatabase, module: hir::Module) { - let mut diagnostics = DiagnosticSink::default(); - module.diagnostics(db, &mut diagnostics); - for decl in module.declarations(db) { - match decl { - hir::ModuleDef::Function(f) => f.diagnostics(db, &mut diagnostics), - _ => (), - } - } - - for impl_block in module.impl_blocks(db) { - for item in impl_block.items(db) { - match item { - hir::ImplItem::Method(f) => f.diagnostics(db, &mut diagnostics), - _ => (), - } - } - } - - for d in diagnostics.into_diagnostics().iter() { - if let Some(d) = d.downcast_ref::() { - let source_root = db.file_source_root(d.file().original_file(db)); - let create_file = FileSystemEdit::CreateFile { source_root, path: d.candidate.clone() }; - let fix = SourceChange { - label: "create module".to_string(), - source_file_edits: Vec::new(), - file_system_edits: vec![create_file], - cursor_position: None, - }; - acc.push(Diagnostic { - range: d.syntax_node().range(), - message: d.message(), - severity: Severity::Error, - fix: Some(fix), - }) - } else { - acc.push(Diagnostic { - message: d.message(), - range: d.syntax_node().range(), - severity: Severity::Error, - fix: None, - }) - } - } -} - #[cfg(test)] mod tests { use test_utils::assert_eq_text; -- cgit v1.2.3 From 5ce84f3cbc5d5a3106ea89460da4a3f473618f32 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 Mar 2019 09:40:49 +0300 Subject: tweak diagnostics API --- crates/ra_ide_api/src/diagnostics.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'crates/ra_ide_api/src') diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs index bf77c9ab1..11391ef02 100644 --- a/crates/ra_ide_api/src/diagnostics.rs +++ b/crates/ra_ide_api/src/diagnostics.rs @@ -31,7 +31,7 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec let mut sink = DiagnosticSink::new(|d| { res.borrow_mut().push(Diagnostic { message: d.message(), - range: d.syntax_node().range(), + range: d.highlight_range(), severity: Severity::Error, fix: None, }) @@ -46,7 +46,7 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec cursor_position: None, }; res.borrow_mut().push(Diagnostic { - range: d.syntax_node().range(), + range: d.highlight_range(), message: d.message(), severity: Severity::Error, fix: Some(fix), -- cgit v1.2.3 From e9af69d9db8856d79f0da7ae7da66169cc225aac Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 Mar 2019 10:56:55 +0300 Subject: simplify --- crates/ra_ide_api/src/diagnostics.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'crates/ra_ide_api/src') diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs index 11391ef02..841103322 100644 --- a/crates/ra_ide_api/src/diagnostics.rs +++ b/crates/ra_ide_api/src/diagnostics.rs @@ -39,12 +39,7 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec .on::(|d| { let source_root = db.file_source_root(d.file().original_file(db)); let create_file = FileSystemEdit::CreateFile { source_root, path: d.candidate.clone() }; - let fix = SourceChange { - label: "create module".to_string(), - source_file_edits: Vec::new(), - file_system_edits: vec![create_file], - cursor_position: None, - }; + let fix = SourceChange::file_system_edit("create module", create_file); res.borrow_mut().push(Diagnostic { range: d.highlight_range(), message: d.message(), -- cgit v1.2.3 From 309716cffe93d065bcad0344b0f332425576c1e5 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 Mar 2019 14:28:04 +0300 Subject: move tests to where they belong --- crates/ra_ide_api/src/diagnostics.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'crates/ra_ide_api/src') diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs index 841103322..5a78e94d8 100644 --- a/crates/ra_ide_api/src/diagnostics.rs +++ b/crates/ra_ide_api/src/diagnostics.rs @@ -152,6 +152,9 @@ fn check_struct_shorthand_initialization( #[cfg(test)] mod tests { use test_utils::assert_eq_text; + use insta::assert_debug_snapshot_matches; + + use crate::mock_analysis::single_file; use super::*; @@ -180,6 +183,34 @@ mod tests { assert_eq_text!(after, &actual); } + #[test] + fn test_unresolved_module_diagnostic() { + let (analysis, file_id) = single_file("mod foo;"); + let diagnostics = analysis.diagnostics(file_id).unwrap(); + assert_debug_snapshot_matches!(diagnostics, @r####"[ + Diagnostic { + message: "unresolved module", + range: [0; 8), + fix: Some( + SourceChange { + label: "create module", + source_file_edits: [], + file_system_edits: [ + CreateFile { + source_root: SourceRootId( + 0 + ), + path: "foo.rs" + } + ], + cursor_position: None + } + ), + severity: Error + } +]"####); + } + #[test] fn test_check_unnecessary_braces_in_use_statement() { check_not_applicable( -- cgit v1.2.3