diff --git a/docs/test_cases/t00014.md b/docs/test_cases/t00014.md index 471189bd..adec4d43 100644 --- a/docs/test_cases/t00014.md +++ b/docs/test_cases/t00014.md @@ -13,11 +13,16 @@ diagrams: include: namespaces: - clanguml::t00014 + exclude: + namespaces: + - std + - clanguml::t00014::std ``` ## Source code ```cpp #include +#include #include #include #include @@ -46,6 +51,9 @@ template struct A { template using AString = A; +template using GeneralCallback = std::function; +using VoidCallback = GeneralCallback<>; + struct B { std::string value; }; @@ -65,6 +73,8 @@ class R { AStringString stringstring; BVector bs; BVector2 bs2; + GeneralCallback cb; + VoidCallback vcb; }; } } diff --git a/docs/test_cases/t00014_class.png b/docs/test_cases/t00014_class.png index 12ffc9e8..c0d9b9db 100644 Binary files a/docs/test_cases/t00014_class.png and b/docs/test_cases/t00014_class.png differ diff --git a/docs/test_cases/t00015_class.png b/docs/test_cases/t00015_class.png index 06c5af8c..e6f9ed2c 100644 Binary files a/docs/test_cases/t00015_class.png and b/docs/test_cases/t00015_class.png differ diff --git a/docs/test_cases/t00016_class.png b/docs/test_cases/t00016_class.png index 2fb91e5e..9e82fe13 100644 Binary files a/docs/test_cases/t00016_class.png and b/docs/test_cases/t00016_class.png differ diff --git a/src/config/config.h b/src/config/config.h index 978e2f6c..06866cf6 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -111,8 +111,10 @@ struct diagram { auto name = clanguml::util::unqualify(name_); for (const auto &ex : exclude.namespaces) { - if (name.find(ex) == 0) + if (name.find(ex) == 0) { + spdlog::debug("Skipping from diagram: {}", name); return false; + } } // If no inclusive namespaces are provided, diff --git a/src/puml/class_diagram_generator.h b/src/puml/class_diagram_generator.h index d00a1ea3..1ed6a9e8 100644 --- a/src/puml/class_diagram_generator.h +++ b/src/puml/class_diagram_generator.h @@ -341,16 +341,24 @@ public: if (m_config.should_include_entities("classes")) { for (const auto &c : m_model.classes) { + if (!c.is_template_instantiation && + !m_config.should_include(c.name)) + continue; generate_alias(c, ostr); ostr << std::endl; } for (const auto &e : m_model.enums) { + if (!m_config.should_include(e.name)) + continue; generate_alias(e, ostr); ostr << std::endl; } for (const auto &c : m_model.classes) { + if (!c.is_template_instantiation && + !m_config.should_include(c.name)) + continue; generate(c, ostr); ostr << std::endl; } diff --git a/src/uml/class_diagram_visitor.cc b/src/uml/class_diagram_visitor.cc index 2bade83c..8b26f103 100644 --- a/src/uml/class_diagram_visitor.cc +++ b/src/uml/class_diagram_visitor.cc @@ -1048,31 +1048,40 @@ void tu_visitor::find_relationships(const cppast::cpp_type &t_, class_ tu_visitor::build_template_instantiation( const cppast::cpp_template_instantiation_type &t) { - const auto &primary_template_ref = - static_cast( - t.primary_template().get(ctx.entity_index)[0].get()) - .class_(); - - auto full_template_name = - cx::util::full_name(ctx.namespace_, primary_template_ref); - - LOG_DBG("Found template instantiation: {} ({}) ..|> {}, {}", - cppast::to_string(t), cppast::to_string(t.canonical()), - t.primary_template().name(), full_template_name); - class_ tinst; + std::string full_template_name; - if (full_template_name.back() == ':') - tinst.name = full_template_name + tinst.name; + if (t.primary_template().get(ctx.entity_index).size()) { + const auto &primary_template_ref = + static_cast( + t.primary_template().get(ctx.entity_index)[0].get()) + .class_(); - if (primary_template_ref.user_data()) { - tinst.base_template_usr = - static_cast(primary_template_ref.user_data()); - LOG_DBG("Primary template ref set to: {}", tinst.base_template_usr); + full_template_name = + cx::util::full_name(ctx.namespace_, primary_template_ref); + + LOG_DBG("Found template instantiation: {} ({}) ..|> {}, {}", + cppast::to_string(t), cppast::to_string(t.canonical()), + t.primary_template().name(), full_template_name); + + if (full_template_name.back() == ':') + tinst.name = full_template_name + tinst.name; + + if (primary_template_ref.user_data()) { + tinst.base_template_usr = + static_cast(primary_template_ref.user_data()); + LOG_DBG("Primary template ref set to: {}", tinst.base_template_usr); + } + else + LOG_WARN("No user data for base template {}", + primary_template_ref.name()); + } + else { + LOG_WARN("Template instantiation {} has no primary template", + cppast::to_string(t)); + + full_template_name = cppast::to_string(t); } - else - LOG_WARN( - "No user data for base template {}", primary_template_ref.name()); // Extract namespace from base template name auto ns_toks = clanguml::util::split( diff --git a/tests/t00014/.clanguml b/tests/t00014/.clanguml index b6e5b791..2534f83f 100644 --- a/tests/t00014/.clanguml +++ b/tests/t00014/.clanguml @@ -10,3 +10,7 @@ diagrams: include: namespaces: - clanguml::t00014 + exclude: + namespaces: + - std + - clanguml::t00014::std diff --git a/tests/t00014/t00014.cc b/tests/t00014/t00014.cc index 45460849..1f84ed26 100644 --- a/tests/t00014/t00014.cc +++ b/tests/t00014/t00014.cc @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -27,6 +28,9 @@ template struct A { template using AString = A; +template using GeneralCallback = std::function; +using VoidCallback = GeneralCallback<>; + struct B { std::string value; }; @@ -46,6 +50,8 @@ class R { AStringString stringstring; BVector bs; BVector2 bs2; + GeneralCallback cb; + VoidCallback vcb; }; } } diff --git a/tests/t00014/test_case.h b/tests/t00014/test_case.h index 1f82924e..1bf5ceef 100644 --- a/tests/t00014/test_case.h +++ b/tests/t00014/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00014/test_case.cc + * tests/t00014/test_case.h * * Copyright (c) 2021 Bartek Kryza * @@ -27,7 +27,7 @@ TEST_CASE("t00014", "[test-case][class]") REQUIRE_THAT(diagram->include.namespaces, VectorContains(std::string{"clanguml::t00014"})); - REQUIRE(diagram->exclude.namespaces.size() == 0); + REQUIRE(diagram->exclude.namespaces.size() == 2); REQUIRE(diagram->should_include("clanguml::t00014::S")); @@ -46,9 +46,6 @@ TEST_CASE("t00014", "[test-case][class]") REQUIRE_THAT(puml, IsClassTemplate("AString", "float")); REQUIRE_THAT(puml, IsInstantiation(_A("A"), _A("A"))); - // TODO - // REQUIRE_THAT(puml, IsInstantiation(_A("A"), - // _A("A"))); REQUIRE_THAT( puml, IsInstantiation(_A("A"), _A("AString"))); REQUIRE_THAT(