From 25adff0080f62d2e9c5f59e2ac4951b1278f01d4 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Mon, 15 Jan 2024 23:00:13 +0100 Subject: [PATCH] Extended sequence diagram config type alias test case (#227) --- .../visitor/translation_unit_visitor.cc | 30 +++++++++++-------- .../visitor/translation_unit_visitor.h | 10 +++++++ tests/t20012/test_case.h | 15 ++++++---- tests/t20039/.clang-uml | 2 ++ tests/t20039/t20039.cc | 4 +++ tests/t20039/test_case.h | 4 +++ 6 files changed, 47 insertions(+), 18 deletions(-) diff --git a/src/sequence_diagram/visitor/translation_unit_visitor.cc b/src/sequence_diagram/visitor/translation_unit_visitor.cc index 13b0f268..dffaa1f4 100644 --- a/src/sequence_diagram/visitor/translation_unit_visitor.cc +++ b/src/sequence_diagram/visitor/translation_unit_visitor.cc @@ -30,6 +30,10 @@ translation_unit_visitor::translation_unit_visitor(clang::SourceManager &sm, : common::visitor::translation_unit_visitor{sm, config} , diagram_{diagram} , config_{config} + , template_builder_{diagram_, config_, *this, + [uns = config_.using_namespace()](const clang::NamedDecl * /*decl*/) { + return std::make_unique(uns); + }} { } @@ -371,6 +375,7 @@ bool translation_unit_visitor::VisitFunctionTemplateDecl( process_comment(*declaration, *function_template_model); set_source_location(*declaration, *function_template_model); + set_owning_module(*declaration, *function_template_model); function_template_model->is_void( declaration->getAsFunction()->getReturnType()->isVoidType()); @@ -1882,6 +1887,9 @@ translation_unit_visitor::process_template_specialization( clang::ClassTemplateSpecializationDecl *cls) { auto c_ptr{std::make_unique(config_.using_namespace())}; + + tbuilder().build_from_class_template_specialization(*c_ptr, *cls); + auto &template_instantiation = *c_ptr; // TODO: refactor to method get_qualified_name() @@ -1898,17 +1906,11 @@ translation_unit_visitor::process_template_specialization( process_comment(*cls, template_instantiation); set_source_location(*cls, template_instantiation); + set_owning_module(*cls, template_instantiation); if (template_instantiation.skip()) return {}; - const auto template_args_count = cls->getTemplateArgs().size(); - for (auto arg_it = 0U; arg_it < template_args_count; arg_it++) { - const auto arg = cls->getTemplateArgs().get(arg_it); - process_template_specialization_argument( - cls, template_instantiation, arg, arg_it); - } - template_instantiation.set_id( common::to_id(template_instantiation.full_name(false))); @@ -2435,15 +2437,16 @@ translation_unit_visitor::create_method_model(clang::CXXMethodDecl *declaration) LOG_DBG("Getting method's class with local id {}", parent_decl->getID()); - if (!get_participant(parent_decl)) { + const auto maybe_method_class = get_participant(parent_decl); + + if (!maybe_method_class) { LOG_DBG("Cannot find parent class_ for method {} in class {}", declaration->getQualifiedNameAsString(), declaration->getParent()->getQualifiedNameAsString()); return {}; } - const auto &method_class = - get_participant(parent_decl).value(); + const auto &method_class = maybe_method_class.value(); method_model_ptr->is_void(declaration->getReturnType()->isVoidType()); @@ -2459,9 +2462,12 @@ translation_unit_visitor::create_method_model(clang::CXXMethodDecl *declaration) declaration->getReturnType(), declaration->getASTContext())); for (const auto *param : declaration->parameters()) { + auto parameter_type = + common::to_string(param->getType(), param->getASTContext()); + common::ensure_lambda_type_is_relative(config(), parameter_type); + parameter_type = simplify_system_template(parameter_type); method_model_ptr->add_parameter(config().using_namespace().relative( - simplify_system_template(common::to_string( - param->getType(), declaration->getASTContext(), false)))); + simplify_system_template(parameter_type))); } return method_model_ptr; diff --git a/src/sequence_diagram/visitor/translation_unit_visitor.h b/src/sequence_diagram/visitor/translation_unit_visitor.h index d1190096..109cf779 100644 --- a/src/sequence_diagram/visitor/translation_unit_visitor.h +++ b/src/sequence_diagram/visitor/translation_unit_visitor.h @@ -18,6 +18,7 @@ #pragma once #include "call_expression_context.h" +#include "common/visitor/template_builder.h" #include "common/visitor/translation_unit_visitor.h" #include "config/config.h" #include "sequence_diagram/model/diagram.h" @@ -510,6 +511,13 @@ private: const clang::SourceManager &sm, const clang::ASTContext &context, int64_t caller_id, const clang::Stmt *stmt); + /** + * @brief Get template builder reference + * + * @return Reference to 'template_builder' instance + */ + common::visitor::template_builder &tbuilder() { return template_builder_; } + // Reference to the output diagram model clanguml::sequence_diagram::model::diagram &diagram_; @@ -549,5 +557,7 @@ private: mutable std::set> processed_comments_; + + common::visitor::template_builder template_builder_; }; } // namespace clanguml::sequence_diagram::visitor diff --git a/tests/t20012/test_case.h b/tests/t20012/test_case.h index 12100f25..ddebb1d5 100644 --- a/tests/t20012/test_case.h +++ b/tests/t20012/test_case.h @@ -59,9 +59,12 @@ TEST_CASE("t20012", "[test-case][sequence]") REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "ccc()")); REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("R"), "r()")); + HasCall(_A("tmain()"), _A("R<(lambda at t20012.cc:86:9)>"), + "R((lambda at t20012.cc:86:9) &&)")); REQUIRE_THAT(src, - HasCall(_A("R"), + HasCall(_A("tmain()"), _A("R<(lambda at t20012.cc:86:9)>"), "r()")); + REQUIRE_THAT(src, + HasCall(_A("R<(lambda at t20012.cc:86:9)>"), _A("tmain()::(lambda t20012.cc:86:9)"), "operator()()")); REQUIRE_THAT(src, HasCall(_A("tmain()::(lambda t20012.cc:86:9)"), _A("C"), "c()")); @@ -88,8 +91,8 @@ TEST_CASE("t20012", "[test-case][sequence]") FindMessage(j, "C", "C", "cc()"), FindMessage(j, "C", "C", "ccc()"), FindMessage(j, "tmain()::(lambda t20012.cc:80:20)", "tmain()::(lambda t20012.cc:67:20)", "operator()()"), - FindMessage(j, "tmain()", "R", "r()"), - FindMessage(j, "R", + FindMessage(j, "tmain()", "R<(lambda at t20012.cc:86:9)>", "r()"), + FindMessage(j, "R<(lambda at t20012.cc:86:9)>", "tmain()::(lambda t20012.cc:86:9)", "operator()()"), FindMessage(j, "tmain()::(lambda t20012.cc:86:9)", "C", "c()"), // @todo #168 @@ -131,9 +134,9 @@ TEST_CASE("t20012", "[test-case][sequence]") REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "ccc()")); REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("R"), "r()")); + HasCall(_A("tmain()"), _A("R<(lambda at t20012.cc:86:9)>"), "r()")); REQUIRE_THAT(src, - HasCall(_A("R"), + HasCall(_A("R<(lambda at t20012.cc:86:9)>"), _A("tmain()::(lambda t20012.cc:86:9)"), "operator()()")); REQUIRE_THAT(src, HasCall(_A("tmain()::(lambda t20012.cc:86:9)"), _A("C"), "c()")); diff --git a/tests/t20039/.clang-uml b/tests/t20039/.clang-uml index ff038945..f73b133e 100644 --- a/tests/t20039/.clang-uml +++ b/tests/t20039/.clang-uml @@ -9,6 +9,8 @@ diagrams: using_namespace: clanguml::t20039 type_aliases: "std::vector": int_vec_t + "std::vector": string_vec_t "std::map": int_map_t + "std::map": string_map_t from: - function: "clanguml::t20039::tmain()" \ No newline at end of file diff --git a/tests/t20039/t20039.cc b/tests/t20039/t20039.cc index 62804d36..a8a53579 100644 --- a/tests/t20039/t20039.cc +++ b/tests/t20039/t20039.cc @@ -12,13 +12,17 @@ template struct A { struct R { A a_int; A> a_intvec; + A> a_stringvec; A> a_intmap; + A> a_stringmap; void run() { a_int.a({}); a_intvec.a({}); + a_stringvec.a({}); a_intmap.a({}); + a_stringmap.a({}); } }; diff --git a/tests/t20039/test_case.h b/tests/t20039/test_case.h index 5c41852d..b6f1d976 100644 --- a/tests/t20039/test_case.h +++ b/tests/t20039/test_case.h @@ -39,7 +39,11 @@ TEST_CASE("t20039", "[test-case][sequence]") REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("R"), "run()")); REQUIRE_THAT(src, HasCall(_A("R"), _A("A"), "a(int)")); REQUIRE_THAT(src, HasCall(_A("R"), _A("A"), "a(int_vec_t)")); + REQUIRE_THAT( + src, HasCall(_A("R"), _A("A"), "a(string_vec_t)")); REQUIRE_THAT(src, HasCall(_A("R"), _A("A"), "a(int_map_t)")); + REQUIRE_THAT( + src, HasCall(_A("R"), _A("A"), "a(string_map_t)")); save_puml(config.output_directory(), diagram->name + ".puml", src); }