Skip to main content

xidl_parser/typed_ast/
interface.rs

1use crate::typed_ast::ScopedName;
2use serde::{Deserialize, Serialize};
3
4use super::{AnnotationAppl, ConstDcl, ExceptDcl, Identifier, SimpleDeclarator, TypeDcl, TypeSpec};
5use xidl_parser_derive::Parser;
6
7#[derive(Debug, Serialize, Deserialize)]
8pub struct InterfaceDcl {
9    pub annotations: Vec<AnnotationAppl>,
10    pub decl: InterfaceDclInner,
11}
12
13#[derive(Debug, Parser, Serialize, Deserialize)]
14#[ts(transparent)]
15pub enum InterfaceDclInner {
16    InterfaceForwardDcl(InterfaceForwardDcl),
17    InterfaceDef(InterfaceDef),
18}
19
20impl<'a> crate::parser::FromTreeSitter<'a> for InterfaceDcl {
21    fn from_node(
22        node: tree_sitter::Node<'a>,
23        ctx: &mut crate::parser::ParseContext<'a>,
24    ) -> crate::error::ParserResult<Self> {
25        assert_eq!(
26            node.kind_id(),
27            xidl_parser_derive::node_id!("interface_dcl")
28        );
29        let mut annotations = vec![];
30        let mut decl = None;
31        for ch in node.children(&mut node.walk()) {
32            match ch.kind_id() {
33                xidl_parser_derive::node_id!("annotation_appl")
34                | xidl_parser_derive::node_id!("extend_annotation_appl") => {
35                    annotations.push(AnnotationAppl::from_node(ch, ctx)?);
36                }
37                xidl_parser_derive::node_id!("interface_def")
38                | xidl_parser_derive::node_id!("interface_forward_dcl") => {
39                    decl = Some(InterfaceDclInner::from_node(ch, ctx)?);
40                }
41                _ => {}
42            }
43        }
44        Ok(Self {
45            annotations,
46            decl: decl.ok_or_else(|| {
47                crate::error::ParseError::UnexpectedNode(format!(
48                    "parent: {}, got: missing interface decl",
49                    node.kind()
50                ))
51            })?,
52        })
53    }
54}
55
56#[derive(Debug, Parser, Serialize, Deserialize)]
57pub struct InterfaceForwardDcl {
58    pub kind: InterfaceKind,
59    pub ident: Identifier,
60}
61
62#[derive(Debug, Parser, Serialize, Deserialize)]
63#[ts(mark)]
64pub struct InterfaceKind;
65
66#[derive(Debug, Parser, Serialize, Deserialize)]
67pub struct InterfaceDef {
68    pub header: InterfaceHeader,
69    pub interface_body: Option<InterfaceBody>,
70}
71
72#[derive(Debug, Parser, Serialize, Deserialize)]
73pub struct InterfaceHeader {
74    pub kind: InterfaceKind,
75    pub ident: Identifier,
76    pub parent: Option<InterfaceInheritanceSpec>,
77}
78
79#[derive(Debug, Parser, Serialize, Deserialize)]
80pub struct InterfaceInheritanceSpec(pub Vec<InterfaceName>);
81
82#[derive(Debug, Parser, Serialize, Deserialize)]
83pub struct InterfaceName(pub ScopedName);
84
85#[derive(Debug, Parser, Serialize, Deserialize)]
86pub struct InterfaceBody(pub Vec<Export>);
87
88#[derive(Debug, Parser, Serialize, Deserialize)]
89pub enum Export {
90    OpDcl(OpDcl),
91    AttrDcl(AttrDcl),
92    TypeDcl(TypeDcl),
93    ConstDcl(ConstDcl),
94    ExceptDcl(ExceptDcl),
95}
96
97#[derive(Debug, Serialize, Deserialize)]
98pub struct OpDcl {
99    pub annotations: Vec<AnnotationAppl>,
100    pub ty: OpTypeSpec,
101    pub ident: Identifier,
102    pub parameter: Option<ParameterDcls>,
103    pub raises: Option<RaisesExpr>,
104}
105
106impl<'a> crate::parser::FromTreeSitter<'a> for OpDcl {
107    fn from_node(
108        node: tree_sitter::Node<'a>,
109        ctx: &mut crate::parser::ParseContext<'a>,
110    ) -> crate::error::ParserResult<Self> {
111        assert_eq!(node.kind_id(), xidl_parser_derive::node_id!("op_dcl"));
112        let mut annotations = Vec::new();
113        let mut ty = None;
114        let mut ident = None;
115        let mut parameter = None;
116        let mut raises = None;
117        for ch in node.children(&mut node.walk()) {
118            match ch.kind_id() {
119                xidl_parser_derive::node_id!("annotation_appl")
120                | xidl_parser_derive::node_id!("extend_annotation_appl") => {
121                    annotations.push(AnnotationAppl::from_node(ch, ctx)?);
122                }
123                xidl_parser_derive::node_id!("op_type_spec") => {
124                    ty = Some(OpTypeSpec::from_node(ch, ctx)?);
125                }
126                xidl_parser_derive::node_id!("identifier") => {
127                    ident = Some(Identifier::from_node(ch, ctx)?);
128                }
129                xidl_parser_derive::node_id!("parameter_dcls") => {
130                    parameter = Some(ParameterDcls::from_node(ch, ctx)?);
131                }
132                xidl_parser_derive::node_id!("raises_expr") => {
133                    raises = Some(RaisesExpr::from_node(ch, ctx)?);
134                }
135                _ => {}
136            }
137        }
138        Ok(Self {
139            annotations,
140            ty: ty.ok_or_else(|| {
141                crate::error::ParseError::UnexpectedNode(format!(
142                    "parent: {}, got: missing op type",
143                    node.kind()
144                ))
145            })?,
146            ident: ident.ok_or_else(|| {
147                crate::error::ParseError::UnexpectedNode(format!(
148                    "parent: {}, got: missing identifier",
149                    node.kind()
150                ))
151            })?,
152            parameter,
153            raises,
154        })
155    }
156}
157#[derive(Debug, Serialize, Deserialize)]
158#[allow(clippy::large_enum_variant)]
159pub enum OpTypeSpec {
160    Void,
161    TypeSpec(TypeSpec),
162}
163
164impl<'a> crate::parser::FromTreeSitter<'a> for OpTypeSpec {
165    fn from_node(
166        node: tree_sitter::Node<'a>,
167        ctx: &mut crate::parser::ParseContext<'a>,
168    ) -> crate::error::ParserResult<Self> {
169        #[allow(clippy::never_loop)]
170        for ch in node.children(&mut node.walk()) {
171            if ctx.node_text(&ch)? == "void" {
172                return Ok(Self::Void);
173            }
174
175            return match ch.kind_id() {
176                xidl_parser_derive::node_id!("type_spec") => Ok(Self::TypeSpec(
177                    crate::parser::FromTreeSitter::from_node(ch, ctx)?,
178                )),
179                _ => Err(crate::error::ParseError::UnexpectedNode(format!(
180                    "parent: {}, got: {}",
181                    node.kind(),
182                    ch.kind()
183                ))),
184            };
185        }
186        unreachable!()
187    }
188}
189
190#[derive(Debug, Parser, Serialize, Deserialize)]
191pub struct ParameterDcls(pub Vec<ParamDcl>);
192
193#[derive(Debug, Serialize, Deserialize)]
194pub struct ParamDcl {
195    pub annotations: Vec<AnnotationAppl>,
196    pub attr: Option<ParamAttribute>,
197    pub ty: TypeSpec,
198    pub declarator: SimpleDeclarator,
199}
200
201impl<'a> crate::parser::FromTreeSitter<'a> for ParamDcl {
202    fn from_node(
203        node: tree_sitter::Node<'a>,
204        ctx: &mut crate::parser::ParseContext<'a>,
205    ) -> crate::error::ParserResult<Self> {
206        assert_eq!(node.kind_id(), xidl_parser_derive::node_id!("param_dcl"));
207        let mut annotations = Vec::new();
208        let mut attr = None;
209        let mut ty = None;
210        let mut declarator = None;
211        for ch in node.children(&mut node.walk()) {
212            match ch.kind_id() {
213                xidl_parser_derive::node_id!("annotation_appl")
214                | xidl_parser_derive::node_id!("extend_annotation_appl") => {
215                    annotations.push(AnnotationAppl::from_node(ch, ctx)?);
216                }
217                xidl_parser_derive::node_id!("param_attribute") => {
218                    attr = Some(ParamAttribute::from_node(ch, ctx)?);
219                }
220                xidl_parser_derive::node_id!("type_spec") => {
221                    ty = Some(TypeSpec::from_node(ch, ctx)?);
222                }
223                xidl_parser_derive::node_id!("simple_declarator") => {
224                    declarator = Some(SimpleDeclarator::from_node(ch, ctx)?);
225                }
226                _ => {}
227            }
228        }
229        Ok(Self {
230            annotations,
231            attr,
232            ty: ty.ok_or_else(|| {
233                crate::error::ParseError::UnexpectedNode(format!(
234                    "parent: {}, got: missing type spec",
235                    node.kind()
236                ))
237            })?,
238            declarator: declarator.ok_or_else(|| {
239                crate::error::ParseError::UnexpectedNode(format!(
240                    "parent: {}, got: missing simple declarator",
241                    node.kind()
242                ))
243            })?,
244        })
245    }
246}
247
248#[derive(Debug, Serialize, Deserialize)]
249pub struct ParamAttribute(pub String);
250
251impl<'a> crate::parser::FromTreeSitter<'a> for ParamAttribute {
252    fn from_node(
253        node: tree_sitter::Node<'a>,
254        ctx: &mut crate::parser::ParseContext<'a>,
255    ) -> crate::error::ParserResult<Self> {
256        assert_eq!(
257            node.kind_id(),
258            xidl_parser_derive::node_id!("param_attribute")
259        );
260
261        Ok(Self(ctx.node_text(&node)?.to_string()))
262    }
263}
264
265#[derive(Debug, Parser, Serialize, Deserialize)]
266pub struct RaisesExpr(pub Vec<ScopedName>);
267
268#[derive(Debug, Serialize, Deserialize)]
269pub struct AttrDcl {
270    pub annotations: Vec<AnnotationAppl>,
271    pub decl: AttrDclInner,
272}
273
274#[derive(Debug, Parser, Serialize, Deserialize)]
275#[ts(transparent)]
276pub enum AttrDclInner {
277    ReadonlyAttrSpec(ReadonlyAttrSpec),
278    AttrSpec(AttrSpec),
279}
280
281impl<'a> crate::parser::FromTreeSitter<'a> for AttrDcl {
282    fn from_node(
283        node: tree_sitter::Node<'a>,
284        ctx: &mut crate::parser::ParseContext<'a>,
285    ) -> crate::error::ParserResult<Self> {
286        assert_eq!(node.kind_id(), xidl_parser_derive::node_id!("attr_dcl"));
287        let mut annotations = vec![];
288        let mut decl = None;
289        for ch in node.children(&mut node.walk()) {
290            match ch.kind_id() {
291                xidl_parser_derive::node_id!("annotation_appl")
292                | xidl_parser_derive::node_id!("extend_annotation_appl") => {
293                    annotations.push(AnnotationAppl::from_node(ch, ctx)?);
294                }
295                xidl_parser_derive::node_id!("readonly_attr_spec")
296                | xidl_parser_derive::node_id!("attr_spec") => {
297                    decl = Some(AttrDclInner::from_node(ch, ctx)?);
298                }
299                _ => {}
300            }
301        }
302        Ok(Self {
303            annotations,
304            decl: decl.ok_or_else(|| {
305                crate::error::ParseError::UnexpectedNode(format!(
306                    "parent: {}, got: missing attr decl",
307                    node.kind()
308                ))
309            })?,
310        })
311    }
312}
313
314#[derive(Debug, Parser, Serialize, Deserialize)]
315pub struct ReadonlyAttrSpec {
316    pub ty: TypeSpec,
317    pub declarator: ReadonlyAttrDeclarator,
318}
319
320#[derive(Debug, Parser, Serialize, Deserialize)]
321pub enum ReadonlyAttrDeclarator {
322    SimpleDeclarator(SimpleDeclarator),
323    RaisesExpr(RaisesExpr),
324}
325
326#[derive(Debug, Parser, Serialize, Deserialize)]
327pub struct AttrSpec {
328    pub type_spec: TypeSpec,
329    pub declarator: AttrDeclarator,
330}
331
332#[derive(Debug, Serialize, Deserialize)]
333pub enum AttrDeclarator {
334    SimpleDeclarator(Vec<SimpleDeclarator>),
335    WithRaises {
336        declarator: SimpleDeclarator,
337        raises: AttrRaisesExpr,
338    },
339}
340
341impl<'a> crate::parser::FromTreeSitter<'a> for AttrDeclarator {
342    fn from_node(
343        node: tree_sitter::Node<'a>,
344        ctx: &mut crate::parser::ParseContext<'a>,
345    ) -> crate::error::ParserResult<Self> {
346        let mut declarator = vec![];
347        let mut raises = None;
348
349        for ch in node.children(&mut node.walk()) {
350            match ch.kind_id() {
351                xidl_parser_derive::node_id!("simple_declarator") => {
352                    declarator.push(SimpleDeclarator::from_node(ch, ctx)?);
353                }
354                xidl_parser_derive::node_id!("attr_raises_expr") => {
355                    raises = Some(AttrRaisesExpr::from_node(ch, ctx)?);
356                }
357                _ => {}
358            };
359        }
360        if let Some(raises) = raises {
361            let mut iter = declarator.into_iter();
362            let declarator = iter.next().ok_or_else(|| {
363                crate::error::ParseError::UnexpectedNode(format!(
364                    "parent: {}, got: missing declarator",
365                    node.kind(),
366                ))
367            })?;
368            if iter.next().is_some() {
369                return Err(crate::error::ParseError::UnexpectedNode(format!(
370                    "parent: {}, got: extra declarator",
371                    node.kind()
372                )));
373            }
374            Ok(Self::WithRaises { declarator, raises })
375        } else {
376            Ok(Self::SimpleDeclarator(declarator))
377        }
378    }
379}
380
381#[derive(Debug, Serialize, Deserialize)]
382pub enum AttrRaisesExpr {
383    Case1(GetExcepExpr, Option<SetExcepExpr>),
384    SetExcepExpr(SetExcepExpr),
385}
386
387#[derive(Debug, Parser, Serialize, Deserialize)]
388pub struct GetExcepExpr {
389    pub expr: ExceptionList,
390}
391
392#[derive(Debug, Parser, Serialize, Deserialize)]
393pub struct SetExcepExpr {
394    pub expr: ExceptionList,
395}
396
397#[derive(Debug, Parser, Serialize, Deserialize)]
398pub struct ExceptionList(pub Vec<ScopedName>);
399
400impl<'a> crate::parser::FromTreeSitter<'a> for AttrRaisesExpr {
401    fn from_node(
402        node: tree_sitter::Node<'a>,
403        ctx: &mut crate::parser::ParseContext<'a>,
404    ) -> crate::error::ParserResult<Self> {
405        assert_eq!(
406            node.kind_id(),
407            xidl_parser_derive::node_id!("attr_raises_expr")
408        );
409        let mut get_excep = None;
410        let mut set_excep = None;
411        for ch in node.children(&mut node.walk()) {
412            match ch.kind_id() {
413                xidl_parser_derive::node_id!("get_excep_expr") => {
414                    get_excep = Some(crate::parser::FromTreeSitter::from_node(ch, ctx)?);
415                }
416                xidl_parser_derive::node_id!("set_excep_expr") => {
417                    set_excep = Some(crate::parser::FromTreeSitter::from_node(ch, ctx)?);
418                }
419                _ => {}
420            }
421        }
422        if let Some(get_excep) = get_excep {
423            Ok(Self::Case1(get_excep, set_excep))
424        } else if let Some(set_excep) = set_excep {
425            Ok(Self::SetExcepExpr(set_excep))
426        } else {
427            Err(crate::error::ParseError::UnexpectedNode(format!(
428                "parent: {}, got: missing raises",
429                node.kind()
430            )))
431        }
432    }
433}