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