Added package dependencies and dependants filter

This commit is contained in:
Bartek Kryza
2022-04-18 19:29:08 +02:00
parent 2043727565
commit 5b8e40c1eb
29 changed files with 359 additions and 92 deletions

View File

@@ -72,4 +72,5 @@ private:
bool complete_{false};
};
template <typename DiagramT> bool check_diagram_type(diagram_t t);
}

View File

@@ -19,6 +19,8 @@
#include "diagram_filter.h"
#include "class_diagram/model/class.h"
#include "common/model/package.h"
#include "package_diagram/model/diagram.h"
namespace clanguml::common::model {
@@ -38,6 +40,13 @@ view(const class_diagram::model::diagram &d)
return d.enums();
}
template <>
const std::vector<type_safe::object_ref<const common::model::package>> &view(
const package_diagram::model::diagram &d)
{
return d.packages();
}
template <>
const type_safe::optional_ref<const class_diagram::model::class_> get(
const class_diagram::model::diagram &d, const std::string &full_name)
@@ -45,6 +54,13 @@ const type_safe::optional_ref<const class_diagram::model::class_> get(
return d.get_class(full_name);
}
template <>
const type_safe::optional_ref<const common::model::package> get(
const package_diagram::model::diagram &d, const std::string &full_name)
{
return d.get_package(full_name);
}
}
filter_visitor::filter_visitor(filter_t type)
@@ -357,17 +373,22 @@ void diagram_filter::init_filters(const config::diagram &c)
if (c.include) {
add_inclusive_filter(std::make_unique<namespace_filter>(
filter_t::kInclusive, c.include().namespaces));
add_inclusive_filter(std::make_unique<relationship_filter>(
filter_t::kInclusive, c.include().relationships));
add_inclusive_filter(std::make_unique<access_filter>(
filter_t::kInclusive, c.include().access));
add_inclusive_filter(std::make_unique<paths_filter>(
filter_t::kInclusive, c.base_directory(), c.include().paths));
// Include any of these matches even if one them does not match
std::vector<std::unique_ptr<filter_visitor>> element_filters;
element_filters.emplace_back(std::make_unique<element_filter>(
filter_t::kInclusive, c.include().elements));
element_filters.emplace_back(std::make_unique<subclass_filter>(
filter_t::kInclusive, c.include().subclasses));
@@ -381,11 +402,21 @@ void diagram_filter::init_filters(const config::diagram &c)
class_diagram::model::class_>>(filter_t::kInclusive,
relationship_t::kDependency, c.include().dependants));
element_filters.emplace_back(std::make_unique<tree_element_filter<
package_diagram::model::diagram, common::model::package>>(
filter_t::kInclusive, 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<tree_element_filter<
package_diagram::model::diagram, common::model::package>>(
filter_t::kInclusive, relationship_t::kDependency,
c.include().dependencies, true));
element_filters.emplace_back(std::make_unique<context_filter>(
filter_t::kInclusive, c.include().context));
@@ -397,28 +428,47 @@ void diagram_filter::init_filters(const config::diagram &c)
if (c.exclude) {
add_exclusive_filter(std::make_unique<namespace_filter>(
filter_t::kExclusive, c.exclude().namespaces));
add_exclusive_filter(std::make_unique<paths_filter>(
filter_t::kExclusive, c.base_directory(), c.exclude().paths));
add_exclusive_filter(std::make_unique<element_filter>(
filter_t::kExclusive, c.exclude().elements));
add_exclusive_filter(std::make_unique<relationship_filter>(
filter_t::kExclusive, c.exclude().relationships));
add_exclusive_filter(std::make_unique<access_filter>(
filter_t::kExclusive, c.exclude().access));
add_exclusive_filter(std::make_unique<subclass_filter>(
filter_t::kExclusive, c.exclude().subclasses));
add_exclusive_filter(
std::make_unique<tree_element_filter<class_diagram::model::diagram,
class_diagram::model::class_>>(filter_t::kExclusive,
relationship_t::kInstantiation, c.exclude().specializations));
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().dependants));
add_exclusive_filter(std::make_unique<tree_element_filter<
package_diagram::model::diagram, common::model::package>>(
filter_t::kExclusive, 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<tree_element_filter<
package_diagram::model::diagram, common::model::package>>(
filter_t::kExclusive, relationship_t::kDependency,
c.exclude().dependencies, true));
add_exclusive_filter(std::make_unique<context_filter>(
filter_t::kExclusive, c.exclude().context));
}

View File

@@ -125,14 +125,17 @@ struct tree_element_filter : public filter_visitor {
tvl::value_t match(const diagram &d, const element &e) const override
{
if (roots_.empty())
return {};
// This filter should only be run on the completely generated diagram
// model by visitor
if (!d.complete())
return {};
if (!check_diagram_type<DiagramT>(d.type()))
return {};
if (roots_.empty())
return {};
const auto &cd = dynamic_cast<const DiagramT &>(d);
// Calculate the set of matching elements
@@ -146,14 +149,10 @@ struct tree_element_filter : public filter_visitor {
return false;
// Now check if the e element is contained in the calculated set
const auto &e_full_name = e.full_name(false);
bool res =
std::find_if(matching_elements_.begin(), matching_elements_.end(),
[&e_full_name](const auto &te) {
return te->full_name(false) == e_full_name;
}) != matching_elements_.end();
return res;
return std::any_of(matching_elements_.begin(), matching_elements_.end(),
[&e](const auto &te) {
return te->full_name(false) == e.full_name(false);
});
}
private:
@@ -207,6 +206,27 @@ private:
}
}
if constexpr (std::is_same_v<ElementT, common::model::package>) {
if (type() == filter_t::kInclusive) {
// For package diagrams, add also all parents of matching
// packages
decltype(matching_elements_) parents;
util::for_each(matching_elements_,
[this, &cd, &parents](const auto &package) {
auto parent_path = package.get().path();
auto parent = cd.get_package(parent_path.to_string());
while (parent.has_value()) {
parents.emplace(type_safe::ref(parent.value()));
parent = cd.get_package(
parent.value().path().to_string());
}
});
matching_elements_.insert(
std::begin(parents), std::end(parents));
}
}
initialized_ = true;
}

View File

@@ -1,5 +1,5 @@
/**
* src/class_diagram/model/enums.cc
* src/common/model/enums.cc
*
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
*
@@ -74,4 +74,21 @@ std::string to_string(message_t r)
assert(false);
}
}
std::string to_string(const diagram_t t)
{
switch (t) {
case diagram_t::kClass:
return "class";
case diagram_t::kSequence:
return "sequence";
case diagram_t::kPackage:
return "package";
case diagram_t::kInclude:
return "include";
default:
assert(false);
}
}
}

View File

@@ -1,5 +1,5 @@
/**
* src/class_diagram/model/enums.h
* src/common/model/enums.h
*
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
*
@@ -21,7 +21,7 @@
namespace clanguml::common::model {
enum class diagram_t { kClass, kSequence, kPackage };
enum class diagram_t { kClass, kSequence, kPackage, kInclude };
enum class access_t { kPublic, kProtected, kPrivate };
@@ -47,4 +47,6 @@ std::string to_string(access_t r);
std::string to_string(message_t r);
std::string to_string(diagram_t r);
}

View File

@@ -1,5 +1,5 @@
/**
* src/common/model/class.h
* src/common/model/package.cc
*
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
*
@@ -18,8 +18,6 @@
#include "package.h"
#include "util/util.h"
#include <sstream>
namespace clanguml::common::model {
@@ -35,11 +33,11 @@ std::string package::full_name(bool relative) const
return res.to_string();
}
return (get_namespace().relative_to(using_namespace()) | name())
.to_string();
return (get_namespace() | name()).to_string();
}
bool package::is_deprecated() const { return is_deprecated_; }
void package::set_deprecated(bool deprecated) { is_deprecated_ = deprecated; }
}

View File

@@ -1,5 +1,5 @@
/**
* src/package_diagram/model/class.h
* src/common/model/package.h
*
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
*
@@ -54,3 +54,17 @@ private:
bool is_deprecated_{false};
};
}
namespace std {
template <>
struct hash<type_safe::object_ref<const clanguml::common::model::package>> {
std::size_t operator()(
const type_safe::object_ref<const clanguml::common::model::package>
&key) const
{
using clanguml::common::model::package;
return std::hash<std::string>{}(key.get().full_name(false));
}
};
}

View File

@@ -1,5 +1,5 @@
/**
* src/common/model/class_relationship.cc
* src/common/model/relationship.cc
*
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
*

View File

@@ -1,5 +1,5 @@
/**
* src/class_diagram/model/stylable_element.cc
* src/common/model/stylable_element.cc
*
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
*

View File

@@ -1,5 +1,5 @@
/**
* src/class_diagram/model/stylable_element.h
* src/common/model/stylable_element.h
*
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
*