From cf908434e2d35f4afd025282f7f65676f033eb75 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Mon, 9 May 2022 23:30:22 +0200 Subject: [PATCH] Refactored class template model --- src/class_diagram/model/class.cc | 4 +- src/class_diagram/model/class.h | 8 ++-- ...lass_template.cc => template_parameter.cc} | 44 ++++++++++++------- ...{class_template.h => template_parameter.h} | 29 ++++++++---- .../visitor/translation_unit_visitor.cc | 20 ++++----- .../visitor/translation_unit_visitor.h | 8 ++-- src/cx/util.cc | 23 +++++----- src/cx/util.h | 4 +- tests/test_util.cc | 24 +++++----- 9 files changed, 96 insertions(+), 68 deletions(-) rename src/class_diagram/model/{class_template.cc => template_parameter.cc} (69%) rename src/class_diagram/model/{class_template.h => template_parameter.h} (71%) diff --git a/src/class_diagram/model/class.cc b/src/class_diagram/model/class.cc index dc2baeae..60abcb23 100644 --- a/src/class_diagram/model/class.cc +++ b/src/class_diagram/model/class.cc @@ -62,7 +62,7 @@ void class_::add_parent(class_parent &&parent) bases_.emplace_back(std::move(parent)); } -void class_::add_template(class_template tmplt) +void class_::add_template(template_parameter tmplt) { templates_.emplace_back(std::move(tmplt)); } @@ -73,7 +73,7 @@ const std::vector &class_::methods() const { return methods_; } const std::vector &class_::parents() const { return bases_; } -const std::vector &class_::templates() const +const std::vector &class_::templates() const { return templates_; } diff --git a/src/class_diagram/model/class.h b/src/class_diagram/model/class.h index e9f17ef9..c4a714b7 100644 --- a/src/class_diagram/model/class.h +++ b/src/class_diagram/model/class.h @@ -20,10 +20,10 @@ #include "class_member.h" #include "class_method.h" #include "class_parent.h" -#include "class_template.h" #include "common/model/element.h" #include "common/model/enums.h" #include "common/model/stylable_element.h" +#include "template_parameter.h" #include "type_alias.h" #include @@ -55,12 +55,12 @@ public: void add_member(class_member &&member); void add_method(class_method &&method); void add_parent(class_parent &&parent); - void add_template(class_template tmplt); + void add_template(template_parameter tmplt); const std::vector &members() const; const std::vector &methods() const; const std::vector &parents() const; - const std::vector &templates() const; + const std::vector &templates() const; void set_base_template(const std::string &full_name); std::string base_template() const; @@ -89,7 +89,7 @@ private: std::vector members_; std::vector methods_; std::vector bases_; - std::vector templates_; + std::vector templates_; std::string base_template_full_name_; std::map type_aliases_; diff --git a/src/class_diagram/model/class_template.cc b/src/class_diagram/model/template_parameter.cc similarity index 69% rename from src/class_diagram/model/class_template.cc rename to src/class_diagram/model/template_parameter.cc index a1494852..a19f549b 100644 --- a/src/class_diagram/model/class_template.cc +++ b/src/class_diagram/model/template_parameter.cc @@ -1,5 +1,5 @@ /** - * src/class_diagram/model/class_template.cc + * src/class_diagram/model/template_parameter.cc * * Copyright (c) 2021-2022 Bartek Kryza * @@ -16,14 +16,14 @@ * limitations under the License. */ -#include "class_template.h" +#include "template_parameter.h" #include #include namespace clanguml::class_diagram::model { -class_template::class_template(const std::string &type, const std::string &name, - const std::string &default_value, bool is_variadic) +template_parameter::template_parameter(const std::string &type, + const std::string &name, const std::string &default_value, bool is_variadic) : default_value_{default_value} , is_variadic_{is_variadic} { @@ -31,11 +31,11 @@ class_template::class_template(const std::string &type, const std::string &name, set_type(type); } -void class_template::set_type(const std::string &type) { type_ = type; } +void template_parameter::set_type(const std::string &type) { type_ = type; } -std::string class_template::type() const { return type_; } +std::string template_parameter::type() const { return type_; } -void class_template::set_name(const std::string &name) +void template_parameter::set_name(const std::string &name) { name_ = name; // TODO: Add a configurable mapping for simplifying non-interesting @@ -44,7 +44,7 @@ void class_template::set_name(const std::string &name) util::replace_all(name_, "std::basic_string", "std::wstring"); } -std::string class_template::name() const +std::string template_parameter::name() const { if (is_variadic_) return name_ + "..."; @@ -52,21 +52,22 @@ std::string class_template::name() const return name_; } -void class_template::set_default_value(const std::string &value) +void template_parameter::set_default_value(const std::string &value) { default_value_ = value; } -std::string class_template::default_value() const { return default_value_; } +std::string template_parameter::default_value() const { return default_value_; } -void class_template::is_variadic(bool is_variadic) noexcept +void template_parameter::is_variadic(bool is_variadic) noexcept { is_variadic_ = is_variadic; } -bool class_template::is_variadic() const noexcept { return is_variadic_; } +bool template_parameter::is_variadic() const noexcept { return is_variadic_; } -bool class_template::is_specialization_of(const class_template &ct) const +bool template_parameter::is_specialization_of( + const template_parameter &ct) const { if ((ct.is_template_parameter() || ct.is_template_template_parameter()) && !is_template_parameter()) @@ -75,7 +76,18 @@ bool class_template::is_specialization_of(const class_template &ct) const return false; } -bool operator==(const class_template &l, const class_template &r) +void template_parameter::add_template_param(template_parameter &&ct) +{ + template_params_.emplace_back(std::move(ct)); +} + +const std::vector & +template_parameter::template_params() const +{ + return template_params_; +} + +bool operator==(const template_parameter &l, const template_parameter &r) { bool res{false}; @@ -95,12 +107,12 @@ bool operator==(const class_template &l, const class_template &r) return res && (l.template_params_ == r.template_params_); } -bool operator!=(const class_template &l, const class_template &r) +bool operator!=(const template_parameter &l, const template_parameter &r) { return !(l == r); } -std::string class_template::to_string( +std::string template_parameter::to_string( const clanguml::common::model::namespace_ &using_namespace) const { using clanguml::common::model::namespace_; diff --git a/src/class_diagram/model/class_template.h b/src/class_diagram/model/template_parameter.h similarity index 71% rename from src/class_diagram/model/class_template.h rename to src/class_diagram/model/template_parameter.h index 0a014c80..a25b0a8d 100644 --- a/src/class_diagram/model/class_template.h +++ b/src/class_diagram/model/template_parameter.h @@ -1,5 +1,5 @@ /** - * src/class_diagram/model/class_template.h + * src/class_diagram/model/template_parameter.h * * Copyright (c) 2021-2022 Bartek Kryza * @@ -24,10 +24,16 @@ namespace clanguml::class_diagram::model { -class class_template { +/// @brief Represents template parameter or template parameter instantiation +/// +/// This class can represent both template parameter and template parameter +/// instantiation, including variadic parameters and instantiations with +/// nested templates +class template_parameter { public: - class_template(const std::string &type = "", const std::string &name = "", - const std::string &default_value = "", bool is_variadic = false); + template_parameter(const std::string &type = "", + const std::string &name = "", const std::string &default_value = "", + bool is_variadic = false); void set_type(const std::string &type); std::string type() const; @@ -41,10 +47,12 @@ public: void is_variadic(bool is_variadic) noexcept; bool is_variadic() const noexcept; - bool is_specialization_of(const class_template &ct) const; + bool is_specialization_of(const template_parameter &ct) const; - friend bool operator==(const class_template &l, const class_template &r); - friend bool operator!=(const class_template &l, const class_template &r); + friend bool operator==( + const template_parameter &l, const template_parameter &r); + friend bool operator!=( + const template_parameter &l, const template_parameter &r); bool is_template_parameter() const { return is_template_parameter_; } @@ -66,7 +74,9 @@ public: std::string to_string( const clanguml::common::model::namespace_ &using_namespace) const; - std::vector template_params_; + void add_template_param(template_parameter &&ct); + + const std::vector &template_params() const; private: /// Represents the type of non-type template parameters @@ -89,5 +99,8 @@ private: /// Whether the template parameter is variadic bool is_variadic_{false}; + + // Nested template parameters + std::vector template_params_; }; } diff --git a/src/class_diagram/visitor/translation_unit_visitor.cc b/src/class_diagram/visitor/translation_unit_visitor.cc index e3c00faf..061113a3 100644 --- a/src/class_diagram/visitor/translation_unit_visitor.cc +++ b/src/class_diagram/visitor/translation_unit_visitor.cc @@ -40,10 +40,10 @@ using clanguml::class_diagram::model::class_; using clanguml::class_diagram::model::class_member; using clanguml::class_diagram::model::class_method; using clanguml::class_diagram::model::class_parent; -using clanguml::class_diagram::model::class_template; using clanguml::class_diagram::model::diagram; using clanguml::class_diagram::model::enum_; using clanguml::class_diagram::model::method_parameter; +using clanguml::class_diagram::model::template_parameter; using clanguml::class_diagram::model::type_alias; using clanguml::common::model::access_t; using clanguml::common::model::relationship; @@ -1272,7 +1272,7 @@ void translation_unit_visitor:: void translation_unit_visitor::process_template_type_parameter( const cppast::cpp_template_type_parameter &t, class_ &parent) { - class_template ct; + template_parameter ct; ct.set_type(""); ct.is_template_parameter(true); ct.set_name(t.name()); @@ -1285,7 +1285,7 @@ void translation_unit_visitor::process_template_type_parameter( void translation_unit_visitor::process_template_nontype_parameter( const cppast::cpp_non_type_template_parameter &t, class_ &parent) { - class_template ct; + template_parameter ct; ct.set_type(cppast::to_string(t.type())); ct.is_template_parameter(false); ct.set_name(t.name()); @@ -1298,7 +1298,7 @@ void translation_unit_visitor::process_template_nontype_parameter( void translation_unit_visitor::process_template_template_parameter( const cppast::cpp_template_template_parameter &t, class_ &parent) { - class_template ct; + template_parameter ct; ct.set_type(""); ct.is_template_template_parameter(true); ct.set_name(t.name() + "<>"); @@ -1577,7 +1577,7 @@ bool translation_unit_visitor::find_relationships_in_array( } bool translation_unit_visitor::find_relationships_in_unexposed_template_params( - const class_template &ct, found_relationships_t &relationships) const + const template_parameter &ct, found_relationships_t &relationships) const { bool found{false}; LOG_DBG("Finding relationships in user defined type: {}", @@ -1596,7 +1596,7 @@ bool translation_unit_visitor::find_relationships_in_unexposed_template_params( found = true; } - for (const auto &nested_template_params : ct.template_params_) { + for (const auto &nested_template_params : ct.template_params()) { found = find_relationships_in_unexposed_template_params( nested_template_params, relationships) || found; @@ -1670,7 +1670,7 @@ std::unique_ptr translation_unit_visitor::build_template_instantiation( auto has_variadic_params = false; for (const auto &targ : t.arguments().value()) { - class_template ct; + template_parameter ct; if (targ.type()) { build_template_instantiation_process_type_argument(parent, tinst, targ, ct, nested_relationships, @@ -1755,7 +1755,7 @@ std::unique_ptr translation_unit_visitor::build_template_instantiation( bool translation_unit_visitor::build_template_instantiation_add_base_classes( class_ &tinst, std::deque> &template_base_params, - int arg_index, bool variadic_params, const class_template &ct) const + int arg_index, bool variadic_params, const template_parameter &ct) const { bool add_template_argument_as_base_class = false; @@ -1785,7 +1785,7 @@ bool translation_unit_visitor::build_template_instantiation_add_base_classes( void translation_unit_visitor:: build_template_instantiation_process_expression_argument( - const cppast::cpp_template_argument &targ, class_template &ct) const + const cppast::cpp_template_argument &targ, template_parameter &ct) const { const auto &exp = targ.expression().value(); if (exp.kind() == cppast::cpp_expression_kind::literal_t) @@ -1803,7 +1803,7 @@ void translation_unit_visitor:: build_template_instantiation_process_type_argument( const std::optional &parent, class_ &tinst, const cppast::cpp_template_argument &targ, - class_template &ct, found_relationships_t &nested_relationships, + template_parameter &ct, found_relationships_t &nested_relationships, common::model::relationship_t relationship_hint) { ct.set_name(cppast::to_string(targ.type().value())); diff --git a/src/class_diagram/visitor/translation_unit_visitor.h b/src/class_diagram/visitor/translation_unit_visitor.h index 56195fee..5768b8c1 100644 --- a/src/class_diagram/visitor/translation_unit_visitor.h +++ b/src/class_diagram/visitor/translation_unit_visitor.h @@ -199,7 +199,7 @@ private: common::model::relationship_t relationship_type) const; bool find_relationships_in_unexposed_template_params( - const model::class_template &ct, + const model::template_parameter &ct, found_relationships_t &relationships) const; void build_template_instantiation_primary_template( @@ -212,19 +212,19 @@ private: void build_template_instantiation_process_type_argument( const std::optional &parent, model::class_ &tinst, const cppast::cpp_template_argument &targ, - class_diagram::model::class_template &ct, + class_diagram::model::template_parameter &ct, found_relationships_t &relationships, common::model::relationship_t relationship_hint = common::model::relationship_t::kAggregation); void build_template_instantiation_process_expression_argument( const cppast::cpp_template_argument &targ, - model::class_template &ct) const; + model::template_parameter &ct) const; bool build_template_instantiation_add_base_classes(model::class_ &tinst, std::deque> &template_base_params, int arg_index, bool variadic_params, - const model::class_template &ct) const; + const model::template_parameter &ct) const; void process_function_parameter_find_relationships_in_template( model::class_ &c, const std::set &template_parameter_names, diff --git a/src/cx/util.cc b/src/cx/util.cc index 08c99d28..4de3512e 100644 --- a/src/cx/util.cc +++ b/src/cx/util.cc @@ -25,7 +25,7 @@ #include #include -#include +#include #include namespace clanguml { @@ -254,19 +254,19 @@ const cppast::cpp_type &unreferenced(const cppast::cpp_type &t) return t; } -std::vector +std::vector parse_unexposed_template_params(const std::string ¶ms, std::function ns_resolve) { - using class_diagram::model::class_template; + using class_diagram::model::template_parameter; - std::vector res; + std::vector res; int nested_template_level{0}; auto it = params.begin(); std::string type{}; - std::vector nested_params; + std::vector nested_params; bool complete_class_template{false}; while (it != params.end()) { @@ -293,7 +293,8 @@ parse_unexposed_template_params(const std::string ¶ms, nested_params = parse_unexposed_template_params(nested_params_str, ns_resolve); if (nested_params.empty()) - nested_params.emplace_back(class_template{nested_params_str}); + nested_params.emplace_back( + template_parameter{nested_params_str}); it = bracket_match_end - 1; } else if (*it == '>') { @@ -306,10 +307,11 @@ parse_unexposed_template_params(const std::string ¶ms, type += *it; } if (complete_class_template) { - class_template t; + template_parameter t; t.set_type(ns_resolve(clanguml::util::trim(type))); type = ""; - t.template_params_ = std::move(nested_params); + for (auto &¶m : nested_params) + t.add_template_param(std::move(param)); res.emplace_back(std::move(t)); complete_class_template = false; @@ -318,10 +320,11 @@ parse_unexposed_template_params(const std::string ¶ms, } if (!type.empty()) { - class_template t; + template_parameter t; t.set_type(ns_resolve(clanguml::util::trim(type))); type = ""; - t.template_params_ = std::move(nested_params); + for (auto &¶m : nested_params) + t.add_template_param(std::move(param)); res.emplace_back(std::move(t)); complete_class_template = false; diff --git a/src/cx/util.h b/src/cx/util.h index cd8e1564..6a052095 100644 --- a/src/cx/util.h +++ b/src/cx/util.h @@ -24,7 +24,7 @@ #include #include -#include +#include #include namespace clanguml { @@ -54,7 +54,7 @@ std::pair split_ns( bool is_inside_class(const cppast::cpp_entity &e); -std::vector +std::vector parse_unexposed_template_params(const std::string ¶ms, std::function ns_resolve); diff --git a/tests/test_util.cc b/tests/test_util.cc index 0901000a..01bede11 100644 --- a/tests/test_util.cc +++ b/tests/test_util.cc @@ -99,9 +99,9 @@ TEST_CASE("Test parse_unexposed_template_params", "[unit-test]") int_template_str, [](const auto &n) { return n; }); CHECK(int_template.size() == 1); - CHECK(int_template[0].template_params_.size() == 1); + CHECK(int_template[0].template_params().size() == 1); CHECK(int_template[0].type() == "ns1::ns2::class1"); - CHECK(int_template[0].template_params_[0].type() == "int"); + CHECK(int_template[0].template_params()[0].type() == "int"); const std::string int_int_template_str{"ns1::ns2::class1"}; @@ -109,10 +109,10 @@ TEST_CASE("Test parse_unexposed_template_params", "[unit-test]") int_int_template_str, [](const auto &n) { return n; }); CHECK(int_int_template.size() == 1); - CHECK(int_int_template[0].template_params_.size() == 2); + CHECK(int_int_template[0].template_params().size() == 2); CHECK(int_int_template[0].type() == "ns1::ns2::class1"); - CHECK(int_int_template[0].template_params_[0].type() == "int"); - CHECK(int_int_template[0].template_params_[1].type() == "int"); + CHECK(int_int_template[0].template_params()[0].type() == "int"); + CHECK(int_int_template[0].template_params()[1].type() == "int"); const std::string nested_template_str{ "class1>>"}; @@ -121,13 +121,13 @@ TEST_CASE("Test parse_unexposed_template_params", "[unit-test]") nested_template_str, [](const auto &n) { return n; }); CHECK(nested_template.size() == 1); - CHECK(nested_template[0].template_params_.size() == 2); + CHECK(nested_template[0].template_params().size() == 2); CHECK(nested_template[0].type() == "class1"); - CHECK(nested_template[0].template_params_[0].type() == "int"); - const auto &class2 = nested_template[0].template_params_[1]; + CHECK(nested_template[0].template_params()[0].type() == "int"); + const auto &class2 = nested_template[0].template_params()[1]; CHECK(class2.type() == "ns1::class2"); - CHECK(class2.template_params_[0].type() == "int"); - CHECK(class2.template_params_[1].type() == "std::vector"); - CHECK( - class2.template_params_[1].template_params_[0].type() == "std::string"); + CHECK(class2.template_params()[0].type() == "int"); + CHECK(class2.template_params()[1].type() == "std::vector"); + CHECK(class2.template_params()[1].template_params()[0].type() == + "std::string"); }