Skip to main content

xidl_parser/typed_ast/
preproc.rs

1use super::*;
2use serde::{Deserialize, Serialize};
3use xidl_parser_derive::Parser;
4
5#[derive(Debug, Parser, Serialize, Deserialize)]
6pub struct PreprocDefine {
7    #[ts(id = "args", text)]
8    pub args: String,
9}
10
11#[derive(Debug, Parser, Serialize, Deserialize)]
12pub struct PreprocCall {
13    pub directive: PreprocDirective,
14    pub argument: Option<PreprocArg>,
15}
16
17#[derive(Debug, Parser, Serialize, Deserialize)]
18#[ts(transparent)]
19pub struct PreprocDirective(pub String);
20
21#[derive(Debug, Parser, Serialize, Deserialize)]
22#[ts(transparent)]
23pub struct PreprocArg(pub String);
24
25#[derive(Debug, Serialize, Deserialize)]
26pub struct PreprocInclude {
27    pub path: PreprocIncludePath,
28}
29
30#[derive(Debug, Serialize, Deserialize)]
31pub enum PreprocIncludePath {
32    StringLiteral(String),
33    SystemLibString(String),
34    Identifier(Identifier),
35}
36
37impl<'a> crate::parser::FromTreeSitter<'a> for PreprocInclude {
38    fn from_node(
39        node: tree_sitter::Node<'a>,
40        ctx: &mut crate::parser::ParseContext<'a>,
41    ) -> crate::error::ParserResult<Self> {
42        assert_eq!(
43            node.kind_id(),
44            xidl_parser_derive::node_id!("preproc_include")
45        );
46        let mut path = None;
47        for ch in node.children(&mut node.walk()) {
48            match ch.kind_id() {
49                xidl_parser_derive::node_id!("string_literal") => {
50                    path = Some(PreprocIncludePath::StringLiteral(
51                        ctx.node_text(&ch)?.to_string(),
52                    ));
53                }
54                xidl_parser_derive::node_id!("system_lib_string") => {
55                    path = Some(PreprocIncludePath::SystemLibString(
56                        ctx.node_text(&ch)?.to_string(),
57                    ));
58                }
59                xidl_parser_derive::node_id!("identifier") => {
60                    path = Some(PreprocIncludePath::Identifier(
61                        crate::parser::FromTreeSitter::from_node(ch, ctx)?,
62                    ));
63                }
64                _ => {}
65            }
66        }
67        let Some(path) = path else {
68            return Err(crate::error::ParseError::UnexpectedNode(format!(
69                "parent: {}, got: missing include path",
70                node.kind()
71            )));
72        };
73        Ok(Self { path })
74    }
75}