kotlin_parser/parse/declaration/
property.rs1use 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}