Added generation of packages in class diagrams

This commit is contained in:
Bartek Kryza
2022-02-24 22:16:50 +01:00
parent 8854f764a5
commit fe3c4aedf1
4 changed files with 90 additions and 32 deletions

View File

@@ -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 << " <<deprecated>>";
if (!p.style().empty())
ostr << " " << p.style();
ostr << " {" << '\n';
}
for (const auto &subpackage : p) {
if (dynamic_cast<package *>(subpackage.get())) {
generate(dynamic_cast<package &>(*subpackage), ostr);
}
if (dynamic_cast<class_ *>(subpackage.get())) {
generate_alias(dynamic_cast<class_ &>(*subpackage), ostr);
generate(dynamic_cast<class_ &>(*subpackage), ostr);
}
if (dynamic_cast<enum_ *>(subpackage.get())) {
generate_alias(dynamic_cast<enum_ &>(*subpackage), ostr);
generate(dynamic_cast<enum_ &>(*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<package *>(p.get())) {
generate(dynamic_cast<package &>(*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<class_ *>(p.get())) {
generate_alias(dynamic_cast<class_ &>(*p), ostr);
generate(dynamic_cast<class_ &>(*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<enum_ *>(p.get())) {
generate_alias(dynamic_cast<enum_ &>(*p), ostr);
generate(dynamic_cast<enum_ &>(*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';
}
}

View File

@@ -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;
};

View File

@@ -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<std::string> 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

View File

@@ -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};