diff --git a/src/puml/class_diagram_generator.h b/src/puml/class_diagram_generator.h index c274addd..94b8017e 100644 --- a/src/puml/class_diagram_generator.h +++ b/src/puml/class_diagram_generator.h @@ -124,7 +124,7 @@ public: } } - void generate_aliases(const class_ &c, std::ostream &ostr) const + void generate_alias(const class_ &c, std::ostream &ostr) const { std::string class_type{"class"}; if (c.is_abstract()) @@ -135,6 +135,13 @@ public: ostr << "\" as " << c.alias() << std::endl; } + void generate_alias(const enum_ &e, std::ostream &ostr) const + { + ostr << "enum" << " \"" << e.full_name(m_config.using_namespace); + + ostr << "\" as " << e.alias() << std::endl; + } + void generate(const class_ &c, std::ostream &ostr) const { std::string class_type{"class"}; @@ -266,7 +273,7 @@ public: void generate(const enum_ &e, std::ostream &ostr) const { - ostr << "enum " << ns_relative(m_config.using_namespace, e.name) << " {" + ostr << "enum " << e.alias() << " {" << std::endl; for (const auto &enum_constant : e.constants) { @@ -325,7 +332,12 @@ public: if (m_config.should_include_entities("classes")) { for (const auto &c : m_model.classes) { - generate_aliases(c, ostr); + generate_alias(c, ostr); + ostr << std::endl; + } + + for (const auto &e : m_model.enums) { + generate_alias(e, ostr); ostr << std::endl; } diff --git a/src/uml/class_diagram_model.h b/src/uml/class_diagram_model.h index c7a70c19..b61b2866 100644 --- a/src/uml/class_diagram_model.h +++ b/src/uml/class_diagram_model.h @@ -175,9 +175,9 @@ public: void add_relationship(class_relationship &&cr) { - if (cr.destination.empty() || type_aliases.count(cr.destination) == 0) { + if (cr.destination.empty()) { LOG_WARN( - "Skipping relationship '{}' - {} - '{}' due to missing alias", + "Skipping relationship '{}' - {} - '{}' due empty destination", cr.destination, to_string(cr.type), usr); return; } @@ -240,6 +240,18 @@ struct enum_ : public element { { return l.name == r.name; } + + std::string full_name( + const std::vector &using_namespaces) const + { + using namespace clanguml::util; + + std::ostringstream ostr; + ostr << ns_relative(using_namespaces, name); + + return ostr.str(); + } + }; struct diagram { @@ -289,6 +301,12 @@ struct diagram { } } + for (const auto &e : enums) { + if (e.full_name(using_namespaces) == full_name) { + return e.alias(); + } + } + throw error::uml_alias_missing( fmt::format("Missing alias for {}", full_name)); } diff --git a/tests/t00002/t00002.cc b/tests/t00002/t00002.cc index b76abf07..6a8b92dd 100644 --- a/tests/t00002/t00002.cc +++ b/tests/t00002/t00002.cc @@ -33,6 +33,29 @@ public: a->foo_c(); } +private: + std::vector as; +}; + +// +// NOTE: libclang fails on: +// +// class D : public virtual B, public virtual C { +// +class E : virtual public B, virtual public C { +public: + void foo_a() override + { + for (auto a : as) + a->foo_a(); + } + + void foo_c() override + { + for (auto a : as) + a->foo_c(); + } + private: std::vector as; }; diff --git a/tests/t00004/test_case.h b/tests/t00004/test_case.h index 399ea1be..6508c5ed 100644 --- a/tests/t00004/test_case.h +++ b/tests/t00004/test_case.h @@ -46,10 +46,10 @@ TEST_CASE("t00004", "[test-case][class]") REQUIRE_THAT(puml, IsClass(_A("A"))); REQUIRE_THAT(puml, IsClass(_A("AA"))); REQUIRE_THAT(puml, IsClass(_A("AAA"))); - REQUIRE_THAT(puml, IsEnum("Lights")); + REQUIRE_THAT(puml, IsEnum(_A("Lights"))); REQUIRE_THAT(puml, IsInnerClass(_A("A"), _A("AA"))); REQUIRE_THAT(puml, IsInnerClass(_A("AA"), _A("AAA"))); - REQUIRE_THAT(puml, IsInnerClass(_A("AA"), "Lights")); + REQUIRE_THAT(puml, IsInnerClass(_A("AA"), _A("Lights"))); REQUIRE_THAT(puml, (IsMethod("foo"))); REQUIRE_THAT(puml, (IsMethod("foo2")));