compose_syntax/ast/
bindings.rs

1use crate::ast::func::Pattern;
2use crate::ast::{node, AstNode, Expr, Ident};
3use crate::kind::SyntaxKind;
4use crate::Span;
5
6node! {
7    struct LetBinding
8}
9
10impl<'a> LetBinding<'a> {
11    pub fn has_initial_value(self) -> bool {
12        self.0.children().any(|n| n.kind() == SyntaxKind::Eq)
13    }
14
15    pub fn initial_value(self) -> Option<Expr<'a>> {
16        self.0
17            .children()
18            .skip_while(|n| n.kind() != SyntaxKind::Eq)
19            .nth(1)
20            .and_then(|n| n.cast())
21    }
22
23    fn bindings(self) -> Vec<Ident<'a>> {
24        let pattern: Pattern = self.0.try_cast_first().expect("expected pattern");
25        pattern.bindings()
26    }
27
28    pub fn pattern(self) -> Pattern<'a> {
29        self.0.cast_first()
30    }
31
32    pub fn is_mut(self) -> bool {
33        self.0.children().any(|n| n.kind() == SyntaxKind::Mut)
34    }
35
36    pub fn eq_span(self) -> Span {
37        self.0
38            .children()
39            .find(|&n| n.kind() == SyntaxKind::Eq)
40            .map(|n| n.span())
41            .unwrap_or_else(|| self.0.span())
42    }
43
44    pub fn mut_span(self) -> Option<Span> {
45        self.0
46            .children()
47            .find(|&n| n.kind() == SyntaxKind::Mut)
48            .map(|n| n.span())
49    }
50
51    pub fn initial_value_span(self) -> Option<Span> {
52        self.initial_value().map(|e| e.span())
53    }
54
55    pub fn is_public(self) -> bool {
56        self.0.children().any(|n| n.kind() == SyntaxKind::Pub)
57    }
58
59    pub fn pub_span(self) -> Option<Span> {
60        self.0
61            .children()
62            .find(|&n| n.kind() == SyntaxKind::Pub)
63            .map(|n| n.span())
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use super::*;
70    use crate::assert_ast;
71    use crate::ast::Int;
72
73    #[test]
74    fn test_let_binding() {
75        assert_ast!(
76            "let x = 1",
77            binding as LetBinding {
78                binding.bindings().into_iter() => [
79                    ident as Ident {
80                        assert_eq!(ident.get(), "x");
81                    }
82                ]
83                with init: Int = binding.initial_value().unwrap() => {
84                    assert_eq!(init.get(), 1);
85                }
86            }
87        )
88    }
89}