kotlin_parser/parse/ty/
function.rs

1use crate::{ast::*, parse::declaration::annotation::annotations_parser};
2use chumsky::prelude::*;
3
4use super::type_parser;
5
6pub fn function_type_parser() -> impl Parser<char, Type, Error = Simple<char>> {
7    let core_function_type = (type_parser().then_ignore(just('.')))
8        .or_not()
9        .then(anonymous_params_parser())
10        .delimited_by(just('('), just(')'))
11        .then_ignore(just("->"))
12        .then(type_parser());
13
14    just('(')
15        .or_not()
16        .then(core_function_type)
17        .then(just(')').or_not())
18        .then(just('?').or_not())
19        .try_map(
20            |(((left_paren, function), right_paren), is_nullable), span| {
21                if left_paren.is_some() && right_paren.is_none() {
22                    return Err(Simple::custom(span, "Expected ')'"));
23                } else if left_paren.is_none() && right_paren.is_some() {
24                    return Err(Simple::custom(span, "Expected '('"));
25                }
26
27                let ((receiver, params), return_ty) = function;
28
29                Ok(Type::Function(Box::new(FunctionType {
30                    receiver,
31                    params,
32                    return_ty,
33                    is_nullable: is_nullable.is_some(),
34                })))
35            },
36        )
37}
38
39pub fn anonymous_params_parser(
40) -> impl Parser<char, Vec<AnonymousParam>, Error = Simple<char>> {
41    text::ident()
42        .padded()
43        .then_ignore(just(':'))
44        .padded()
45        .or_not()
46        .then(type_parser())
47        .separated_by(just(',').padded())
48        .map(|params| {
49            params
50                .into_iter()
51                .map(|(name, ty)| AnonymousParam { name, ty })
52                .collect()
53        })
54}
55
56pub fn function_params_parser(
57    expr_parser: impl Parser<char, Expression, Error = Simple<char>>,
58) -> impl Parser<char, Vec<Param>, Error = Simple<char>> {
59    param_parser(expr_parser)
60        .separated_by(just(',').padded())
61        .collect()
62}
63
64pub fn param_parser(
65    expr_parser: impl Parser<char, Expression, Error = Simple<char>>,
66) -> impl Parser<char, Param, Error = Simple<char>> {
67    annotations_parser(expr_parser)
68        .repeated()
69        .or_not()
70        .then(
71            text::ident()
72                .padded()
73                .then_ignore(just(':'))
74                .padded()
75                .then(type_parser()),
76        )
77        .map(|(annotations, (name, ty))| Param {
78            annotations: annotations.unwrap_or_default(),
79            name,
80            ty,
81        })
82}