1mod expr_ext;
4mod interpol;
5mod nodes;
6mod operators;
7mod path_util;
8mod str_util;
9mod tokens;
10
11use crate::{NixLanguage, SyntaxKind, SyntaxToken};
12
13pub use expr_ext::LiteralKind;
14pub use interpol::*;
15pub use nodes::*;
16pub use operators::{BinOpKind, UnaryOpKind};
17pub use tokens::*;
18
19pub trait AstNode: rowan::ast::AstNode<Language = NixLanguage> {}
20
21impl<T> AstNode for T where T: rowan::ast::AstNode<Language = NixLanguage> {}
22
23pub trait AstToken {
24 fn can_cast(from: SyntaxKind) -> bool
25 where
26 Self: Sized;
27
28 fn cast(from: SyntaxToken) -> Option<Self>
31 where
32 Self: Sized;
33
34 fn syntax(&self) -> &SyntaxToken;
35}
36
37mod support {
38 use rowan::ast::AstChildren;
39
40 use super::{AstNode, AstToken};
41 use crate::{SyntaxElement, SyntaxKind, SyntaxToken};
42
43 pub(super) fn nth<N: AstNode, NN: AstNode>(parent: &N, n: usize) -> Option<NN> {
44 parent.syntax().children().flat_map(NN::cast).nth(n)
45 }
46
47 pub(super) fn children<N: AstNode, NN: AstNode>(parent: &N) -> AstChildren<NN> {
48 rowan::ast::support::children(parent.syntax())
49 }
50
51 pub(super) fn token<N: AstNode, T: AstToken>(parent: &N) -> Option<T> {
52 children_tokens(parent).nth(0)
53 }
54
55 pub(super) fn token_u<N: AstNode>(parent: &N, kind: SyntaxKind) -> Option<SyntaxToken> {
57 children_tokens_u(parent).find(|it| it.kind() == kind)
58 }
59
60 pub(super) fn children_tokens<N: AstNode, T: AstToken>(parent: &N) -> impl Iterator<Item = T> {
61 parent
62 .syntax()
63 .children_with_tokens()
64 .filter_map(SyntaxElement::into_token)
65 .filter_map(T::cast)
66 }
67
68 pub(super) fn children_tokens_u<N: AstNode>(parent: &N) -> impl Iterator<Item = SyntaxToken> {
69 parent.syntax().children_with_tokens().filter_map(SyntaxElement::into_token)
70 }
71}