Refactored unexposed template paramter parsing

This commit is contained in:
Bartek Kryza
2022-03-13 12:11:55 +01:00
parent 8ad4c4f5dc
commit 98a118db1d
6 changed files with 66 additions and 54 deletions

View File

@@ -62,7 +62,7 @@ void class_::add_parent(class_parent &&parent)
bases_.emplace_back(std::move(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)); templates_.emplace_back(std::move(tmplt));
} }
@@ -141,24 +141,7 @@ std::ostringstream &class_::render_template_params(
std::vector<std::string> tnames; std::vector<std::string> tnames;
std::transform(templates_.cbegin(), templates_.cend(), std::transform(templates_.cbegin(), templates_.cend(),
std::back_inserter(tnames), [this](const auto &tmplt) { std::back_inserter(tnames), [this](const auto &tmplt) {
std::vector<std::string> res; return tmplt.to_string(using_namespace());
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, " "));
}); });
ostr << fmt::format("<{}>", fmt::join(tnames, ",")); ostr << fmt::format("<{}>", fmt::join(tnames, ","));
} }

View File

@@ -53,7 +53,7 @@ public:
void add_member(class_member &&member); void add_member(class_member &&member);
void add_method(class_method &&method); void add_method(class_method &&method);
void add_parent(class_parent &&parent); void add_parent(class_parent &&parent);
void add_template(class_template &&tmplt); void add_template(class_template tmplt);
const std::vector<class_member> &members() const; const std::vector<class_member> &members() const;
const std::vector<class_method> &methods() const; const std::vector<class_method> &methods() const;

View File

@@ -17,6 +17,8 @@
*/ */
#include "class_template.h" #include "class_template.h"
#include <common/model/namespace.h>
#include <fmt/format.h>
namespace clanguml::class_diagram::model { 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()); 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<std::string> 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;
}
} }

View File

@@ -17,6 +17,8 @@
*/ */
#pragma once #pragma once
#include "common/model/namespace.h"
#include <string> #include <string>
#include <vector> #include <vector>
@@ -43,6 +45,9 @@ public:
std::vector<class_template> template_params_; std::vector<class_template> template_params_;
std::string to_string(
const clanguml::common::model::namespace_ &using_namespace) const;
private: private:
std::string type_; std::string type_;
std::string name_; std::string name_;

View File

@@ -490,43 +490,31 @@ void translation_unit_visitor::
{ {
auto ua = tspec.value().unexposed_arguments().as_string(); auto ua = tspec.value().unexposed_arguments().as_string();
// Naive parse of template arguments: auto template_params = cx::util::parse_unexposed_template_params(ua);
auto toks = util::split(ua, ","); for (const auto &param : template_params) {
for (const auto &t : toks) { c.add_template(param);
c.add_template({t}); }
if (!tspec.value().primary_template().is_overloaded()) { const auto &primary_template_ref =
if (tspec.value() static_cast<const cppast::cpp_class_template &>(
.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 &>(
tspec.value().primary_template().get(ctx.entity_index())[0].get()) tspec.value().primary_template().get(ctx.entity_index())[0].get())
.class_(); .class_();
if (primary_template_ref.user_data()) { if (primary_template_ref.user_data()) {
auto base_template_full_name = auto base_template_full_name =
static_cast<const char *>(primary_template_ref.user_data()); static_cast<const char *>(primary_template_ref.user_data());
LOG_DBG("Primary template ref set to: {}", base_template_full_name); LOG_DBG("Primary template ref set to: {}", base_template_full_name);
// Add template specialization/instantiation // Add template specialization/instantiation
// relationship // relationship
c.add_relationship( c.add_relationship(
{relationship_t::kInstantiation, base_template_full_name}); {relationship_t::kInstantiation, base_template_full_name});
} }
else { else {
LOG_WARN("No user data for base template {}", LOG_WARN(
primary_template_ref.name()); "No user data for base template {}", primary_template_ref.name());
}
} }
} }
void translation_unit_visitor::process_class_bases( void translation_unit_visitor::process_class_bases(
const cppast::cpp_class &cls, class_ &c) const const cppast::cpp_class &cls, class_ &c) const
{ {

View File

@@ -345,7 +345,7 @@ parse_unexposed_template_params(const std::string &params)
else { else {
type += *it; type += *it;
} }
if(complete_class_template) { if (complete_class_template) {
class_template t; class_template t;
t.set_type(clanguml::util::trim(type)); t.set_type(clanguml::util::trim(type));
type = ""; type = "";
@@ -357,7 +357,7 @@ parse_unexposed_template_params(const std::string &params)
it++; it++;
} }
if(!type.empty()) { if (!type.empty()) {
class_template t; class_template t;
t.set_type(clanguml::util::trim(type)); t.set_type(clanguml::util::trim(type));
type = ""; type = "";