From c0678bc74c8aa05808151951dd45c1ce71dcb313 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Fri, 15 Apr 2022 18:58:36 +0200 Subject: [PATCH] Fixed handling of template constructor in package diagrams --- .../visitor/translation_unit_visitor.cc | 50 +++++++++++++------ .../visitor/translation_unit_visitor.h | 3 +- tests/t00008/t00008.cc | 2 + tests/t30002/t30002.cc | 4 ++ 4 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/package_diagram/visitor/translation_unit_visitor.cc b/src/package_diagram/visitor/translation_unit_visitor.cc index 3b14a745..598bd98e 100644 --- a/src/package_diagram/visitor/translation_unit_visitor.cc +++ b/src/package_diagram/visitor/translation_unit_visitor.cc @@ -65,6 +65,12 @@ access_t cpp_access_specifier_to_access( return access; } + +bool is_constructor(const cppast::cpp_entity &e) +{ + return dynamic_cast( + dynamic_cast(&e)) != nullptr; +} } translation_unit_visitor::translation_unit_visitor( @@ -79,6 +85,7 @@ void translation_unit_visitor::operator()(const cppast::cpp_entity &file) { cppast::visit(file, [&, this](const cppast::cpp_entity &e, cppast::visitor_info info) { + auto name = e.name(); if (e.kind() == cppast::cpp_entity_kind::namespace_t) { if (info.event == cppast::visitor_info::container_entity_enter) { @@ -201,11 +208,13 @@ void translation_unit_visitor::operator()(const cppast::cpp_entity &file) cx::util::full_name(ctx.get_namespace(), e), cppast::to_string(e.kind())); - auto &f = static_cast( - static_cast(e) - .function()); + auto &function_template = + static_cast(e); - process_function(f); + auto &f = static_cast( + function_template.function()); + + process_function(f, detail::is_constructor(f)); } else if (e.kind() == cppast::cpp_entity_kind::type_alias_t) { LOG_DBG("========== Visiting '{}' - {}", @@ -247,6 +256,7 @@ void translation_unit_visitor::process_class_declaration( // Process class elements for (auto &child : cls) { + auto name = child.name(); if (child.kind() == cppast::cpp_entity_kind::access_specifier_t) { auto &as = static_cast(child); last_access_specifier = as.access_specifier(); @@ -261,6 +271,14 @@ void translation_unit_visitor::process_class_declaration( find_relationships( mv.type(), relationships, relationship_t::kDependency); } + else if (child.kind() == cppast::cpp_entity_kind::constructor_t) { + auto &mc = static_cast(child); + process_function(mc, true); + } + else if (child.kind() == cppast::cpp_entity_kind::destructor_t) { + // Skip - destructor won't have any interesting candidates + // for relationships + } else if (child.kind() == cppast::cpp_entity_kind::member_function_t) { auto &mf = static_cast(child); for (const auto ¶m : mf.parameters()) @@ -319,7 +337,8 @@ void translation_unit_visitor::process_class_declaration( } } -void translation_unit_visitor::process_function(const cppast::cpp_function &f) +void translation_unit_visitor::process_function( + const cppast::cpp_function &f, bool skip_return_type) { std::vector> relationships; auto current_package = ctx.get_current_package(); @@ -331,17 +350,20 @@ void translation_unit_visitor::process_function(const cppast::cpp_function &f) find_relationships( param.type(), relationships, relationship_t::kDependency); - find_relationships( - f.return_type(), relationships, relationship_t::kDependency); + if (!skip_return_type) { + find_relationships( + f.return_type(), relationships, relationship_t::kDependency); - for (const auto &dependency : relationships) { - auto destination = common::model::namespace_{std::get<0>(dependency)}; + for (const auto &dependency : relationships) { + auto destination = + common::model::namespace_{std::get<0>(dependency)}; - if (!ctx.get_namespace().starts_with(destination) && - !destination.starts_with(ctx.get_namespace())) { - relationship r{ - relationship_t::kDependency, std::get<0>(dependency)}; - current_package.value().add_relationship(std::move(r)); + if (!ctx.get_namespace().starts_with(destination) && + !destination.starts_with(ctx.get_namespace())) { + relationship r{ + relationship_t::kDependency, std::get<0>(dependency)}; + current_package.value().add_relationship(std::move(r)); + } } } } diff --git a/src/package_diagram/visitor/translation_unit_visitor.h b/src/package_diagram/visitor/translation_unit_visitor.h index f290072c..051f6cd8 100644 --- a/src/package_diagram/visitor/translation_unit_visitor.h +++ b/src/package_diagram/visitor/translation_unit_visitor.h @@ -55,7 +55,8 @@ public: type_safe::optional_ref tspec = nullptr); - void process_function(const cppast::cpp_function &f); + void process_function( + const cppast::cpp_function &f, bool skip_return_type = false); bool find_relationships(const cppast::cpp_type &t_, std::vector> diff --git a/tests/t00008/t00008.cc b/tests/t00008/t00008.cc index 9987e03c..763162f8 100644 --- a/tests/t00008/t00008.cc +++ b/tests/t00008/t00008.cc @@ -28,6 +28,8 @@ template typename C> struct B { struct D { B ints; + template D(std::tuple * /*items*/) { } + void add(int i) { ints.template_template.values.push_back(i); } }; } diff --git a/tests/t30002/t30002.cc b/tests/t30002/t30002.cc index 690ec7c9..bd04af2f 100644 --- a/tests/t30002/t30002.cc +++ b/tests/t30002/t30002.cc @@ -65,6 +65,10 @@ struct CBA : public A::AA::A6::CF { std::shared_ptr cc_; std::map> cd_; + CBA() = default; + + template CBA(std::tuple &items) { } + void ce(const std::vector /*ce_*/) { } std::shared_ptr cg() { return {}; }