luaur_ast/methods/
parser_run_parse.rs1use crate::records::allocator::Allocator;
2use crate::records::ast_name_table::AstNameTable;
3use crate::records::lexeme::Type;
4use crate::records::parse_node_result::ParseNodeResult;
5use crate::records::parse_options::ParseOptions;
6use crate::records::parser::Parser;
7use luaur_common::macros::luau_timetrace_scope::LUAU_TIMETRACE_SCOPE;
8
9impl Parser {
10 pub fn run_parse<Node, F>(
11 buffer: &str,
12 buffer_size: usize,
13 names: &mut AstNameTable,
14 allocator: &mut Allocator,
15 options: ParseOptions,
16 f: F,
17 ) -> ParseNodeResult<Node>
18 where
19 F: FnOnce(&mut Parser) -> *mut Node,
20 {
21 LUAU_TIMETRACE_SCOPE!("Parser::parse", "Parser");
22
23 crate::functions::install_parse_error_panic_hook::install_parse_error_panic_hook();
27
28 let mut p = Parser::new(buffer, names, allocator as *mut Allocator, options);
29
30 let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
35 let expr = f(&mut p);
36 let current_lexeme = p.lexer.current();
37
38 let mut lines = current_lexeme.location.end.line;
39 if buffer_size > 0 && buffer.as_bytes()[buffer_size - 1] != b'\n' {
40 lines += 1;
41 }
42
43 let eof = p.lexer.next();
44 let mut root = expr;
45
46 if eof.r#type != Type::Eof {
47 root = core::ptr::null_mut();
48 p.parse_errors
49 .push(crate::records::parse_error::ParseError::new(
50 eof.location,
51 "Expected end of file".to_string(),
52 ));
53 }
54
55 ParseNodeResult {
56 root,
57 lines: lines as usize,
58 hotcomments: std::mem::take(&mut p.hotcomments),
59 errors: std::mem::take(&mut p.parse_errors),
60 comment_locations: std::mem::take(&mut p.comment_locations),
61 cst_node_map: core::mem::replace(
62 &mut p.cst_node_map,
63 luaur_common::records::dense_hash_map::DenseHashMap::new(core::ptr::null_mut()),
64 ),
65 }
66 }));
67
68 match result {
69 Ok(res) => res,
70 Err(payload) => {
71 if let Some(err) = payload.downcast_ref::<crate::records::parse_error::ParseError>()
73 {
74 p.parse_errors.push(err.clone());
75
76 ParseNodeResult {
77 root: core::ptr::null_mut(),
78 lines: 0,
79 hotcomments: Vec::new(),
80 errors: std::mem::take(&mut p.parse_errors),
81 comment_locations: Vec::new(),
82 cst_node_map: core::mem::replace(
83 &mut p.cst_node_map,
84 luaur_common::records::dense_hash_map::DenseHashMap::new(
85 core::ptr::null_mut(),
86 ),
87 ),
88 }
89 } else {
90 std::panic::resume_unwind(payload);
92 }
93 }
94 }
95 }
96}