diff options
Diffstat (limited to 'crates/ra_hir_ty/src/diagnostics.rs')
-rw-r--r-- | crates/ra_hir_ty/src/diagnostics.rs | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs new file mode 100644 index 000000000..4a13fac23 --- /dev/null +++ b/crates/ra_hir_ty/src/diagnostics.rs | |||
@@ -0,0 +1,91 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use std::any::Any; | ||
4 | |||
5 | use hir_expand::{db::AstDatabase, name::Name, HirFileId, Source}; | ||
6 | use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr}; | ||
7 | |||
8 | pub use hir_def::diagnostics::UnresolvedModule; | ||
9 | pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink}; | ||
10 | |||
11 | #[derive(Debug)] | ||
12 | pub struct NoSuchField { | ||
13 | pub file: HirFileId, | ||
14 | pub field: AstPtr<ast::RecordField>, | ||
15 | } | ||
16 | |||
17 | impl Diagnostic for NoSuchField { | ||
18 | fn message(&self) -> String { | ||
19 | "no such field".to_string() | ||
20 | } | ||
21 | |||
22 | fn source(&self) -> Source<SyntaxNodePtr> { | ||
23 | Source { file_id: self.file, value: self.field.into() } | ||
24 | } | ||
25 | |||
26 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | ||
27 | self | ||
28 | } | ||
29 | } | ||
30 | |||
31 | #[derive(Debug)] | ||
32 | pub struct MissingFields { | ||
33 | pub file: HirFileId, | ||
34 | pub field_list: AstPtr<ast::RecordFieldList>, | ||
35 | pub missed_fields: Vec<Name>, | ||
36 | } | ||
37 | |||
38 | impl Diagnostic for MissingFields { | ||
39 | fn message(&self) -> String { | ||
40 | use std::fmt::Write; | ||
41 | let mut message = String::from("Missing structure fields:\n"); | ||
42 | for field in &self.missed_fields { | ||
43 | write!(message, "- {}\n", field).unwrap(); | ||
44 | } | ||
45 | message | ||
46 | } | ||
47 | fn source(&self) -> Source<SyntaxNodePtr> { | ||
48 | Source { file_id: self.file, value: self.field_list.into() } | ||
49 | } | ||
50 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | ||
51 | self | ||
52 | } | ||
53 | } | ||
54 | |||
55 | impl AstDiagnostic for MissingFields { | ||
56 | type AST = ast::RecordFieldList; | ||
57 | |||
58 | fn ast(&self, db: &impl AstDatabase) -> Self::AST { | ||
59 | let root = db.parse_or_expand(self.source().file_id).unwrap(); | ||
60 | let node = self.source().value.to_node(&root); | ||
61 | ast::RecordFieldList::cast(node).unwrap() | ||
62 | } | ||
63 | } | ||
64 | |||
65 | #[derive(Debug)] | ||
66 | pub struct MissingOkInTailExpr { | ||
67 | pub file: HirFileId, | ||
68 | pub expr: AstPtr<ast::Expr>, | ||
69 | } | ||
70 | |||
71 | impl Diagnostic for MissingOkInTailExpr { | ||
72 | fn message(&self) -> String { | ||
73 | "wrap return expression in Ok".to_string() | ||
74 | } | ||
75 | fn source(&self) -> Source<SyntaxNodePtr> { | ||
76 | Source { file_id: self.file, value: self.expr.into() } | ||
77 | } | ||
78 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | ||
79 | self | ||
80 | } | ||
81 | } | ||
82 | |||
83 | impl AstDiagnostic for MissingOkInTailExpr { | ||
84 | type AST = ast::Expr; | ||
85 | |||
86 | fn ast(&self, db: &impl AstDatabase) -> Self::AST { | ||
87 | let root = db.parse_or_expand(self.file).unwrap(); | ||
88 | let node = self.source().value.to_node(&root); | ||
89 | ast::Expr::cast(node).unwrap() | ||
90 | } | ||
91 | } | ||