Added support for class diagram filtering based on C++20 modules (#195)

This commit is contained in:
Bartek Kryza
2023-12-17 20:49:41 +01:00
parent f2fe1ca2cf
commit ea6892f754
21 changed files with 310 additions and 21 deletions

View File

@@ -285,6 +285,39 @@ tvl::value_t namespace_filter::match(const diagram &d, const element &e) const
return result;
}
modules_filter::modules_filter(
filter_t type, std::vector<common::string_or_regex> modules)
: filter_visitor{type}
, modules_{std::move(modules)}
{
}
tvl::value_t modules_filter::match(const diagram &d, const element &e) const
{
if (modules_.empty())
return {};
if (!e.module().has_value())
return {false};
const auto module_toks = util::split(e.module().value(), ".");
auto result = tvl::any_of(modules_.begin(), modules_.end(),
[&e, &module_toks](const auto &modit) {
if (std::holds_alternative<std::string>(modit.value())) {
const auto &modit_str = std::get<std::string>(modit.value());
const auto modit_toks = util::split(modit_str, ".");
return e.module() == modit_str ||
util::starts_with(module_toks, modit_toks);
}
return std::get<common::regex>(modit.value()) %= e.module().value();
});
return result;
}
element_filter::element_filter(
filter_t type, std::vector<common::string_or_regex> elements)
: filter_visitor{type}
@@ -887,6 +920,9 @@ void diagram_filter::init_filters(const config::diagram &c)
add_inclusive_filter(std::make_unique<namespace_filter>(
filter_t::kInclusive, c.include().namespaces));
add_inclusive_filter(std::make_unique<modules_filter>(
filter_t::kInclusive, c.include().modules));
add_inclusive_filter(std::make_unique<relationship_filter>(
filter_t::kInclusive, c.include().relationships));
@@ -997,6 +1033,9 @@ void diagram_filter::init_filters(const config::diagram &c)
add_exclusive_filter(std::make_unique<namespace_filter>(
filter_t::kExclusive, c.exclude().namespaces));
add_exclusive_filter(std::make_unique<modules_filter>(
filter_t::kExclusive, c.exclude().modules));
add_exclusive_filter(std::make_unique<paths_filter>(
filter_t::kExclusive, c.root_directory(), c.exclude().paths));

View File

@@ -154,6 +154,21 @@ private:
std::vector<common::namespace_or_regex> namespaces_;
};
/**
* Match diagram elements to a set of specified modules or
* module regex patterns.
*/
struct modules_filter : public filter_visitor {
modules_filter(filter_t type, std::vector<common::string_or_regex> modules);
~modules_filter() override = default;
tvl::value_t match(const diagram &d, const element &e) const override;
private:
std::vector<common::string_or_regex> modules_;
};
/**
* Match element's name to a set of names or regex patterns.
*/

View File

@@ -87,6 +87,20 @@ public:
*/
const namespace_ &path() const { return ns_; }
/**
* Set elements owning module.
*
* @param module C++20 module.
*/
void set_module(const std::string &module) { module_ = module; }
/**
* Return elements owning module, if any.
*
* @return C++20 module.
*/
std::optional<std::string> module() const { return module_; }
/**
* Return elements full name.
*
@@ -120,5 +134,6 @@ public:
private:
namespace_ ns_;
namespace_ using_namespace_;
std::optional<std::string> module_;
};
} // namespace clanguml::common::model

View File

@@ -21,6 +21,8 @@
#include "comment/clang_visitor.h"
#include "comment/plain_visitor.h"
#include "clang/Basic/Module.h"
namespace clanguml::common::visitor {
translation_unit_visitor::translation_unit_visitor(
@@ -161,4 +163,12 @@ void translation_unit_visitor::set_source_location(
element.set_location_id(location.getHashValue());
}
void translation_unit_visitor::set_owning_module(
const clang::Decl &decl, clanguml::common::model::element &element)
{
if (const clang::Module *module = decl.getOwningModule();
module != nullptr) {
element.set_module(module->Name);
}
}
} // namespace clanguml::common::visitor

View File

@@ -100,6 +100,9 @@ public:
void set_source_location(const clang::SourceLocation &location,
clanguml::common::model::source_location &element);
void set_owning_module(
const clang::Decl &decl, clanguml::common::model::element &element);
protected:
/**
* @brief Process comment directives in comment attached to a declaration