Fixed t00044
This commit is contained in:
@@ -124,17 +124,7 @@ bool class_::is_abstract() const
|
|||||||
int class_::calculate_template_specialization_match(
|
int class_::calculate_template_specialization_match(
|
||||||
const class_ &other, const std::string &full_name) const
|
const class_ &other, const std::string &full_name) const
|
||||||
{
|
{
|
||||||
int res{};
|
int res{0};
|
||||||
|
|
||||||
LOG_DBG("### Comparing {} with {}", this->full_name(false),
|
|
||||||
other.full_name(false));
|
|
||||||
|
|
||||||
if (this->full_name(false) ==
|
|
||||||
"clanguml::t00044::signal_handler<Ret(Args...),A>" &&
|
|
||||||
other.full_name(false) ==
|
|
||||||
"clanguml::t00044::signal_handler<void(int),bool>") {
|
|
||||||
LOG_DBG("AAAAAAAAA");
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string left = name_and_ns();
|
const std::string left = name_and_ns();
|
||||||
// TODO: handle variadic templates
|
// TODO: handle variadic templates
|
||||||
@@ -143,27 +133,7 @@ int class_::calculate_template_specialization_match(
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate over all template arguments
|
return template_trait::calculate_template_specialization_match(
|
||||||
for (auto i = 0U; i < other.templates().size(); i++) {
|
other, full_name);
|
||||||
const auto &template_arg = templates().at(i);
|
|
||||||
const auto &other_template_arg = other.templates().at(i);
|
|
||||||
|
|
||||||
if (template_arg == other_template_arg) {
|
|
||||||
res++;
|
|
||||||
}
|
|
||||||
else if (other_template_arg.is_specialization_of(template_arg)) {
|
|
||||||
if (template_arg.is_function_template() &&
|
|
||||||
other_template_arg.is_function_template()) {
|
|
||||||
res++;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
res = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
} // namespace clanguml::class_diagram::model
|
} // namespace clanguml::class_diagram::model
|
||||||
|
|||||||
@@ -1836,7 +1836,7 @@ void translation_unit_visitor::process_template_specialization_argument(
|
|||||||
cls, return_type_name);
|
cls, return_type_name);
|
||||||
|
|
||||||
if (maybe_return_arg)
|
if (maybe_return_arg)
|
||||||
a .add_template_param(*maybe_return_arg);
|
a.add_template_param(*maybe_return_arg);
|
||||||
else {
|
else {
|
||||||
a.add_template_param(
|
a.add_template_param(
|
||||||
template_parameter::make_argument(return_type_name));
|
template_parameter::make_argument(return_type_name));
|
||||||
@@ -1844,8 +1844,9 @@ void translation_unit_visitor::process_template_specialization_argument(
|
|||||||
|
|
||||||
// Set function template argument types
|
// Set function template argument types
|
||||||
for (const auto ¶m_type : function_type->param_types()) {
|
for (const auto ¶m_type : function_type->param_types()) {
|
||||||
auto maybe_arg = get_template_argument_from_type_parameter_string(
|
auto maybe_arg =
|
||||||
cls, param_type.getAsString());
|
get_template_argument_from_type_parameter_string(
|
||||||
|
cls, param_type.getAsString());
|
||||||
|
|
||||||
if (maybe_arg) {
|
if (maybe_arg) {
|
||||||
a.add_template_param(*maybe_arg);
|
a.add_template_param(*maybe_arg);
|
||||||
@@ -1862,43 +1863,8 @@ void translation_unit_visitor::process_template_specialization_argument(
|
|||||||
param_type->getAs<clang::RecordType>();
|
param_type->getAs<clang::RecordType>();
|
||||||
if (param_record_type == nullptr)
|
if (param_record_type == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// auto *classTemplateSpecialization =
|
|
||||||
// llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(
|
|
||||||
// param_type->getAsRecordDecl());
|
|
||||||
/*
|
|
||||||
if (classTemplateSpecialization != nullptr) {
|
|
||||||
// Read arg info as needed.
|
|
||||||
auto nested_template_instantiation =
|
|
||||||
build_template_instantiation_from_class_template_specialization(
|
|
||||||
*classTemplateSpecialization, *param_record_type,
|
|
||||||
diagram().should_include(
|
|
||||||
full_template_specialization_name)
|
|
||||||
? std::make_optional(&template_instantiation)
|
|
||||||
: parent);
|
|
||||||
|
|
||||||
const auto nested_template_name =
|
|
||||||
classTemplateSpecialization->getQualifiedNameAsString();
|
|
||||||
|
|
||||||
if (nested_template_instantiation) {
|
|
||||||
if (parent.has_value())
|
|
||||||
parent.value()->add_relationship(
|
|
||||||
{relationship_t::kDependency,
|
|
||||||
nested_template_instantiation->id()});
|
|
||||||
}
|
|
||||||
|
|
||||||
auto nested_template_instantiation_full_name =
|
|
||||||
nested_template_instantiation->full_name(false);
|
|
||||||
if (diagram().should_include(
|
|
||||||
nested_template_instantiation_full_name)) {
|
|
||||||
diagram().add_class(
|
|
||||||
std::move(nested_template_instantiation));
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
argument = a;
|
argument = a;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (const auto *nested_template_type =
|
else if (const auto *nested_template_type =
|
||||||
arg.getAsType()
|
arg.getAsType()
|
||||||
|
|||||||
@@ -108,17 +108,59 @@ void template_parameter::is_variadic(bool is_variadic) noexcept
|
|||||||
|
|
||||||
bool template_parameter::is_variadic() const noexcept { return is_variadic_; }
|
bool template_parameter::is_variadic() const noexcept { return is_variadic_; }
|
||||||
|
|
||||||
bool template_parameter::is_specialization_of(
|
int template_parameter::calculate_specialization_match(
|
||||||
const template_parameter &ct) const
|
const template_parameter &ct) const
|
||||||
{
|
{
|
||||||
if(is_function_template() && ct.is_function_template()) {
|
int res{0};
|
||||||
bool res{true};
|
|
||||||
|
if (ct.type().has_value() && type().has_value() &&
|
||||||
|
!ct.is_template_parameter() && !is_template_parameter() &&
|
||||||
|
ct.type().value() != type().value())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (ct.is_function_template() && !is_function_template())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (template_params().size() > 0 && ct.template_params().size() > 0) {
|
||||||
|
// More generic template params
|
||||||
|
const auto &template_params = ct.template_params();
|
||||||
|
const auto &specialization_params = this->template_params();
|
||||||
|
auto template_index{0U};
|
||||||
|
auto arg_index{0U};
|
||||||
|
|
||||||
|
while (arg_index < specialization_params.size() &&
|
||||||
|
template_index < template_params.size()) {
|
||||||
|
auto match = specialization_params.at(arg_index)
|
||||||
|
.calculate_specialization_match(
|
||||||
|
template_params.at(template_index));
|
||||||
|
|
||||||
|
if (match == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!template_params.at(template_index).is_variadic())
|
||||||
|
template_index++;
|
||||||
|
|
||||||
|
res += match;
|
||||||
|
|
||||||
|
// Add 1 point for argument match
|
||||||
|
if (!specialization_params.at(arg_index).is_template_parameter())
|
||||||
|
res++;
|
||||||
|
|
||||||
|
arg_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg_index == specialization_params.size())
|
||||||
|
return res;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ct.is_template_parameter() ||
|
if ((ct.is_template_parameter() || ct.is_template_template_parameter()) &&
|
||||||
ct.is_template_template_parameter()) &&
|
!is_template_parameter())
|
||||||
!is_template_parameter();
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void template_parameter::add_template_param(template_parameter &&ct)
|
void template_parameter::add_template_param(template_parameter &&ct)
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ public:
|
|||||||
p.set_kind(template_parameter_kind_t::template_type);
|
p.set_kind(template_parameter_kind_t::template_type);
|
||||||
p.set_name(name);
|
p.set_name(name);
|
||||||
p.is_variadic(is_variadic);
|
p.is_variadic(is_variadic);
|
||||||
|
p.is_template_parameter(true);
|
||||||
if (default_value)
|
if (default_value)
|
||||||
p.set_default_value(default_value.value());
|
p.set_default_value(default_value.value());
|
||||||
return p;
|
return p;
|
||||||
@@ -121,7 +122,7 @@ public:
|
|||||||
void is_variadic(bool is_variadic) noexcept;
|
void is_variadic(bool is_variadic) noexcept;
|
||||||
bool is_variadic() const noexcept;
|
bool is_variadic() const noexcept;
|
||||||
|
|
||||||
bool is_specialization_of(const template_parameter &ct) const;
|
int calculate_specialization_match(const template_parameter &ct) const;
|
||||||
|
|
||||||
friend bool operator==(
|
friend bool operator==(
|
||||||
const template_parameter &l, const template_parameter &r);
|
const template_parameter &l, const template_parameter &r);
|
||||||
|
|||||||
@@ -66,12 +66,7 @@ const std::vector<template_parameter> &template_trait::templates() const
|
|||||||
int template_trait::calculate_template_specialization_match(
|
int template_trait::calculate_template_specialization_match(
|
||||||
const template_trait &other, const std::string & /*full_name*/) const
|
const template_trait &other, const std::string & /*full_name*/) const
|
||||||
{
|
{
|
||||||
int res{};
|
int res{0};
|
||||||
|
|
||||||
// TODO: handle variadic templates
|
|
||||||
if (templates().size() != other.templates().size()) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iterate over all template arguments
|
// Iterate over all template arguments
|
||||||
for (auto i = 0U; i < other.templates().size(); i++) {
|
for (auto i = 0U; i < other.templates().size(); i++) {
|
||||||
@@ -80,9 +75,17 @@ int template_trait::calculate_template_specialization_match(
|
|||||||
|
|
||||||
if (template_arg == other_template_arg) {
|
if (template_arg == other_template_arg) {
|
||||||
res++;
|
res++;
|
||||||
|
|
||||||
|
if (!template_arg.is_template_parameter())
|
||||||
|
res++;
|
||||||
|
|
||||||
|
if (!other_template_arg.is_template_parameter())
|
||||||
|
res++;
|
||||||
}
|
}
|
||||||
else if (other_template_arg.is_specialization_of(template_arg)) {
|
else if (auto match = other_template_arg.calculate_specialization_match(
|
||||||
continue;
|
template_arg);
|
||||||
|
match > 0) {
|
||||||
|
res += match;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
res = 0;
|
res = 0;
|
||||||
|
|||||||
@@ -49,6 +49,11 @@ TEST_CASE("t00044", "[test-case][class]")
|
|||||||
IsInstantiation(_A("sink<T>"),
|
IsInstantiation(_A("sink<T>"),
|
||||||
_A("sink<clanguml::t00044::signal_handler<Ret(Args...),A>>")));
|
_A("sink<clanguml::t00044::signal_handler<Ret(Args...),A>>")));
|
||||||
|
|
||||||
|
REQUIRE_THAT(puml,
|
||||||
|
IsInstantiation(
|
||||||
|
_A("sink<clanguml::t00044::signal_handler<Ret(Args...),A>>"),
|
||||||
|
_A("sink<clanguml::t00044::signal_handler<void(int),bool>>")));
|
||||||
|
|
||||||
REQUIRE_THAT(puml, IsClassTemplate("signal_handler", "T,A"));
|
REQUIRE_THAT(puml, IsClassTemplate("signal_handler", "T,A"));
|
||||||
REQUIRE_THAT(puml,
|
REQUIRE_THAT(puml,
|
||||||
IsInstantiation(_A("signal_handler<T,A>"),
|
IsInstantiation(_A("signal_handler<T,A>"),
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "catch.h"
|
#include "catch.h"
|
||||||
|
|
||||||
#include "common/model/namespace.h"
|
#include "common/model/namespace.h"
|
||||||
|
#include "common/model/template_parameter.h"
|
||||||
|
|
||||||
TEST_CASE("Test namespace_", "[unit-test]")
|
TEST_CASE("Test namespace_", "[unit-test]")
|
||||||
{
|
{
|
||||||
@@ -69,4 +70,163 @@ TEST_CASE("Test namespace_", "[unit-test]")
|
|||||||
namespace_ ns8{"aaa::bbb"};
|
namespace_ ns8{"aaa::bbb"};
|
||||||
const std::string name{"aaa::bbb::ccc<std::unique_ptr<aaa::bbb::ddd>>"};
|
const std::string name{"aaa::bbb::ccc<std::unique_ptr<aaa::bbb::ddd>>"};
|
||||||
CHECK(ns8.relative(name) == "ccc<std::unique_ptr<ddd>>");
|
CHECK(ns8.relative(name) == "ccc<std::unique_ptr<ddd>>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE(
|
||||||
|
"Test template_parameter::calculate_specialization_match", "[unit-test]")
|
||||||
|
{
|
||||||
|
using clanguml::common::model::template_parameter;
|
||||||
|
|
||||||
|
{
|
||||||
|
auto tp1 = template_parameter::make_template_type("T");
|
||||||
|
auto tp2 = template_parameter::make_argument("int");
|
||||||
|
|
||||||
|
CHECK(tp2.calculate_specialization_match(tp1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto tp1 = template_parameter::make_template_type("T");
|
||||||
|
auto tp2 = template_parameter::make_argument("vector");
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("int"));
|
||||||
|
|
||||||
|
CHECK(tp2.calculate_specialization_match(tp1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto tp1 = template_parameter::make_argument("vector");
|
||||||
|
tp1.add_template_param(template_parameter::make_template_type("T"));
|
||||||
|
|
||||||
|
auto tp2 = template_parameter::make_argument("vector");
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("int"));
|
||||||
|
|
||||||
|
CHECK(tp2.calculate_specialization_match(tp1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto tp1 = template_parameter::make_argument("vector");
|
||||||
|
tp1.add_template_param(template_parameter::make_template_type("T"));
|
||||||
|
|
||||||
|
auto tp2 = template_parameter::make_argument("string");
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("char"));
|
||||||
|
|
||||||
|
CHECK(!tp2.calculate_specialization_match(tp1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto tp1 = template_parameter::make_argument("tuple");
|
||||||
|
tp1.add_template_param(
|
||||||
|
template_parameter::make_template_type("Args", {}, true));
|
||||||
|
|
||||||
|
auto tp2 = template_parameter::make_argument("tuple");
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("char"));
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("int"));
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("double"));
|
||||||
|
|
||||||
|
CHECK(tp2.calculate_specialization_match(tp1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto tp1 = template_parameter::make_argument("tuple");
|
||||||
|
tp1.add_template_param(
|
||||||
|
template_parameter::make_template_type("Args", {}, true));
|
||||||
|
tp1.add_template_param(template_parameter::make_argument("int"));
|
||||||
|
|
||||||
|
auto tp2 = template_parameter::make_argument("tuple");
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("char"));
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("int"));
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("double"));
|
||||||
|
|
||||||
|
CHECK(!tp2.calculate_specialization_match(tp1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto tp1 = template_parameter::make_argument("tuple");
|
||||||
|
tp1.add_template_param(template_parameter::make_template_type("T1"));
|
||||||
|
tp1.add_template_param(template_parameter::make_template_type("T2"));
|
||||||
|
|
||||||
|
auto tp2 = template_parameter::make_argument("tuple");
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("char"));
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("int"));
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("double"));
|
||||||
|
|
||||||
|
CHECK(!tp2.calculate_specialization_match(tp1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto tp1 = template_parameter::make_template_type({});
|
||||||
|
tp1.set_function_template(true);
|
||||||
|
tp1.add_template_param(template_parameter::make_template_type("Ret"));
|
||||||
|
tp1.add_template_param(template_parameter::make_template_type("Arg1"));
|
||||||
|
tp1.add_template_param(template_parameter::make_template_type("Arg2"));
|
||||||
|
|
||||||
|
auto tp2 = template_parameter::make_argument({});
|
||||||
|
tp2.set_function_template(true);
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("char"));
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("int"));
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("double"));
|
||||||
|
|
||||||
|
CHECK(tp2.calculate_specialization_match(tp1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto tp1 = template_parameter::make_template_type({});
|
||||||
|
tp1.set_function_template(true);
|
||||||
|
tp1.add_template_param(template_parameter::make_template_type("Ret"));
|
||||||
|
tp1.add_template_param(template_parameter::make_template_type("Arg1"));
|
||||||
|
tp1.add_template_param(template_parameter::make_template_type("Arg2"));
|
||||||
|
|
||||||
|
auto tp2 = template_parameter::make_argument({});
|
||||||
|
tp2.set_function_template(false);
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("char"));
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("int"));
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("double"));
|
||||||
|
|
||||||
|
CHECK(!tp2.calculate_specialization_match(tp1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto tp1 = template_parameter::make_template_type({});
|
||||||
|
tp1.set_function_template(true);
|
||||||
|
tp1.add_template_param(template_parameter::make_template_type("Ret"));
|
||||||
|
tp1.add_template_param(
|
||||||
|
template_parameter::make_template_type("Args", {}, true));
|
||||||
|
|
||||||
|
auto tp2 = template_parameter::make_argument({});
|
||||||
|
tp2.set_function_template(true);
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("char"));
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("int"));
|
||||||
|
tp2.add_template_param(template_parameter::make_argument("double"));
|
||||||
|
|
||||||
|
CHECK(tp2.calculate_specialization_match(tp1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto sink_t = template_parameter::make_argument("sink");
|
||||||
|
auto sh1 =
|
||||||
|
template_parameter::make_argument("ns1::ns2::signal_handler");
|
||||||
|
auto sh1_t1 = template_parameter::make_template_type({});
|
||||||
|
sh1_t1.set_function_template(true);
|
||||||
|
sh1_t1.add_template_param(
|
||||||
|
template_parameter::make_template_type("Ret"));
|
||||||
|
sh1_t1.add_template_param(
|
||||||
|
template_parameter::make_template_type("Args", {}, true));
|
||||||
|
auto sh1_t2 = template_parameter::make_template_type("A");
|
||||||
|
sh1.add_template_param(sh1_t1);
|
||||||
|
sh1.add_template_param(sh1_t2);
|
||||||
|
sink_t.add_template_param(sh1);
|
||||||
|
|
||||||
|
auto sink_s = template_parameter::make_argument("sink");
|
||||||
|
auto sh2 =
|
||||||
|
template_parameter::make_argument("ns1::ns2::signal_handler");
|
||||||
|
auto sh2_a1 = template_parameter::make_argument({});
|
||||||
|
sh2_a1.set_function_template(true);
|
||||||
|
sh2_a1.add_template_param(template_parameter::make_argument("void"));
|
||||||
|
sh2_a1.add_template_param(template_parameter::make_argument("int"));
|
||||||
|
auto sh2_a2 = template_parameter::make_argument("bool");
|
||||||
|
sh2.add_template_param(sh2_a1);
|
||||||
|
sh2.add_template_param(sh2_a2);
|
||||||
|
sink_s.add_template_param(sh2);
|
||||||
|
|
||||||
|
CHECK(sink_s.calculate_specialization_match(sink_t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user