use super::*;
pub fn parse_constraint_body<P: SysMLParser>(p: &mut P) {
p.start_node(SyntaxKind::CONSTRAINT_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) {
if p.at(SyntaxKind::COMMENT_KW)
|| p.at(SyntaxKind::DOC_KW)
|| p.at(SyntaxKind::LOCALE_KW)
{
parse_annotation(p);
p.skip_trivia();
}
else if p.at(SyntaxKind::REP_KW) {
parse_textual_representation(p);
p.skip_trivia();
}
else if p.at(SyntaxKind::IN_KW)
|| p.at(SyntaxKind::OUT_KW)
|| p.at(SyntaxKind::INOUT_KW)
|| p.at(SyntaxKind::RETURN_KW)
{
parse_usage(p);
p.skip_trivia();
}
else if p.at(SyntaxKind::IF_KW) {
parse_expression(p);
p.skip_trivia();
break;
}
else if p.at_any(SYSML_USAGE_KEYWORDS) {
parse_usage(p);
p.skip_trivia();
}
else if p.at(SyntaxKind::COLON_GT_GT)
|| p.at(SyntaxKind::COLON_GT)
|| p.at(SyntaxKind::REDEFINES_KW)
|| p.at(SyntaxKind::SUBSETS_KW)
{
parse_redefines_feature_member(p);
p.skip_trivia();
}
else if p.at_name_token() {
let lookahead = skip_trivia_lookahead(p, 1);
if p.peek_kind(lookahead) == SyntaxKind::COLON {
bump_keyword(p); bump_keyword(p); parse_qualified_name_and_skip(p); consume_if(p, SyntaxKind::SEMICOLON);
} else {
parse_expression(p);
p.skip_trivia();
break;
}
}
else if p.can_start_expression() {
parse_expression(p);
p.skip_trivia();
break; }
else {
break;
}
}
p.expect(SyntaxKind::R_BRACE);
} else {
error_missing_body_terminator(p, "constraint");
}
p.finish_node();
}
pub(super) fn parse_textual_representation<P: SysMLParser>(p: &mut P) {
p.start_node(SyntaxKind::TEXTUAL_REPRESENTATION);
if p.at(SyntaxKind::REP_KW) {
bump_keyword(p);
if p.at_name_token() {
bump_keyword(p);
}
}
if p.at(SyntaxKind::LANGUAGE_KW) {
bump_keyword(p);
if p.at(SyntaxKind::STRING) {
bump_keyword(p);
}
}
p.finish_node();
}
pub fn parse_dependency<P: SysMLParser>(p: &mut P) {
p.start_node(SyntaxKind::DEPENDENCY);
expect_and_skip(p, SyntaxKind::DEPENDENCY_KW);
if p.at(SyntaxKind::FROM_KW) {
bump_keyword(p);
} else if p.at_name_token() && !p.at(SyntaxKind::TO_KW) {
let next = p.peek_kind(1);
if next == SyntaxKind::FROM_KW {
p.parse_identification();
p.skip_trivia();
expect_and_skip(p, SyntaxKind::FROM_KW);
}
}
if p.at_name_token() && !p.at(SyntaxKind::TO_KW) {
parse_qualified_name_and_skip(p);
while p.at(SyntaxKind::COMMA) {
bump_keyword(p);
if p.at_name_token() && !p.at(SyntaxKind::TO_KW) {
parse_qualified_name_and_skip(p);
}
}
}
if p.at(SyntaxKind::TO_KW) {
bump_keyword(p);
parse_qualified_name_and_skip(p);
while p.at(SyntaxKind::COMMA) {
bump_keyword(p);
if p.at_name_token() {
parse_qualified_name_and_skip(p);
}
}
}
p.parse_body();
p.finish_node();
}
pub fn parse_filter<P: SysMLParser>(p: &mut P) {
p.start_node(SyntaxKind::ELEMENT_FILTER_MEMBER);
p.expect(SyntaxKind::FILTER_KW);
p.skip_trivia();
parse_expression(p);
p.skip_trivia();
p.expect(SyntaxKind::SEMICOLON);
p.finish_node();
}
pub fn parse_metadata_usage<P: SysMLParser>(p: &mut P) {
p.start_node(SyntaxKind::METADATA_USAGE);
p.expect(SyntaxKind::AT);
p.skip_trivia();
p.parse_qualified_name();
p.skip_trivia();
if p.at(SyntaxKind::ABOUT_KW) {
p.bump();
p.skip_trivia();
p.parse_qualified_name_list();
p.skip_trivia();
}
if is_definition_or_usage_start(p) {
p.finish_node();
p.parse_definition_or_usage();
return;
}
parse_body_or_semicolon(p);
p.finish_node();
}
fn is_definition_or_usage_start<P: SysMLParser>(p: &P) -> bool {
p.at_any(&[
SyntaxKind::PART_KW,
SyntaxKind::ATTRIBUTE_KW,
SyntaxKind::PORT_KW,
SyntaxKind::ITEM_KW,
SyntaxKind::STATE_KW,
SyntaxKind::OCCURRENCE_KW,
SyntaxKind::CONSTRAINT_KW,
SyntaxKind::REQUIREMENT_KW,
SyntaxKind::CASE_KW,
SyntaxKind::CALC_KW,
SyntaxKind::CONNECTION_KW,
SyntaxKind::INTERFACE_KW,
SyntaxKind::ALLOCATION_KW,
SyntaxKind::VIEW_KW,
SyntaxKind::ACTION_KW,
SyntaxKind::VIEWPOINT_KW,
SyntaxKind::RENDERING_KW,
SyntaxKind::METADATA_KW,
SyntaxKind::ENUM_KW,
SyntaxKind::ANALYSIS_KW,
SyntaxKind::VERIFICATION_KW,
SyntaxKind::USE_KW,
SyntaxKind::CONCERN_KW,
SyntaxKind::FLOW_KW,
SyntaxKind::PARALLEL_KW,
SyntaxKind::EVENT_KW,
SyntaxKind::MESSAGE_KW,
SyntaxKind::SNAPSHOT_KW,
SyntaxKind::TIMESLICE_KW,
SyntaxKind::ABSTRACT_KW,
SyntaxKind::VARIATION_KW,
SyntaxKind::INDIVIDUAL_KW,
SyntaxKind::DERIVED_KW,
SyntaxKind::READONLY_KW,
SyntaxKind::VAR_KW,
SyntaxKind::REF_KW,
SyntaxKind::COMPOSITE_KW,
SyntaxKind::PORTION_KW,
SyntaxKind::IN_KW,
SyntaxKind::OUT_KW,
SyntaxKind::INOUT_KW,
SyntaxKind::END_KW,
])
}
pub fn parse_variant_usage<P: SysMLParser>(p: &mut P) {
p.start_node(SyntaxKind::USAGE);
p.expect(SyntaxKind::VARIANT_KW);
p.skip_trivia();
if p.at(SyntaxKind::USE_KW) {
p.bump(); p.skip_trivia();
if p.at(SyntaxKind::CASE_KW) {
p.bump(); p.skip_trivia();
}
} else if p.at_any(SYSML_USAGE_KEYWORDS) {
p.bump();
p.skip_trivia();
}
if p.at_name_token() || p.at(SyntaxKind::LT) {
p.parse_identification();
p.skip_trivia();
}
if p.at(SyntaxKind::L_BRACKET) {
p.parse_multiplicity();
p.skip_trivia();
}
parse_optional_typing(p);
parse_specializations_with_skip(p);
if p.at(SyntaxKind::L_BRACE) {
p.parse_body();
} else {
p.expect(SyntaxKind::SEMICOLON);
}
p.finish_node();
}
pub fn parse_redefines_feature_member<P: SysMLParser>(p: &mut P) {
p.start_node(SyntaxKind::USAGE);
while p.at_any(USAGE_PREFIX_KEYWORDS) {
p.bump();
p.skip_trivia();
}
p.start_node(SyntaxKind::SPECIALIZATION);
p.bump(); p.skip_trivia();
if p.at_name_token() {
p.parse_qualified_name();
p.skip_trivia();
}
p.finish_node();
while p.at(SyntaxKind::COMMA) {
p.bump();
p.skip_trivia();
p.start_node(SyntaxKind::SPECIALIZATION);
p.parse_qualified_name();
p.skip_trivia();
p.finish_node();
}
parse_optional_typing(p);
parse_optional_multiplicity(p);
parse_specializations_with_skip(p);
parse_optional_default_value(p);
if p.at(SyntaxKind::L_BRACE) {
p.parse_body();
} else {
p.expect(SyntaxKind::SEMICOLON);
}
p.finish_node();
}
pub(super) fn parse_anonymous_usage<P: SysMLParser>(p: &mut P) {
p.start_node(SyntaxKind::USAGE);
p.parse_typing();
p.skip_trivia();
parse_specializations_with_skip(p);
parse_optional_default_value(p);
if p.at(SyntaxKind::L_BRACE) {
p.parse_body();
} else {
p.expect(SyntaxKind::SEMICOLON);
}
p.finish_node();
}
pub fn parse_shorthand_feature_member<P: SysMLParser>(p: &mut P) {
p.start_node(SyntaxKind::USAGE);
if matches!(
p.current_kind(),
SyntaxKind::ACTOR_KW
| SyntaxKind::SUBJECT_KW
| SyntaxKind::STAKEHOLDER_KW
| SyntaxKind::OBJECTIVE_KW
| SyntaxKind::FILTER_KW
) {
p.bump(); p.skip_trivia();
}
p.parse_identification();
p.skip_trivia();
if p.at(SyntaxKind::L_BRACKET) {
p.parse_multiplicity();
p.skip_trivia();
}
parse_optional_typing(p);
parse_specializations_with_skip(p);
parse_optional_default_value(p);
if p.at(SyntaxKind::L_BRACE) {
p.parse_body();
} else {
p.expect(SyntaxKind::SEMICOLON);
}
p.finish_node();
}
pub fn parse_definition_or_usage<P: SysMLParser>(p: &mut P) {
if has_def_keyword(p) {
parse_definition(p);
} else {
parse_usage(p);
}
}
fn has_def_keyword<P: SysMLParser>(p: &P) -> bool {
for i in 0..20 {
let kind = p.peek_kind(i);
if kind == SyntaxKind::DEF_KW {
return true;
}
if kind == SyntaxKind::SEMICOLON
|| kind == SyntaxKind::L_BRACE
|| kind == SyntaxKind::COLON
|| kind == SyntaxKind::COLON_GT
|| kind == SyntaxKind::COLON_GT_GT
|| kind == SyntaxKind::EQ
|| kind == SyntaxKind::ERROR
{
return false;
}
}
false
}
fn parse_definition<P: SysMLParser>(p: &mut P) {
p.start_node(SyntaxKind::DEFINITION);
while p.at(SyntaxKind::ABSTRACT_KW)
|| p.at(SyntaxKind::VARIATION_KW)
|| p.at(SyntaxKind::INDIVIDUAL_KW)
{
bump_keyword(p);
}
let is_constraint = p.at(SyntaxKind::CONSTRAINT_KW);
let is_calc = p.at(SyntaxKind::CALC_KW);
let is_action = p.at(SyntaxKind::ACTION_KW);
let is_state = p.at(SyntaxKind::STATE_KW);
let is_analysis = p.at(SyntaxKind::ANALYSIS_KW);
let is_verification = p.at(SyntaxKind::VERIFICATION_KW);
let is_metadata = p.at(SyntaxKind::METADATA_KW);
let is_usecase = p.at(SyntaxKind::USE_KW);
parse_definition_keyword(p);
p.skip_trivia();
consume_if(p, SyntaxKind::CASE_KW);
expect_and_skip(p, SyntaxKind::DEF_KW);
if p.at(SyntaxKind::IDENT) || p.at(SyntaxKind::LT) {
p.parse_identification();
}
p.skip_trivia();
parse_specializations_with_skip(p);
if is_constraint {
parse_constraint_body(p);
} else if is_calc {
parse_sysml_calc_body(p);
} else if is_action {
parse_action_body(p);
} else if is_state {
parse_state_body(p);
} else if is_analysis || is_verification || is_usecase {
parse_case_body(p);
} else if is_metadata {
parse_metadata_body(p);
} else {
p.parse_body();
}
p.finish_node();
}