pactole_syntax/diagnostics.rs
1//! Diagnostics reported while tolerantly parsing a `.pactole` source text.
2
3use crate::span::Span;
4
5/// The nature of a syntax diagnostic, mirroring tree-sitter's own error taxonomy.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7pub enum DiagnosticKind {
8 /// The parser encountered a sequence of tokens it could not fit into the grammar.
9 /// Corresponds to a tree-sitter `ERROR` node.
10 Error,
11 /// The parser inferred that a token was expected but absent from the input.
12 /// Corresponds to a tree-sitter "missing" node.
13 Missing,
14}
15
16/// A single syntax-level diagnostic produced by tolerant parsing.
17///
18/// Diagnostics are purely syntactic: they do not reference `pactole-core` domain
19/// concepts and only describe where the concrete syntax tree deviates from a
20/// fully valid parse.
21#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct SyntaxDiagnostic {
23 /// Whether this diagnostic reports an `ERROR` node or a `MISSING` node.
24 pub kind: DiagnosticKind,
25 /// The span in the source text this diagnostic refers to.
26 pub span: Span,
27 /// A human-readable description of the diagnostic (e.g. "missing an
28 /// account name in an `open` directive", or "unexpected syntax after a
29 /// date: `foo bar`"), derived from the tree-sitter node's kind and its
30 /// surrounding context (parent node kind) rather than a raw
31 /// tree-sitter S-expression.
32 pub message: String,
33}
34
35impl SyntaxDiagnostic {
36 /// Builds a new [`SyntaxDiagnostic`].
37 pub fn new(kind: DiagnosticKind, span: Span, message: impl Into<String>) -> Self {
38 Self {
39 kind,
40 span,
41 message: message.into(),
42 }
43 }
44}