Added dependencies filter

This commit is contained in:
Bartek Kryza
2022-04-18 12:50:19 +02:00
parent 11dccf1496
commit 4ff563354f
7 changed files with 92 additions and 10 deletions

View File

@@ -381,6 +381,11 @@ void diagram_filter::init_filters(const config::diagram &c)
class_diagram::model::class_>>(filter_t::kInclusive, class_diagram::model::class_>>(filter_t::kInclusive,
relationship_t::kDependency, c.include().dependants)); relationship_t::kDependency, c.include().dependants));
element_filters.emplace_back(
std::make_unique<tree_element_filter<class_diagram::model::diagram,
class_diagram::model::class_>>(filter_t::kInclusive,
relationship_t::kDependency, c.include().dependencies, true));
element_filters.emplace_back(std::make_unique<context_filter>( element_filters.emplace_back(std::make_unique<context_filter>(
filter_t::kInclusive, c.include().context)); filter_t::kInclusive, c.include().context));
@@ -410,6 +415,10 @@ void diagram_filter::init_filters(const config::diagram &c)
std::make_unique<tree_element_filter<class_diagram::model::diagram, std::make_unique<tree_element_filter<class_diagram::model::diagram,
class_diagram::model::class_>>(filter_t::kExclusive, class_diagram::model::class_>>(filter_t::kExclusive,
relationship_t::kDependency, c.exclude().dependants)); relationship_t::kDependency, c.exclude().dependants));
add_exclusive_filter(
std::make_unique<tree_element_filter<class_diagram::model::diagram,
class_diagram::model::class_>>(filter_t::kExclusive,
relationship_t::kDependency, c.exclude().dependencies, true));
add_exclusive_filter(std::make_unique<context_filter>( add_exclusive_filter(std::make_unique<context_filter>(
filter_t::kExclusive, c.exclude().context)); filter_t::kExclusive, c.exclude().context));
} }

View File

@@ -115,10 +115,11 @@ private:
template <typename DiagramT, typename ElementT> template <typename DiagramT, typename ElementT>
struct tree_element_filter : public filter_visitor { struct tree_element_filter : public filter_visitor {
tree_element_filter(filter_t type, relationship_t relationship, tree_element_filter(filter_t type, relationship_t relationship,
std::vector<std::string> roots) std::vector<std::string> roots, bool forward = false)
: filter_visitor{type} : filter_visitor{type}
, relationship_{relationship} , relationship_{relationship}
, roots_{roots} , roots_{roots}
, forward_{forward}
{ {
} }
@@ -187,17 +188,40 @@ private:
} }
}; };
if (!forward_)
while (found_new_template) { while (found_new_template) {
found_new_template = false; found_new_template = false;
// For each element of type ElementT in the diagram // For each element of type ElementT in the diagram
for (const auto &el : detail::view<ElementT>(cd)) { for (const auto &el : detail::view<ElementT>(cd)) {
// Check if any of its relationships of type relationship_ // Check if any of its relationships of type relationship_
// points to an element already in the matching_elements_ set // points to an element already in the matching_elements_
// set
for (const auto &rel : el->relationships()) { for (const auto &rel : el->relationships()) {
reverse_relationship_match(rel, el); reverse_relationship_match(rel, el);
} }
} }
} }
else
while (found_new_template) {
found_new_template = false;
// For each of the already matched elements
for (const auto &already_matching : matching_elements_)
// Check if any of its relationships of type relationship_
// points to an element already in the matching_elements_
// set
for (const auto &rel : already_matching->relationships()) {
if (rel.type() == relationship_) {
for (const auto &el : detail::view<ElementT>(cd)) {
if (rel.destination() == el->full_name(false)) {
auto inserted =
matching_elements_.insert(el);
if (inserted.second)
found_new_template = true;
}
}
}
}
}
initialized_ = true; initialized_ = true;
} }
@@ -207,6 +231,7 @@ private:
mutable bool initialized_{false}; mutable bool initialized_{false};
mutable std::unordered_set<type_safe::object_ref<const ElementT, false>> mutable std::unordered_set<type_safe::object_ref<const ElementT, false>>
matching_elements_; matching_elements_;
bool forward_;
}; };
struct relationship_filter : public filter_visitor { struct relationship_filter : public filter_visitor {

View File

@@ -415,6 +415,10 @@ template <> struct convert<filter> {
if (node["dependants"]) if (node["dependants"])
rhs.dependants = node["dependants"].as<decltype(rhs.dependants)>(); rhs.dependants = node["dependants"].as<decltype(rhs.dependants)>();
if (node["dependencies"])
rhs.dependencies =
node["dependencies"].as<decltype(rhs.dependencies)>();
if (node["context"]) if (node["context"])
rhs.context = node["context"].as<decltype(rhs.context)>(); rhs.context = node["context"].as<decltype(rhs.context)>();

View File

@@ -74,6 +74,8 @@ struct filter {
std::vector<std::string> dependants; std::vector<std::string> dependants;
std::vector<std::string> dependencies;
std::vector<std::string> context; std::vector<std::string> context;
std::vector<std::filesystem::path> paths; std::vector<std::filesystem::path> paths;

View File

@@ -11,5 +11,7 @@ diagrams:
include: include:
dependants: dependants:
- clanguml::t00043::dependants::A - clanguml::t00043::dependants::A
dependencies:
- clanguml::t00043::dependencies::J
relationships: relationships:
- dependency - dependency

View File

@@ -29,4 +29,30 @@ struct F {
}; };
} // namespace dependants } // namespace dependants
namespace dependencies {
struct G {
};
struct GG {
};
struct H {
void h(G *g) { }
void hh(GG *gg) { }
};
struct HH {
void hh(G *g) { }
};
struct I {
void i(H *h) { }
};
struct J {
void i(I *i) { }
};
} // namespace dependencies
} // namespace clanguml::t00043 } // namespace clanguml::t00043

View File

@@ -35,6 +35,7 @@ TEST_CASE("t00043", "[test-case][class]")
REQUIRE_THAT(puml, StartsWith("@startuml")); REQUIRE_THAT(puml, StartsWith("@startuml"));
REQUIRE_THAT(puml, EndsWith("@enduml\n")); REQUIRE_THAT(puml, EndsWith("@enduml\n"));
// Check dependants filter
REQUIRE_THAT(puml, IsClass(_A("A"))); REQUIRE_THAT(puml, IsClass(_A("A")));
REQUIRE_THAT(puml, IsClass(_A("B"))); REQUIRE_THAT(puml, IsClass(_A("B")));
REQUIRE_THAT(puml, IsClass(_A("BB"))); REQUIRE_THAT(puml, IsClass(_A("BB")));
@@ -48,6 +49,19 @@ TEST_CASE("t00043", "[test-case][class]")
REQUIRE_THAT(puml, IsDependency(_A("D"), _A("C"))); REQUIRE_THAT(puml, IsDependency(_A("D"), _A("C")));
REQUIRE_THAT(puml, IsDependency(_A("E"), _A("D"))); REQUIRE_THAT(puml, IsDependency(_A("E"), _A("D")));
// Check dependencies filter
REQUIRE_THAT(puml, IsClass(_A("G")));
REQUIRE_THAT(puml, IsClass(_A("GG")));
REQUIRE_THAT(puml, IsClass(_A("H")));
REQUIRE_THAT(puml, !IsClass(_A("HH")));
REQUIRE_THAT(puml, IsClass(_A("I")));
REQUIRE_THAT(puml, IsClass(_A("J")));
REQUIRE_THAT(puml, IsDependency(_A("H"), _A("G")));
REQUIRE_THAT(puml, IsDependency(_A("H"), _A("GG")));
REQUIRE_THAT(puml, IsDependency(_A("I"), _A("H")));
REQUIRE_THAT(puml, IsDependency(_A("J"), _A("I")));
save_puml( save_puml(
"./" + config.output_directory() + "/" + diagram->name + ".puml", puml); "./" + config.output_directory() + "/" + diagram->name + ".puml", puml);
} }