kotlin_parser/parse/declaration/
property.rs

1use crate::{
2    ast::*,
3    parse::{
4        expression::call::{block_parser, inner_block_parser, vars_parser},
5        ty::{type_bounds_parser, type_params_parser, type_parser},
6    },
7};
8use chumsky::prelude::*;
9
10use super::{annotation::annotations_parser, modifier_parser};
11
12pub fn property_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, PropertyDeclaration, Error = Simple<char>> {
16    let modifiers = modifier_parser().repeated().or_not();
17    let is_const = just("const")
18        .padded()
19        .or_not()
20        .map(|is_const| is_const.is_some());
21    let is_mutable = choice((just("var").to(true), just("val").to(false)));
22    let type_params = type_params_parser(expr_parser.clone());
23    let receiver = type_parser()
24        .padded()
25        .then_ignore(just('.').padded())
26        .or_not();
27    let vars = vars_parser();
28    let init = choice((just("by").to(true), just('=').to(false)))
29        .then(expr_parser.clone())
30        .or_not();
31    let bounds = type_bounds_parser().or_not();
32    let accessors = choice((
33        get_accessor_parser(stmt_parser.clone(), expr_parser.clone()).then(
34            set_accessor_parser(stmt_parser.clone(), expr_parser.clone())
35                .or_not(),
36        ),
37        set_accessor_parser(stmt_parser.clone(), expr_parser.clone()).then(
38            get_accessor_parser(stmt_parser.clone(), expr_parser.clone())
39                .or_not(),
40        ),
41    ))
42    .or_not();
43
44    modifiers
45        .then(is_const)
46        .then(is_mutable)
47        .then(type_params)
48        .then(receiver)
49        .then(vars)
50        .then(init)
51        .then(bounds)
52        .then(accessors)
53        .map(
54            |(
55                (
56                    (
57                        (
58                            (
59                                (
60                                    ((modifiers, is_const), is_mutable),
61                                    type_params,
62                                ),
63                                receiver,
64                            ),
65                            vars,
66                        ),
67                        body,
68                    ),
69                    bounds,
70                ),
71                accessors_pair,
72            )| {
73                let (is_delegated, init) =
74                    body.map(|(a, b)| (a, Some(b))).unwrap_or((false, None));
75
76                let mut accessors = Vec::with_capacity(2);
77                if let Some((a, b)) = accessors_pair {
78                    accessors.push(a);
79                    if let Some(b) = b {
80                        accessors.push(b);
81                    }
82                }
83
84                PropertyDeclaration {
85                    modifiers: modifiers.unwrap_or_default(),
86                    is_const,
87                    is_mutable,
88                    is_delegated,
89                    type_params,
90                    receiver,
91                    vars,
92                    init,
93                    bounds: bounds.unwrap_or_default(),
94                    accessors,
95                }
96            },
97        )
98}
99
100pub fn get_accessor_parser(
101    stmt_parser: impl Parser<char, Statement, Error = Simple<char>>,
102    expr_parser: impl Parser<char, Expression, Error = Simple<char>> + Clone,
103) -> impl Parser<char, PropertyAccessor, Error = Simple<char>> {
104    annotations_parser(expr_parser)
105        .repeated()
106        .or_not()
107        .then(modifier_parser().repeated().or_not())
108        .then_ignore(just("get").padded())
109        .then_ignore(
110            just('(').padded().then_ignore(just(')').padded()).or_not(),
111        )
112        .then(just(':').ignore_then(type_parser()).or_not())
113        .then(block_parser(stmt_parser).or_not())
114        .map(|(((annotations, modifiers), return_ty), body)| {
115            PropertyAccessor::Getter {
116                modifiers: modifiers.unwrap_or_default(),
117                annotations: annotations.unwrap_or_default(),
118                return_ty,
119                body,
120            }
121        })
122}
123
124pub fn set_accessor_parser(
125    stmt_parser: impl Parser<char, Statement, Error = Simple<char>>,
126    expr_parser: impl Parser<char, Expression, Error = Simple<char>> + Clone,
127) -> impl Parser<char, PropertyAccessor, Error = Simple<char>> {
128    annotations_parser(expr_parser)
129        .repeated()
130        .or_not()
131        .then(modifier_parser().repeated().or_not())
132        .then_ignore(just("set").padded())
133        .then(
134            text::ident()
135                .padded()
136                .then(just(':').padded().ignore_then(type_parser()).or_not())
137                .delimited_by(just('(').padded(), just(')').padded())
138                .map(|(name, ty)| PropertySetterField { name, ty })
139                .or_not(),
140        )
141        .then(just(':').padded().ignore_then(type_parser()).or_not())
142        .then(
143            just('{')
144                .padded()
145                .ignore_then(inner_block_parser(stmt_parser))
146                .then_ignore(just('}').padded())
147                .or_not(),
148        )
149        .map(|((((annotations, modifiers), field), return_ty), body)| {
150            PropertyAccessor::Setter {
151                modifiers: modifiers.unwrap_or_default(),
152                annotations: annotations.unwrap_or_default(),
153                field,
154                return_ty,
155                body,
156            }
157        })
158}