Skip to main content

luaur_ast/methods/
parser_parse_method_call.rs

1use crate::records::ast_expr::AstExpr;
2use crate::records::ast_expr_call::AstExprCall;
3use crate::records::ast_expr_index_name::AstExprIndexName;
4use crate::records::ast_type_or_pack::AstTypeOrPack;
5use crate::records::cst_expr_call::CstExprCall;
6use crate::records::cst_type_instantiation::CstTypeInstantiation;
7use crate::records::lexeme::Type;
8use crate::records::location::Location;
9use crate::records::name::Name;
10use crate::records::parser::Parser;
11use crate::records::position::Position;
12
13impl Parser {
14    pub fn parse_method_call(&mut self, start: Position, mut expr: *mut AstExpr) -> *mut AstExpr {
15        let op_position = self.lexer.current().location.begin;
16        self.next_lexeme();
17
18        let index: Name = self.parse_index_name("method name", &op_position);
19
20        let func = unsafe {
21            (*self.allocator).alloc(AstExprIndexName::new(
22                Location::new(start, index.location.end),
23                expr,
24                index.name,
25                index.location,
26                op_position,
27                ':' as i8,
28            ))
29        };
30
31        let mut type_arguments: crate::records::ast_array::AstArray<AstTypeOrPack> =
32            crate::records::ast_array::AstArray {
33                data: core::ptr::null_mut(),
34                size: 0,
35            };
36
37        let mut cst_type_arguments: *mut CstTypeInstantiation = if self.options.store_cst_data {
38            unsafe { (*self.allocator).alloc(CstTypeInstantiation::default()) }
39        } else {
40            core::ptr::null_mut()
41        };
42
43        if self.lexer.current().r#type == Type('<' as i32)
44            && self.lexer.lookahead().r#type == Type('<' as i32)
45        {
46            type_arguments = self.parse_type_instantiation_expr(cst_type_arguments, None);
47        }
48
49        expr = self.parse_function_args(func as *mut AstExpr, true);
50
51        if self.options.store_cst_data {
52            if let Some(cst_node_ptr) = self
53                .cst_node_map
54                .find(&(expr as *mut crate::records::ast_node::AstNode))
55            {
56                let cst_node = unsafe { crate::rtti::cst_node_as::<CstExprCall>(*cst_node_ptr) };
57                if !cst_node.is_null() {
58                    unsafe {
59                        (*cst_node).explicit_types = cst_type_arguments;
60                    }
61                } else {
62                    luaur_common::LUAU_ASSERT!(false);
63                }
64            }
65        }
66
67        if !expr.is_null() && type_arguments.size > 0 {
68            let call = unsafe {
69                crate::rtti::ast_node_as::<AstExprCall>(
70                    expr as *mut crate::records::ast_node::AstNode,
71                )
72            };
73            if !call.is_null() {
74                unsafe {
75                    (*call).type_arguments = type_arguments;
76                }
77            }
78        }
79
80        expr
81    }
82}