use crate::parse_recovery::RecoveryResult;
use crate::prelude::*;
use crate::ParserProgress;
use biome_rowan::SyntaxKind;
pub trait ParseNodeList {
type Kind: SyntaxKind;
type Parser<'source>: Parser<Kind = Self::Kind>;
const LIST_KIND: Self::Kind;
fn parse_element(&mut self, p: &mut Self::Parser<'_>) -> ParsedSyntax;
fn start_list(&mut self, p: &mut Self::Parser<'_>) -> Marker {
p.start()
}
fn is_at_list_end(&self, p: &mut Self::Parser<'_>) -> bool;
fn recover(&mut self, p: &mut Self::Parser<'_>, parsed_element: ParsedSyntax)
-> RecoveryResult;
fn finish_list(&mut self, p: &mut Self::Parser<'_>, m: Marker) -> CompletedMarker {
m.complete(p, Self::LIST_KIND)
}
fn parse_list(&mut self, p: &mut Self::Parser<'_>) -> CompletedMarker {
let elements = self.start_list(p);
let mut progress = ParserProgress::default();
while !p.at(<<Self::Parser<'_> as Parser>::Kind as SyntaxKind>::EOF)
&& !self.is_at_list_end(p)
{
progress.assert_progressing(p);
let parsed_element = self.parse_element(p);
if self.recover(p, parsed_element).is_err() {
break;
}
}
self.finish_list(p, elements)
}
}
pub trait ParseSeparatedList {
type Kind: SyntaxKind;
type Parser<'source>: Parser<Kind = Self::Kind>;
const LIST_KIND: Self::Kind;
fn parse_element(&mut self, p: &mut Self::Parser<'_>) -> ParsedSyntax;
fn start_list(&mut self, p: &mut Self::Parser<'_>) -> Marker {
p.start()
}
fn is_at_list_end(&self, p: &mut Self::Parser<'_>) -> bool;
fn recover(&mut self, p: &mut Self::Parser<'_>, parsed_element: ParsedSyntax)
-> RecoveryResult;
fn finish_list(&mut self, p: &mut Self::Parser<'_>, m: Marker) -> CompletedMarker {
m.complete(p, Self::LIST_KIND)
}
fn allow_empty(&self) -> bool {
true
}
fn separating_element_kind(&mut self) -> Self::Kind;
fn allow_trailing_separating_element(&self) -> bool {
false
}
fn expect_separator(&mut self, p: &mut Self::Parser<'_>) -> bool {
p.expect(self.separating_element_kind())
}
fn parse_list(&mut self, p: &mut Self::Parser<'_>) -> CompletedMarker {
let elements = self.start_list(p);
let mut progress = ParserProgress::default();
let mut first = true;
while (!self.allow_empty() && first)
|| (!p.at(<Self::Parser<'_> as Parser>::Kind::EOF) && !self.is_at_list_end(p))
{
if first {
first = false;
} else {
self.expect_separator(p);
if self.allow_trailing_separating_element() && self.is_at_list_end(p) {
break;
}
}
progress.assert_progressing(p);
let parsed_element = self.parse_element(p);
if parsed_element.is_absent() && p.at(self.separating_element_kind()) {
continue;
}
if self.recover(p, parsed_element).is_err() {
break;
}
}
self.finish_list(p, elements)
}
}