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}