kotlin_parser/parse/declaration/
entity.rs

1use crate::{
2    ast::*,
3    parse::{
4        expression::call::block_parser,
5        ty::{class_type_params_parser, type_bounds_parser, type_parser},
6    },
7};
8use chumsky::prelude::*;
9
10use super::{annotation::annotations_parser, modifier_parser};
11
12pub fn entity_parser(
13    stmt_parser: impl Parser<char, Statement, Error = Simple<char>> + Clone,
14    expr_parser: impl Parser<char, Expression, Error = Simple<char>> + Clone,
15) -> impl Parser<char, EntityDeclaration, Error = Simple<char>> {
16    modifier_parser()
17        .repeated()
18        .or_not()
19        .then(entity_kind_parser().padded())
20        .then(text::ident().padded().or_not())
21        .then(
22            class_type_params_parser(expr_parser.clone())
23                .padded()
24                .or_not(),
25        )
26        .then(primary_constructor_parser(expr_parser).or_not())
27        .then(extends_parser().padded().or_not())
28        .then(type_bounds_parser().padded().or_not())
29        .then(block_parser(stmt_parser).or_not())
30        .map(
31            |(
32                (
33                    (
34                        (
35                            (((modifiers, kind), name), type_params),
36                            primary_constructor,
37                        ),
38                        extends,
39                    ),
40                    bounds,
41                ),
42                inner,
43            )| {
44                EntityDeclaration {
45                    modifiers: modifiers.unwrap_or_default(),
46                    kind,
47                    name,
48                    type_params: type_params.unwrap_or_default(),
49                    primary_constructor,
50                    bounds: bounds.unwrap_or_default(),
51                    extends: extends.unwrap_or_default(),
52                    body: inner,
53                }
54            },
55        )
56}
57
58pub fn entity_kind_parser(
59) -> impl Parser<char, EntityDeclarationKind, Error = Simple<char>> {
60    choice((
61        just("enum")
62            .padded()
63            .then(just("class"))
64            .to(EntityDeclarationKind::Enum),
65        just("interface").to(EntityDeclarationKind::Interface),
66        just("class").to(EntityDeclarationKind::Class),
67        just("companion")
68            .padded()
69            .then(just("object"))
70            .to(EntityDeclarationKind::CompanionObject),
71        just("object").to(EntityDeclarationKind::Object),
72    ))
73}
74
75pub fn extends_parser() -> impl Parser<char, Vec<Type>, Error = Simple<char>> {
76    just(':')
77        .padded()
78        .ignore_then(type_parser())
79        .separated_by(just(',').padded())
80}
81
82pub fn primary_constructor_parser(
83    expr_parser: impl Parser<char, Expression, Error = Simple<char>>,
84) -> impl Parser<char, PrimaryConstructorDeclaration, Error = Simple<char>> {
85    modifier_parser()
86        .repeated()
87        .or_not()
88        .then(
89            constructor_param_parser(expr_parser)
90                .separated_by(just(',').padded())
91                .delimited_by(just('(').padded(), just(')').padded()),
92        )
93        .map(|(modifiers, params)| PrimaryConstructorDeclaration {
94            modifiers: modifiers.unwrap_or_default(),
95            params,
96        })
97}
98
99pub fn constructor_param_parser(
100    expr_parser: impl Parser<char, Expression, Error = Simple<char>>,
101) -> impl Parser<char, ConstructorParam, Error = Simple<char>> {
102    annotations_parser(expr_parser)
103        .repeated()
104        .or_not()
105        .then(modifier_parser().repeated().or_not())
106        .then(
107            choice((
108                just("var").to(PropertyType::Var),
109                just("val").to(PropertyType::Val),
110            ))
111            .padded()
112            .or_not(),
113        )
114        .then(
115            text::ident()
116                .padded()
117                .then_ignore(just(':'))
118                .padded()
119                .then(type_parser()),
120        )
121        .map(|(((annotations, modifiers), property_type), (name, ty))| {
122            ConstructorParam {
123                modifiers: modifiers.unwrap_or_default(),
124                property_type,
125                param: Param {
126                    annotations: annotations.unwrap_or_default(),
127                    name,
128                    ty,
129                },
130            }
131        })
132}