Added regex support to specializations filter
This commit is contained in:
@@ -681,8 +681,9 @@ void diagram_filter::init_filters(const config::diagram &c)
|
||||
|
||||
element_filters.emplace_back(std::make_unique<
|
||||
edge_traversal_filter<class_diagram::model::diagram,
|
||||
class_diagram::model::class_>>(filter_t::kInclusive,
|
||||
relationship_t::kInstantiation, c.include().specializations));
|
||||
class_diagram::model::class_, common::string_or_regex>>(
|
||||
filter_t::kInclusive, relationship_t::kInstantiation,
|
||||
c.include().specializations));
|
||||
|
||||
element_filters.emplace_back(std::make_unique<
|
||||
edge_traversal_filter<class_diagram::model::diagram,
|
||||
@@ -719,15 +720,15 @@ void diagram_filter::init_filters(const config::diagram &c)
|
||||
dependencies.emplace_back(dep_path.lexically_normal().string());
|
||||
}
|
||||
|
||||
element_filters.emplace_back(std::make_unique<
|
||||
edge_traversal_filter<include_diagram::model::diagram,
|
||||
common::model::source_file, common::model::source_file>>(
|
||||
element_filters.emplace_back(std::make_unique<edge_traversal_filter<
|
||||
include_diagram::model::diagram, common::model::source_file,
|
||||
std::string, common::model::source_file>>(
|
||||
filter_t::kInclusive, relationship_t::kAssociation,
|
||||
dependants));
|
||||
|
||||
element_filters.emplace_back(std::make_unique<
|
||||
edge_traversal_filter<include_diagram::model::diagram,
|
||||
common::model::source_file, common::model::source_file>>(
|
||||
element_filters.emplace_back(std::make_unique<edge_traversal_filter<
|
||||
include_diagram::model::diagram, common::model::source_file,
|
||||
std::string, common::model::source_file>>(
|
||||
filter_t::kInclusive, relationship_t::kAssociation,
|
||||
dependencies, true));
|
||||
}
|
||||
@@ -777,8 +778,9 @@ void diagram_filter::init_filters(const config::diagram &c)
|
||||
add_exclusive_filter(std::make_unique<parents_filter>(
|
||||
filter_t::kExclusive, c.exclude().parents));
|
||||
|
||||
add_exclusive_filter(std::make_unique<edge_traversal_filter<
|
||||
class_diagram::model::diagram, class_diagram::model::class_>>(
|
||||
add_exclusive_filter(std::make_unique<
|
||||
edge_traversal_filter<class_diagram::model::diagram,
|
||||
class_diagram::model::class_, common::string_or_regex>>(
|
||||
filter_t::kExclusive, relationship_t::kInstantiation,
|
||||
c.exclude().specializations));
|
||||
|
||||
|
||||
@@ -184,10 +184,11 @@ private:
|
||||
};
|
||||
|
||||
template <typename DiagramT, typename ElementT,
|
||||
typename ConfigEntryT = std::string,
|
||||
typename MatchOverrideT = common::model::element>
|
||||
struct edge_traversal_filter : public filter_visitor {
|
||||
edge_traversal_filter(filter_t type, relationship_t relationship,
|
||||
std::vector<std::string> roots, bool forward = false)
|
||||
std::vector<ConfigEntryT> roots, bool forward = false)
|
||||
: filter_visitor{type}
|
||||
, roots_{std::move(roots)}
|
||||
, relationship_{relationship}
|
||||
@@ -199,8 +200,8 @@ struct edge_traversal_filter : public filter_visitor {
|
||||
|
||||
tvl::value_t match(const diagram &d, const MatchOverrideT &e) const override
|
||||
{
|
||||
// This filter should only be run on the completely generated diagram
|
||||
// model by visitor
|
||||
// This filter should only be run only on diagram models after the
|
||||
// entire AST has been visited
|
||||
if (!d.complete())
|
||||
return {};
|
||||
|
||||
@@ -285,10 +286,22 @@ private:
|
||||
// First get all elements specified in the filter configuration
|
||||
// which will serve as starting points for the search
|
||||
// of matching elements
|
||||
for (const auto &template_root : roots_) {
|
||||
auto template_ref = detail::get<ElementT>(cd, template_root);
|
||||
if (template_ref.has_value()) {
|
||||
matching_elements_.emplace(template_ref.value());
|
||||
for (const auto &root_pattern : roots_) {
|
||||
if constexpr (std::is_same_v<ConfigEntryT,
|
||||
common::string_or_regex>) {
|
||||
auto root_refs = cd.template find<class_diagram::model::class_>(
|
||||
root_pattern);
|
||||
|
||||
for (auto &root : root_refs) {
|
||||
if (root.has_value())
|
||||
matching_elements_.emplace(root.value());
|
||||
}
|
||||
}
|
||||
else {
|
||||
auto root_ref = detail::get<ElementT>(cd, root_pattern);
|
||||
if (root_ref.has_value()) {
|
||||
matching_elements_.emplace(root_ref.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,7 +331,7 @@ private:
|
||||
initialized_ = true;
|
||||
}
|
||||
|
||||
std::vector<std::string> roots_;
|
||||
std::vector<ConfigEntryT> roots_;
|
||||
relationship_t relationship_;
|
||||
mutable bool initialized_{false};
|
||||
mutable clanguml::common::reference_set<ElementT> matching_elements_;
|
||||
|
||||
@@ -101,7 +101,7 @@ struct filter {
|
||||
|
||||
std::vector<common::string_or_regex> parents;
|
||||
|
||||
std::vector<std::string> specializations;
|
||||
std::vector<common::string_or_regex> specializations;
|
||||
|
||||
std::vector<std::string> dependants;
|
||||
|
||||
|
||||
@@ -58,4 +58,9 @@ diagrams:
|
||||
type: class
|
||||
include:
|
||||
parents:
|
||||
- r: 'ns1::ns2::.+[1|2]'
|
||||
- r: 'ns1::ns2::.+[1|2]'
|
||||
regex_specializations_test:
|
||||
type: class
|
||||
include:
|
||||
specializations:
|
||||
- r: 'A<int,.+>'
|
||||
@@ -416,6 +416,80 @@ TEST_CASE("Test parents regexp filter", "[unit-test]")
|
||||
CHECK(!filter.should_include(*c));
|
||||
}
|
||||
|
||||
TEST_CASE("Test specializations regexp filter", "[unit-test]")
|
||||
{
|
||||
using clanguml::class_diagram::model::class_method;
|
||||
using clanguml::class_diagram::model::class_parent;
|
||||
using clanguml::common::to_id;
|
||||
using clanguml::common::model::access_t;
|
||||
using clanguml::common::model::diagram_filter;
|
||||
using clanguml::common::model::namespace_;
|
||||
using clanguml::common::model::package;
|
||||
using clanguml::common::model::relationship;
|
||||
using clanguml::common::model::relationship_t;
|
||||
using clanguml::common::model::source_file;
|
||||
using clanguml::common::model::template_parameter;
|
||||
using namespace std::string_literals;
|
||||
|
||||
using clanguml::class_diagram::model::class_;
|
||||
|
||||
auto cfg = clanguml::config::load("./test_config_data/filters.yml");
|
||||
|
||||
auto &config = *cfg.diagrams["regex_specializations_test"];
|
||||
clanguml::class_diagram::model::diagram diagram;
|
||||
|
||||
const auto template_id = to_id("A<Ts...>"s);
|
||||
|
||||
auto c = std::make_unique<class_>(config.using_namespace());
|
||||
c->set_name("A");
|
||||
c->add_template(
|
||||
template_parameter::make_template_type("T", std::nullopt, true));
|
||||
c->set_id(template_id);
|
||||
diagram.add(namespace_{}, std::move(c));
|
||||
|
||||
c = std::make_unique<class_>(config.using_namespace());
|
||||
c->set_name("A");
|
||||
c->add_template(template_parameter::make_argument("double"));
|
||||
c->set_id(to_id("A<double>"s));
|
||||
c->add_relationship(
|
||||
relationship{relationship_t::kInstantiation, template_id});
|
||||
diagram.add(namespace_{}, std::move(c));
|
||||
|
||||
c = std::make_unique<class_>(config.using_namespace());
|
||||
c->set_name("A");
|
||||
c->add_template(template_parameter::make_argument("int"));
|
||||
c->set_id(to_id("A<int>"s));
|
||||
c->add_relationship(
|
||||
relationship{relationship_t::kInstantiation, template_id});
|
||||
diagram.add(namespace_{}, std::move(c));
|
||||
|
||||
c = std::make_unique<class_>(config.using_namespace());
|
||||
c->set_name("A");
|
||||
c->add_template(template_parameter::make_argument("int"));
|
||||
c->add_template(template_parameter::make_argument("std::string"));
|
||||
c->set_id(to_id("A<int,std::string>"s));
|
||||
c->add_relationship(
|
||||
relationship{relationship_t::kInstantiation, template_id});
|
||||
diagram.add(namespace_{}, std::move(c));
|
||||
|
||||
diagram.set_complete(true);
|
||||
|
||||
diagram_filter filter(diagram, config);
|
||||
|
||||
c = std::make_unique<class_>(config.using_namespace());
|
||||
c->set_name("A");
|
||||
c->add_template(template_parameter::make_argument("int"));
|
||||
c->add_template(template_parameter::make_argument("std::string"));
|
||||
c->set_id(to_id("A<int,std::string>"s));
|
||||
CHECK(filter.should_include(*c));
|
||||
|
||||
c = std::make_unique<class_>(config.using_namespace());
|
||||
c->set_name("A");
|
||||
c->add_template(template_parameter::make_argument("double"));
|
||||
c->set_id(to_id("A<double>"s));
|
||||
CHECK(!filter.should_include(*c));
|
||||
}
|
||||
|
||||
///
|
||||
/// Main test function
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user