Skip to main content

neo_devpack_solidity/frontend/
frontend_errors.rs

1/// A single structured parser diagnostic, carrying the byte range so
2/// standard-JSON output can emit a precise `sourceLocation` (start/end) per
3/// error instead of collapsing every parse error into one opaque blob.
4#[derive(Debug, Clone)]
5pub struct ParseDiagnostic {
6    /// Human-readable message, prefixed with `line:column:` where known.
7    pub message: String,
8    /// Inclusive start byte offset in the source.
9    pub start: usize,
10    /// Exclusive end byte offset in the source.
11    pub end: usize,
12}
13
14/// Errors emitted by the frontend while parsing Solidity code.
15#[derive(Debug, Error)]
16pub enum FrontendError {
17    /// Parsing failed; the contained message aggregates all diagnostics.
18    #[error("Solidity parsing failed:\n{0}")]
19    Parse(String),
20
21    /// Parsing failed; structured per-diagnostic form (preferred). Preserves
22    /// each diagnostic's byte range for precise tooling output.
23    #[error("Solidity parsing failed with {} error(s)", .0.len())]
24    ParseDiagnostics(Vec<ParseDiagnostic>),
25
26    /// Invalid Solidity version pragma
27    #[error("Unsupported Solidity version: {0}")]
28    UnsupportedVersion(String),
29
30    /// Import resolution failed
31    #[error("Failed to resolve import '{path}': {reason}")]
32    ImportError { path: String, reason: String },
33
34    /// Contract not found in source
35    #[error("Contract '{0}' not found in source")]
36    ContractNotFound(String),
37}
38
39impl FrontendError {
40    /// Create a parse error with location info
41    pub fn parse_at(line: usize, column: usize, message: impl Into<String>) -> Self {
42        Self::Parse(format!("{}:{}: {}", line, column, message.into()))
43    }
44
45    /// Create an import error
46    pub fn import_error(path: impl Into<String>, reason: impl Into<String>) -> Self {
47        Self::ImportError {
48            path: path.into(),
49            reason: reason.into(),
50        }
51    }
52
53    /// Check if this is a recoverable error
54    pub fn is_recoverable(&self) -> bool {
55        matches!(self, Self::UnsupportedVersion(_))
56    }
57}
58