use crate::SyntaxKind::{
self, AT, AT_L_BRACKET, BANG, BLOCK, COLON_COLON, DIVERT, EOF, HASH, KW_CONST, KW_IMPORT,
KW_RETURN, KW_USE, KW_VAR, L_BRACE, L_PAREN, NEWLINE, R_BRACE, THREAD, TILDE,
};
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);
let outer_chain = p.set_cue_chain(false);
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.set_cue_chain(outer_chain);
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::element::at_scene_heading(p) {
p.set_cue_chain(false);
super::element::scene_stitch(p, doc);
return;
}
if try_declaration(p, doc) {
p.set_cue_chain(false);
return;
}
body_line(p);
}
fn try_declaration(p: &mut Parser<'_, '_>, doc: Option<rowan::Checkpoint>) -> bool {
if super::decl::at_flow_decl(p) || super::decl::at_pub_flow_decl(p) {
super::decl::flow_decl(p, doc);
return true;
}
if super::decl::at_fn_decl(p) || super::decl::at_pub_fn_decl(p) {
super::decl::fn_decl(p, doc);
return true;
}
if (p.at(KW_VAR) && super::decl::at_binding_decl(p)) || super::decl::at_pub_var_decl(p) {
super::decl::var_decl(p, doc);
return true;
}
if (p.at(KW_CONST) && super::decl::at_binding_decl(p)) || super::decl::at_pub_const_decl(p) {
super::decl::const_decl(p, doc);
return true;
}
if super::decl::at_flags_decl(p) || super::decl::at_pub_flags_decl(p) {
super::decl::flags_decl(p, doc);
return true;
}
if super::decl::at_struct_decl(p) || super::decl::at_pub_struct_decl(p) {
super::decl::struct_decl(p, doc);
return true;
}
if super::decl::at_extern_decl(p) || super::decl::at_pub_extern_decl(p) {
super::decl::extern_decl(p, doc);
return true;
}
if p.at(KW_IMPORT) && super::decl::at_import_decl(p) {
super::decl::import_decl(p, doc);
return true;
}
if p.at(KW_USE) && super::decl::at_use_decl(p) {
super::decl::use_decl(p, doc);
return true;
}
if p.at(KW_USE) && p.nth(1) == COLON_COLON {
p.error("a `use` path cannot start with `::`".into());
}
if super::decl::at_module_decl(p) {
super::decl::module_decl(p, doc);
return true;
}
false
}
pub(crate) fn body_line(p: &mut Parser<'_, '_>) {
match p.current() {
NEWLINE => {
p.bump();
p.set_cue_chain(false);
}
HASH => {
super::content::tag_line(p);
p.set_cue_chain(false);
}
AT_L_BRACKET => {
super::annotation::annotation_line(p);
p.set_cue_chain(false);
}
AT if super::element::at_cue(p) => {
super::element::cue_line(p);
p.set_cue_chain(true);
}
BANG if super::element::at_bang_dispatch(p) => {
super::element::bang_dispatch(p);
p.set_cue_chain(false);
}
L_PAREN if super::element::at_parenthetical(p) => super::element::parenthetical(p),
DIVERT => {
super::divert::divert_or_tunnel(p);
p.set_cue_chain(false);
}
KW_RETURN => {
super::divert::return_stmt(p);
p.set_cue_chain(false);
}
TILDE => {
super::stmt::logic_line(p);
p.set_cue_chain(false);
}
THREAD => {
super::choice::splice_outside_choice_point(p);
p.set_cue_chain(false);
}
L_BRACE if super::family::at_choice_point(p) => {
super::choice::choice_point(p);
p.set_cue_chain(false);
}
L_BRACE if super::family::at_conditional(p) => {
super::family::conditional_block(p);
p.set_cue_chain(false);
}
L_BRACE if super::family::at_alternation(p) => {
super::family::alternation_block(p);
p.set_cue_chain(false);
}
EOF => {}
_ => super::content::content_line(p),
}
}