From 98a118db1de7bcf92956a1e5cf7e775a091ea364 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 13 Mar 2022 12:11:55 +0100 Subject: [PATCH] Refactored unexposed template paramter parsing --- src/class_diagram/model/class.cc | 21 +------- src/class_diagram/model/class.h | 2 +- src/class_diagram/model/class_template.cc | 36 +++++++++++++ src/class_diagram/model/class_template.h | 5 ++ .../visitor/translation_unit_visitor.cc | 52 +++++++------------ src/cx/util.cc | 4 +- 6 files changed, 66 insertions(+), 54 deletions(-) diff --git a/src/class_diagram/model/class.cc b/src/class_diagram/model/class.cc index 0e05acd0..c1d068ca 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(class_template tmplt) { templates_.emplace_back(std::move(tmplt)); } @@ -141,24 +141,7 @@ std::ostringstream &class_::render_template_params( std::vector tnames; std::transform(templates_.cbegin(), templates_.cend(), std::back_inserter(tnames), [this](const auto &tmplt) { - std::vector res; - - if (!tmplt.type().empty()) - res.push_back(namespace_{tmplt.type()} - .relative_to(using_namespace()) - .to_string()); - - if (!tmplt.name().empty()) - res.push_back(namespace_{tmplt.name()} - .relative_to(using_namespace()) - .to_string()); - - if (!tmplt.default_value().empty()) { - res.push_back("="); - res.push_back(tmplt.default_value()); - } - - return fmt::format("{}", fmt::join(res, " ")); + return tmplt.to_string(using_namespace()); }); ostr << fmt::format("<{}>", fmt::join(tnames, ",")); } diff --git a/src/class_diagram/model/class.h b/src/class_diagram/model/class.h index 5d17ad84..8b66d0f4 100644 --- a/src/class_diagram/model/class.h +++ b/src/class_diagram/model/class.h @@ -53,7 +53,7 @@ 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(class_template tmplt); const std::vector &members() const; const std::vector &methods() const; diff --git a/src/class_diagram/model/class_template.cc b/src/class_diagram/model/class_template.cc index 94a95e41..589bdede 100644 --- a/src/class_diagram/model/class_template.cc +++ b/src/class_diagram/model/class_template.cc @@ -17,6 +17,8 @@ */ #include "class_template.h" +#include +#include namespace clanguml::class_diagram::model { @@ -57,4 +59,38 @@ bool operator==(const class_template &l, const class_template &r) { return (l.name() == r.name()) && (l.type() == r.type()); } + +std::string class_template::to_string( + const clanguml::common::model::namespace_ &using_namespace) const +{ + using clanguml::common::model::namespace_; + + std::string res; + if (!type().empty()) + res += namespace_{type()}.relative_to(using_namespace).to_string(); + + // Render nested template params + if (!template_params_.empty()) { + std::vector params; + for (const auto &template_param : template_params_) { + params.push_back(template_param.to_string(using_namespace)); + } + + res += fmt::format("<{}>", fmt::join(params, ",")); + } + + if (!name().empty()) { + if (!type().empty()) + res += " "; + res += namespace_{name()}.relative_to(using_namespace).to_string(); + } + + if (!default_value().empty()) { + res += "="; + res += default_value(); + } + + return res; +} + } diff --git a/src/class_diagram/model/class_template.h b/src/class_diagram/model/class_template.h index 149292d4..603443e4 100644 --- a/src/class_diagram/model/class_template.h +++ b/src/class_diagram/model/class_template.h @@ -17,6 +17,8 @@ */ #pragma once +#include "common/model/namespace.h" + #include #include @@ -43,6 +45,9 @@ public: std::vector template_params_; + std::string to_string( + const clanguml::common::model::namespace_ &using_namespace) const; + private: std::string type_; std::string name_; diff --git a/src/class_diagram/visitor/translation_unit_visitor.cc b/src/class_diagram/visitor/translation_unit_visitor.cc index e4d41c67..c0c6f5e3 100644 --- a/src/class_diagram/visitor/translation_unit_visitor.cc +++ b/src/class_diagram/visitor/translation_unit_visitor.cc @@ -490,43 +490,31 @@ void translation_unit_visitor:: { auto ua = tspec.value().unexposed_arguments().as_string(); - // Naive parse of template arguments: - auto toks = util::split(ua, ","); - for (const auto &t : toks) { - c.add_template({t}); + auto template_params = cx::util::parse_unexposed_template_params(ua); + for (const auto ¶m : template_params) { + c.add_template(param); + } - if (!tspec.value().primary_template().is_overloaded()) { - if (tspec.value() - .primary_template() - .get(ctx.entity_index()) - .size() == 0) { - LOG_WARN("Template {} has no exposed parameters", - tspec.value().name()); - - continue; - } - } - - const auto &primary_template_ref = static_cast< - const cppast::cpp_class_template &>( + const auto &primary_template_ref = + static_cast( tspec.value().primary_template().get(ctx.entity_index())[0].get()) - .class_(); + .class_(); - if (primary_template_ref.user_data()) { - auto base_template_full_name = - static_cast(primary_template_ref.user_data()); - LOG_DBG("Primary template ref set to: {}", base_template_full_name); - // Add template specialization/instantiation - // relationship - c.add_relationship( - {relationship_t::kInstantiation, base_template_full_name}); - } - else { - LOG_WARN("No user data for base template {}", - primary_template_ref.name()); - } + if (primary_template_ref.user_data()) { + auto base_template_full_name = + static_cast(primary_template_ref.user_data()); + LOG_DBG("Primary template ref set to: {}", base_template_full_name); + // Add template specialization/instantiation + // relationship + c.add_relationship( + {relationship_t::kInstantiation, base_template_full_name}); + } + else { + LOG_WARN( + "No user data for base template {}", primary_template_ref.name()); } } + void translation_unit_visitor::process_class_bases( const cppast::cpp_class &cls, class_ &c) const { diff --git a/src/cx/util.cc b/src/cx/util.cc index 1779c23a..d462dc11 100644 --- a/src/cx/util.cc +++ b/src/cx/util.cc @@ -345,7 +345,7 @@ parse_unexposed_template_params(const std::string ¶ms) else { type += *it; } - if(complete_class_template) { + if (complete_class_template) { class_template t; t.set_type(clanguml::util::trim(type)); type = ""; @@ -357,7 +357,7 @@ parse_unexposed_template_params(const std::string ¶ms) it++; } - if(!type.empty()) { + if (!type.empty()) { class_template t; t.set_type(clanguml::util::trim(type)); type = "";