Added participant generation in sequence diagrams

This commit is contained in:
Bartek Kryza
2022-10-24 01:09:40 +02:00
parent 1fe9918c1a
commit ad5ec1c973
7 changed files with 63 additions and 24 deletions

View File

@@ -43,7 +43,7 @@ public:
void set_id(id_t id);
std::string alias() const;
virtual std::string alias() const;
void set_name(const std::string &name) { name_ = name; }

View File

@@ -38,11 +38,11 @@ generator::generator(
void generator::generate_call(const message &m, std::ostream &ostr) const
{
const auto from = m_config.using_namespace().relative(m.from_name);
const auto to = m_config.using_namespace().relative(m.to_name);
const auto &from = m_model.get_participant<model::participant>(m.from);
const auto &to = m_model.get_participant<model::participant>(m.to);
if (from.empty() || to.empty()) {
LOG_DBG("Skipping empty call from '{}' to '{}'", from, to);
if (!from || !to) {
LOG_DBG("Skipping empty call from '{}' to '{}'", m.from, m.to);
return;
}
@@ -52,9 +52,9 @@ void generator::generate_call(const message &m, std::ostream &ostr) const
message += "()";
}
ostr << '"' << from << "\" "
<< common::generators::plantuml::to_plantuml(message_t::kCall) << " \""
<< to << "\" : " << message << std::endl;
ostr << from.value().alias() << " "
<< common::generators::plantuml::to_plantuml(message_t::kCall) << " "
<< to.value().alias() << " : " << message << std::endl;
LOG_DBG("Generated call '{}' from {} [{}] to {} [{}]", message, from,
m.from_name, to, m.to_name);
@@ -65,28 +65,26 @@ void generator::generate_return(const message &m, std::ostream &ostr) const
// Add return activity only for messages between different actors and
// only if the return type is different than void
if ((m.from != m.to) && (m.return_type != "void")) {
const auto from = m_config.using_namespace().relative(m.from_name);
const auto to = m_config.using_namespace().relative(m.to_name);
const auto &from = m_model.get_participant<model::participant>(m.from);
const auto &to = m_model.get_participant<model::participant>(m.to);
ostr << '"' << to << "\" "
ostr << to.value().alias() << " "
<< common::generators::plantuml::to_plantuml(message_t::kReturn)
<< " \"" << from << "\"" << std::endl;
<< " " << from.value().alias() << '\n';
}
}
void generator::generate_activity(const activity &a, std::ostream &ostr) const
{
for (const auto &m : a.messages) {
const auto to = m_config.using_namespace().relative(m.to_name);
if (to.empty())
const auto &to = m_model.get_participant<model::participant>(m.to);
if (!to)
continue;
LOG_DBG("Generating message {} --> {}",
m.from_name, m.to_name);
LOG_DBG("Generating message {} --> {}", m.from_name, m.to_name);
generate_call(m, ostr);
ostr << "activate " << '"' << to << '"' << std::endl;
ostr << "activate " << to.value().alias() << std::endl;
if (m_model.sequences.find(m.to) != m_model.sequences.end()) {
LOG_DBG("Creating activity {} --> {} - missing sequence {}",
@@ -99,7 +97,23 @@ void generator::generate_activity(const activity &a, std::ostream &ostr) const
generate_return(m, ostr);
ostr << "deactivate " << '"' << to << '"' << std::endl;
ostr << "deactivate " << to.value().alias() << std::endl;
}
}
void generator::generate_participants(std::ostream &ostr) const
{
for (const auto participant_id : m_model.active_participants_) {
const auto &participant =
m_model.get_participant<model::participant>(participant_id).value();
if (participant.type_name() == "method")
continue;
ostr << "participant \""
<< m_config.using_namespace().relative(
participant.full_name(false))
<< "\" as " << participant.alias()<< '\n';
}
}
@@ -111,6 +125,8 @@ void generator::generate(std::ostream &ostr) const
generate_plantuml_directives(ostr, m_config.puml().before);
generate_participants(ostr);
for (const auto &sf : m_config.start_from()) {
if (sf.location_type == source_location::location_t::function) {
std::int64_t start_from;

View File

@@ -52,6 +52,8 @@ public:
void generate_return(const clanguml::sequence_diagram::model::message &m,
std::ostream &ostr) const;
void generate_participants(std::ostream &ostr) const;
void generate_activity(const clanguml::sequence_diagram::model::activity &a,
std::ostream &ostr) const;

View File

@@ -79,10 +79,17 @@ public:
}
}
void add_active_participant(common::model::diagram_element::id_t id)
{
active_participants_.emplace(id);
}
std::map<common::model::diagram_element::id_t, activity> sequences;
std::map<common::model::diagram_element::id_t, std::unique_ptr<participant>>
participants;
std::set<common::model::diagram_element::id_t> active_participants_;
};
}

View File

@@ -128,4 +128,11 @@ method::method(const common::model::namespace_ &using_namespace)
: participant{using_namespace}
{
}
std::string method::alias() const
{
assert(class_id_ >= 0);
return fmt::format("C_{:022}", class_id_);
}
}

View File

@@ -157,11 +157,11 @@ struct method : public participant {
std::string type_name() const override { return "method"; }
const std::string method_name() const {
return method_name_;
}
const std::string method_name() const { return method_name_; }
void set_method_name(const std::string& name) { method_name_ = name; }
std::string alias() const override;
void set_method_name(const std::string &name) { method_name_ = name; }
void set_class_id(diagram_element::id_t id) { class_id_ = id; }

View File

@@ -339,6 +339,10 @@ bool translation_unit_visitor::VisitCallExpr(clang::CallExpr *expr)
m.message_name = method_decl->getNameAsString();
m.return_type = method_call_expr->getCallReturnType(current_ast_context)
.getAsString();
if (get_ast_local_id(callee_decl->getID()))
diagram().add_active_participant(
get_ast_local_id(callee_decl->getID()).value());
}
else if (const auto *function_call_expr =
clang::dyn_cast_or_null<clang::CallExpr>(expr);
@@ -400,7 +404,7 @@ bool translation_unit_visitor::VisitCallExpr(clang::CallExpr *expr)
return true;
}
if(m.from > 0 && m.to > 0) {
if (m.from > 0 && m.to > 0) {
if (diagram().sequences.find(m.from) == diagram().sequences.end()) {
activity a;
a.usr = m.from;
@@ -408,6 +412,9 @@ bool translation_unit_visitor::VisitCallExpr(clang::CallExpr *expr)
diagram().sequences.insert({m.from, std::move(a)});
}
diagram().add_active_participant(m.from);
diagram().add_active_participant(m.to);
LOG_DBG("Found call {} from {} [{}] to {} [{}] ", m.message_name,
m.from_name, m.from, m.to_name, m.to);