oxc/crates/oxc_parser/src/list.rs
overlookmotel 0bdecb5043
refactor(parser): wrapper type for parser (#2339)
Split parser into public interface `Parser` and internal implementation `ParserImpl`.

This involves no changes to public API.

This change is a bit annoying, but justification is that it's required for #2341, which I believe to be very worthwhile.

The `ParserOptions` type also makes it a bit clearer what the defaults for `allow_return_outside_function` and `preserve_parens` are. It came as a surprise to me that `preserve_parens` defaults to `true`, and this refactor makes that a bit more obvious when reading the code.

All the real changes are in [oxc_parser/src/lib.rs](https://github.com/oxc-project/oxc/pull/2339/files#diff-8e59dfd35fc50b6ac9a9ccd991e25c8b5d30826e006d565a2e01f3d15dc5f7cb). The rest of the diff is basically replacing `Parser` with `ParserImpl` everywhere else.
2024-02-07 23:22:08 +08:00

69 lines
1.6 KiB
Rust

use oxc_diagnostics::Result;
use crate::{lexer::Kind, ParserImpl};
pub trait NormalList<'a> {
/// Open element, e.g.. `{` `[` `(`
fn open(&self) -> Kind;
/// Close element, e.g.. `}` `]` `)`
fn close(&self) -> Kind;
fn parse_element(&mut self, p: &mut ParserImpl<'a>) -> Result<()>;
/// Main entry point, parse the list
fn parse(&mut self, p: &mut ParserImpl<'a>) -> Result<()> {
p.expect(self.open())?;
while !p.at(self.close()) && !p.at(Kind::Eof) {
self.parse_element(p)?;
}
p.expect(self.close())?;
Ok(())
}
}
pub trait SeparatedList<'a>: Sized {
fn new(p: &ParserImpl<'a>) -> Self;
fn parse(p: &mut ParserImpl<'a>) -> Result<Self> {
let mut list = Self::new(p);
list.parse_list(p)?;
Ok(list)
}
/// Open element, e.g.. `{` `[` `(`
fn open(&self) -> Kind;
/// Close element, e.g.. `}` `]` `)`
fn close(&self) -> Kind;
/// Separator element, e.g. `,`
fn separator(&self) -> Kind {
Kind::Comma
}
fn parse_element(&mut self, p: &mut ParserImpl<'a>) -> Result<()>;
/// Main entry point, parse the list
fn parse_list(&mut self, p: &mut ParserImpl<'a>) -> Result<()> {
p.expect(self.open())?;
let mut first = true;
while !p.at(self.close()) && !p.at(Kind::Eof) {
if first {
first = false;
} else {
p.expect(self.separator())?;
if p.at(self.close()) {
break;
}
}
self.parse_element(p)?;
}
p.expect(self.close())?;
Ok(())
}
}