use crate::SyntaxKind::{
self, AT_L_BRACKET, BLOCK, DIVERT, EOF, HASH, KW_CONST, KW_IMPORT, KW_RETURN, KW_USE, KW_VAR,
L_BRACE, NEWLINE, R_BRACE,
};
use super::Parser;
pub(crate) fn block(p: &mut Parser<'_, '_>) {
braced_item_list(p, BLOCK);
}
pub(crate) fn braced_item_list(p: &mut Parser<'_, '_>, kind: SyntaxKind) {
p.start_node(kind);
p.expect(L_BRACE);
if kind == BLOCK {
loop {
p.skip_ws();
if p.current() == NEWLINE {
p.bump();
} else {
break;
}
}
super::doc_comment::maybe_consume_inner_run(p);
}
if p.enter_depth() {
loop {
p.skip_ws();
if p.at(R_BRACE) || p.at_eof() {
break;
}
let before = p.pos();
item(p);
if p.pos() == before {
p.error_recover("unexpected token inside block");
}
}
p.exit_depth();
} else {
while !p.at(R_BRACE) && !p.at_eof() {
p.skip_ws();
if p.at(R_BRACE) || p.at_eof() {
break;
}
let before = p.pos();
p.error_recover("skipped inside over-deep block");
if p.pos() == before {
break;
}
}
}
p.expect(R_BRACE);
p.finish_node();
}
pub(crate) fn item(p: &mut Parser<'_, '_>) {
let doc = super::doc_comment::maybe_consume_leading_run(p);
if super::decl::at_flow_decl(p) {
super::decl::flow_decl(p, doc);
return;
}
if super::decl::at_fn_decl(p) {
super::decl::fn_decl(p, doc);
return;
}
if p.at(KW_VAR) && super::decl::at_binding_decl(p) {
super::decl::var_decl(p, doc);
return;
}
if p.at(KW_CONST) && super::decl::at_binding_decl(p) {
super::decl::const_decl(p, doc);
return;
}
if super::decl::at_flags_decl(p) {
super::decl::flags_decl(p, doc);
return;
}
if super::decl::at_struct_decl(p) {
super::decl::struct_decl(p, doc);
return;
}
if super::decl::at_extern_decl(p) {
super::decl::extern_decl(p, doc);
return;
}
if p.at(KW_IMPORT) && super::decl::at_import_decl(p) {
super::decl::import_decl(p, doc);
return;
}
if p.at(KW_USE) && super::decl::at_use_decl(p) {
super::decl::use_decl(p, doc);
return;
}
if super::decl::at_module_decl(p) {
super::decl::module_decl(p, doc);
return;
}
body_line(p);
}
pub(crate) fn body_line(p: &mut Parser<'_, '_>) {
match p.current() {
NEWLINE => {
p.bump();
}
HASH => super::content::tag_line(p),
AT_L_BRACKET => super::annotation::annotation_line(p),
DIVERT => super::divert::divert_or_tunnel(p),
KW_RETURN => super::divert::return_stmt(p),
L_BRACE if super::family::at_choice_point(p) => super::choice::choice_point(p),
L_BRACE if super::family::at_conditional(p) => super::family::conditional_block(p),
L_BRACE if super::family::at_alternation(p) => super::family::alternation_block(p),
EOF => {}
_ => super::content::content_line(p),
}
}