Refactored class template model

This commit is contained in:
Bartek Kryza
2022-05-09 23:30:22 +02:00
parent 641469d1bd
commit cf908434e2
9 changed files with 96 additions and 68 deletions

View File

@@ -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_method> &class_::methods() const { return methods_; }
const std::vector<class_parent> &class_::parents() const { return bases_; }
const std::vector<class_template> &class_::templates() const
const std::vector<template_parameter> &class_::templates() const
{
return templates_;
}

View File

@@ -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 <type_safe/reference.hpp>
@@ -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<class_member> &members() const;
const std::vector<class_method> &methods() const;
const std::vector<class_parent> &parents() const;
const std::vector<class_template> &templates() const;
const std::vector<template_parameter> &templates() const;
void set_base_template(const std::string &full_name);
std::string base_template() const;
@@ -89,7 +89,7 @@ private:
std::vector<class_member> members_;
std::vector<class_method> methods_;
std::vector<class_parent> bases_;
std::vector<class_template> templates_;
std::vector<template_parameter> templates_;
std::string base_template_full_name_;
std::map<std::string, type_alias> type_aliases_;

View File

@@ -1,5 +1,5 @@
/**
* src/class_diagram/model/class_template.cc
* src/class_diagram/model/template_parameter.cc
*
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
*
@@ -16,14 +16,14 @@
* limitations under the License.
*/
#include "class_template.h"
#include "template_parameter.h"
#include <common/model/namespace.h>
#include <fmt/format.h>
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<wchar_t>", "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_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_;

View File

@@ -1,5 +1,5 @@
/**
* src/class_diagram/model/class_template.h
* src/class_diagram/model/template_parameter.h
*
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
*
@@ -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<class_template> template_params_;
void add_template_param(template_parameter &&ct);
const std::vector<template_parameter> &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_parameter> template_params_;
};
}

View File

@@ -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<class_> 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<class_> translation_unit_visitor::build_template_instantiation(
bool translation_unit_visitor::build_template_instantiation_add_base_classes(
class_ &tinst,
std::deque<std::tuple<std::string, int, bool>> &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<clanguml::class_diagram::model::class_ *> &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()));

View File

@@ -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<clanguml::class_diagram::model::class_ *> &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<std::tuple<std::string, int, bool>> &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<std::string> &template_parameter_names,

View File

@@ -25,7 +25,7 @@
#include <cppast/cpp_template.hpp>
#include <spdlog/spdlog.h>
#include <class_diagram/model/class_template.h>
#include <class_diagram/model/template_parameter.h>
#include <list>
namespace clanguml {
@@ -254,19 +254,19 @@ const cppast::cpp_type &unreferenced(const cppast::cpp_type &t)
return t;
}
std::vector<class_diagram::model::class_template>
std::vector<class_diagram::model::template_parameter>
parse_unexposed_template_params(const std::string &params,
std::function<std::string(const std::string &)> ns_resolve)
{
using class_diagram::model::class_template;
using class_diagram::model::template_parameter;
std::vector<class_template> res;
std::vector<template_parameter> res;
int nested_template_level{0};
auto it = params.begin();
std::string type{};
std::vector<class_template> nested_params;
std::vector<template_parameter> nested_params;
bool complete_class_template{false};
while (it != params.end()) {
@@ -293,7 +293,8 @@ parse_unexposed_template_params(const std::string &params,
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 &params,
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 &&param : 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 &params,
}
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 &&param : nested_params)
t.add_template_param(std::move(param));
res.emplace_back(std::move(t));
complete_class_template = false;

View File

@@ -24,7 +24,7 @@
#include <cppast/cpp_entity.hpp>
#include <cppast/cpp_type.hpp>
#include <class_diagram/model/class_template.h>
#include <class_diagram/model/template_parameter.h>
#include <string>
namespace clanguml {
@@ -54,7 +54,7 @@ std::pair<common::model::namespace_, std::string> split_ns(
bool is_inside_class(const cppast::cpp_entity &e);
std::vector<class_diagram::model::class_template>
std::vector<class_diagram::model::template_parameter>
parse_unexposed_template_params(const std::string &params,
std::function<std::string(const std::string &)> ns_resolve);

View File

@@ -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<int, int>"};
@@ -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<int, ns1::class2<int, std::vector<std::string>>>"};
@@ -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");
}