Fixed template instantiations generation without known primary template
This commit is contained in:
@@ -13,11 +13,16 @@ diagrams:
|
|||||||
include:
|
include:
|
||||||
namespaces:
|
namespaces:
|
||||||
- clanguml::t00014
|
- clanguml::t00014
|
||||||
|
exclude:
|
||||||
|
namespaces:
|
||||||
|
- std
|
||||||
|
- clanguml::t00014::std
|
||||||
|
|
||||||
```
|
```
|
||||||
## Source code
|
## Source code
|
||||||
```cpp
|
```cpp
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
#include <ios>
|
#include <ios>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
@@ -46,6 +51,9 @@ template <typename T, typename P> struct A {
|
|||||||
|
|
||||||
template <typename T> using AString = A<T, std::string>;
|
template <typename T> using AString = A<T, std::string>;
|
||||||
|
|
||||||
|
template <typename... T> using GeneralCallback = std::function<void(T..., int)>;
|
||||||
|
using VoidCallback = GeneralCallback<>;
|
||||||
|
|
||||||
struct B {
|
struct B {
|
||||||
std::string value;
|
std::string value;
|
||||||
};
|
};
|
||||||
@@ -65,6 +73,8 @@ class R {
|
|||||||
AStringString stringstring;
|
AStringString stringstring;
|
||||||
BVector bs;
|
BVector bs;
|
||||||
BVector2 bs2;
|
BVector2 bs2;
|
||||||
|
GeneralCallback<AIntString> cb;
|
||||||
|
VoidCallback vcb;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 31 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@@ -111,8 +111,10 @@ struct diagram {
|
|||||||
auto name = clanguml::util::unqualify(name_);
|
auto name = clanguml::util::unqualify(name_);
|
||||||
|
|
||||||
for (const auto &ex : exclude.namespaces) {
|
for (const auto &ex : exclude.namespaces) {
|
||||||
if (name.find(ex) == 0)
|
if (name.find(ex) == 0) {
|
||||||
|
spdlog::debug("Skipping from diagram: {}", name);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no inclusive namespaces are provided,
|
// If no inclusive namespaces are provided,
|
||||||
|
|||||||
@@ -341,16 +341,24 @@ public:
|
|||||||
|
|
||||||
if (m_config.should_include_entities("classes")) {
|
if (m_config.should_include_entities("classes")) {
|
||||||
for (const auto &c : m_model.classes) {
|
for (const auto &c : m_model.classes) {
|
||||||
|
if (!c.is_template_instantiation &&
|
||||||
|
!m_config.should_include(c.name))
|
||||||
|
continue;
|
||||||
generate_alias(c, ostr);
|
generate_alias(c, ostr);
|
||||||
ostr << std::endl;
|
ostr << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &e : m_model.enums) {
|
for (const auto &e : m_model.enums) {
|
||||||
|
if (!m_config.should_include(e.name))
|
||||||
|
continue;
|
||||||
generate_alias(e, ostr);
|
generate_alias(e, ostr);
|
||||||
ostr << std::endl;
|
ostr << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &c : m_model.classes) {
|
for (const auto &c : m_model.classes) {
|
||||||
|
if (!c.is_template_instantiation &&
|
||||||
|
!m_config.should_include(c.name))
|
||||||
|
continue;
|
||||||
generate(c, ostr);
|
generate(c, ostr);
|
||||||
ostr << std::endl;
|
ostr << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1048,31 +1048,40 @@ void tu_visitor::find_relationships(const cppast::cpp_type &t_,
|
|||||||
class_ tu_visitor::build_template_instantiation(
|
class_ tu_visitor::build_template_instantiation(
|
||||||
const cppast::cpp_template_instantiation_type &t)
|
const cppast::cpp_template_instantiation_type &t)
|
||||||
{
|
{
|
||||||
const auto &primary_template_ref =
|
|
||||||
static_cast<const cppast::cpp_class_template &>(
|
|
||||||
t.primary_template().get(ctx.entity_index)[0].get())
|
|
||||||
.class_();
|
|
||||||
|
|
||||||
auto full_template_name =
|
|
||||||
cx::util::full_name(ctx.namespace_, primary_template_ref);
|
|
||||||
|
|
||||||
LOG_DBG("Found template instantiation: {} ({}) ..|> {}, {}",
|
|
||||||
cppast::to_string(t), cppast::to_string(t.canonical()),
|
|
||||||
t.primary_template().name(), full_template_name);
|
|
||||||
|
|
||||||
class_ tinst;
|
class_ tinst;
|
||||||
|
std::string full_template_name;
|
||||||
|
|
||||||
if (full_template_name.back() == ':')
|
if (t.primary_template().get(ctx.entity_index).size()) {
|
||||||
tinst.name = full_template_name + tinst.name;
|
const auto &primary_template_ref =
|
||||||
|
static_cast<const cppast::cpp_class_template &>(
|
||||||
|
t.primary_template().get(ctx.entity_index)[0].get())
|
||||||
|
.class_();
|
||||||
|
|
||||||
if (primary_template_ref.user_data()) {
|
full_template_name =
|
||||||
tinst.base_template_usr =
|
cx::util::full_name(ctx.namespace_, primary_template_ref);
|
||||||
static_cast<const char *>(primary_template_ref.user_data());
|
|
||||||
LOG_DBG("Primary template ref set to: {}", tinst.base_template_usr);
|
LOG_DBG("Found template instantiation: {} ({}) ..|> {}, {}",
|
||||||
|
cppast::to_string(t), cppast::to_string(t.canonical()),
|
||||||
|
t.primary_template().name(), full_template_name);
|
||||||
|
|
||||||
|
if (full_template_name.back() == ':')
|
||||||
|
tinst.name = full_template_name + tinst.name;
|
||||||
|
|
||||||
|
if (primary_template_ref.user_data()) {
|
||||||
|
tinst.base_template_usr =
|
||||||
|
static_cast<const char *>(primary_template_ref.user_data());
|
||||||
|
LOG_DBG("Primary template ref set to: {}", tinst.base_template_usr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LOG_WARN("No user data for base template {}",
|
||||||
|
primary_template_ref.name());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG_WARN("Template instantiation {} has no primary template",
|
||||||
|
cppast::to_string(t));
|
||||||
|
|
||||||
|
full_template_name = cppast::to_string(t);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
LOG_WARN(
|
|
||||||
"No user data for base template {}", primary_template_ref.name());
|
|
||||||
|
|
||||||
// Extract namespace from base template name
|
// Extract namespace from base template name
|
||||||
auto ns_toks = clanguml::util::split(
|
auto ns_toks = clanguml::util::split(
|
||||||
|
|||||||
@@ -10,3 +10,7 @@ diagrams:
|
|||||||
include:
|
include:
|
||||||
namespaces:
|
namespaces:
|
||||||
- clanguml::t00014
|
- clanguml::t00014
|
||||||
|
exclude:
|
||||||
|
namespaces:
|
||||||
|
- std
|
||||||
|
- clanguml::t00014::std
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
#include <ios>
|
#include <ios>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
@@ -27,6 +28,9 @@ template <typename T, typename P> struct A {
|
|||||||
|
|
||||||
template <typename T> using AString = A<T, std::string>;
|
template <typename T> using AString = A<T, std::string>;
|
||||||
|
|
||||||
|
template <typename... T> using GeneralCallback = std::function<void(T..., int)>;
|
||||||
|
using VoidCallback = GeneralCallback<>;
|
||||||
|
|
||||||
struct B {
|
struct B {
|
||||||
std::string value;
|
std::string value;
|
||||||
};
|
};
|
||||||
@@ -46,6 +50,8 @@ class R {
|
|||||||
AStringString stringstring;
|
AStringString stringstring;
|
||||||
BVector bs;
|
BVector bs;
|
||||||
BVector2 bs2;
|
BVector2 bs2;
|
||||||
|
GeneralCallback<AIntString> cb;
|
||||||
|
VoidCallback vcb;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* tests/t00014/test_case.cc
|
* tests/t00014/test_case.h
|
||||||
*
|
*
|
||||||
* Copyright (c) 2021 Bartek Kryza <bkryza@gmail.com>
|
* Copyright (c) 2021 Bartek Kryza <bkryza@gmail.com>
|
||||||
*
|
*
|
||||||
@@ -27,7 +27,7 @@ TEST_CASE("t00014", "[test-case][class]")
|
|||||||
REQUIRE_THAT(diagram->include.namespaces,
|
REQUIRE_THAT(diagram->include.namespaces,
|
||||||
VectorContains(std::string{"clanguml::t00014"}));
|
VectorContains(std::string{"clanguml::t00014"}));
|
||||||
|
|
||||||
REQUIRE(diagram->exclude.namespaces.size() == 0);
|
REQUIRE(diagram->exclude.namespaces.size() == 2);
|
||||||
|
|
||||||
REQUIRE(diagram->should_include("clanguml::t00014::S"));
|
REQUIRE(diagram->should_include("clanguml::t00014::S"));
|
||||||
|
|
||||||
@@ -46,9 +46,6 @@ TEST_CASE("t00014", "[test-case][class]")
|
|||||||
REQUIRE_THAT(puml, IsClassTemplate("AString", "float"));
|
REQUIRE_THAT(puml, IsClassTemplate("AString", "float"));
|
||||||
|
|
||||||
REQUIRE_THAT(puml, IsInstantiation(_A("A<T,P>"), _A("A<T,std::string>")));
|
REQUIRE_THAT(puml, IsInstantiation(_A("A<T,P>"), _A("A<T,std::string>")));
|
||||||
// TODO
|
|
||||||
// REQUIRE_THAT(puml, IsInstantiation(_A("A<T,std::string>"),
|
|
||||||
// _A("A<bool,std::string>")));
|
|
||||||
REQUIRE_THAT(
|
REQUIRE_THAT(
|
||||||
puml, IsInstantiation(_A("A<T,std::string>"), _A("AString<float>")));
|
puml, IsInstantiation(_A("A<T,std::string>"), _A("AString<float>")));
|
||||||
REQUIRE_THAT(
|
REQUIRE_THAT(
|
||||||
|
|||||||
Reference in New Issue
Block a user