diff options
author | Kirill Bulatov <[email protected]> | 2020-07-27 16:45:08 +0100 |
---|---|---|
committer | Kirill Bulatov <[email protected]> | 2020-08-11 13:09:08 +0100 |
commit | 21e5224484b9214648826e1b15aa9150c79a407c (patch) | |
tree | 39825273cf9d97796ef9e1705004c1171d32efab | |
parent | 26e102a567aadcf86f2e5b575cb6b915991ba088 (diff) |
Custom ranges for missing fields
-rw-r--r-- | crates/ra_hir_expand/src/diagnostics.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/diagnostics.rs | 52 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/diagnostics/expr.rs | 1 | ||||
-rw-r--r-- | crates/ra_ide/src/diagnostics.rs | 6 |
4 files changed, 56 insertions, 8 deletions
diff --git a/crates/ra_hir_expand/src/diagnostics.rs b/crates/ra_hir_expand/src/diagnostics.rs index 84ba97b14..e889f070f 100644 --- a/crates/ra_hir_expand/src/diagnostics.rs +++ b/crates/ra_hir_expand/src/diagnostics.rs | |||
@@ -36,8 +36,9 @@ pub trait AstDiagnostic { | |||
36 | 36 | ||
37 | impl dyn Diagnostic { | 37 | impl dyn Diagnostic { |
38 | pub fn syntax_node(&self, db: &impl AstDatabase) -> SyntaxNode { | 38 | pub fn syntax_node(&self, db: &impl AstDatabase) -> SyntaxNode { |
39 | let node = db.parse_or_expand(self.source().file_id).unwrap(); | 39 | let source = self.source(); |
40 | self.source().value.to_node(&node) | 40 | let node = db.parse_or_expand(source.file_id).unwrap(); |
41 | source.value.to_node(&node) | ||
41 | } | 42 | } |
42 | 43 | ||
43 | pub fn downcast_ref<D: Diagnostic>(&self) -> Option<&D> { | 44 | pub fn downcast_ref<D: Diagnostic>(&self) -> Option<&D> { |
diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs index 977c0525b..a5b00ed48 100644 --- a/crates/ra_hir_ty/src/diagnostics.rs +++ b/crates/ra_hir_ty/src/diagnostics.rs | |||
@@ -9,7 +9,7 @@ use hir_def::DefWithBodyId; | |||
9 | use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink}; | 9 | use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink}; |
10 | use hir_expand::{db::AstDatabase, name::Name, HirFileId, InFile}; | 10 | use hir_expand::{db::AstDatabase, name::Name, HirFileId, InFile}; |
11 | use ra_prof::profile; | 11 | use ra_prof::profile; |
12 | use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr}; | 12 | use ra_syntax::{ast, AstNode, AstPtr, SyntaxNode, SyntaxNodePtr}; |
13 | use stdx::format_to; | 13 | use stdx::format_to; |
14 | 14 | ||
15 | use crate::db::HirDatabase; | 15 | use crate::db::HirDatabase; |
@@ -61,6 +61,17 @@ pub struct MissingFields { | |||
61 | pub file: HirFileId, | 61 | pub file: HirFileId, |
62 | pub field_list: AstPtr<ast::RecordExprFieldList>, | 62 | pub field_list: AstPtr<ast::RecordExprFieldList>, |
63 | pub missed_fields: Vec<Name>, | 63 | pub missed_fields: Vec<Name>, |
64 | pub list_parent_path: Option<AstPtr<ast::Path>>, | ||
65 | } | ||
66 | |||
67 | impl MissingFields { | ||
68 | fn root(&self, db: &dyn AstDatabase) -> SyntaxNode { | ||
69 | db.parse_or_expand(self.file).unwrap() | ||
70 | } | ||
71 | |||
72 | pub fn list_parent_ast(&self, db: &dyn AstDatabase) -> Option<ast::Path> { | ||
73 | self.list_parent_path.as_ref().map(|path| path.to_node(&self.root(db))) | ||
74 | } | ||
64 | } | 75 | } |
65 | 76 | ||
66 | impl Diagnostic for MissingFields { | 77 | impl Diagnostic for MissingFields { |
@@ -83,9 +94,7 @@ impl AstDiagnostic for MissingFields { | |||
83 | type AST = ast::RecordExprFieldList; | 94 | type AST = ast::RecordExprFieldList; |
84 | 95 | ||
85 | fn ast(&self, db: &dyn AstDatabase) -> Self::AST { | 96 | fn ast(&self, db: &dyn AstDatabase) -> Self::AST { |
86 | let root = db.parse_or_expand(self.source().file_id).unwrap(); | 97 | self.field_list.to_node(&self.root(db)) |
87 | let node = self.source().value.to_node(&root); | ||
88 | ast::RecordExprFieldList::cast(node).unwrap() | ||
89 | } | 98 | } |
90 | } | 99 | } |
91 | 100 | ||
@@ -319,6 +328,41 @@ mod tests { | |||
319 | } | 328 | } |
320 | 329 | ||
321 | #[test] | 330 | #[test] |
331 | fn structure_name_highlighted_for_missing_fields() { | ||
332 | check_diagnostics( | ||
333 | r#" | ||
334 | struct Beefy { | ||
335 | one: i32, | ||
336 | two: i32, | ||
337 | three: i32, | ||
338 | four: i32, | ||
339 | five: i32, | ||
340 | six: i32, | ||
341 | seven: i32, | ||
342 | eight: i32, | ||
343 | nine: i32, | ||
344 | ten: i32, | ||
345 | } | ||
346 | fn baz() { | ||
347 | let zz = Beefy { | ||
348 | //^^^^^... Missing structure fields: | ||
349 | // | - seven | ||
350 | one: (), | ||
351 | two: (), | ||
352 | three: (), | ||
353 | four: (), | ||
354 | five: (), | ||
355 | six: (), | ||
356 | eight: (), | ||
357 | nine: (), | ||
358 | ten: (), | ||
359 | }; | ||
360 | } | ||
361 | "#, | ||
362 | ); | ||
363 | } | ||
364 | |||
365 | #[test] | ||
322 | fn no_such_field_diagnostics() { | 366 | fn no_such_field_diagnostics() { |
323 | check_diagnostics( | 367 | check_diagnostics( |
324 | r#" | 368 | r#" |
diff --git a/crates/ra_hir_ty/src/diagnostics/expr.rs b/crates/ra_hir_ty/src/diagnostics/expr.rs index 95bbf2d95..3c37fc58e 100644 --- a/crates/ra_hir_ty/src/diagnostics/expr.rs +++ b/crates/ra_hir_ty/src/diagnostics/expr.rs | |||
@@ -111,6 +111,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
111 | file: source_ptr.file_id, | 111 | file: source_ptr.file_id, |
112 | field_list: AstPtr::new(&field_list), | 112 | field_list: AstPtr::new(&field_list), |
113 | missed_fields, | 113 | missed_fields, |
114 | list_parent_path: record_lit.path().map(|path| AstPtr::new(&path)), | ||
114 | }) | 115 | }) |
115 | } | 116 | } |
116 | } | 117 | } |
diff --git a/crates/ra_ide/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs index 5c8ea46ab..7ae4bda0b 100644 --- a/crates/ra_ide/src/diagnostics.rs +++ b/crates/ra_ide/src/diagnostics.rs | |||
@@ -100,8 +100,10 @@ pub(crate) fn diagnostics( | |||
100 | }; | 100 | }; |
101 | 101 | ||
102 | res.borrow_mut().push(Diagnostic { | 102 | res.borrow_mut().push(Diagnostic { |
103 | // TODO kb use a smaller range here | 103 | range: d |
104 | range, | 104 | .list_parent_ast(db) |
105 | .map(|path| path.syntax().text_range()) | ||
106 | .unwrap_or(range), | ||
105 | message: d.message(), | 107 | message: d.message(), |
106 | severity: Severity::Error, | 108 | severity: Severity::Error, |
107 | fix, | 109 | fix, |