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.rs39
1 files changed, 19 insertions, 20 deletions
diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs
index 923008708..4cf2a0b70 100644
--- a/crates/ra_ide_api/src/diagnostics.rs
+++ b/crates/ra_ide_api/src/diagnostics.rs
@@ -4,7 +4,7 @@ use itertools::Itertools;
4use hir::{source_binder, diagnostics::{Diagnostic as _, DiagnosticSink}}; 4use hir::{source_binder, diagnostics::{Diagnostic as _, DiagnosticSink}};
5use ra_db::SourceDatabase; 5use ra_db::SourceDatabase;
6use ra_syntax::{ 6use ra_syntax::{
7 T, Location, SourceFile, TextRange, SyntaxNode, 7 T, Location, TextRange, SyntaxNode,
8 ast::{self, AstNode, NamedFieldList, NamedField}, 8 ast::{self, AstNode, NamedFieldList, NamedField},
9}; 9};
10use ra_assists::ast_editor::{AstEditor, AstBuilder}; 10use ra_assists::ast_editor::{AstEditor, AstBuilder};
@@ -21,10 +21,17 @@ pub enum Severity {
21 21
22pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic> { 22pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic> {
23 let _p = profile("diagnostics"); 23 let _p = profile("diagnostics");
24 let source_file = db.parse(file_id); 24 let parse = db.parse(file_id);
25 let mut res = Vec::new(); 25 let mut res = Vec::new();
26 26
27 syntax_errors(&mut res, &source_file); 27 res.extend(parse.errors.iter().map(|err| Diagnostic {
28 range: location_to_range(err.location()),
29 message: format!("Syntax Error: {}", err),
30 severity: Severity::Error,
31 fix: None,
32 }));
33
34 let source_file = parse.tree;
28 35
29 for node in source_file.syntax().descendants() { 36 for node in source_file.syntax().descendants() {
30 check_unnecessary_braces_in_use_statement(&mut res, file_id, node); 37 check_unnecessary_braces_in_use_statement(&mut res, file_id, node);
@@ -51,8 +58,9 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
51 }) 58 })
52 }) 59 })
53 .on::<hir::diagnostics::MissingFields, _>(|d| { 60 .on::<hir::diagnostics::MissingFields, _>(|d| {
61 //TODO: commment
54 let file_id = d.file().original_file(db); 62 let file_id = d.file().original_file(db);
55 let source_file = db.parse(file_id); 63 let source_file = db.parse(file_id).tree;
56 let syntax_node = d.syntax_node_ptr(); 64 let syntax_node = d.syntax_node_ptr();
57 let node = NamedFieldList::cast(syntax_node.to_node(source_file.syntax())).unwrap(); 65 let node = NamedFieldList::cast(syntax_node.to_node(source_file.syntax())).unwrap();
58 let mut ast_editor = AstEditor::new(node); 66 let mut ast_editor = AstEditor::new(node);
@@ -77,21 +85,11 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
77 drop(sink); 85 drop(sink);
78 res.into_inner() 86 res.into_inner()
79} 87}
80 88fn location_to_range(location: Location) -> TextRange {
81fn syntax_errors(acc: &mut Vec<Diagnostic>, source_file: &SourceFile) { 89 match location {
82 fn location_to_range(location: Location) -> TextRange { 90 Location::Offset(offset) => TextRange::offset_len(offset, 1.into()),
83 match location { 91 Location::Range(range) => range,
84 Location::Offset(offset) => TextRange::offset_len(offset, 1.into()),
85 Location::Range(range) => range,
86 }
87 } 92 }
88
89 acc.extend(source_file.errors().into_iter().map(|err| Diagnostic {
90 range: location_to_range(err.location()),
91 message: format!("Syntax Error: {}", err),
92 severity: Severity::Error,
93 fix: None,
94 }));
95} 93}
96 94
97fn check_unnecessary_braces_in_use_statement( 95fn check_unnecessary_braces_in_use_statement(
@@ -177,6 +175,7 @@ fn check_struct_shorthand_initialization(
177mod tests { 175mod tests {
178 use test_utils::assert_eq_text; 176 use test_utils::assert_eq_text;
179 use insta::assert_debug_snapshot_matches; 177 use insta::assert_debug_snapshot_matches;
178 use ra_syntax::SourceFile;
180 179
181 use crate::mock_analysis::single_file; 180 use crate::mock_analysis::single_file;
182 181
@@ -185,7 +184,7 @@ mod tests {
185 type DiagnosticChecker = fn(&mut Vec<Diagnostic>, FileId, &SyntaxNode) -> Option<()>; 184 type DiagnosticChecker = fn(&mut Vec<Diagnostic>, FileId, &SyntaxNode) -> Option<()>;
186 185
187 fn check_not_applicable(code: &str, func: DiagnosticChecker) { 186 fn check_not_applicable(code: &str, func: DiagnosticChecker) {
188 let file = SourceFile::parse(code); 187 let file = SourceFile::parse(code).tree;
189 let mut diagnostics = Vec::new(); 188 let mut diagnostics = Vec::new();
190 for node in file.syntax().descendants() { 189 for node in file.syntax().descendants() {
191 func(&mut diagnostics, FileId(0), node); 190 func(&mut diagnostics, FileId(0), node);
@@ -194,7 +193,7 @@ mod tests {
194 } 193 }
195 194
196 fn check_apply(before: &str, after: &str, func: DiagnosticChecker) { 195 fn check_apply(before: &str, after: &str, func: DiagnosticChecker) {
197 let file = SourceFile::parse(before); 196 let file = SourceFile::parse(before).tree;
198 let mut diagnostics = Vec::new(); 197 let mut diagnostics = Vec::new();
199 for node in file.syntax().descendants() { 198 for node in file.syntax().descendants() {
200 func(&mut diagnostics, FileId(0), node); 199 func(&mut diagnostics, FileId(0), node);