Refactored JSON sequence diagram generator
This commit is contained in:
@@ -111,6 +111,8 @@ std::string to_string(message_t r)
|
|||||||
return "end switch";
|
return "end switch";
|
||||||
case message_t::kConditional:
|
case message_t::kConditional:
|
||||||
return "conditional";
|
return "conditional";
|
||||||
|
case message_t::kConditionalElse:
|
||||||
|
return "conditional else";
|
||||||
case message_t::kConditionalEnd:
|
case message_t::kConditionalEnd:
|
||||||
return "end conditional";
|
return "end conditional";
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ enum class message_t {
|
|||||||
kCase,
|
kCase,
|
||||||
kSwitchEnd,
|
kSwitchEnd,
|
||||||
kConditional,
|
kConditional,
|
||||||
|
kConditionalElse,
|
||||||
kConditionalEnd,
|
kConditionalEnd,
|
||||||
kNone
|
kNone
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -97,9 +97,6 @@ void generator::generate_call(const message &m, nlohmann::json &parent) const
|
|||||||
.message_name(render_mode);
|
.message_name(render_mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// const std::string from_alias = generate_alias(from.value());
|
|
||||||
// const std::string to_alias = generate_alias(to.value());
|
|
||||||
|
|
||||||
nlohmann::json msg;
|
nlohmann::json msg;
|
||||||
|
|
||||||
@@ -149,11 +146,77 @@ void generator::generate_activity(
|
|||||||
{
|
{
|
||||||
// Generate calls from this activity to other activities
|
// Generate calls from this activity to other activities
|
||||||
for (const auto &m : a.messages()) {
|
for (const auto &m : a.messages()) {
|
||||||
if (m.type() == message_t::kCall) {
|
switch (m.type()) {
|
||||||
const auto &to =
|
case message_t::kCall:
|
||||||
m_model.get_participant<model::participant>(m.to());
|
process_call_message(m, visited);
|
||||||
|
break;
|
||||||
|
case message_t::kIf:
|
||||||
|
process_if_message(m);
|
||||||
|
break;
|
||||||
|
case message_t::kElseIf:
|
||||||
|
case message_t::kElse:
|
||||||
|
process_else_if_message();
|
||||||
|
break;
|
||||||
|
case message_t::kIfEnd:
|
||||||
|
process_end_if_message();
|
||||||
|
break;
|
||||||
|
case message_t::kWhile:
|
||||||
|
process_while_message(m);
|
||||||
|
break;
|
||||||
|
case message_t::kWhileEnd:
|
||||||
|
process_end_while_message();
|
||||||
|
break;
|
||||||
|
case message_t::kFor:
|
||||||
|
process_for_message(m);
|
||||||
|
break;
|
||||||
|
case message_t::kForEnd:
|
||||||
|
process_end_for_message();
|
||||||
|
break;
|
||||||
|
case message_t::kDo:
|
||||||
|
process_do_message(m);
|
||||||
|
break;
|
||||||
|
case message_t::kDoEnd:
|
||||||
|
process_end_do_message();
|
||||||
|
break;
|
||||||
|
case message_t::kTry:
|
||||||
|
process_try_message(m);
|
||||||
|
break;
|
||||||
|
case message_t::kCatch:
|
||||||
|
process_catch_message();
|
||||||
|
break;
|
||||||
|
case message_t::kTryEnd:
|
||||||
|
process_end_try_message();
|
||||||
|
break;
|
||||||
|
case message_t::kSwitch:
|
||||||
|
process_switch_message(m);
|
||||||
|
break;
|
||||||
|
case message_t::kCase:
|
||||||
|
process_case_message(m);
|
||||||
|
break;
|
||||||
|
case message_t::kSwitchEnd:
|
||||||
|
process_end_switch_message();
|
||||||
|
break;
|
||||||
|
case message_t::kConditional:
|
||||||
|
process_conditional_message(m);
|
||||||
|
break;
|
||||||
|
case message_t::kConditionalElse:
|
||||||
|
process_conditional_else_message();
|
||||||
|
break;
|
||||||
|
case message_t::kConditionalEnd:
|
||||||
|
process_end_conditional_message();
|
||||||
|
break;
|
||||||
|
case message_t::kNone:
|
||||||
|
case message_t::kReturn:; // noop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void generator::process_call_message(const model::message &m,
|
||||||
|
std::vector<common::model::diagram_element::id_t> &visited) const
|
||||||
|
{
|
||||||
|
const auto &to = m_model.get_participant<model::participant>(m.to());
|
||||||
if (!to || to.value().skip())
|
if (!to || to.value().skip())
|
||||||
continue;
|
return;
|
||||||
|
|
||||||
visited.push_back(m.from());
|
visited.push_back(m.from());
|
||||||
|
|
||||||
@@ -163,8 +226,7 @@ void generator::generate_activity(
|
|||||||
|
|
||||||
if (m_model.sequences().find(m.to()) != m_model.sequences().end()) {
|
if (m_model.sequences().find(m.to()) != m_model.sequences().end()) {
|
||||||
if (std::find(visited.begin(), visited.end(), m.to()) ==
|
if (std::find(visited.begin(), visited.end(), m.to()) ==
|
||||||
visited
|
visited.end()) { // break infinite recursion on recursive calls
|
||||||
.end()) { // break infinite recursion on recursive calls
|
|
||||||
|
|
||||||
LOG_DBG("Creating activity {} --> {} - missing sequence {}",
|
LOG_DBG("Creating activity {} --> {} - missing sequence {}",
|
||||||
m.from(), m.to(), m.to());
|
m.from(), m.to(), m.to());
|
||||||
@@ -174,103 +236,75 @@ void generator::generate_activity(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LOG_DBG("Skipping activity {} --> {} - missing sequence {}",
|
LOG_DBG("Skipping activity {} --> {} - missing sequence {}", m.from(),
|
||||||
m.from(), m.to(), m.to());
|
m.to(), m.to());
|
||||||
}
|
}
|
||||||
else if (m.type() == message_t::kIf) {
|
|
||||||
nlohmann::json if_block;
|
|
||||||
if_block["type"] = "alt";
|
|
||||||
if_block["name"] = "if";
|
|
||||||
if_block["activity_id"] = std::to_string(m.from());
|
|
||||||
|
|
||||||
current_block_statement()["messages"].push_back(
|
void generator::process_while_message(const message &m) const
|
||||||
std::move(if_block));
|
{
|
||||||
|
|
||||||
block_statements_stack_.push_back(
|
|
||||||
std::ref(current_block_statement()["messages"].back()));
|
|
||||||
|
|
||||||
nlohmann::json branch;
|
|
||||||
branch["type"] = "consequent";
|
|
||||||
current_block_statement()["branches"].push_back(std::move(branch));
|
|
||||||
|
|
||||||
block_statements_stack_.push_back(
|
|
||||||
std::ref(current_block_statement()["branches"].back()));
|
|
||||||
}
|
|
||||||
else if (m.type() == message_t::kElseIf ||
|
|
||||||
m.type() == message_t::kElse) {
|
|
||||||
// remove previous branch from the stack
|
|
||||||
block_statements_stack_.pop_back();
|
|
||||||
|
|
||||||
nlohmann::json branch;
|
|
||||||
branch["type"] = "alternative";
|
|
||||||
current_block_statement()["branches"].push_back(std::move(branch));
|
|
||||||
|
|
||||||
block_statements_stack_.push_back(
|
|
||||||
std::ref(current_block_statement()["branches"].back()));
|
|
||||||
}
|
|
||||||
else if (m.type() == message_t::kIfEnd) {
|
|
||||||
// Remove last if branch from the stack
|
|
||||||
block_statements_stack_.pop_back();
|
|
||||||
|
|
||||||
// Remove the if statement block from the stack
|
|
||||||
block_statements_stack_.pop_back();
|
|
||||||
}
|
|
||||||
else if (m.type() == message_t::kWhile) {
|
|
||||||
nlohmann::json while_block;
|
nlohmann::json while_block;
|
||||||
while_block["type"] = "loop";
|
while_block["type"] = "loop";
|
||||||
while_block["name"] = "while";
|
while_block["name"] = "while";
|
||||||
while_block["activity_id"] = std::to_string(m.from());
|
while_block["activity_id"] = std::to_string(m.from());
|
||||||
|
|
||||||
current_block_statement()["messages"].push_back(
|
current_block_statement()["messages"].push_back(std::move(while_block));
|
||||||
std::move(while_block));
|
|
||||||
|
|
||||||
block_statements_stack_.push_back(
|
block_statements_stack_.push_back(
|
||||||
std::ref(current_block_statement()["messages"].back()));
|
std::ref(current_block_statement()["messages"].back()));
|
||||||
}
|
}
|
||||||
else if (m.type() == message_t::kWhileEnd) {
|
|
||||||
|
void generator::process_end_while_message() const
|
||||||
|
{
|
||||||
// Remove the while statement block from the stack
|
// Remove the while statement block from the stack
|
||||||
block_statements_stack_.pop_back();
|
block_statements_stack_.pop_back();
|
||||||
}
|
}
|
||||||
else if (m.type() == message_t::kFor) {
|
|
||||||
|
void generator::process_for_message(const message &m) const
|
||||||
|
{
|
||||||
nlohmann::json for_block;
|
nlohmann::json for_block;
|
||||||
for_block["type"] = "loop";
|
for_block["type"] = "loop";
|
||||||
for_block["name"] = "for";
|
for_block["name"] = "for";
|
||||||
for_block["activity_id"] = std::to_string(m.from());
|
for_block["activity_id"] = std::to_string(m.from());
|
||||||
|
|
||||||
current_block_statement()["messages"].push_back(
|
current_block_statement()["messages"].push_back(std::move(for_block));
|
||||||
std::move(for_block));
|
|
||||||
|
|
||||||
block_statements_stack_.push_back(
|
block_statements_stack_.push_back(
|
||||||
std::ref(current_block_statement()["messages"].back()));
|
std::ref(current_block_statement()["messages"].back()));
|
||||||
}
|
}
|
||||||
else if (m.type() == message_t::kForEnd) {
|
|
||||||
|
void generator::process_end_for_message() const
|
||||||
|
{
|
||||||
// Remove the while statement block from the stack
|
// Remove the while statement block from the stack
|
||||||
block_statements_stack_.pop_back();
|
block_statements_stack_.pop_back();
|
||||||
}
|
}
|
||||||
else if (m.type() == message_t::kDo) {
|
|
||||||
|
void generator::process_do_message(const message &m) const
|
||||||
|
{
|
||||||
nlohmann::json do_block;
|
nlohmann::json do_block;
|
||||||
do_block["type"] = "loop";
|
do_block["type"] = "loop";
|
||||||
do_block["name"] = "do";
|
do_block["name"] = "do";
|
||||||
do_block["activity_id"] = std::to_string(m.from());
|
do_block["activity_id"] = std::to_string(m.from());
|
||||||
|
|
||||||
current_block_statement()["messages"].push_back(
|
current_block_statement()["messages"].push_back(std::move(do_block));
|
||||||
std::move(do_block));
|
|
||||||
|
|
||||||
block_statements_stack_.push_back(
|
block_statements_stack_.push_back(
|
||||||
std::ref(current_block_statement()["messages"].back()));
|
std::ref(current_block_statement()["messages"].back()));
|
||||||
}
|
}
|
||||||
else if (m.type() == message_t::kDoEnd) {
|
|
||||||
|
void generator::process_end_do_message() const
|
||||||
|
{
|
||||||
// Remove the do statement block from the stack
|
// Remove the do statement block from the stack
|
||||||
block_statements_stack_.pop_back();
|
block_statements_stack_.pop_back();
|
||||||
}
|
}
|
||||||
else if (m.type() == message_t::kTry) {
|
|
||||||
|
void generator::process_try_message(const message &m) const
|
||||||
|
{
|
||||||
nlohmann::json try_block;
|
nlohmann::json try_block;
|
||||||
try_block["type"] = "break";
|
try_block["type"] = "break";
|
||||||
try_block["name"] = "try";
|
try_block["name"] = "try";
|
||||||
try_block["activity_id"] = std::to_string(m.from());
|
try_block["activity_id"] = std::to_string(m.from());
|
||||||
|
|
||||||
current_block_statement()["messages"].push_back(
|
current_block_statement()["messages"].push_back(std::move(try_block));
|
||||||
std::move(try_block));
|
|
||||||
|
|
||||||
block_statements_stack_.push_back(
|
block_statements_stack_.push_back(
|
||||||
std::ref(current_block_statement()["messages"].back()));
|
std::ref(current_block_statement()["messages"].back()));
|
||||||
@@ -282,7 +316,9 @@ void generator::generate_activity(
|
|||||||
block_statements_stack_.push_back(
|
block_statements_stack_.push_back(
|
||||||
std::ref(current_block_statement()["blocks"].back()));
|
std::ref(current_block_statement()["blocks"].back()));
|
||||||
}
|
}
|
||||||
else if (m.type() == message_t::kCatch) {
|
|
||||||
|
void generator::process_catch_message() const
|
||||||
|
{
|
||||||
// remove previous block from the stack
|
// remove previous block from the stack
|
||||||
block_statements_stack_.pop_back();
|
block_statements_stack_.pop_back();
|
||||||
|
|
||||||
@@ -293,26 +329,31 @@ void generator::generate_activity(
|
|||||||
block_statements_stack_.push_back(
|
block_statements_stack_.push_back(
|
||||||
std::ref(current_block_statement()["blocks"].back()));
|
std::ref(current_block_statement()["blocks"].back()));
|
||||||
}
|
}
|
||||||
else if (m.type() == message_t::kTryEnd) {
|
|
||||||
|
void generator::process_end_try_message() const
|
||||||
|
{
|
||||||
// Remove last if block from the stack
|
// Remove last if block from the stack
|
||||||
block_statements_stack_.pop_back();
|
block_statements_stack_.pop_back();
|
||||||
|
|
||||||
// Remove the try statement block from the stack
|
// Remove the try statement block from the stack
|
||||||
block_statements_stack_.pop_back();
|
block_statements_stack_.pop_back();
|
||||||
}
|
}
|
||||||
else if (m.type() == message_t::kSwitch) {
|
|
||||||
|
void generator::process_switch_message(const message &m) const
|
||||||
|
{
|
||||||
nlohmann::json if_block;
|
nlohmann::json if_block;
|
||||||
if_block["type"] = "alt";
|
if_block["type"] = "alt";
|
||||||
if_block["name"] = "switch";
|
if_block["name"] = "switch";
|
||||||
if_block["activity_id"] = std::to_string(m.from());
|
if_block["activity_id"] = std::to_string(m.from());
|
||||||
|
|
||||||
current_block_statement()["messages"].push_back(
|
current_block_statement()["messages"].push_back(std::move(if_block));
|
||||||
std::move(if_block));
|
|
||||||
|
|
||||||
block_statements_stack_.push_back(
|
block_statements_stack_.push_back(
|
||||||
std::ref(current_block_statement()["messages"].back()));
|
std::ref(current_block_statement()["messages"].back()));
|
||||||
}
|
}
|
||||||
else if (m.type() == message_t::kCase) {
|
|
||||||
|
void generator::process_case_message(const message &m) const
|
||||||
|
{
|
||||||
if (current_block_statement()["type"] == "case")
|
if (current_block_statement()["type"] == "case")
|
||||||
block_statements_stack_.pop_back();
|
block_statements_stack_.pop_back();
|
||||||
|
|
||||||
@@ -324,21 +365,23 @@ void generator::generate_activity(
|
|||||||
block_statements_stack_.push_back(
|
block_statements_stack_.push_back(
|
||||||
std::ref(current_block_statement()["cases"].back()));
|
std::ref(current_block_statement()["cases"].back()));
|
||||||
}
|
}
|
||||||
else if (m.type() == message_t::kSwitchEnd) {
|
|
||||||
// Remove last case block from the stack
|
void generator::process_end_switch_message() const
|
||||||
|
{ // Remove last case block from the stack
|
||||||
block_statements_stack_.pop_back();
|
block_statements_stack_.pop_back();
|
||||||
|
|
||||||
// Remove the switch statement block from the stack
|
// Remove the switch statement block from the stack
|
||||||
block_statements_stack_.pop_back();
|
block_statements_stack_.pop_back();
|
||||||
}
|
}
|
||||||
else if (m.type() == message_t::kConditional) {
|
|
||||||
|
void generator::process_conditional_message(const message &m) const
|
||||||
|
{
|
||||||
nlohmann::json if_block;
|
nlohmann::json if_block;
|
||||||
if_block["type"] = "alt";
|
if_block["type"] = "alt";
|
||||||
if_block["name"] = "conditional";
|
if_block["name"] = "conditional";
|
||||||
if_block["activity_id"] = std::to_string(m.from());
|
if_block["activity_id"] = std::to_string(m.from());
|
||||||
|
|
||||||
current_block_statement()["messages"].push_back(
|
current_block_statement()["messages"].push_back(std::move(if_block));
|
||||||
std::move(if_block));
|
|
||||||
|
|
||||||
block_statements_stack_.push_back(
|
block_statements_stack_.push_back(
|
||||||
std::ref(current_block_statement()["messages"].back()));
|
std::ref(current_block_statement()["messages"].back()));
|
||||||
@@ -350,7 +393,9 @@ void generator::generate_activity(
|
|||||||
block_statements_stack_.push_back(
|
block_statements_stack_.push_back(
|
||||||
std::ref(current_block_statement()["branches"].back()));
|
std::ref(current_block_statement()["branches"].back()));
|
||||||
}
|
}
|
||||||
else if (m.type() == message_t::kElse) {
|
|
||||||
|
void generator::process_conditional_else_message() const
|
||||||
|
{
|
||||||
// remove previous branch from the stack
|
// remove previous branch from the stack
|
||||||
block_statements_stack_.pop_back();
|
block_statements_stack_.pop_back();
|
||||||
|
|
||||||
@@ -361,18 +406,56 @@ void generator::generate_activity(
|
|||||||
block_statements_stack_.push_back(
|
block_statements_stack_.push_back(
|
||||||
std::ref(current_block_statement()["branches"].back()));
|
std::ref(current_block_statement()["branches"].back()));
|
||||||
}
|
}
|
||||||
else if (m.type() == message_t::kConditionalEnd) {
|
|
||||||
|
void generator::process_end_conditional_message() const
|
||||||
|
{
|
||||||
// Remove last if branch from the stack
|
// Remove last if branch from the stack
|
||||||
block_statements_stack_.pop_back();
|
block_statements_stack_.pop_back();
|
||||||
|
|
||||||
// Remove the if statement block from the stack
|
// Remove the if statement block from the stack
|
||||||
block_statements_stack_.pop_back();
|
block_statements_stack_.pop_back();
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// Unhandled message_t case
|
void generator::process_end_if_message() const
|
||||||
assert(false);
|
{
|
||||||
|
// Remove last if branch from the stack
|
||||||
|
block_statements_stack_.pop_back();
|
||||||
|
|
||||||
|
// Remove the if statement block from the stack
|
||||||
|
block_statements_stack_.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void generator::process_else_if_message() const
|
||||||
|
{
|
||||||
|
// remove previous branch from the stack
|
||||||
|
block_statements_stack_.pop_back();
|
||||||
|
|
||||||
|
nlohmann::json branch;
|
||||||
|
branch["type"] = "alternative";
|
||||||
|
current_block_statement()["branches"].push_back(std::move(branch));
|
||||||
|
|
||||||
|
block_statements_stack_.push_back(
|
||||||
|
std::ref(current_block_statement()["branches"].back()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void generator::process_if_message(const message &m) const
|
||||||
|
{
|
||||||
|
nlohmann::json if_block;
|
||||||
|
if_block["type"] = "alt";
|
||||||
|
if_block["name"] = "if";
|
||||||
|
if_block["activity_id"] = std::to_string(m.from());
|
||||||
|
|
||||||
|
current_block_statement()["messages"].push_back(std::move(if_block));
|
||||||
|
|
||||||
|
block_statements_stack_.push_back(
|
||||||
|
std::ref(current_block_statement()["messages"].back()));
|
||||||
|
|
||||||
|
nlohmann::json branch;
|
||||||
|
branch["type"] = "consequent";
|
||||||
|
current_block_statement()["branches"].push_back(std::move(branch));
|
||||||
|
|
||||||
|
block_statements_stack_.push_back(
|
||||||
|
std::ref(current_block_statement()["branches"].back()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void generator::generate_participant(
|
void generator::generate_participant(
|
||||||
|
|||||||
@@ -76,6 +76,28 @@ private:
|
|||||||
|
|
||||||
mutable std::vector<std::reference_wrapper<nlohmann::json>>
|
mutable std::vector<std::reference_wrapper<nlohmann::json>>
|
||||||
block_statements_stack_;
|
block_statements_stack_;
|
||||||
|
|
||||||
|
void process_call_message(const model::message &m,
|
||||||
|
std::vector<common::model::diagram_element::id_t> &visited) const;
|
||||||
|
|
||||||
|
void process_if_message(const model::message &m) const;
|
||||||
|
void process_else_if_message() const;
|
||||||
|
void process_end_if_message() const;
|
||||||
|
void process_end_conditional_message() const;
|
||||||
|
void process_conditional_else_message() const;
|
||||||
|
void process_conditional_message(const model::message &m) const;
|
||||||
|
void process_end_switch_message() const;
|
||||||
|
void process_case_message(const model::message &m) const;
|
||||||
|
void process_switch_message(const model::message &m) const;
|
||||||
|
void process_end_try_message() const;
|
||||||
|
void process_catch_message() const;
|
||||||
|
void process_try_message(const model::message &m) const;
|
||||||
|
void process_end_do_message() const;
|
||||||
|
void process_do_message(const model::message &m) const;
|
||||||
|
void process_end_for_message() const;
|
||||||
|
void process_for_message(const model::message &m) const;
|
||||||
|
void process_end_while_message() const;
|
||||||
|
void process_while_message(const model::message &m) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace clanguml::sequence_diagram::generators::json
|
} // namespace clanguml::sequence_diagram::generators::json
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ void generator::generate_activity(const activity &a, std::ostream &ostr,
|
|||||||
print_debug(m, ostr);
|
print_debug(m, ostr);
|
||||||
ostr << "alt\n";
|
ostr << "alt\n";
|
||||||
}
|
}
|
||||||
else if (m.type() == message_t::kElse) {
|
else if (m.type() == message_t::kConditionalElse) {
|
||||||
print_debug(m, ostr);
|
print_debug(m, ostr);
|
||||||
ostr << "else\n";
|
ostr << "else\n";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -821,7 +821,7 @@ bool translation_unit_visitor::TraverseConditionalOperator(
|
|||||||
stmt->getTrueExpr());
|
stmt->getTrueExpr());
|
||||||
|
|
||||||
if (current_caller_id != 0) {
|
if (current_caller_id != 0) {
|
||||||
model::message m{message_t::kElse, current_caller_id};
|
model::message m{message_t::kConditionalElse, current_caller_id};
|
||||||
set_source_location(*stmt, m);
|
set_source_location(*stmt, m);
|
||||||
diagram().add_message(std::move(m));
|
diagram().add_message(std::move(m));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user