Refactored sequence diagram visitor

This commit is contained in:
Bartek Kryza
2022-12-26 21:46:45 +01:00
parent 6a167f0835
commit 1a344f9d8c
4 changed files with 102 additions and 306 deletions

View File

@@ -96,200 +96,43 @@ activity &diagram::get_activity(common::model::diagram_element::id_t id)
return sequences_.at(id);
}
void diagram::add_for_stmt(
const common::model::diagram_element::id_t current_caller_id)
void diagram::add_message(model::message &&message)
{
add_loop_stmt(current_caller_id, common::model::message_t::kFor);
}
void diagram::end_for_stmt(
const common::model::diagram_element::id_t current_caller_id)
{
end_loop_stmt(current_caller_id, common::model::message_t::kForEnd);
}
void diagram::add_while_stmt(
const common::model::diagram_element::id_t current_caller_id)
{
add_loop_stmt(current_caller_id, common::model::message_t::kWhile);
}
void diagram::end_while_stmt(
const common::model::diagram_element::id_t current_caller_id)
{
end_loop_stmt(current_caller_id, common::model::message_t::kWhileEnd);
}
void diagram::add_do_stmt(
const common::model::diagram_element::id_t current_caller_id)
{
add_loop_stmt(current_caller_id, common::model::message_t::kDo);
}
void diagram::end_do_stmt(
const common::model::diagram_element::id_t current_caller_id)
{
end_loop_stmt(current_caller_id, common::model::message_t::kDoEnd);
}
void diagram::add_loop_stmt(
const common::model::diagram_element::id_t current_caller_id,
common::model::message_t type)
{
using clanguml::common::model::message_t;
if (current_caller_id == 0)
return;
if (sequences_.find(current_caller_id) == sequences_.end()) {
activity a{current_caller_id};
sequences_.insert({current_caller_id, std::move(a)});
const auto caller_id = message.from();
if (sequences_.find(caller_id) == sequences_.end()) {
activity a{caller_id};
sequences_.insert({caller_id, std::move(a)});
}
get_activity(current_caller_id).add_message({type, current_caller_id});
get_activity(caller_id).add_message(std::move(message));
}
void diagram::end_loop_stmt(
const common::model::diagram_element::id_t current_caller_id,
common::model::message_t type)
void diagram::add_block_message(model::message &&message)
{
using clanguml::common::model::message_t;
if (current_caller_id == 0)
return;
message m{type, current_caller_id};
message_t loop_type = message_t::kWhile;
if (type == message_t::kForEnd)
loop_type = message_t::kFor;
else if (type == message_t::kDoEnd)
loop_type = message_t::kDo;
if (sequences_.find(current_caller_id) != sequences_.end()) {
auto &current_messages = get_activity(current_caller_id).messages();
fold_or_end_block_statement(std::move(m), loop_type, current_messages);
}
add_message(std::move(message));
}
void diagram::add_if_stmt(
const common::model::diagram_element::id_t current_caller_id,
common::model::message_t type)
void diagram::end_block_message(
model::message &&message, common::model::message_t start_type)
{
using clanguml::common::model::message_t;
const auto caller_id = message.from();
if (sequences_.find(current_caller_id) == sequences_.end()) {
activity a{current_caller_id};
sequences_.insert({current_caller_id, std::move(a)});
}
get_activity(current_caller_id).add_message({type, current_caller_id});
}
void diagram::end_if_stmt(
const common::model::diagram_element::id_t current_caller_id,
common::model::message_t /*type*/)
{
using clanguml::common::model::message_t;
message m{message_t::kIfEnd, current_caller_id};
if (sequences_.find(current_caller_id) != sequences_.end()) {
auto &current_messages = get_activity(current_caller_id).messages();
if (sequences_.find(caller_id) != sequences_.end()) {
auto &current_messages = get_activity(caller_id).messages();
fold_or_end_block_statement(
std::move(m), message_t::kIf, current_messages);
std::move(message), start_type, current_messages);
}
}
void diagram::add_try_stmt(
const common::model::diagram_element::id_t current_caller_id)
void diagram::add_case_stmt_message(
model::message &&m)
{
using clanguml::common::model::message_t;
const auto caller_id = m.from();
if (sequences_.find(current_caller_id) == sequences_.end()) {
activity a{current_caller_id};
sequences_.insert({current_caller_id, std::move(a)});
}
get_activity(current_caller_id)
.add_message({message_t::kTry, current_caller_id});
}
void diagram::end_try_stmt(
const common::model::diagram_element::id_t current_caller_id)
{
using clanguml::common::model::message_t;
message m{message_t::kTryEnd, current_caller_id};
if (sequences_.find(current_caller_id) != sequences_.end()) {
auto &current_messages = get_activity(current_caller_id).messages();
fold_or_end_block_statement(
std::move(m), message_t::kTry, current_messages);
}
}
void diagram::add_catch_stmt(
const int64_t current_caller_id, std::string caught_type)
{
using clanguml::common::model::message_t;
if (sequences_.find(current_caller_id) == sequences_.end()) {
activity a{current_caller_id};
sequences_.insert({current_caller_id, std::move(a)});
}
message m{message_t::kCatch, current_caller_id};
m.set_message_name(std::move(caught_type));
get_activity(current_caller_id).add_message(std::move(m));
}
void diagram::add_switch_stmt(
common::model::diagram_element::id_t current_caller_id)
{
using clanguml::common::model::message_t;
if (sequences_.find(current_caller_id) == sequences_.end()) {
activity a{current_caller_id};
sequences_.insert({current_caller_id, std::move(a)});
}
message m{message_t::kSwitch, current_caller_id};
get_activity(current_caller_id).add_message(std::move(m));
}
void diagram::end_switch_stmt(
common::model::diagram_element::id_t current_caller_id)
{
using clanguml::common::model::message_t;
message m{message_t::kSwitchEnd, current_caller_id};
if (sequences_.find(current_caller_id) != sequences_.end()) {
auto &current_messages = get_activity(current_caller_id).messages();
fold_or_end_block_statement(
std::move(m), message_t::kSwitch, current_messages);
}
}
void diagram::add_case_stmt(
common::model::diagram_element::id_t current_caller_id,
const std::string &case_label)
{
using clanguml::common::model::message_t;
message m{message_t::kCase, current_caller_id};
m.set_message_name(case_label);
if (sequences_.find(current_caller_id) != sequences_.end()) {
auto &current_messages = get_activity(current_caller_id).messages();
if (sequences_.find(caller_id) != sequences_.end()) {
auto &current_messages = get_activity(caller_id).messages();
if (current_messages.back().type() == message_t::kCase) {
// Do nothing - fallthroughs not supported yet...
@@ -300,66 +143,6 @@ void diagram::add_case_stmt(
}
}
void diagram::add_default_stmt(
common::model::diagram_element::id_t current_caller_id)
{
using clanguml::common::model::message_t;
message m{message_t::kCase, current_caller_id};
m.set_message_name("default");
if (sequences_.find(current_caller_id) != sequences_.end()) {
auto &current_messages = get_activity(current_caller_id).messages();
if (current_messages.back().type() == message_t::kCase) {
current_messages.pop_back();
}
else {
current_messages.emplace_back(std::move(m));
}
}
}
void diagram::add_conditional_stmt(
const common::model::diagram_element::id_t current_caller_id)
{
using clanguml::common::model::message_t;
if (sequences_.find(current_caller_id) == sequences_.end()) {
activity a{current_caller_id};
sequences_.insert({current_caller_id, std::move(a)});
}
get_activity(current_caller_id)
.add_message({message_t::kConditional, current_caller_id});
}
void diagram::add_conditional_elsestmt(
const common::model::diagram_element::id_t current_caller_id)
{
using clanguml::common::model::message_t;
get_activity(current_caller_id)
.add_message({message_t::kElse, current_caller_id});
}
void diagram::end_conditional_stmt(
const common::model::diagram_element::id_t current_caller_id)
{
using common::model::message_t;
message m{message_t::kConditionalEnd, current_caller_id};
if (sequences_.find(current_caller_id) != sequences_.end()) {
auto &current_messages = get_activity(current_caller_id).messages();
const message_t begin_stmt_message_type{message_t::kConditional};
fold_or_end_block_statement(
std::move(m), begin_stmt_message_type, current_messages);
}
}
bool diagram::started() const { return started_; }
void diagram::started(bool s) { started_ = s; }

View File

@@ -80,44 +80,14 @@ public:
activity &get_activity(common::model::diagram_element::id_t id);
void add_if_stmt(common::model::diagram_element::id_t current_caller_id,
common::model::message_t type);
void end_if_stmt(common::model::diagram_element::id_t current_caller_id,
common::model::message_t type);
void add_message(model::message &&message);
void add_try_stmt(common::model::diagram_element::id_t current_caller_id);
void end_try_stmt(common::model::diagram_element::id_t current_caller_id);
void add_block_message(model::message &&message);
void add_loop_stmt(common::model::diagram_element::id_t current_caller_id,
common::model::message_t type);
void end_loop_stmt(common::model::diagram_element::id_t current_caller_id,
common::model::message_t type);
void end_block_message(
model::message &&message, common::model::message_t start_type);
void add_while_stmt(common::model::diagram_element::id_t current_caller_id);
void end_while_stmt(common::model::diagram_element::id_t current_caller_id);
void add_do_stmt(common::model::diagram_element::id_t current_caller_id);
void end_do_stmt(common::model::diagram_element::id_t current_caller_id);
void add_for_stmt(common::model::diagram_element::id_t current_caller_id);
void end_for_stmt(common::model::diagram_element::id_t current_caller_id);
void add_switch_stmt(
common::model::diagram_element::id_t current_caller_id);
void end_switch_stmt(
common::model::diagram_element::id_t current_caller_id);
void add_case_stmt(common::model::diagram_element::id_t current_caller_id);
void add_case_stmt(common::model::diagram_element::id_t current_caller_id,
const std::string &case_label);
void add_default_stmt(
common::model::diagram_element::id_t current_caller_id);
void add_conditional_stmt(
common::model::diagram_element::id_t current_caller_id);
void add_conditional_elsestmt(
common::model::diagram_element::id_t current_caller_id);
void end_conditional_stmt(
common::model::diagram_element::id_t current_caller_id);
void add_case_stmt_message(model::message &&m);
bool started() const;
void started(bool s);
@@ -139,9 +109,6 @@ public:
const std::set<common::model::diagram_element::id_t> &
active_participants() const;
void add_catch_stmt(common::model::diagram_element::id_t current_caller_id,
std::string caught_type);
private:
void fold_or_end_block_statement(message &&m,
common::model::message_t statement_begin,

View File

@@ -71,7 +71,11 @@ clang::ASTContext *call_expression_context::get_ast_context() const
if (current_function_template_decl_ != nullptr)
return &current_function_template_decl_->getASTContext();
return &current_function_decl_->getASTContext();
if (current_function_decl_ != nullptr) {
return &current_function_decl_->getASTContext();
}
return nullptr;
}
void call_expression_context::update(clang::CXXRecordDecl *cls)

View File

@@ -509,9 +509,9 @@ bool translation_unit_visitor::TraverseCompoundStmt(clang::CompoundStmt *stmt)
const auto current_caller_id = context().caller_id();
if (current_caller_id != 0) {
diagram()
.get_activity(current_caller_id)
.add_message({message_t::kElse, current_caller_id});
model::message m{message_t::kElse, current_caller_id};
set_source_location(*stmt, m);
diagram().add_message(std::move(m));
}
}
}
@@ -520,9 +520,9 @@ bool translation_unit_visitor::TraverseCompoundStmt(clang::CompoundStmt *stmt)
const auto current_caller_id = context().caller_id();
if (current_caller_id != 0) {
diagram()
.get_activity(current_caller_id)
.add_message({message_t::kElse, current_caller_id});
model::message m{message_t::kElse, current_caller_id};
set_source_location(*stmt, m);
diagram().add_message(std::move(m));
}
}
}
@@ -556,20 +556,27 @@ bool translation_unit_visitor::TraverseIfStmt(clang::IfStmt *stmt)
}
if ((current_caller_id != 0) && !stmt->isConstexpr()) {
context().enter_ifstmt(stmt);
if (elseif_block) {
context().enter_elseifstmt(stmt);
diagram().add_if_stmt(current_caller_id, message_t::kElseIf);
message m{message_t::kElseIf, current_caller_id};
set_source_location(*stmt, m);
diagram().add_block_message(std::move(m));
}
else {
diagram().add_if_stmt(current_caller_id, message_t::kIf);
context().enter_ifstmt(stmt);
message m{message_t::kIf, current_caller_id};
set_source_location(*stmt, m);
diagram().add_block_message(std::move(m));
}
}
RecursiveASTVisitor<translation_unit_visitor>::TraverseIfStmt(stmt);
if ((current_caller_id != 0) && !stmt->isConstexpr() && !elseif_block) {
diagram().end_if_stmt(current_caller_id, message_t::kIfEnd);
diagram().end_block_message(
{message_t::kIfEnd, current_caller_id}, message_t::kIf);
}
return true;
@@ -585,12 +592,15 @@ bool translation_unit_visitor::TraverseWhileStmt(clang::WhileStmt *stmt)
if (current_caller_id != 0) {
context().enter_loopstmt(stmt);
diagram().add_while_stmt(current_caller_id);
message m{message_t::kWhile, current_caller_id};
set_source_location(*stmt, m);
diagram().add_block_message(std::move(m));
}
RecursiveASTVisitor<translation_unit_visitor>::TraverseWhileStmt(stmt);
if (current_caller_id != 0) {
diagram().end_while_stmt(current_caller_id);
diagram().end_block_message(
{message_t::kWhileEnd, current_caller_id}, message_t::kWhile);
context().leave_loopstmt();
}
@@ -607,14 +617,17 @@ bool translation_unit_visitor::TraverseDoStmt(clang::DoStmt *stmt)
if (current_caller_id != 0) {
context().enter_loopstmt(stmt);
diagram().add_do_stmt(current_caller_id);
message m{message_t::kDo, current_caller_id};
set_source_location(*stmt, m);
diagram().add_block_message(std::move(m));
}
RecursiveASTVisitor<translation_unit_visitor>::TraverseDoStmt(stmt);
if (current_caller_id != 0) {
diagram().end_block_message(
{message_t::kDoEnd, current_caller_id}, message_t::kDo);
context().leave_loopstmt();
diagram().end_do_stmt(current_caller_id);
}
return true;
@@ -630,14 +643,17 @@ bool translation_unit_visitor::TraverseForStmt(clang::ForStmt *stmt)
if (current_caller_id != 0) {
context().enter_loopstmt(stmt);
diagram().add_for_stmt(current_caller_id);
message m{message_t::kFor, current_caller_id};
set_source_location(*stmt, m);
diagram().add_block_message(std::move(m));
}
RecursiveASTVisitor<translation_unit_visitor>::TraverseForStmt(stmt);
if (current_caller_id != 0) {
diagram().end_block_message(
{message_t::kForEnd, current_caller_id}, message_t::kFor);
context().leave_loopstmt();
diagram().end_for_stmt(current_caller_id);
}
return true;
@@ -653,14 +669,17 @@ bool translation_unit_visitor::TraverseCXXTryStmt(clang::CXXTryStmt *stmt)
if (current_caller_id != 0) {
context().enter_trystmt(stmt);
diagram().add_try_stmt(current_caller_id);
message m{message_t::kTry, current_caller_id};
set_source_location(*stmt, m);
diagram().add_block_message(std::move(m));
}
RecursiveASTVisitor<translation_unit_visitor>::TraverseCXXTryStmt(stmt);
if (current_caller_id != 0) {
diagram().end_block_message(
{message_t::kTryEnd, current_caller_id}, message_t::kTry);
context().leave_trystmt();
diagram().end_try_stmt(current_caller_id);
}
return true;
@@ -682,7 +701,9 @@ bool translation_unit_visitor::TraverseCXXCatchStmt(clang::CXXCatchStmt *stmt)
caught_type = common::to_string(
stmt->getCaughtType(), *context().get_ast_context());
diagram().add_catch_stmt(current_caller_id, std::move(caught_type));
model::message m{message_t::kCatch, current_caller_id};
m.set_message_name(std::move(caught_type));
diagram().add_message(std::move(m));
}
RecursiveASTVisitor<translation_unit_visitor>::TraverseCXXCatchStmt(stmt);
@@ -701,15 +722,18 @@ bool translation_unit_visitor::TraverseCXXForRangeStmt(
if (current_caller_id != 0) {
context().enter_loopstmt(stmt);
diagram().add_for_stmt(current_caller_id);
message m{message_t::kFor, current_caller_id};
set_source_location(*stmt, m);
diagram().add_block_message(std::move(m));
}
RecursiveASTVisitor<translation_unit_visitor>::TraverseCXXForRangeStmt(
stmt);
if (current_caller_id != 0) {
diagram().end_block_message(
{message_t::kForEnd, current_caller_id}, message_t::kFor);
context().leave_loopstmt();
diagram().end_for_stmt(current_caller_id);
}
return true;
@@ -717,18 +741,23 @@ bool translation_unit_visitor::TraverseCXXForRangeStmt(
bool translation_unit_visitor::TraverseSwitchStmt(clang::SwitchStmt *stmt)
{
using clanguml::common::model::message_t;
const auto current_caller_id = context().caller_id();
if (current_caller_id != 0) {
context().enter_switchstmt(stmt);
diagram().add_switch_stmt(current_caller_id);
model::message m{message_t::kSwitch, current_caller_id};
set_source_location(*stmt, m);
diagram().add_block_message(std::move(m));
}
RecursiveASTVisitor<translation_unit_visitor>::TraverseSwitchStmt(stmt);
if (current_caller_id != 0) {
context().leave_switchstmt();
diagram().end_switch_stmt(current_caller_id);
diagram().end_block_message(
{message_t::kSwitchEnd, current_caller_id}, message_t::kSwitch);
}
return true;
@@ -736,11 +765,14 @@ bool translation_unit_visitor::TraverseSwitchStmt(clang::SwitchStmt *stmt)
bool translation_unit_visitor::TraverseCaseStmt(clang::CaseStmt *stmt)
{
using clanguml::common::model::message_t;
const auto current_caller_id = context().caller_id();
if (current_caller_id != 0) {
diagram().add_case_stmt(
current_caller_id, common::to_string(stmt->getLHS()));
model::message m{message_t::kCase, current_caller_id};
m.set_message_name(common::to_string(stmt->getLHS()));
diagram().add_case_stmt_message(std::move(m));
}
RecursiveASTVisitor<translation_unit_visitor>::TraverseCaseStmt(stmt);
@@ -750,10 +782,14 @@ bool translation_unit_visitor::TraverseCaseStmt(clang::CaseStmt *stmt)
bool translation_unit_visitor::TraverseDefaultStmt(clang::DefaultStmt *stmt)
{
using clanguml::common::model::message_t;
const auto current_caller_id = context().caller_id();
if (current_caller_id != 0) {
diagram().add_default_stmt(current_caller_id);
model::message m{message_t::kCase, current_caller_id};
m.set_message_name("default");
diagram().add_case_stmt_message(std::move(m));
}
RecursiveASTVisitor<translation_unit_visitor>::TraverseDefaultStmt(stmt);
@@ -764,11 +800,15 @@ bool translation_unit_visitor::TraverseDefaultStmt(clang::DefaultStmt *stmt)
bool translation_unit_visitor::TraverseConditionalOperator(
clang::ConditionalOperator *stmt)
{
using clanguml::common::model::message_t;
const auto current_caller_id = context().caller_id();
if (current_caller_id != 0) {
context().enter_conditionaloperator(stmt);
diagram().add_conditional_stmt(current_caller_id);
model::message m{message_t::kConditional, current_caller_id};
set_source_location(*stmt, m);
diagram().add_block_message(std::move(m));
}
RecursiveASTVisitor<translation_unit_visitor>::TraverseStmt(
@@ -778,7 +818,9 @@ bool translation_unit_visitor::TraverseConditionalOperator(
stmt->getTrueExpr());
if (current_caller_id != 0) {
diagram().add_conditional_elsestmt(current_caller_id);
model::message m{message_t::kElse, current_caller_id};
set_source_location(*stmt, m);
diagram().add_message(std::move(m));
}
RecursiveASTVisitor<translation_unit_visitor>::TraverseStmt(
@@ -786,7 +828,9 @@ bool translation_unit_visitor::TraverseConditionalOperator(
if (current_caller_id != 0) {
context().leave_conditionaloperator();
diagram().end_conditional_stmt(current_caller_id);
diagram().end_block_message(
{message_t::kConditionalEnd, current_caller_id},
message_t::kConditional);
}
return true;
@@ -1975,8 +2019,6 @@ translation_unit_visitor::build_template_instantiation(
auto templated_decl_id =
template_type.getTemplateName().getAsTemplateDecl()->getID();
// auto templated_decl_local_id =
// get_unique_id(templated_decl_id).value_or(0);
if (best_match_id > 0) {
destination = best_match_full_name;