From fdd549594026b7ee989a8469f317b7427e03b3cf Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 5 Jun 2022 12:16:44 +0200 Subject: [PATCH] Fixed generating relationships from function template arguments --- .../visitor/translation_unit_visitor.cc | 38 ++++++++++++++----- .../visitor/translation_unit_visitor.h | 2 +- tests/t00014/t00014.cc | 7 ++-- tests/t00014/test_case.h | 6 ++- 4 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/class_diagram/visitor/translation_unit_visitor.cc b/src/class_diagram/visitor/translation_unit_visitor.cc index d2a0eb82..83ca6db7 100644 --- a/src/class_diagram/visitor/translation_unit_visitor.cc +++ b/src/class_diagram/visitor/translation_unit_visitor.cc @@ -18,6 +18,7 @@ #include "translation_unit_visitor.h" +#include "cppast/cpp_function_type.hpp" #include "cx/util.h" #include @@ -26,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -719,11 +721,12 @@ bool translation_unit_visitor::process_field_with_template_instantiation( found_relationships_t nested_relationships; if (tr_declaration == tr_unaliased_declaration) - tinst_ptr = build_template_instantiation(unaliased); + tinst_ptr = build_template_instantiation(unaliased, {&c}); else tinst_ptr = build_template_instantiation( static_cast( - type.canonical())); + type.canonical()), + {&c}); auto &tinst = *tinst_ptr; @@ -1707,7 +1710,7 @@ std::unique_ptr translation_unit_visitor::build_template_instantiation( template_parameter ct; if (targ.type()) { build_template_instantiation_process_type_argument( - parent, tinst, targ, ct); + parent, tinst, targ.type().value(), ct); } else if (targ.expression()) { build_template_instantiation_process_expression_argument( @@ -1824,15 +1827,15 @@ void translation_unit_visitor:: void translation_unit_visitor:: build_template_instantiation_process_type_argument( const std::optional &parent, - class_ &tinst, const cppast::cpp_template_argument &targ, + class_ &tinst, const cppast::cpp_type &targ_type, template_parameter &ct) { auto full_name = cx::util::full_name( - cppast::remove_cv(cx::util::unreferenced(targ.type().value())), + cppast::remove_cv(cx::util::unreferenced(targ_type)), ctx.entity_index(), false); auto [fn_ns, fn_name] = cx::util::split_ns(full_name); - auto template_argument_kind = targ.type().value().kind(); + auto template_argument_kind = targ_type.kind(); if (template_argument_kind == cppast::cpp_type_kind::unexposed_t) { // Here we're on our own - just make a best guess @@ -1858,14 +1861,14 @@ void translation_unit_visitor:: // Check if this template should be simplified (e.g. system // template aliases such as std:basic_string should be simply - // std::string + // std::string) if (simplify_system_template(ct, full_name)) { return; } const auto &nested_template_parameter = static_cast( - targ.type().value()); + targ_type); auto [tinst_ns, tinst_name] = cx::util::split_ns(tinst.full_name(false)); @@ -1924,10 +1927,27 @@ void translation_unit_visitor:: full_name, tinst.full_name(), tinst_dependency.destination()); } } + else if (template_argument_kind == cppast::cpp_type_kind::function_t) { + const auto &function_argument = + static_cast(targ_type); + + const auto &rt = function_argument.return_type(); + + // Search for relationships in argument return type + // TODO... + + // Build instantiations of each of the arguments + for (const auto &arg : function_argument.parameter_types()) { + template_parameter ctt; + + build_template_instantiation_process_type_argument( + parent, tinst, arg, ctt); + } + } else if (template_argument_kind == cppast::cpp_type_kind::user_defined_t) { relationship tinst_dependency{relationship_t::kDependency, cx::util::full_name( - cppast::remove_cv(cx::util::unreferenced(targ.type().value())), + cppast::remove_cv(cx::util::unreferenced(targ_type)), ctx.entity_index(), false)}; LOG_DBG("Creating nested template dependency to user defined " diff --git a/src/class_diagram/visitor/translation_unit_visitor.h b/src/class_diagram/visitor/translation_unit_visitor.h index 00286c19..4149b13c 100644 --- a/src/class_diagram/visitor/translation_unit_visitor.h +++ b/src/class_diagram/visitor/translation_unit_visitor.h @@ -213,7 +213,7 @@ private: void build_template_instantiation_process_type_argument( const std::optional &parent, - model::class_ &tinst, const cppast::cpp_template_argument &targ, + model::class_ &tinst, const cppast::cpp_type &targ_type, class_diagram::model::template_parameter &ct); void build_template_instantiation_process_expression_argument( diff --git a/tests/t00014/t00014.cc b/tests/t00014/t00014.cc index dca89263..e9b11839 100644 --- a/tests/t00014/t00014.cc +++ b/tests/t00014/t00014.cc @@ -39,13 +39,14 @@ template using ASharedPtr = std::shared_ptr>; template using AAPtr = std::unique_ptr, A>>; -template using GeneralCallback = std::function; -using VoidCallback = GeneralCallback<>; +template using GeneralCallback = std::function; +using VoidCallback = GeneralCallback; using BVector = std::vector; using BVector2 = BVector; using AIntString = AString; +using ACharString = AString; using AStringString = AString; using BStringString = AStringString; @@ -66,7 +67,7 @@ protected: public: BVector2 bs2; - GeneralCallback cb; + GeneralCallback cb; VoidCallback vcb; VectorPtr vps; }; diff --git a/tests/t00014/test_case.h b/tests/t00014/test_case.h index 7c24ace2..a7427ad3 100644 --- a/tests/t00014/test_case.h +++ b/tests/t00014/test_case.h @@ -45,6 +45,7 @@ TEST_CASE("t00014", "[test-case][class]") REQUIRE_THAT(puml, IsClassTemplate("A", "long,float")); REQUIRE_THAT(puml, IsClassTemplate("A", "double,float")); REQUIRE_THAT(puml, IsClassTemplate("A", "bool,std::string")); + REQUIRE_THAT(puml, IsClassTemplate("A", "char,std::string")); REQUIRE_THAT(puml, IsClass(_A("B"))); REQUIRE_THAT(puml, IsField("bapair", "PairPairBA")); @@ -59,7 +60,7 @@ TEST_CASE("t00014", "[test-case][class]") REQUIRE_THAT(puml, IsField("bs", "BVector")); - REQUIRE_THAT(puml, IsField("cb", "GeneralCallback")); + REQUIRE_THAT(puml, IsField("cb", "GeneralCallback")); REQUIRE_THAT(puml, IsField("vcb", "VoidCallback")); REQUIRE_THAT( @@ -79,6 +80,8 @@ TEST_CASE("t00014", "[test-case][class]") REQUIRE_THAT(puml, IsInstantiation(_A("A"), _A("A"))); REQUIRE_THAT(puml, IsInstantiation(_A("A"), _A("A"))); + REQUIRE_THAT(puml, + IsInstantiation(_A("A"), _A("A"))); REQUIRE_THAT(puml, IsInstantiation(_A("A>"), @@ -100,6 +103,7 @@ TEST_CASE("t00014", "[test-case][class]") REQUIRE_THAT(puml, IsAggregation(_A("R"), _A("A>"), "-floatstring")); + REQUIRE_THAT(puml, IsDependency(_A("R"), _A("A"))); save_puml( "./" + config.output_directory() + "/" + diagram->name + ".puml", puml);