• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vcfxb / wright-lang / 14120649496

28 Mar 2025 02:25AM UTC coverage: 74.175% (-0.9%) from 75.076%
14120649496

push

github

vcfxb
nit: remove unused import

1011 of 1363 relevant lines covered (74.17%)

29.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

57.89
/wright/src/parser/error.rs
1
//! Representation and implementation relating to errors that may be encountered in parsing.
2

3
use crate::{
4
    reporting::{Diagnostic, Highlight},
5
    source_tracking::fragment::Fragment,
6
};
7
use std::borrow::Cow;
8

9
/// All the different errors that can be produced in the process of parsing.
10
/// The names of these should be self-describing, but in cases when one of these needs to appear in a diagnostic,
11
/// use [ParserErrorKind::describe].
12
#[allow(missing_docs)]
13
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
14
pub enum ParserErrorKind {
15
    EncounteredUnknownToken,
16
    EncounteredUnterminatedComment,
17
    EncounteredUnterminatedString,
18
    ExpectedAtomicTypeSignature,
19
    ExpectedBooleanLiteral,
20
    ExpectedIdentifier,
21
    ExpectedImportDeclaration,
22
    ExpectedIntegerLiteral,
23
    ExpectedPath,
24
    ExpectedWhitespace,
25
    ImportMustEndWithSemicolon,
26
}
27

28
impl ParserErrorKind {
29
    /// Get a short description of this kind of error.
30
    pub const fn describe(self) -> &'static str {
1✔
31
        use ParserErrorKind::*;
32

33
        match self {
1✔
34
            EncounteredUnknownToken => "encountered unknown token",
×
35
            EncounteredUnterminatedComment => {
36
                "encountered unterminated multiline comment while parsing"
×
37
            }
38
            EncounteredUnterminatedString => {
39
                "encountered unterminated string literal while parsing"
×
40
            }
41
            ExpectedAtomicTypeSignature => "expected atomic primitive type",
×
42
            ExpectedBooleanLiteral => "expected boolean literal",
×
43
            ExpectedIdentifier => "expected identifier",
1✔
44
            ExpectedImportDeclaration => "expected import declaration",
×
45
            ExpectedIntegerLiteral => "expected integer literal",
×
46
            ExpectedPath => "expected path or identifier",
×
47
            ExpectedWhitespace => "expected whitespace character(s)",
×
48
            ImportMustEndWithSemicolon => "import declarations must end with a semicolon",
×
49
        }
50
    }
1✔
51

52
    /// Construct a [ParserError] by adding a location [Fragment] to this error variant.
53
    pub const fn at(self, f: Fragment) -> ParserError {
14✔
54
        ParserError {
14✔
55
            kind: self,
14✔
56
            location: f,
14✔
57
            help: None,
14✔
58
        }
14✔
59
    }
14✔
60
}
61

62
/// An error that occurred while parsing.
63
/// This error structure is pretty simple compared to what can be represented using a diagnostic. That's fine,
64
/// since most of the more complex errors arise when typechecking, rather than checking syntax.
65
#[derive(Debug)]
66
pub struct ParserError {
67
    /// What type/cause there is for this error.
68
    pub kind: ParserErrorKind,
69

70
    /// Where this error occurred.
71
    pub location: Fragment,
72

73
    /// Optionally, a help string that can be printed with this error.
74
    pub help: Option<Cow<'static, str>>,
75
}
76

77
impl ParserError {
78
    /// Builder-style method to add a help string to a [ParserError].
79
    pub fn with_help(mut self, help: impl Into<Cow<'static, str>>) -> Self {
×
80
        self.help = Some(help.into());
×
81
        self
×
82
    }
×
83

84
    /// Turn this parser error into a full blown compiler error.
85
    pub fn as_diagnostic(self) -> Diagnostic {
1✔
86
        let description = self.kind.describe();
1✔
87

88
        // Put a little clarification if the parser reached end of source and then produced an error.
89
        let message = if self.location.is_empty_at_end_of_source() {
1✔
90
            Cow::Borrowed("found end of source here")
×
91
        } else {
92
            Cow::Borrowed("")
1✔
93
        };
94

95
        let mut diagnostic = Diagnostic::error()
1✔
96
            .with_message(description)
1✔
97
            .with_highlights([Highlight::primary(self.location.clone(), message)]);
1✔
98

99
        if let Some(help) = self.help {
1✔
100
            diagnostic = diagnostic.with_notes([help]);
×
101
        }
1✔
102

103
        diagnostic
1✔
104
    }
1✔
105
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc