From fe3c4aedf15f52d7f6659320f6d4c0e32031fbc7 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Thu, 24 Feb 2022 22:16:50 +0100 Subject: [PATCH] Added generation of packages in class diagrams --- .../plantuml/class_diagram_generator.cc | 88 +++++++++++++------ .../plantuml/class_diagram_generator.h | 3 + src/class_diagram/model/class.cc | 26 +++++- src/class_diagram/model/class.h | 5 ++ 4 files changed, 90 insertions(+), 32 deletions(-) diff --git a/src/class_diagram/generators/plantuml/class_diagram_generator.cc b/src/class_diagram/generators/plantuml/class_diagram_generator.cc index afb5f98f..006f47c6 100644 --- a/src/class_diagram/generators/plantuml/class_diagram_generator.cc +++ b/src/class_diagram/generators/plantuml/class_diagram_generator.cc @@ -33,15 +33,24 @@ void generator::generate_alias(const class_ &c, std::ostream &ostr) const if (c.is_abstract()) class_type = "abstract"; - ostr << class_type << " \"" << c.full_name(); + auto full_name = c.full_name(); + + if (m_config.generate_packages()) + ostr << class_type << " \"" << c.full_name_no_ns(); + else + ostr << class_type << " \"" << c.full_name(); ostr << "\" as " << c.alias() << '\n'; } void generator::generate_alias(const enum_ &e, std::ostream &ostr) const { - ostr << "enum" - << " \"" << e.full_name(); + if (m_config.generate_packages()) + ostr << "enum" + << " \"" << e.name(); + else + ostr << "enum" + << " \"" << e.full_name(); ostr << "\" as " << e.alias() << '\n'; } @@ -269,46 +278,69 @@ void generator::generate(const enum_ &e, std::ostream &ostr) const generate_notes(ostr, e); } +void generator::generate(const package &p, std::ostream &ostr) const +{ + if (m_config.generate_packages()) { + LOG_DBG("Generating package {}", p.name()); + + ostr << "package [" << p.name() << "] "; + ostr << "as " << p.alias(); + + if (p.is_deprecated()) + ostr << " <>"; + + if (!p.style().empty()) + ostr << " " << p.style(); + + ostr << " {" << '\n'; + } + + for (const auto &subpackage : p) { + if (dynamic_cast(subpackage.get())) { + generate(dynamic_cast(*subpackage), ostr); + } + if (dynamic_cast(subpackage.get())) { + generate_alias(dynamic_cast(*subpackage), ostr); + generate(dynamic_cast(*subpackage), ostr); + } + if (dynamic_cast(subpackage.get())) { + generate_alias(dynamic_cast(*subpackage), ostr); + generate(dynamic_cast(*subpackage), ostr); + } + } + + if (m_config.generate_packages()) { + ostr << "}" << '\n'; + } + + generate_notes(ostr, p); +} + void generator::generate(std::ostream &ostr) const { ostr << "@startuml" << '\n'; generate_plantuml_directives(ostr, m_config.puml().before); - if (m_config.should_include_entities("classes")) { - for (const auto &c : m_model.classes()) { - if (!m_config.should_include(c->get_namespace(), c->name())) - continue; - generate_alias(*c, ostr); - ostr << '\n'; + for (const auto &p : m_model) { + if (dynamic_cast(p.get())) { + generate(dynamic_cast(*p), ostr); } - - for (const auto &e : m_model.enums()) { - if (!m_config.should_include(e->get_namespace(), e->name())) - continue; - generate_alias(*e, ostr); - ostr << '\n'; + if (dynamic_cast(p.get())) { + generate_alias(dynamic_cast(*p), ostr); + generate(dynamic_cast(*p), ostr); } - - for (const auto &c : m_model.classes()) { - if (!m_config.should_include(c->get_namespace(), c->name())) - continue; - generate(*c, ostr); - ostr << '\n'; + if (dynamic_cast(p.get())) { + generate_alias(dynamic_cast(*p), ostr); + generate(dynamic_cast(*p), ostr); } + ostr << '\n'; } - if (m_config.should_include_entities("enums")) - for (const auto &e : m_model.enums()) { - generate(*e, ostr); - ostr << '\n'; - } - generate_config_layout_hints(ostr); generate_plantuml_directives(ostr, m_config.puml().after); ostr << "@enduml" << '\n'; } - } diff --git a/src/class_diagram/generators/plantuml/class_diagram_generator.h b/src/class_diagram/generators/plantuml/class_diagram_generator.h index ea6bf845..8e608d29 100644 --- a/src/class_diagram/generators/plantuml/class_diagram_generator.h +++ b/src/class_diagram/generators/plantuml/class_diagram_generator.h @@ -49,6 +49,7 @@ using common_generator = using clanguml::class_diagram::model::class_; using clanguml::class_diagram::model::enum_; +using clanguml::common::model::package; using clanguml::common::model::relationship_t; using clanguml::common::model::scope_t; @@ -66,6 +67,8 @@ public: void generate(const enum_ &e, std::ostream &ostr) const; + void generate(const package &p, std::ostream &ostr) const; + void generate(std::ostream &ostr) const override; }; diff --git a/src/class_diagram/model/class.cc b/src/class_diagram/model/class.cc index ace41003..73cb9468 100644 --- a/src/class_diagram/model/class.cc +++ b/src/class_diagram/model/class.cc @@ -96,6 +96,18 @@ void class_::add_type_alias(type_alias &&ta) type_aliases_[ta.alias()] = std::move(ta); } +std::string class_::full_name_no_ns() const { + using namespace clanguml::util; + + std::ostringstream ostr; + + ostr << name(); + + render_template_params(ostr); + + return ostr.str(); +} + std::string class_::full_name(bool relative) const { using namespace clanguml::util; @@ -106,6 +118,13 @@ std::string class_::full_name(bool relative) const else ostr << name_and_ns(); + render_template_params(ostr); + + return ostr.str(); +} +std::ostringstream &class_::render_template_params( + std::ostringstream &ostr) const +{ if (!templates_.empty()) { std::vector tnames; std::transform(templates_.cbegin(), templates_.cend(), @@ -114,11 +133,11 @@ std::string class_::full_name(bool relative) const if (!tmplt.type().empty()) res.push_back( - ns_relative(using_namespaces(), tmplt.type())); + util::ns_relative(using_namespaces(), tmplt.type())); if (!tmplt.name().empty()) res.push_back( - ns_relative(using_namespaces(), tmplt.name())); + util::ns_relative(using_namespaces(), tmplt.name())); if (!tmplt.default_value().empty()) { res.push_back("="); @@ -129,8 +148,7 @@ std::string class_::full_name(bool relative) const }); ostr << fmt::format("<{}>", fmt::join(tnames, ",")); } - - return ostr.str(); + return ostr; } bool class_::is_abstract() const diff --git a/src/class_diagram/model/class.h b/src/class_diagram/model/class.h index 891a41ec..e500adf9 100644 --- a/src/class_diagram/model/class.h +++ b/src/class_diagram/model/class.h @@ -69,9 +69,14 @@ public: std::string full_name(bool relative = true) const override; + std::string full_name_no_ns() const; + bool is_abstract() const; private: + std::ostringstream &render_template_params( + std::ostringstream &ostr) const; + bool is_struct_{false}; bool is_template_{false}; bool is_template_instantiation_{false};