Added callee_filter for including/excluding messages based on receiver type (#152)

This commit is contained in:
Bartek Kryza
2023-07-01 21:19:51 +02:00
parent 213483dd3b
commit e50a7b1846
24 changed files with 590 additions and 43 deletions

View File

@@ -25,6 +25,7 @@
#include "glob/glob.hpp"
#include "include_diagram/model/diagram.h"
#include "package_diagram/model/diagram.h"
#include "sequence_diagram/model/diagram.h"
namespace clanguml::common::model {
@@ -140,6 +141,12 @@ tvl::value_t filter_visitor::match(
return match(d, m.access());
}
tvl::value_t filter_visitor::match(const diagram & /*d*/,
const sequence_diagram::model::participant & /*p*/) const
{
return {};
}
bool filter_visitor::is_inclusive() const
{
return type_ == filter_t::kInclusive;
@@ -166,6 +173,13 @@ tvl::value_t anyof_filter::match(
[&d, &e](const auto &f) { return f->match(d, e); });
}
tvl::value_t anyof_filter::match(
const diagram &d, const sequence_diagram::model::participant &p) const
{
return tvl::any_of(filters_.begin(), filters_.end(),
[&d, &p](const auto &f) { return f->match(d, p); });
}
tvl::value_t anyof_filter::match(
const diagram &d, const common::model::source_file &e) const
{
@@ -351,6 +365,62 @@ tvl::value_t method_type_filter::match(
});
}
callee_filter::callee_filter(
filter_t type, std::vector<config::callee_type> callee_types)
: filter_visitor{type}
, callee_types_{std::move(callee_types)}
{
}
tvl::value_t callee_filter::match(
const diagram &d, const sequence_diagram::model::participant &p) const
{
using sequence_diagram::model::class_;
using sequence_diagram::model::method;
using sequence_diagram::model::participant;
auto is_lambda = [&d](const method &m) {
auto class_participant =
dynamic_cast<const sequence_diagram::model::diagram &>(d)
.get_participant<class_>(m.class_id());
if (!class_participant)
return false;
return class_participant.value().is_lambda();
};
tvl::value_t res = tvl::any_of(
callee_types_.begin(), callee_types_.end(), [&p, is_lambda](auto ct) {
switch (ct) {
case config::callee_type::method:
return p.type_name() == "method";
case config::callee_type::constructor:
return p.type_name() == "method" &&
((method &)p).is_constructor();
case config::callee_type::assignment:
return p.type_name() == "method" &&
((method &)p).is_assignment();
case config::callee_type::operator_:
return p.type_name() == "method" && ((method &)p).is_operator();
case config::callee_type::defaulted:
return p.type_name() == "method" &&
((method &)p).is_defaulted();
case config::callee_type::static_:
return p.type_name() == "method" && ((method &)p).is_static();
case config::callee_type::function:
return p.type_name() == "function";
case config::callee_type::function_template:
return p.type_name() == "function_template";
case config::callee_type::lambda:
return p.type_name() == "method" && is_lambda((method &)p);
}
return false;
});
return res;
}
subclass_filter::subclass_filter(
filter_t type, std::vector<common::string_or_regex> roots)
: filter_visitor{type}
@@ -771,6 +841,10 @@ void diagram_filter::init_filters(const config::diagram &c)
filter_t::kInclusive, relationship_t::kDependency,
c.include().dependencies, true));
}
else if (c.type() == diagram_t::kSequence) {
element_filters.emplace_back(std::make_unique<callee_filter>(
filter_t::kInclusive, c.include().callee_types));
}
else if (c.type() == diagram_t::kPackage) {
element_filters.emplace_back(
std::make_unique<package_dependants_filter_t>(
@@ -878,7 +952,11 @@ void diagram_filter::init_filters(const config::diagram &c)
filter_t::kExclusive, relationship_t::kDependency,
c.exclude().dependencies, true));
if (c.type() == diagram_t::kInclude) {
if (c.type() == diagram_t::kSequence) {
add_exclusive_filter(std::make_unique<callee_filter>(
filter_t::kExclusive, c.exclude().callee_types));
}
else if (c.type() == diagram_t::kInclude) {
std::vector<std::string> dependants;
std::vector<std::string> dependencies;

View File

@@ -28,6 +28,7 @@
#include "config/config.h"
#include "diagram.h"
#include "include_diagram/model/diagram.h"
#include "sequence_diagram/model/participant.h"
#include "source_file.h"
#include "tvl.h"
@@ -104,6 +105,9 @@ public:
virtual tvl::value_t match(
const diagram &d, const class_diagram::model::class_member &m) const;
virtual tvl::value_t match(
const diagram &d, const sequence_diagram::model::participant &p) const;
bool is_inclusive() const;
bool is_exclusive() const;
@@ -122,6 +126,9 @@ struct anyof_filter : public filter_visitor {
tvl::value_t match(
const diagram &d, const common::model::element &e) const override;
tvl::value_t match(const diagram &d,
const sequence_diagram::model::participant &p) const override;
tvl::value_t match(
const diagram &d, const common::model::source_file &e) const override;
@@ -192,6 +199,21 @@ private:
std::vector<config::method_type> method_types_;
};
/**
* Sequence diagram callee type filter.
*/
struct callee_filter : public filter_visitor {
callee_filter(filter_t type, std::vector<config::callee_type> callee_types);
~callee_filter() override = default;
tvl::value_t match(const diagram &d,
const sequence_diagram::model::participant &p) const override;
private:
std::vector<config::callee_type> callee_types_;
};
/**
* Match element based on whether it is a subclass of a set of base classes,
* or one of them.