use super::*;
pub fn parse_case_body<P: SysMLParser>(p: &mut P) {
if p.at(SyntaxKind::SEMICOLON) {
p.bump();
return;
}
if !p.at(SyntaxKind::L_BRACE) {
error_missing_body_terminator(p, "case definition");
return;
}
p.start_node(SyntaxKind::NAMESPACE_BODY);
p.bump(); p.skip_trivia();
while !p.at(SyntaxKind::R_BRACE) && !p.at(SyntaxKind::ERROR) {
if p.at(SyntaxKind::OBJECTIVE_KW) {
parse_objective_usage(p);
} else if p.at(SyntaxKind::SUBJECT_KW) {
parse_subject_usage(p);
} else if p.at(SyntaxKind::ACTOR_KW) {
parse_actor_usage(p);
} else if p.at(SyntaxKind::STAKEHOLDER_KW) {
parse_stakeholder_usage(p);
} else if p.at(SyntaxKind::RETURN_KW) {
parse_sysml_parameter(p);
} else if p.at(SyntaxKind::IDENT) {
let lookahead = skip_trivia_lookahead(p, 1);
let next = p.peek_kind(lookahead);
if matches!(
next,
SyntaxKind::DOT
| SyntaxKind::COLON_COLON
| SyntaxKind::L_BRACKET
| SyntaxKind::L_PAREN
| SyntaxKind::PLUS
| SyntaxKind::MINUS
| SyntaxKind::STAR
| SyntaxKind::SLASH
| SyntaxKind::PERCENT
| SyntaxKind::GT
| SyntaxKind::LT
| SyntaxKind::EQ_EQ
| SyntaxKind::BANG_EQ
) {
parse_expression(p);
} else {
parse_package_body_element(p);
}
} else {
parse_package_body_element(p);
}
p.skip_trivia();
}
p.expect(SyntaxKind::R_BRACE);
p.finish_node();
}
pub fn parse_metadata_body<P: SysMLParser>(p: &mut P) {
if p.at(SyntaxKind::SEMICOLON) {
p.bump();
return;
}
if !p.at(SyntaxKind::L_BRACE) {
error_missing_body_terminator(p, "metadata definition");
return;
}
p.start_node(SyntaxKind::NAMESPACE_BODY);
p.bump(); p.skip_trivia();
while !p.at(SyntaxKind::R_BRACE) && !p.at(SyntaxKind::ERROR) {
let is_metadata_usage = if p.at(SyntaxKind::REF_KW) {
let lookahead = skip_trivia_lookahead(p, 1);
let next = p.peek_kind(lookahead);
matches!(
next,
SyntaxKind::COLON_GT_GT
| SyntaxKind::COLON_GT
| SyntaxKind::REDEFINES_KW
| SyntaxKind::IDENT
)
} else if p.at(SyntaxKind::COLON_GT_GT) || p.at(SyntaxKind::REDEFINES_KW) {
true
} else if p.at(SyntaxKind::IDENT) {
true
} else {
false
};
if is_metadata_usage {
parse_metadata_body_usage(p);
} else {
parse_package_body_element(p);
}
p.skip_trivia();
}
p.expect(SyntaxKind::R_BRACE);
p.finish_node();
}
fn parse_metadata_body_usage<P: SysMLParser>(p: &mut P) {
p.start_node(SyntaxKind::USAGE);
if p.at(SyntaxKind::REF_KW) {
p.bump();
p.skip_trivia();
}
if p.at(SyntaxKind::COLON_GT_GT) || p.at(SyntaxKind::COLON_GT) || p.at(SyntaxKind::REDEFINES_KW)
{
p.start_node(SyntaxKind::SPECIALIZATION);
p.bump(); p.skip_trivia();
if p.at_name_token() {
p.parse_qualified_name();
p.skip_trivia();
} else {
p.error("expected identifier in metadata body usage");
}
p.finish_node(); } else {
if p.at(SyntaxKind::IDENT) {
p.start_node(SyntaxKind::NAME);
p.bump();
p.finish_node();
p.skip_trivia();
} else {
p.error("expected identifier in metadata body usage");
}
}
parse_optional_typing(p);
parse_specializations_with_skip(p);
if p.at(SyntaxKind::DEFAULT_KW) {
p.bump(); p.skip_trivia();
if p.can_start_expression() {
parse_expression(p);
p.skip_trivia();
}
}
if p.at(SyntaxKind::META_KW) {
p.start_node(SyntaxKind::TYPING);
p.bump(); p.skip_trivia();
if p.at_name_token() {
p.parse_qualified_name();
p.skip_trivia();
}
p.finish_node();
}
if p.at(SyntaxKind::EQ) || p.at(SyntaxKind::COLON_EQ) {
p.bump();
p.skip_trivia();
parse_expression(p);
p.skip_trivia();
}
if p.at(SyntaxKind::L_BRACE) {
parse_metadata_body(p);
} else {
p.expect(SyntaxKind::SEMICOLON);
}
p.finish_node();
}
pub fn parse_sysml_calc_body<P: SysMLParser>(p: &mut P) {
p.start_node(SyntaxKind::NAMESPACE_BODY);
if p.at(SyntaxKind::SEMICOLON) {
p.bump();
} else if p.at(SyntaxKind::L_BRACE) {
p.bump();
p.skip_trivia();
while !p.at(SyntaxKind::R_BRACE) && !p.at(SyntaxKind::ERROR) {
let start_pos = p.get_pos();
if p.at_any(&[SyntaxKind::IN_KW, SyntaxKind::OUT_KW, SyntaxKind::INOUT_KW]) {
parse_usage(p);
}
else if p.at(SyntaxKind::RETURN_KW) {
let lookahead = skip_trivia_lookahead(p, 1);
let after_return = p.peek_kind(lookahead);
if after_return == SyntaxKind::COLON || after_return == SyntaxKind::TYPED_KW {
parse_usage(p);
} else if after_return == SyntaxKind::IDENT {
let after_that = p.peek_kind(skip_trivia_lookahead(p, lookahead + 1));
if after_that == SyntaxKind::COLON
|| after_that == SyntaxKind::TYPED_KW
|| after_that == SyntaxKind::L_BRACKET
|| after_that == SyntaxKind::COLON_GT
|| after_that == SyntaxKind::COLON_GT_GT
|| after_that == SyntaxKind::SEMICOLON
|| after_that == SyntaxKind::EQ
{
parse_usage(p);
} else {
parse_return_expression(p);
}
} else if is_usage_keyword(after_return) {
parse_usage(p);
} else {
parse_return_expression(p);
}
}
else if p.at(SyntaxKind::PERFORM_KW) {
parse_perform_action(p);
} else if p.at(SyntaxKind::SEND_KW) {
parse_send_action(p);
} else if p.at(SyntaxKind::ACCEPT_KW) {
parse_accept_action(p);
}
else if p.at_any(&[
SyntaxKind::ATTRIBUTE_KW,
SyntaxKind::PART_KW,
SyntaxKind::ITEM_KW,
SyntaxKind::CALC_KW,
SyntaxKind::CONSTRAINT_KW,
SyntaxKind::ACTION_KW,
SyntaxKind::DOC_KW,
SyntaxKind::COMMENT_KW,
SyntaxKind::PRIVATE_KW,
SyntaxKind::PUBLIC_KW,
SyntaxKind::PROTECTED_KW,
]) {
parse_package_body_element(p);
}
else if p.can_start_expression() {
parse_expression(p);
p.skip_trivia();
if p.at(SyntaxKind::SEMICOLON) {
p.bump();
}
} else {
parse_package_body_element(p);
}
p.skip_trivia();
if p.get_pos() == start_pos && !p.at(SyntaxKind::R_BRACE) {
let got = if let Some(text) = p.current_token_text() {
format!("'{}'", text)
} else {
p.current_kind().display_name().to_string()
};
p.error(format!("unexpected {} in calc body", got));
p.bump();
}
}
p.expect(SyntaxKind::R_BRACE);
} else {
error_missing_body_terminator(p, "calc definition");
}
p.finish_node();
}
pub fn parse_body<P: SysMLParser>(p: &mut P) {
p.start_node(SyntaxKind::NAMESPACE_BODY);
if p.at(SyntaxKind::SEMICOLON) {
p.bump();
} else if p.at(SyntaxKind::L_BRACE) {
p.bump();
p.skip_trivia();
while !p.at(SyntaxKind::ERROR) && !p.at(SyntaxKind::R_BRACE) {
let start_pos = p.get_pos();
parse_package_body_element(p);
p.skip_trivia();
if p.get_pos() == start_pos && !p.at(SyntaxKind::ERROR) && !p.at(SyntaxKind::R_BRACE) {
let got = if let Some(text) = p.current_token_text() {
format!("'{}' ({})", text, p.current_kind().display_name())
} else {
p.current_kind().display_name().to_string()
};
p.error(format!(
"unexpected {} in definition body—expected a member declaration",
got
));
p.bump();
}
}
p.expect(SyntaxKind::R_BRACE);
} else {
let found = if let Some(text) = p.current_token_text() {
format!("'{}' ({})", text, p.current_kind().display_name())
} else {
"end of file".to_string()
};
p.error(format!(
"expected ';' to end declaration or '{{' to start body, found {}",
found
))
}
p.finish_node();
}