use super::*;
impl<'input, D: Diagnostics, C: ConcreteSyntaxTreeBuilder> ParserState<'input, D, C> {
pub(crate) fn parse_try_catch(&mut self) {
self.start_node(SyntaxKind::TryCatch);
self.parse_try_only();
self.skip_trivia();
while self
.peek()
.is_some_and(|i| i.kind().is(&TokenKind::ControlFlow(ControlFlowKind::Catch)))
{
self.parse_catch_only()
}
self.finish_node();
}
fn parse_try_only(&mut self) {
let checkpoint = self.checkpoint();
self.parse_token(SyntaxKind::Keyword);
self.skip_trivia();
self.parse_brace_with_expression();
self.start_node_at(checkpoint, SyntaxKind::Try);
self.finish_node();
}
pub(crate) fn parse_catch_with_missing_try(&mut self) {
self.start_node(SyntaxKind::TryCatch);
self.emit_missing_try();
self.parse_catch_only();
self.finish_node();
}
fn emit_missing_try(&mut self) {
let diagnostic_details = self.diagnostic_details();
let error = ParseError::missing_try_block();
self.emit_diagnostic(error, diagnostic_details);
}
fn parse_catch_only(&mut self) {
self.start_node(SyntaxKind::Catch);
self.parse_token(SyntaxKind::Keyword);
self.skip_trivia();
if self
.peek_sequence(|peekable| Self::peek_sequence_for_single_function_parameter(peekable))
{
self.parse_single_function_parameter();
self.skip_trivia();
}
self.parse_brace_with_expression();
self.skip_trivia();
self.finish_node();
}
}
mod test {
#[test]
fn test_try_catch() {
crate::test::create_parsing_test("try_catch/try_catch*.skull", |state| {
state.parse_try_catch();
});
}
#[test]
fn test_missing_catch() {
crate::test::create_parsing_test("try_catch/missing_try*.skull", |state| {
state.parse_catch_with_missing_try();
});
}
}