rune/grammar/
classify.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
use crate::ast::Kind::*;

use super::Node;

#[derive(Debug, Clone, Copy)]
pub(crate) enum NodeClass {
    Const,
    Local,
    Item,
    Expr,
}

/// Classify the kind of a node.
pub(crate) fn classify(node: &Node<'_>) -> (bool, NodeClass) {
    match node.kind() {
        Local => return (true, NodeClass::Local),
        Item => {
            for node in node.children() {
                let needs_semi = match node.kind() {
                    ItemConst => return (true, NodeClass::Const),
                    ItemStruct => node
                        .children()
                        .rev()
                        .any(|n| matches!(n.kind(), TupleBody | EmptyBody)),
                    ItemEnum | ItemFn | ItemImpl | ItemMod => false,
                    ItemFileMod => true,
                    _ => continue,
                };

                return (needs_semi, NodeClass::Item);
            }
        }
        Expr => {
            if node.children().rev().map(|n| n.kind()).any(|k| {
                matches!(
                    k,
                    ExprIf | ExprFor | ExprWhile | ExprLoop | ExprMatch | ExprSelect | Block
                )
            }) {
                return (false, NodeClass::Item);
            }
        }
        _ => {}
    }

    (false, NodeClass::Expr)
}