luau_parser/impl/expression/
function.rs

1//! All `impl` blocks for function call-related types:
2//!
3//! * [`FunctionCallInvoked`]
4//! * [`FunctionCall`]
5//! * [`FunctionArguments`]
6//! * [`FunctionArgument`]
7//! * [`Closure`]
8
9use luau_lexer::prelude::{Keyword, Lexer, Literal, ParseError, Symbol, Token, TokenType};
10
11use crate::{
12    force_parse_bracketed, parse_bracketed,
13    types::{
14        Block, BracketedList, Closure, Expression, FunctionArgument, FunctionArguments,
15        FunctionCall, FunctionCallInvoked, Parse, ParseWithArgs, Pointer, PrefixExp, Table,
16        TableAccessPrefix, TryParse, TryParseWithArgs, TypeValue,
17    },
18    utils::{get_token_type_display, get_token_type_display_extended},
19};
20
21impl Parse for FunctionCallInvoked {
22    fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
23        let prefix_exp = Pointer::new(PrefixExp::parse(token, lexer, errors)?);
24
25        maybe_next_token!(lexer, colon, TokenType::Symbol(Symbol::Colon));
26        let Some(colon) = colon else {
27            return Some(Self::Function(prefix_exp));
28        };
29
30        next_token_recoverable!(
31            lexer,
32            method,
33            TokenType::Identifier(_) | TokenType::PartialKeyword(_),
34            TokenType::Identifier("*error*".into(),),
35            errors,
36            "Expected ".to_string() + get_token_type_display(&TokenType::Identifier("".into(),))
37        );
38
39        Some(Self::TableMethod {
40            table: prefix_exp,
41            colon: Pointer::new(colon),
42            method: Pointer::new(method),
43        })
44    }
45}
46impl TryParse for FunctionCallInvoked {}
47
48impl Parse for FunctionCall {
49    fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
50        let invoked = FunctionCallInvoked::parse(token, lexer, errors)?;
51        let arguments = FunctionArguments::try_parse(lexer, errors);
52
53        if let Some(arguments) = arguments {
54            return Some(FunctionCall { invoked, arguments });
55        }
56        if let FunctionCallInvoked::Function(pointer) = invoked {
57            if let PrefixExp::FunctionCall(call) = (*pointer).clone() {
58                return Some(call);
59            }
60        }
61
62        None
63    }
64}
65impl TryParse for FunctionCall {
66    fn try_parse(lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
67        Some(Self {
68            invoked: FunctionCallInvoked::try_parse(lexer, errors)?,
69            arguments: FunctionArguments::try_parse(lexer, errors)?,
70        })
71    }
72}
73
74impl Parse<PrefixExp> for FunctionCall {
75    fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<PrefixExp> {
76        Self::parse(token, lexer, errors).map(PrefixExp::FunctionCall)
77    }
78}
79impl Parse<TableAccessPrefix> for FunctionCall {
80    fn parse(
81        token: Token,
82        lexer: &mut Lexer,
83        errors: &mut Vec<ParseError>,
84    ) -> Option<TableAccessPrefix> {
85        Pointer::<Self>::parse(token, lexer, errors).map(TableAccessPrefix::FunctionCall)
86    }
87}
88
89impl Parse for FunctionArguments {
90    fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
91        if matches!(token.token_type, TokenType::Literal(Literal::String(_))) {
92            return Some(Self::String(token));
93        }
94        if token.token_type == TokenType::Symbol(Symbol::OpeningParenthesis) {
95            return BracketedList::parse_with(
96                token,
97                lexer,
98                errors,
99                ("Expected <expr>", Symbol::ClosingParenthesis),
100            )
101            .map(Self::List);
102        }
103
104        Table::parse(token.clone(), lexer, errors)
105    }
106}
107impl TryParse for FunctionArguments {}
108
109impl Parse for FunctionArgument {
110    fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
111        if matches!(token.token_type, TokenType::Symbol(Symbol::Ellipses)) {
112            Some(Self::VariadicValues(token))
113        } else {
114            Expression::parse(token, lexer, errors).map(Self::Expression)
115        }
116    }
117}
118impl TryParse for FunctionArgument {}
119
120impl Parse for Closure {
121    fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
122        let attributes;
123        let function_keyword;
124
125        match token.token_type {
126            TokenType::Keyword(Keyword::Function) => {
127                attributes = Vec::new();
128                function_keyword = token;
129            }
130            TokenType::Symbol(Symbol::At) => {
131                attributes = safe_unwrap!(
132                    lexer,
133                    errors,
134                    "Expected <attribute>",
135                    Vec::parse(token, lexer, errors)
136                );
137                function_keyword = lexer.next_token();
138            }
139            _ => return None,
140        }
141
142        parse_function!(attributes, function_keyword, lexer, errors)
143    }
144}