Fixed handling of template constructor in package diagrams

This commit is contained in:
Bartek Kryza
2022-04-15 18:58:36 +02:00
parent 153dd55aaa
commit c0678bc74c
4 changed files with 44 additions and 15 deletions

View File

@@ -65,6 +65,12 @@ access_t cpp_access_specifier_to_access(
return access;
}
bool is_constructor(const cppast::cpp_entity &e)
{
return dynamic_cast<const cppast::cpp_constructor *>(
dynamic_cast<const cppast::cpp_function_base *>(&e)) != nullptr;
}
}
translation_unit_visitor::translation_unit_visitor(
@@ -79,6 +85,7 @@ void translation_unit_visitor::operator()(const cppast::cpp_entity &file)
{
cppast::visit(file,
[&, this](const cppast::cpp_entity &e, cppast::visitor_info info) {
auto name = e.name();
if (e.kind() == cppast::cpp_entity_kind::namespace_t) {
if (info.event ==
cppast::visitor_info::container_entity_enter) {
@@ -201,11 +208,13 @@ void translation_unit_visitor::operator()(const cppast::cpp_entity &file)
cx::util::full_name(ctx.get_namespace(), e),
cppast::to_string(e.kind()));
auto &f = static_cast<const cppast::cpp_function &>(
static_cast<const cppast::cpp_function_template &>(e)
.function());
auto &function_template =
static_cast<const cppast::cpp_function_template &>(e);
process_function(f);
auto &f = static_cast<const cppast::cpp_function &>(
function_template.function());
process_function(f, detail::is_constructor(f));
}
else if (e.kind() == cppast::cpp_entity_kind::type_alias_t) {
LOG_DBG("========== Visiting '{}' - {}",
@@ -247,6 +256,7 @@ void translation_unit_visitor::process_class_declaration(
// Process class elements
for (auto &child : cls) {
auto name = child.name();
if (child.kind() == cppast::cpp_entity_kind::access_specifier_t) {
auto &as = static_cast<const cppast::cpp_access_specifier &>(child);
last_access_specifier = as.access_specifier();
@@ -261,6 +271,14 @@ void translation_unit_visitor::process_class_declaration(
find_relationships(
mv.type(), relationships, relationship_t::kDependency);
}
else if (child.kind() == cppast::cpp_entity_kind::constructor_t) {
auto &mc = static_cast<const cppast::cpp_function &>(child);
process_function(mc, true);
}
else if (child.kind() == cppast::cpp_entity_kind::destructor_t) {
// Skip - destructor won't have any interesting candidates
// for relationships
}
else if (child.kind() == cppast::cpp_entity_kind::member_function_t) {
auto &mf = static_cast<const cppast::cpp_member_function &>(child);
for (const auto &param : mf.parameters())
@@ -319,7 +337,8 @@ void translation_unit_visitor::process_class_declaration(
}
}
void translation_unit_visitor::process_function(const cppast::cpp_function &f)
void translation_unit_visitor::process_function(
const cppast::cpp_function &f, bool skip_return_type)
{
std::vector<std::pair<std::string, relationship_t>> relationships;
auto current_package = ctx.get_current_package();
@@ -331,17 +350,20 @@ void translation_unit_visitor::process_function(const cppast::cpp_function &f)
find_relationships(
param.type(), relationships, relationship_t::kDependency);
find_relationships(
f.return_type(), relationships, relationship_t::kDependency);
if (!skip_return_type) {
find_relationships(
f.return_type(), relationships, relationship_t::kDependency);
for (const auto &dependency : relationships) {
auto destination = common::model::namespace_{std::get<0>(dependency)};
for (const auto &dependency : relationships) {
auto destination =
common::model::namespace_{std::get<0>(dependency)};
if (!ctx.get_namespace().starts_with(destination) &&
!destination.starts_with(ctx.get_namespace())) {
relationship r{
relationship_t::kDependency, std::get<0>(dependency)};
current_package.value().add_relationship(std::move(r));
if (!ctx.get_namespace().starts_with(destination) &&
!destination.starts_with(ctx.get_namespace())) {
relationship r{
relationship_t::kDependency, std::get<0>(dependency)};
current_package.value().add_relationship(std::move(r));
}
}
}
}

View File

@@ -55,7 +55,8 @@ public:
type_safe::optional_ref<const cppast::cpp_template_specialization>
tspec = nullptr);
void process_function(const cppast::cpp_function &f);
void process_function(
const cppast::cpp_function &f, bool skip_return_type = false);
bool find_relationships(const cppast::cpp_type &t_,
std::vector<std::pair<std::string, common::model::relationship_t>>

View File

@@ -28,6 +28,8 @@ template <typename T, template <typename> typename C> struct B {
struct D {
B<int, Vector> ints;
template <typename... Items> D(std::tuple<Items...> * /*items*/) { }
void add(int i) { ints.template_template.values.push_back(i); }
};
}

View File

@@ -65,6 +65,10 @@ struct CBA : public A::AA::A6::CF {
std::shared_ptr<A::AA::A3::CC> cc_;
std::map<std::string, std::unique_ptr<A::AA::A4::CD>> cd_;
CBA() = default;
template <typename... Item> CBA(std::tuple<Item...> &items) { }
void ce(const std::vector<A::AA::A5::CE> /*ce_*/) { }
std::shared_ptr<A::AA::A7::CG> cg() { return {}; }