From 17b0686f5c4a9a8d9b93c11ecdaa8c2c45969a49 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 27 Feb 2022 00:49:25 +0100 Subject: [PATCH] Fixed package generation in class diagrams --- .../plantuml/class_diagram_generator.cc | 28 +++++++++++-------- .../visitor/translation_unit_visitor.cc | 8 ++++-- src/common/model/nested_trait.h | 2 ++ src/config/config.cc | 25 +++++++++++++++++ src/config/config.h | 2 ++ uml/class_model_class_diagram.yml | 3 +- 6 files changed, 52 insertions(+), 16 deletions(-) diff --git a/src/class_diagram/generators/plantuml/class_diagram_generator.cc b/src/class_diagram/generators/plantuml/class_diagram_generator.cc index 909f0d54..ace02486 100644 --- a/src/class_diagram/generators/plantuml/class_diagram_generator.cc +++ b/src/class_diagram/generators/plantuml/class_diagram_generator.cc @@ -210,7 +210,7 @@ void generator::generate( << " <|-- " << m_model.to_alias(ns_relative(uns, c.full_name())) << '\n'; - ostr << relstr.str(); + all_relations_str << relstr.str(); } catch (error::uml_alias_missing &e) { LOG_ERROR("=== Skipping inheritance relation from {} to {} due " @@ -300,15 +300,17 @@ void generator::generate(const package &p, std::ostream &ostr, for (const auto &subpackage : p) { if (dynamic_cast(subpackage.get())) { - generate( - dynamic_cast(*subpackage), ostr, relationships_ostr); + // TODO: add option - generate_empty_packages + const auto &sp = dynamic_cast(*subpackage); + if (!sp.is_empty()) + generate(sp, ostr, relationships_ostr); } - if (dynamic_cast(subpackage.get())) { + else if (dynamic_cast(subpackage.get())) { generate_alias(dynamic_cast(*subpackage), ostr); generate( dynamic_cast(*subpackage), ostr, relationships_ostr); } - if (dynamic_cast(subpackage.get())) { + else if (dynamic_cast(subpackage.get())) { generate_alias(dynamic_cast(*subpackage), ostr); generate( dynamic_cast(*subpackage), ostr, relationships_ostr); @@ -326,26 +328,28 @@ void generator::generate(std::ostream &ostr) const { ostr << "@startuml" << '\n'; - std::stringstream relationship_ostr; + std::stringstream relationships_ostr; generate_plantuml_directives(ostr, m_config.puml().before); for (const auto &p : m_model) { if (dynamic_cast(p.get())) { - generate(dynamic_cast(*p), ostr, relationship_ostr); + const auto &sp = dynamic_cast(*p); + if (!sp.is_empty()) + generate(sp, ostr, relationships_ostr); } - if (dynamic_cast(p.get())) { + else if (dynamic_cast(p.get())) { generate_alias(dynamic_cast(*p), ostr); - generate(dynamic_cast(*p), ostr, relationship_ostr); + generate(dynamic_cast(*p), ostr, relationships_ostr); } - if (dynamic_cast(p.get())) { + else if (dynamic_cast(p.get())) { generate_alias(dynamic_cast(*p), ostr); - generate(dynamic_cast(*p), ostr, relationship_ostr); + generate(dynamic_cast(*p), ostr, relationships_ostr); } ostr << '\n'; } - ostr << relationship_ostr.str(); + ostr << relationships_ostr.str(); generate_config_layout_hints(ostr); diff --git a/src/class_diagram/visitor/translation_unit_visitor.cc b/src/class_diagram/visitor/translation_unit_visitor.cc index 18e50fab..ebbfda63 100644 --- a/src/class_diagram/visitor/translation_unit_visitor.cc +++ b/src/class_diagram/visitor/translation_unit_visitor.cc @@ -228,7 +228,7 @@ void translation_unit_visitor::process_namespace( auto usn = util::split(ctx.config().using_namespace()[0], "::"); - if (!util::starts_with(usn, package_path)) { + if (ctx.config().should_include_package(util::join(package_path, "::"))) { auto p = std::make_unique(usn); util::remove_prefix(package_path, usn); @@ -362,7 +362,8 @@ void translation_unit_visitor::process_class_declaration( fmt::ptr(reinterpret_cast(&cls))); assert(c_ptr); - ctx.diagram().add_class(std::move(c_ptr)); + if (ctx.config().should_include(c.full_name(false))) + ctx.diagram().add_class(std::move(c_ptr)); } void translation_unit_visitor::process_class_containment( @@ -1105,7 +1106,8 @@ void translation_unit_visitor:: c.add_relationship(std::move(rr)); - ctx.diagram().add_class(std::move(tinst_ptr)); + if (ctx.config().should_include(c.full_name(false))) + ctx.diagram().add_class(std::move(tinst_ptr)); } } } diff --git a/src/common/model/nested_trait.h b/src/common/model/nested_trait.h index 1cc7779a..31de7363 100644 --- a/src/common/model/nested_trait.h +++ b/src/common/model/nested_trait.h @@ -126,6 +126,8 @@ public: elements_.end(); } + bool is_empty() const { return elements_.empty(); } + auto begin() { return elements_.begin(); } auto end() { return elements_.end(); } diff --git a/src/config/config.cc b/src/config/config.cc index 39c67509..8248907e 100644 --- a/src/config/config.cc +++ b/src/config/config.cc @@ -169,6 +169,31 @@ bool diagram::should_include(const std::string &name_) const return false; } +bool diagram::should_include_package(const std::string &name) const +{ + + for (const auto &ex : exclude().namespaces) { + if (name.find(ex) == 0) { + LOG_DBG("Skipping from diagram: {}", name); + return false; + } + } + + // If no inclusive namespaces are provided, + // allow all + if (include().namespaces.empty()) + return true; + + for (const auto &in : include().namespaces) { + if (in.find(name) == 0 || name.find(in) == 0) + return true; + } + + LOG_DBG("Skipping from diagram: {}", name); + + return false; +} + bool diagram::should_include(const clanguml::common::model::scope_t scope) const { for (const auto &s : exclude().scopes) { diff --git a/src/config/config.h b/src/config/config.h index d220f7c7..14cee6c2 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -103,6 +103,8 @@ struct diagram : public inheritable_diagram_options { bool should_include_relationship(const std::string &rel); + bool should_include_package(const std::string &name) const; + bool should_include( const std::pair, std::string> &name) const; diff --git a/uml/class_model_class_diagram.yml b/uml/class_model_class_diagram.yml index f705aca9..35e896a1 100644 --- a/uml/class_model_class_diagram.yml +++ b/uml/class_model_class_diagram.yml @@ -1,6 +1,7 @@ type: class include_relations_also_as_members: false generate_method_arguments: none +generate_packages: true glob: - src/common/model/*.h - src/common/model/*.cc @@ -11,7 +12,7 @@ include: - clanguml::common::model - clanguml::class_diagram::model using_namespace: - - clanguml::class_diagram::model + - clanguml plantuml: before: - 'title clang-uml class diagram model' \ No newline at end of file