Initial support for concept dependency relationships in class diagrams

This commit is contained in:
Bartek Kryza
2023-02-25 01:50:07 +01:00
parent 20a0f2d338
commit 274a698713
15 changed files with 750 additions and 34 deletions

View File

@@ -102,6 +102,23 @@ void generator::generate_alias(const enum_ &e, std::ostream &ostr) const
m_generated_aliases.emplace(e.alias());
}
void generator::generate_alias(const concept_ &c, std::ostream &ostr) const
{
print_debug(c, ostr);
if (m_config.generate_packages())
ostr << "annotation"
<< " \"" << c.name();
else
ostr << "annotation"
<< " \"" << render_name(c.full_name());
ostr << "\" as " << c.alias() << '\n';
// Register the added alias
m_generated_aliases.emplace(c.alias());
}
void generator::generate(const class_ &c, std::ostream &ostr) const
{
namespace plantuml_common = clanguml::common::generators::plantuml;
@@ -279,6 +296,26 @@ void generator::generate(const class_ &c, std::ostream &ostr) const
generate_member_notes(ostr, method, c.alias());
}
void generator::generate(const concept_ &c, std::ostream &ostr) const
{
namespace plantuml_common = clanguml::common::generators::plantuml;
std::string class_type{"annotation"};
ostr << class_type << " " << c.alias() << " <<concept>>";
if (m_config.generate_links) {
common_generator<diagram_config, diagram_model>::generate_link(ostr, c);
}
if (!c.style().empty())
ostr << " " << c.style();
ostr << " {" << '\n';
ostr << "}" << '\n';
}
void generator::generate_member_notes(std::ostream &ostr,
const class_element &member, const std::string &alias) const
{
@@ -309,6 +346,11 @@ void generator::generate_relationships(std::ostream &ostr) const
generate_relationships(*enm, ostr);
}
}
else if (auto *cpt = dynamic_cast<concept_ *>(p.get()); cpt) {
if (m_model.should_include(*cpt)) {
generate_relationships(*cpt, ostr);
}
}
}
}
@@ -409,6 +451,82 @@ void generator::generate_relationships(
ostr << all_relations_str.str();
}
void generator::generate_relationships(
const concept_ &c, std::ostream &ostr) const
{
namespace plantuml_common = clanguml::common::generators::plantuml;
//
// Process relationships
//
std::set<std::string> rendered_relations;
std::stringstream all_relations_str;
std::set<std::string> unique_relations;
for (const auto &r : c.relationships()) {
if (!m_model.should_include(r.type()))
continue;
LOG_DBG("== Processing relationship {}",
plantuml_common::to_plantuml(r.type(), r.style()));
std::stringstream relstr;
clanguml::common::id_t destination{0};
try {
destination = r.destination();
std::string puml_relation;
if (!r.multiplicity_source().empty())
puml_relation += "\"" + r.multiplicity_source() + "\" ";
puml_relation += plantuml_common::to_plantuml(r.type(), r.style());
if (!r.multiplicity_destination().empty())
puml_relation += " \"" + r.multiplicity_destination() + "\"";
std::string target_alias;
try {
target_alias = m_model.to_alias(destination);
}
catch (...) {
LOG_DBG("Failed to find alias to {}", destination);
continue;
}
if (m_generated_aliases.find(target_alias) ==
m_generated_aliases.end())
continue;
relstr << c.alias() << " " << puml_relation << " " << target_alias;
if (!r.label().empty()) {
relstr << " : " << plantuml_common::to_plantuml(r.access())
<< r.label();
rendered_relations.emplace(r.label());
}
if (unique_relations.count(relstr.str()) == 0) {
unique_relations.emplace(relstr.str());
relstr << '\n';
LOG_DBG("=== Adding relation {}", relstr.str());
all_relations_str << relstr.str();
}
}
catch (error::uml_alias_missing &e) {
LOG_DBG("=== Skipping {} relation from {} to {} due "
"to: {}",
plantuml_common::to_plantuml(r.type(), r.style()),
c.full_name(), destination, e.what());
}
}
ostr << all_relations_str.str();
}
void generator::generate(const enum_ &e, std::ostream &ostr) const
{
ostr << "enum " << e.alias();
@@ -534,6 +652,20 @@ void generator::generate(const package &p, std::ostream &ostr) const
}
}
}
else if (auto *cpt = dynamic_cast<concept_ *>(subpackage.get()); cpt) {
if (m_model.should_include(*subpackage)) {
auto together_group =
m_config.get_together_group(cpt->full_name(false));
if (together_group) {
together_group_stack_.group_together(
together_group.value(), cpt);
}
else {
generate_alias(*cpt, ostr);
generate(*cpt, ostr);
}
}
}
}
if (m_config.generate_packages()) {
@@ -552,6 +684,10 @@ void generator::generate(const package &p, std::ostream &ostr) const
generate_alias(*enm, ostr);
generate(*enm, ostr);
}
if (auto *cpt = dynamic_cast<concept_ *>(e); cpt) {
generate_alias(*cpt, ostr);
generate(*cpt, ostr);
}
}
ostr << "}\n";
@@ -589,6 +725,12 @@ void generator::generate_relationships(
dynamic_cast<enum_ &>(*subpackage), ostr);
}
}
else if (dynamic_cast<concept_ *>(subpackage.get()) != nullptr) {
if (m_model.should_include(*subpackage)) {
generate_relationships(
dynamic_cast<concept_ &>(*subpackage), ostr);
}
}
}
}
@@ -648,6 +790,20 @@ void generator::generate_top_level_elements(std::ostream &ostr) const
}
}
}
else if (auto *cpt = dynamic_cast<concept_ *>(p.get()); cpt) {
if (m_model.should_include(*cpt)) {
auto together_group =
m_config.get_together_group(cpt->full_name(false));
if (together_group) {
together_group_stack_.group_together(
together_group.value(), cpt);
}
else {
generate_alias(*cpt, ostr);
generate(*cpt, ostr);
}
}
}
}
}
@@ -666,6 +822,10 @@ void generator::generate_groups(std::ostream &ostr) const
generate_alias(*enm, ostr);
generate(*enm, ostr);
}
if (auto *cpt = dynamic_cast<concept_ *>(e); cpt) {
generate_alias(*cpt, ostr);
generate(*cpt, ostr);
}
}
ostr << "}\n";

View File

@@ -18,6 +18,7 @@
#pragma once
#include "class_diagram/model/class.h"
#include "class_diagram/model/concept.h"
#include "class_diagram/model/diagram.h"
#include "class_diagram/model/enum.h"
#include "class_diagram/visitor/translation_unit_visitor.h"
@@ -47,6 +48,7 @@ using common_generator =
using clanguml::class_diagram::model::class_;
using clanguml::class_diagram::model::class_element;
using clanguml::class_diagram::model::concept_;
using clanguml::class_diagram::model::enum_;
using clanguml::common::model::access_t;
using clanguml::common::model::package;
@@ -65,6 +67,8 @@ public:
void generate_alias(const enum_ &e, std::ostream &ostr) const;
void generate_alias(const concept_ &c, std::ostream &ostr) const;
void generate(const class_ &c, std::ostream &ostr) const;
void generate_top_level_elements(std::ostream &ostr) const;
@@ -77,6 +81,10 @@ public:
void generate_relationships(const enum_ &c, std::ostream &ostr) const;
void generate(const concept_ &c, std::ostream &ostr) const;
void generate_relationships(const concept_ &c, std::ostream &ostr) const;
void generate(const package &p, std::ostream &ostr) const;
void generate_relationships(const package &p, std::ostream &ostr) const;