Skip to main content

lintspec_core/
parser.rs

1//! Solidity parser interface
2use std::{collections::HashMap, io, path::Path};
3
4use crate::{definitions::Definition, error::Result};
5
6#[cfg_attr(docsrs, doc(cfg(feature = "slang")))]
7#[cfg(feature = "slang")]
8pub mod slang;
9
10#[cfg_attr(docsrs, doc(cfg(feature = "solar")))]
11#[cfg(feature = "solar")]
12pub mod solar;
13
14#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
15pub struct DocumentId(u64);
16
17impl DocumentId {
18    /// Generate a new random and unique document ID
19    #[must_use]
20    pub fn new() -> Self {
21        DocumentId(fastrand::u64(..))
22    }
23}
24
25/// The result of parsing and identifying source items in a document
26#[derive(Debug)]
27pub struct ParsedDocument {
28    /// A unique ID for the document given by the parser
29    ///
30    /// Can be used to retrieve the document contents after parsing (via [`Parse::get_sources`]).
31    pub id: DocumentId,
32
33    /// The list of definitions found in the document
34    pub definitions: Vec<Definition>,
35}
36
37/// The trait implemented by all parsers
38///
39/// Ideally, cloning a parser should not duplicate the contents of the sources. The underlying data should be wrapped
40/// in an [`Arc`][std::sync::Arc], so that the last clone of a parser is able to retrieve the sources' contents for
41/// all files.
42pub trait Parse: Clone {
43    /// Parse a document from a reader and identify the relevant source items
44    ///
45    /// If a path is provided, then this can be used to enrich diagnostics.
46    /// The fact that this takes in a mutable reference to the parser allows for stateful parsers.
47    fn parse_document(
48        &mut self,
49        input: impl io::Read,
50        path: Option<impl AsRef<Path>>,
51        keep_contents: bool,
52    ) -> Result<ParsedDocument>;
53
54    /// Retrieve the contents of the source files after parsing is done
55    ///
56    /// This consumes the parser, so that ownership of the contents can be retrieved safely.
57    /// Note that documents which were parsed with `keep_contents` to `false` will no be present in the map.
58    ///
59    /// This can return an error if there are more than one clone of the parser.
60    fn get_sources(self) -> Result<HashMap<DocumentId, String>>;
61}