Refactored include and exclude filters
This commit is contained in:
@@ -110,7 +110,7 @@ void generator::generate(
|
||||
// Process methods
|
||||
//
|
||||
for (const auto &m : c.methods()) {
|
||||
if (!m_config.should_include(m.scope()))
|
||||
if (!m_model.should_include(m.scope()))
|
||||
continue;
|
||||
|
||||
if (m.is_pure_virtual())
|
||||
@@ -168,8 +168,7 @@ void generator::generate(
|
||||
std::stringstream all_relations_str;
|
||||
std::set<std::string> unique_relations;
|
||||
for (const auto &r : c.relationships()) {
|
||||
if (!m_config.should_include_relationship(
|
||||
common::model::to_string(r.type())))
|
||||
if (!m_model.should_include(r.type()))
|
||||
continue;
|
||||
|
||||
LOG_DBG("== Processing relationship {}",
|
||||
@@ -223,7 +222,7 @@ void generator::generate(
|
||||
// Process members
|
||||
//
|
||||
for (const auto &m : c.members()) {
|
||||
if (!m_config.should_include(m.scope()))
|
||||
if (!m_model.should_include(m.scope()))
|
||||
continue;
|
||||
|
||||
if (!m_config.include_relations_also_as_members() &&
|
||||
@@ -245,7 +244,7 @@ void generator::generate(
|
||||
|
||||
ostr << "}" << '\n';
|
||||
|
||||
if (m_config.should_include_relationship("inheritance")) {
|
||||
if (m_model.should_include(relationship_t::kExtension)) {
|
||||
for (const auto &b : c.parents()) {
|
||||
std::stringstream relstr;
|
||||
try {
|
||||
@@ -288,8 +287,7 @@ void generator::generate(
|
||||
ostr << "}" << '\n';
|
||||
|
||||
for (const auto &r : e.relationships()) {
|
||||
if (!m_config.should_include_relationship(
|
||||
common::model::to_string(r.type())))
|
||||
if (!m_model.should_include(r.type()))
|
||||
continue;
|
||||
|
||||
std::string destination;
|
||||
|
||||
@@ -184,6 +184,11 @@ clanguml::class_diagram::model::diagram &translation_unit_context::diagram()
|
||||
return diagram_;
|
||||
}
|
||||
|
||||
clanguml::class_diagram::model::diagram &translation_unit_context::diagram() const
|
||||
{
|
||||
return diagram_;
|
||||
}
|
||||
|
||||
void translation_unit_context::set_current_package(
|
||||
type_safe::optional_ref<common::model::package> p)
|
||||
{
|
||||
|
||||
@@ -74,6 +74,8 @@ public:
|
||||
|
||||
clanguml::class_diagram::model::diagram &diagram();
|
||||
|
||||
clanguml::class_diagram::model::diagram &diagram() const;
|
||||
|
||||
void set_current_package(type_safe::optional_ref<common::model::package> p);
|
||||
|
||||
type_safe::optional_ref<common::model::package> get_current_package() const;
|
||||
|
||||
@@ -146,7 +146,7 @@ void translation_unit_visitor::operator()(const cppast::cpp_entity &file)
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx.config().should_include(
|
||||
if (ctx.diagram().should_include(
|
||||
ctx.get_namespace(), cls.name()))
|
||||
process_class_declaration(cls);
|
||||
}
|
||||
@@ -157,7 +157,7 @@ void translation_unit_visitor::operator()(const cppast::cpp_entity &file)
|
||||
|
||||
auto &enm = static_cast<const cppast::cpp_enum &>(e);
|
||||
|
||||
if (ctx.config().should_include(
|
||||
if (ctx.diagram().should_include(
|
||||
ctx.get_namespace(), enm.name()))
|
||||
process_enum_declaration(enm);
|
||||
}
|
||||
@@ -214,7 +214,7 @@ void translation_unit_visitor::process_type_alias_template(
|
||||
cx::util::full_name(ctx.get_namespace(), at),
|
||||
type_safe::ref(at.type_alias().underlying_type()));
|
||||
|
||||
if (ctx.config().should_include(tinst->get_namespace() | tinst->name()))
|
||||
if (ctx.diagram().should_include(tinst->get_namespace(), tinst->name()))
|
||||
ctx.diagram().add_class(std::move(tinst));
|
||||
}
|
||||
}
|
||||
@@ -241,7 +241,7 @@ void translation_unit_visitor::process_namespace(
|
||||
|
||||
auto usn = ctx.config().using_namespace();
|
||||
|
||||
if (ctx.config().should_include_package(package_path)) {
|
||||
if (ctx.diagram().should_include(package_path)) {
|
||||
auto p = std::make_unique<common::model::package>(usn);
|
||||
package_path = package_path.relative_to(usn);
|
||||
|
||||
@@ -397,7 +397,8 @@ void translation_unit_visitor::process_class_declaration(
|
||||
fmt::ptr(reinterpret_cast<const void *>(&cls)));
|
||||
|
||||
assert(c_ptr);
|
||||
if (ctx.config().should_include(c.full_name(false)))
|
||||
|
||||
if (ctx.diagram().should_include(c))
|
||||
ctx.diagram().add_class(std::move(c_ptr));
|
||||
}
|
||||
|
||||
@@ -729,7 +730,7 @@ bool translation_unit_visitor::process_field_with_template_instantiation(
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx.config().should_include(tinst.get_namespace(), tinst.name())) {
|
||||
if (ctx.diagram().should_include(tinst.get_namespace(), tinst.name())) {
|
||||
LOG_DBG("Adding field instantiation relationship {} {} {} : {}",
|
||||
rr.destination(), clanguml::common::model::to_string(rr.type()),
|
||||
c.full_name(), rr.label());
|
||||
@@ -1100,7 +1101,8 @@ void translation_unit_visitor::process_function_parameter(
|
||||
relationship_t::kDependency);
|
||||
|
||||
for (const auto &[type, relationship_type] : relationships) {
|
||||
if (ctx.config().should_include(cx::util::split_ns(type)) &&
|
||||
auto [type_ns, type_name] = cx::util::split_ns(type);
|
||||
if (ctx.diagram().should_include(type_ns, type_name) &&
|
||||
(relationship_type != relationship_t::kNone) &&
|
||||
(type != c.name_and_ns())) {
|
||||
relationship r{relationship_t::kDependency, type};
|
||||
@@ -1165,7 +1167,7 @@ void translation_unit_visitor::
|
||||
// arguments string
|
||||
}
|
||||
|
||||
if (!ctx.config().should_include(ctx.get_namespace(),
|
||||
if (!ctx.diagram().should_include(ctx.get_namespace(),
|
||||
template_instantiation_type.primary_template()
|
||||
.get(ctx.entity_index())[0]
|
||||
.get()
|
||||
@@ -1202,7 +1204,7 @@ void translation_unit_visitor::
|
||||
|
||||
c.add_relationship(std::move(rr));
|
||||
|
||||
if (ctx.config().should_include(c.full_name(false)))
|
||||
if (ctx.diagram().should_include(c))
|
||||
ctx.diagram().add_class(std::move(tinst_ptr));
|
||||
}
|
||||
}
|
||||
@@ -1249,7 +1251,7 @@ void translation_unit_visitor::process_friend(
|
||||
if (f.type()) {
|
||||
const auto [name_with_ns, name] =
|
||||
cx::util::split_ns(cppast::to_string(f.type().value()));
|
||||
if (!ctx.config().should_include(name_with_ns, name))
|
||||
if (!ctx.diagram().should_include(name_with_ns, name))
|
||||
return;
|
||||
|
||||
LOG_DBG("Type friend declaration {}", name);
|
||||
@@ -1288,7 +1290,7 @@ void translation_unit_visitor::process_friend(
|
||||
name = cx::util::full_name(ctx.get_namespace(), f.entity().value());
|
||||
}
|
||||
|
||||
if (!ctx.config().should_include(ctx.get_namespace(), name))
|
||||
if (!ctx.diagram().should_include(ctx.get_namespace(), name))
|
||||
return;
|
||||
|
||||
r.set_destination(name);
|
||||
@@ -1398,7 +1400,7 @@ bool translation_unit_visitor::find_relationships_in_template_instantiation(
|
||||
LOG_DBG("Failed to process template argument of std::vector at: {}",
|
||||
fn);
|
||||
}
|
||||
else if (ctx.config().should_include(ns, name)) {
|
||||
else if (ctx.diagram().should_include(ns, name)) {
|
||||
LOG_DBG("User defined template instantiation: {} | {}",
|
||||
cppast::to_string(t_), cppast::to_string(t_.canonical()));
|
||||
|
||||
@@ -1509,7 +1511,7 @@ bool translation_unit_visitor::find_relationships_in_unexposed_template_params(
|
||||
type_with_namespace = common::model::namespace_{ct.type()};
|
||||
}
|
||||
|
||||
if (ctx.config().should_include(type_with_namespace.value())) {
|
||||
if (ctx.diagram().should_include(type_with_namespace.value().to_string())) {
|
||||
relationships.emplace_back(type_with_namespace.value().to_string(),
|
||||
relationship_t::kDependency);
|
||||
found = true;
|
||||
@@ -1704,7 +1706,7 @@ void translation_unit_visitor::
|
||||
|
||||
auto nested_tinst =
|
||||
build_template_instantiation(nested_template_parameter,
|
||||
ctx.config().should_include(tinst_ns, tinst_name)
|
||||
ctx.diagram().should_include(tinst_ns, tinst_name)
|
||||
? std::make_optional(&tinst)
|
||||
: parent);
|
||||
|
||||
@@ -1713,11 +1715,11 @@ void translation_unit_visitor::
|
||||
|
||||
auto nested_tinst_full_name = nested_tinst->full_name();
|
||||
|
||||
if (ctx.config().should_include(fn_ns, fn_name)) {
|
||||
if (ctx.diagram().should_include(fn_ns, fn_name)) {
|
||||
ctx.diagram().add_class(std::move(nested_tinst));
|
||||
}
|
||||
|
||||
if (ctx.config().should_include(tinst_ns, tinst_name)
|
||||
if (ctx.diagram().should_include(tinst_ns, tinst_name)
|
||||
// TODO: check why this breaks t00033:
|
||||
// && ctx.config().should_include(
|
||||
// cx::util::split_ns(tinst_dependency.destination()))
|
||||
@@ -1753,7 +1755,7 @@ void translation_unit_visitor::
|
||||
"type {} -> {}",
|
||||
tinst.full_name(), tinst_dependency.destination());
|
||||
|
||||
if (ctx.config().should_include(fn_ns, fn_name)) {
|
||||
if (ctx.diagram().should_include(fn_ns, fn_name)) {
|
||||
tinst.add_relationship(std::move(tinst_dependency));
|
||||
}
|
||||
else if (parent) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "common/model/diagram_filter.h"
|
||||
#include "config/config.h"
|
||||
#include "util/error.h"
|
||||
#include "util/util.h"
|
||||
@@ -225,16 +226,18 @@ void generator<C, D>::generate_link(
|
||||
template <typename DiagramModel, typename DiagramConfig,
|
||||
typename DiagramVisitor>
|
||||
DiagramModel generate(const cppast::libclang_compilation_database &db,
|
||||
const std::string &name, DiagramConfig &diagram, bool verbose = false)
|
||||
const std::string &name, DiagramConfig &config, bool verbose = false)
|
||||
{
|
||||
LOG_INFO("Generating diagram {}.puml", name);
|
||||
DiagramModel d;
|
||||
d.set_name(name);
|
||||
DiagramModel diagram{};
|
||||
diagram.set_name(name);
|
||||
diagram.set_filter(
|
||||
std::make_unique<model::diagram_filter>(diagram, config));
|
||||
|
||||
// Get all translation units matching the glob from diagram
|
||||
// configuration
|
||||
std::vector<std::string> translation_units{};
|
||||
for (const auto &g : diagram.glob()) {
|
||||
for (const auto &g : config.glob()) {
|
||||
LOG_DBG("Processing glob: {}", g);
|
||||
const auto matches = glob::rglob(g);
|
||||
std::copy(matches.begin(), matches.end(),
|
||||
@@ -248,12 +251,12 @@ DiagramModel generate(const cppast::libclang_compilation_database &db,
|
||||
type_safe::ref(idx), std::move(logger)};
|
||||
|
||||
// Process all matching translation units
|
||||
DiagramVisitor ctx(idx, d, diagram);
|
||||
DiagramVisitor ctx(idx, diagram, config);
|
||||
cppast::parse_files(parser, translation_units, db);
|
||||
for (auto &file : parser.files())
|
||||
ctx(file);
|
||||
|
||||
return std::move(d);
|
||||
return std::move(diagram);
|
||||
}
|
||||
|
||||
template <typename C, typename D> void generator<C, D>::init_context()
|
||||
|
||||
@@ -18,10 +18,63 @@
|
||||
|
||||
#include "diagram.h"
|
||||
|
||||
#include "diagram_filter.h"
|
||||
#include "namespace.h"
|
||||
|
||||
namespace clanguml::common::model {
|
||||
|
||||
diagram::diagram() = default;
|
||||
|
||||
diagram::~diagram() = default;
|
||||
|
||||
diagram::diagram(diagram &&) = default;
|
||||
|
||||
diagram &diagram::operator=(diagram &&) = default;
|
||||
|
||||
std::string diagram::name() const { return name_; }
|
||||
|
||||
void diagram::set_name(const std::string &name) { name_ = name; }
|
||||
|
||||
void diagram::set_filter(std::unique_ptr<diagram_filter> filter)
|
||||
{
|
||||
filter_ = std::move(filter);
|
||||
}
|
||||
|
||||
bool diagram::should_include(const element &e) const {
|
||||
if (filter_.get() == nullptr)
|
||||
return true;
|
||||
|
||||
return filter_->should_include(e);
|
||||
}
|
||||
|
||||
bool diagram::should_include(const std::string &name) const {
|
||||
if (filter_.get() == nullptr)
|
||||
return true;
|
||||
|
||||
return filter_->should_include(name);
|
||||
}
|
||||
|
||||
bool diagram::should_include(const relationship_t r) const {
|
||||
if (filter_.get() == nullptr)
|
||||
return true;
|
||||
|
||||
return filter_->should_include(r);
|
||||
}
|
||||
|
||||
bool diagram::should_include(const scope_t s) const {
|
||||
if (filter_.get() == nullptr)
|
||||
return true;
|
||||
|
||||
return filter_->should_include(s);
|
||||
}
|
||||
|
||||
bool diagram::should_include(
|
||||
const namespace_ &ns, const std::string &name) const
|
||||
{
|
||||
if (filter_.get() == nullptr)
|
||||
return true;
|
||||
|
||||
return filter_->should_include(ns, name);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,18 +17,44 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "enums.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace clanguml::common::model {
|
||||
|
||||
class diagram_filter;
|
||||
class namespace_;
|
||||
class element;
|
||||
class relationship;
|
||||
|
||||
class diagram {
|
||||
public:
|
||||
std::string name() const;
|
||||
diagram();
|
||||
virtual ~diagram();
|
||||
|
||||
diagram(const diagram &) = delete;
|
||||
diagram(diagram &&);
|
||||
diagram &operator=(const diagram &) = delete;
|
||||
diagram &operator=(diagram &&);
|
||||
|
||||
void set_name(const std::string &name);
|
||||
std::string name() const;
|
||||
|
||||
void set_filter(std::unique_ptr<diagram_filter> filter);
|
||||
|
||||
// TODO: refactor to a template method
|
||||
bool should_include(const element &e) const;
|
||||
bool should_include(const std::string &e) const;
|
||||
bool should_include(const relationship r) const;
|
||||
bool should_include(const relationship_t r) const;
|
||||
bool should_include(const scope_t s) const;
|
||||
bool should_include(const namespace_ &ns, const std::string &name) const;
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
std::unique_ptr<diagram_filter> filter_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
53
src/common/model/diagram_filter.cc
Normal file
53
src/common/model/diagram_filter.cc
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* src/common/model/diagram_filter.h
|
||||
*
|
||||
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "diagram_filter.h"
|
||||
|
||||
namespace clanguml::common::model {
|
||||
|
||||
bool filter_visitor::match(const diagram &d, const common::model::element &e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool filter_visitor::match(
|
||||
const diagram &d, const common::model::relationship_t &r)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool filter_visitor::match(const diagram &d, const common::model::scope_t &r)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool filter_visitor::match(
|
||||
const diagram &d, const common::model::namespace_ &ns)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool diagram_filter::should_include<std::string>(const std::string &name)
|
||||
{
|
||||
auto [ns, n] = cx::util::split_ns(name);
|
||||
|
||||
return should_include(ns, n);
|
||||
}
|
||||
|
||||
}
|
||||
266
src/common/model/diagram_filter.h
Normal file
266
src/common/model/diagram_filter.h
Normal file
@@ -0,0 +1,266 @@
|
||||
/**
|
||||
* src/common/model/entity_filter.h
|
||||
*
|
||||
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "common/model/diagram.h"
|
||||
#include "common/model/element.h"
|
||||
#include "common/model/enums.h"
|
||||
#include "common/model/namespace.h"
|
||||
#include "config/config.h"
|
||||
#include "cx/util.h"
|
||||
#include "diagram.h"
|
||||
|
||||
namespace clanguml::common::model {
|
||||
|
||||
enum filter_t { kInclusive, kExclusive };
|
||||
|
||||
class filter_visitor {
|
||||
public:
|
||||
filter_visitor(filter_t type)
|
||||
: type_{type}
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool match(const diagram &d, const common::model::element &e);
|
||||
virtual bool match(
|
||||
const diagram &d, const common::model::relationship_t &r);
|
||||
virtual bool match(const diagram &d, const common::model::scope_t &r);
|
||||
virtual bool match(const diagram &d, const common::model::namespace_ &ns);
|
||||
|
||||
bool is_inclusive() const { return type_ == filter_t::kInclusive; }
|
||||
bool is_exclusive() const { return type_ == filter_t::kExclusive; }
|
||||
|
||||
filter_t type_;
|
||||
};
|
||||
|
||||
struct namespace_filter : public filter_visitor {
|
||||
namespace_filter(filter_t type, std::vector<namespace_> namespaces)
|
||||
: filter_visitor{type}
|
||||
, namespaces_{namespaces}
|
||||
{
|
||||
}
|
||||
|
||||
bool match(const diagram &d, const namespace_ &ns) override
|
||||
{
|
||||
if (namespaces_.empty())
|
||||
return is_inclusive();
|
||||
|
||||
return std::any_of(namespaces_.begin(), namespaces_.end(),
|
||||
[&ns](const auto &nsit) { return ns.starts_with(nsit); });
|
||||
}
|
||||
|
||||
bool match(const diagram &d, const element &e) override
|
||||
{
|
||||
return std::any_of(
|
||||
namespaces_.begin(), namespaces_.end(), [&e](const auto &nsit) {
|
||||
return e.get_namespace().starts_with(nsit);
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<namespace_> namespaces_;
|
||||
};
|
||||
|
||||
struct element_filter : public filter_visitor {
|
||||
element_filter(filter_t type, std::vector<std::string> elements)
|
||||
: filter_visitor{type}
|
||||
, elements_{elements}
|
||||
{
|
||||
}
|
||||
|
||||
bool match(const diagram &d, const element &e) override
|
||||
{
|
||||
return std::any_of(
|
||||
elements_.begin(), elements_.end(), [&e](const auto &el) {
|
||||
auto fn = e.full_name(false);
|
||||
bool result = fn == el;
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<std::string> elements_;
|
||||
};
|
||||
|
||||
struct subclass_filter : public filter_visitor {
|
||||
subclass_filter(filter_t type, std::vector<std::string> roots)
|
||||
: filter_visitor{type}
|
||||
, roots_{roots}
|
||||
{
|
||||
}
|
||||
|
||||
bool match(const diagram &d, const element &e) override
|
||||
{
|
||||
if (roots_.empty())
|
||||
return is_inclusive();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::string> roots_;
|
||||
};
|
||||
|
||||
struct relationship_filter : public filter_visitor {
|
||||
relationship_filter(filter_t type, std::vector<std::string> relationships)
|
||||
: filter_visitor{type}
|
||||
, relationships_{relationships}
|
||||
{
|
||||
}
|
||||
|
||||
bool match(const diagram &d, const relationship_t &r) override
|
||||
{
|
||||
if (relationships_.empty())
|
||||
return is_inclusive();
|
||||
|
||||
return std::any_of(relationships_.begin(), relationships_.end(),
|
||||
[&r](const auto &rel) {
|
||||
bool res = to_string(r) == rel;
|
||||
return res;
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<std::string> relationships_;
|
||||
};
|
||||
|
||||
struct scope_filter : public filter_visitor {
|
||||
scope_filter(filter_t type, std::vector<std::string> scopes)
|
||||
: filter_visitor{type}
|
||||
, scopes_{scopes}
|
||||
{
|
||||
}
|
||||
|
||||
bool match(const diagram &d, const scope_t &s) override
|
||||
{
|
||||
if (scopes_.empty())
|
||||
return is_inclusive();
|
||||
|
||||
return std::any_of(scopes_.begin(), scopes_.end(),
|
||||
[&s](const auto &rel) {
|
||||
bool res = to_string(s) == rel;
|
||||
return res;
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<std::string> scopes_;
|
||||
};
|
||||
|
||||
struct context_filter : public filter_visitor {
|
||||
context_filter(filter_t type, std::vector<std::string> context)
|
||||
: filter_visitor{type}
|
||||
, context_{context}
|
||||
{
|
||||
}
|
||||
|
||||
bool match(const diagram &d, const element &r) override
|
||||
{
|
||||
if (context_.empty())
|
||||
return is_inclusive();
|
||||
|
||||
return std::any_of(context_.begin(), context_.end(),
|
||||
[&r](const auto &rel) { return true; });
|
||||
}
|
||||
|
||||
std::vector<std::string> context_;
|
||||
};
|
||||
|
||||
class diagram_filter {
|
||||
public:
|
||||
diagram_filter(const common::model::diagram &d, const config::diagram &c)
|
||||
: diagram_{d}
|
||||
{
|
||||
init_filters(c);
|
||||
}
|
||||
|
||||
void add_inclusive_filter(std::unique_ptr<filter_visitor> fv)
|
||||
{
|
||||
inclusive_.emplace_back(std::move(fv));
|
||||
}
|
||||
|
||||
void add_exclusive_filter(std::unique_ptr<filter_visitor> fv)
|
||||
{
|
||||
exclusive_.emplace_back(std::move(fv));
|
||||
}
|
||||
|
||||
bool should_include(namespace_ ns, const std::string &name)
|
||||
{
|
||||
if (should_include(ns)) {
|
||||
element e{namespace_{}};
|
||||
e.set_name(name);
|
||||
e.set_namespace(ns);
|
||||
|
||||
return should_include(e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T> bool should_include(const T &e)
|
||||
{
|
||||
if (std::any_of(exclusive_.begin(), exclusive_.end(),
|
||||
[this, &e](const auto &ex) { return ex->match(diagram_, e); }))
|
||||
return false;
|
||||
|
||||
if (std::any_of(inclusive_.begin(), inclusive_.end(),
|
||||
[this, &e](const auto &in) { return in->match(diagram_, e); }))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
void init_filters(const config::diagram &c)
|
||||
{
|
||||
// Process inclusive filters
|
||||
if (c.include) {
|
||||
inclusive_.emplace_back(std::make_unique<namespace_filter>(
|
||||
filter_t::kInclusive, c.include().namespaces));
|
||||
inclusive_.emplace_back(std::make_unique<element_filter>(
|
||||
filter_t::kInclusive, c.include().elements));
|
||||
inclusive_.emplace_back(std::make_unique<relationship_filter>(
|
||||
filter_t::kInclusive, c.include().relationships));
|
||||
inclusive_.emplace_back(std::make_unique<scope_filter>(
|
||||
filter_t::kInclusive, c.include().scopes));
|
||||
inclusive_.emplace_back(std::make_unique<subclass_filter>(
|
||||
filter_t::kInclusive, c.include().subclasses));
|
||||
inclusive_.emplace_back(std::make_unique<context_filter>(
|
||||
filter_t::kInclusive, c.include().context));
|
||||
}
|
||||
|
||||
// Process exclusive filters
|
||||
if (c.exclude) {
|
||||
exclusive_.emplace_back(std::make_unique<namespace_filter>(
|
||||
filter_t::kExclusive, c.exclude().namespaces));
|
||||
exclusive_.emplace_back(std::make_unique<element_filter>(
|
||||
filter_t::kExclusive, c.exclude().elements));
|
||||
exclusive_.emplace_back(std::make_unique<relationship_filter>(
|
||||
filter_t::kExclusive, c.include().relationships));
|
||||
exclusive_.emplace_back(std::make_unique<scope_filter>(
|
||||
filter_t::kExclusive, c.include().scopes));
|
||||
exclusive_.emplace_back(std::make_unique<subclass_filter>(
|
||||
filter_t::kExclusive, c.exclude().subclasses));
|
||||
exclusive_.emplace_back(std::make_unique<context_filter>(
|
||||
filter_t::kExclusive, c.exclude().context));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<filter_visitor>> inclusive_;
|
||||
std::vector<std::unique_ptr<filter_visitor>> exclusive_;
|
||||
const common::model::diagram &diagram_;
|
||||
};
|
||||
|
||||
template <>
|
||||
bool diagram_filter::should_include<std::string>(const std::string &name);
|
||||
}
|
||||
@@ -108,134 +108,6 @@ void inheritable_diagram_options::inherit(
|
||||
git.override(parent.git);
|
||||
}
|
||||
|
||||
bool diagram::should_include_entities(const std::string &ent)
|
||||
{
|
||||
for (const auto &ex : exclude().entity_types) {
|
||||
if (ent == ex)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (include().entity_types.empty())
|
||||
return true;
|
||||
|
||||
for (const auto &in : include().entity_types) {
|
||||
if (ent == in)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool diagram::should_include_relationship(const std::string &rel)
|
||||
{
|
||||
for (const auto &ex : exclude().relationships) {
|
||||
if (rel == ex)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (include().relationships.empty())
|
||||
return true;
|
||||
|
||||
for (const auto &in : include().relationships) {
|
||||
if (rel == in)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool diagram::should_include(
|
||||
const std::pair<common::model::namespace_, std::string> &name) const
|
||||
{
|
||||
return should_include(std::get<0>(name), std::get<1>(name));
|
||||
}
|
||||
|
||||
bool diagram::should_include(
|
||||
const common::model::namespace_ &ns, const std::string &name) const
|
||||
{
|
||||
return should_include(ns | name);
|
||||
}
|
||||
|
||||
bool diagram::should_include(const std::string &name_) const
|
||||
{
|
||||
auto name = clanguml::util::unqualify(name_);
|
||||
|
||||
for (const auto &ex : exclude().namespaces) {
|
||||
if (name.find(ex.to_string()) == 0) {
|
||||
LOG_DBG("Skipping from diagram: {}", name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If no inclusive namespaces are provided,
|
||||
// allow all
|
||||
if (include().namespaces.empty())
|
||||
return true;
|
||||
|
||||
for (const auto &in : include().namespaces) {
|
||||
if (name.find(in.to_string()) == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG_DBG("Skipping from diagram: {}", name);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool diagram::should_include(const common::model::namespace_ &path) const
|
||||
{
|
||||
return should_include(path.to_string());
|
||||
}
|
||||
|
||||
bool diagram::should_include_package(
|
||||
const common::model::namespace_ &path) const
|
||||
{
|
||||
return should_include_package(path.to_string());
|
||||
}
|
||||
|
||||
bool diagram::should_include_package(const std::string &name) const
|
||||
{
|
||||
|
||||
for (const auto &ex : exclude().namespaces) {
|
||||
if (name.find(ex.to_string()) == 0) {
|
||||
LOG_DBG("Skipping from diagram: {}", name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If no inclusive namespaces are provided,
|
||||
// allow all
|
||||
if (include().namespaces.empty())
|
||||
return true;
|
||||
|
||||
for (const auto &in : include().namespaces) {
|
||||
if (in.to_string().find(name) == 0 || name.find(in.to_string()) == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG_DBG("Skipping from diagram: {}", name);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool diagram::should_include(const clanguml::common::model::scope_t scope) const
|
||||
{
|
||||
for (const auto &s : exclude().scopes) {
|
||||
if (s == scope)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (include().scopes.empty())
|
||||
return true;
|
||||
|
||||
for (const auto &s : include().scopes) {
|
||||
if (s == scope)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
diagram_type class_diagram::type() const { return diagram_type::class_diagram; }
|
||||
|
||||
bool class_diagram::has_class(std::string clazz)
|
||||
@@ -445,13 +317,19 @@ template <> struct convert<filter> {
|
||||
rhs.relationships =
|
||||
node["relationships"].as<decltype(rhs.relationships)>();
|
||||
|
||||
if (node["entity_types"])
|
||||
rhs.entity_types =
|
||||
node["entity_types"].as<decltype(rhs.entity_types)>();
|
||||
if (node["elements"])
|
||||
rhs.elements =
|
||||
node["elements"].as<decltype(rhs.elements)>();
|
||||
|
||||
if (node["scopes"])
|
||||
rhs.scopes = node["scopes"].as<decltype(rhs.scopes)>();
|
||||
|
||||
if (node["subclasses"])
|
||||
rhs.subclasses = node["subclasses"].as<decltype(rhs.subclasses)>();
|
||||
|
||||
if (node["context"])
|
||||
rhs.context = node["context"].as<decltype(rhs.context)>();
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
namespace clanguml {
|
||||
namespace config {
|
||||
|
||||
|
||||
enum class diagram_type { class_diagram, sequence_diagram, package_diagram };
|
||||
enum class method_arguments { full, abbreviated, none };
|
||||
|
||||
@@ -48,21 +49,23 @@ struct plantuml {
|
||||
struct filter {
|
||||
std::vector<common::model::namespace_> namespaces;
|
||||
|
||||
// Valid values are:
|
||||
std::vector<std::string> elements;
|
||||
|
||||
// E.g.:
|
||||
// - inheritance
|
||||
// - dependency
|
||||
// - instantiation
|
||||
std::vector<std::string> relationships;
|
||||
|
||||
// E.g.:
|
||||
// - classes
|
||||
// - enums
|
||||
std::vector<std::string> entity_types;
|
||||
|
||||
// E.g.:
|
||||
// - public
|
||||
// - protected
|
||||
// - private
|
||||
std::vector<common::model::scope_t> scopes;
|
||||
std::vector<std::string> scopes;
|
||||
|
||||
std::vector<std::string> subclasses;
|
||||
|
||||
std::vector<std::string> context;
|
||||
};
|
||||
|
||||
enum class hint_t { up, down, left, right };
|
||||
@@ -111,26 +114,6 @@ struct diagram : public inheritable_diagram_options {
|
||||
|
||||
virtual diagram_type type() const = 0;
|
||||
|
||||
bool should_include_entities(const std::string &ent);
|
||||
|
||||
bool should_include_relationship(const std::string &rel);
|
||||
|
||||
bool should_include_package(const std::string &name) const;
|
||||
|
||||
bool should_include_package(const common::model::namespace_ &path) const;
|
||||
|
||||
bool should_include(
|
||||
const std::pair<common::model::namespace_, std::string> &name) const;
|
||||
|
||||
bool should_include(
|
||||
const common::model::namespace_ &ns, const std::string &name) const;
|
||||
|
||||
bool should_include(const common::model::scope_t scope) const;
|
||||
|
||||
bool should_include(const std::string &name_) const;
|
||||
|
||||
bool should_include(const common::model::namespace_ &path) const;
|
||||
|
||||
std::string name;
|
||||
};
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ void generator::generate_relationships(
|
||||
const auto &uns = m_config.using_namespace();
|
||||
|
||||
// Generate this packages relationship
|
||||
if (m_config.should_include_relationship("dependency")) {
|
||||
if (m_model.should_include(relationship_t::kDependency)) {
|
||||
for (const auto &r : p.relationships()) {
|
||||
std::stringstream relstr;
|
||||
try {
|
||||
|
||||
@@ -95,7 +95,7 @@ void translation_unit_visitor::operator()(const cppast::cpp_entity &file)
|
||||
auto package_path = package_parent | e.name();
|
||||
auto usn = ctx.config().using_namespace();
|
||||
|
||||
if (ctx.config().should_include_package(package_path)) {
|
||||
if (ctx.diagram().should_include(package_path)) {
|
||||
auto p = std::make_unique<package>(usn);
|
||||
package_path = package_path.relative_to(usn);
|
||||
|
||||
@@ -465,7 +465,7 @@ bool translation_unit_visitor::find_relationships(const cppast::cpp_type &t_,
|
||||
found = find_relationships(args[0u].type().value(), relationships,
|
||||
relationship_t::kDependency);
|
||||
}
|
||||
else if (ctx.config().should_include(t_ns, t_name)) {
|
||||
else if (ctx.diagram().should_include(t_ns, t_name)) {
|
||||
LOG_DBG("User defined template instantiation: {} | {}",
|
||||
cppast::to_string(t_), cppast::to_string(t_.canonical()));
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ void translation_unit_visitor::process_activities(const cppast::cpp_function &e)
|
||||
.value();
|
||||
m.from = cx::util::ns(caller) + "::" + caller.name();
|
||||
|
||||
if (!ctx.config().should_include(
|
||||
if (!ctx.diagram().should_include(
|
||||
common::model::namespace_{cx::util::ns(caller)}, caller.name()))
|
||||
continue;
|
||||
|
||||
@@ -98,7 +98,7 @@ void translation_unit_visitor::process_activities(const cppast::cpp_function &e)
|
||||
if (callee.kind() == cpp_entity_kind::function_t)
|
||||
m.to += "()";
|
||||
|
||||
if (!ctx.config().should_include(
|
||||
if (!ctx.diagram().should_include(
|
||||
common::model::namespace_{cx::util::ns(callee)}, callee.name()))
|
||||
continue;
|
||||
|
||||
|
||||
@@ -31,13 +31,13 @@ TEST_CASE("t00002", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->exclude().namespaces.size() == 0);
|
||||
|
||||
REQUIRE(diagram->should_include({"clanguml", "t00002"}, "A"));
|
||||
REQUIRE(!diagram->should_include({"std"}, "vector"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00002_class");
|
||||
|
||||
REQUIRE(model.should_include({"clanguml", "t00002"}, "A"));
|
||||
REQUIRE(!model.should_include({"std"}, "vector"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
|
||||
@@ -28,11 +28,10 @@ TEST_CASE("t00003", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->exclude().namespaces.size() == 0);
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00003::A"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00003_class");
|
||||
REQUIRE(model.should_include(std::string("clanguml::t00003::A")));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -27,13 +27,13 @@ TEST_CASE("t00004", "[test-case][class]")
|
||||
REQUIRE(diagram->include().namespaces.size() == 1);
|
||||
REQUIRE(diagram->exclude().namespaces.size() == 0);
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00004::A"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00004::A::AA"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00004::A:::AAA"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00004_class");
|
||||
REQUIRE(!model.should_include("std::vector"));
|
||||
REQUIRE(model.should_include("clanguml::t00004::A"));
|
||||
REQUIRE(model.should_include("clanguml::t00004::A::AA"));
|
||||
REQUIRE(model.should_include("clanguml::t00004::A:::AAA"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,14 +24,13 @@ TEST_CASE("t00005", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00005_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00005::A"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00005::B"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00005::C"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00005::D"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00005_class");
|
||||
REQUIRE(model.should_include("clanguml::t00005::A"));
|
||||
REQUIRE(model.should_include("clanguml::t00005::B"));
|
||||
REQUIRE(model.should_include("clanguml::t00005::C"));
|
||||
REQUIRE(model.should_include("clanguml::t00005::D"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,16 +24,16 @@ TEST_CASE("t00006", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00006_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00006::A"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00006::B"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00006::C"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00006::D"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00006::E"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00006_class");
|
||||
|
||||
REQUIRE(model.should_include("clanguml::t00006::A"));
|
||||
REQUIRE(model.should_include("clanguml::t00006::B"));
|
||||
REQUIRE(model.should_include("clanguml::t00006::C"));
|
||||
REQUIRE(model.should_include("clanguml::t00006::D"));
|
||||
REQUIRE(model.should_include("clanguml::t00006::E"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
|
||||
@@ -24,12 +24,6 @@ TEST_CASE("t00007", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00007_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00007::A"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00007::B"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00007::C"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00007::D"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00007::E"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00007_class");
|
||||
|
||||
@@ -24,9 +24,6 @@ TEST_CASE("t00008", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00008_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00008::A"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00008::B"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00008_class");
|
||||
|
||||
@@ -24,9 +24,6 @@ TEST_CASE("t00009", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00009_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00009::A"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00009::B"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00009_class");
|
||||
|
||||
@@ -24,9 +24,6 @@ TEST_CASE("t00010", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00010_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00010::A"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00010::B"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00010_class");
|
||||
|
||||
@@ -24,9 +24,6 @@ TEST_CASE("t00011", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00011_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00011::A"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00011::B"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00011_class");
|
||||
|
||||
@@ -24,9 +24,6 @@ TEST_CASE("t00012", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00012_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00012::A"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00012::B"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00012_class");
|
||||
|
||||
@@ -24,13 +24,13 @@ TEST_CASE("t00013", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00013_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00013::A"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00013::B"));
|
||||
REQUIRE(diagram->should_include("ABCD::F"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00013_class");
|
||||
REQUIRE(model.should_include("clanguml::t00013::A"));
|
||||
REQUIRE(model.should_include("clanguml::t00013::B"));
|
||||
REQUIRE(model.should_include("ABCD::F"));
|
||||
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,11 +24,11 @@ TEST_CASE("t00014", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00014_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00014::S"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00014_class");
|
||||
REQUIRE(model.should_include("clanguml::t00014::S"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,11 +24,11 @@ TEST_CASE("t00015", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00015_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00015::ns1::ns2::A"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00015_class");
|
||||
REQUIRE(model.should_include("clanguml::t00015::ns1::ns2::A"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,11 +24,11 @@ TEST_CASE("t00016", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00016_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00016::is_numeric"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00016_class");
|
||||
REQUIRE(model.should_include("clanguml::t00016::is_numeric"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,11 +24,6 @@ TEST_CASE("t00017", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00017_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00017::A"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00017::B"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00017::C"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00017::D"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00017_class");
|
||||
|
||||
@@ -24,11 +24,11 @@ TEST_CASE("t00018", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00018_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00018::widget"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00018_class");
|
||||
REQUIRE(model.should_include("clanguml::t00018::widget"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,11 +24,6 @@ TEST_CASE("t00019", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00019_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00019::Layer1"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00019::Layer2"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00019::Layer3"));
|
||||
REQUIRE(diagram->should_include("clanguml::t00019::Base"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00019_class");
|
||||
|
||||
@@ -24,11 +24,11 @@ TEST_CASE("t00020", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00020_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00020::ProductA"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00020_class");
|
||||
REQUIRE(model.should_include("clanguml::t00020::ProductA"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,11 +24,10 @@ TEST_CASE("t00021", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00021_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00021::Visitor"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00021_class");
|
||||
REQUIRE(model.should_include("clanguml::t00021::Visitor"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,11 +24,11 @@ TEST_CASE("t00022", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00022_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00022::A"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00022_class");
|
||||
REQUIRE(model.should_include("clanguml::t00022::A"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,11 +24,11 @@ TEST_CASE("t00023", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00023_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00023::Visitor"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00023_class");
|
||||
REQUIRE(model.should_include("clanguml::t00023::Visitor"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,11 +24,11 @@ TEST_CASE("t00024", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00024_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00024::A"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00024_class");
|
||||
REQUIRE(model.should_include("clanguml::t00024::A"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,11 +24,11 @@ TEST_CASE("t00025", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00025_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00025::A"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00025_class");
|
||||
REQUIRE(model.should_include("clanguml::t00025::A"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,11 +24,11 @@ TEST_CASE("t00026", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00026_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00026::A"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00026_class");
|
||||
REQUIRE(model.should_include("clanguml::t00026::A"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,11 +24,11 @@ TEST_CASE("t00027", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00027_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00027::A"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00027_class");
|
||||
REQUIRE(model.should_include("clanguml::t00027::A"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,11 +24,11 @@ TEST_CASE("t00028", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00028_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00028::A"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00028_class");
|
||||
REQUIRE(model.should_include("clanguml::t00028::A"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,11 +24,11 @@ TEST_CASE("t00029", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00029_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00029::A"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00029_class");
|
||||
REQUIRE(model.should_include("clanguml::t00029::A"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,11 +24,11 @@ TEST_CASE("t00030", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00030_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00030::A"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00030_class");
|
||||
REQUIRE(model.should_include("clanguml::t00030::A"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,11 +24,11 @@ TEST_CASE("t00031", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00031_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00031::A"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00031_class");
|
||||
REQUIRE(model.should_include("clanguml::t00031::A"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,11 +24,11 @@ TEST_CASE("t00032", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00032_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00032::A"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00032_class");
|
||||
REQUIRE(model.should_include("clanguml::t00032::A"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,11 +24,10 @@ TEST_CASE("t00033", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00033_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00033::A"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00033_class");
|
||||
REQUIRE(model.should_include("clanguml::t00033::A"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,11 +24,10 @@ TEST_CASE("t00034", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00034_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00034::A"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00034_class");
|
||||
REQUIRE(model.should_include("clanguml::t00034::A"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
@@ -24,11 +24,10 @@ TEST_CASE("t00035", "[test-case][class]")
|
||||
|
||||
REQUIRE(diagram->name == "t00035_class");
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t00035::A"));
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00035_class");
|
||||
REQUIRE(model.should_include("clanguml::t00035::A"));
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
15
tests/t00039/.clang-uml
Normal file
15
tests/t00039/.clang-uml
Normal file
@@ -0,0 +1,15 @@
|
||||
compilation_database_dir: ..
|
||||
output_directory: puml
|
||||
diagrams:
|
||||
t00039_class:
|
||||
type: class
|
||||
generate_packages: false
|
||||
glob:
|
||||
- ../../tests/t00039/t00039.cc
|
||||
using_namespace:
|
||||
- clanguml::t00039
|
||||
include:
|
||||
subclasses:
|
||||
- clanguml::t00039::A
|
||||
relationships:
|
||||
- inheritance
|
||||
24
tests/t00039/t00039.cc
Normal file
24
tests/t00039/t00039.cc
Normal file
@@ -0,0 +1,24 @@
|
||||
namespace clanguml::t00039 {
|
||||
struct B {
|
||||
};
|
||||
|
||||
namespace ns1 {
|
||||
struct BB : public B {
|
||||
};
|
||||
} // namespace ns1
|
||||
|
||||
struct A {
|
||||
};
|
||||
|
||||
struct AA : public A {
|
||||
};
|
||||
|
||||
struct AAA : public AA {
|
||||
B *b;
|
||||
};
|
||||
|
||||
namespace ns2 {
|
||||
struct AAAA : public AAA {
|
||||
};
|
||||
} // namespace ns2
|
||||
} // namespace clanguml::t00039
|
||||
48
tests/t00039/test_case.h
Normal file
48
tests/t00039/test_case.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* tests/t00039/test_case.cc
|
||||
*
|
||||
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
TEST_CASE("t00039", "[test-case][class]")
|
||||
{
|
||||
auto [config, db] = load_config("t00039");
|
||||
|
||||
auto diagram = config.diagrams["t00039_class"];
|
||||
|
||||
REQUIRE(diagram->name == "t00039_class");
|
||||
REQUIRE(diagram->generate_packages() == false);
|
||||
|
||||
auto model = generate_class_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t00039_class");
|
||||
|
||||
auto puml = generate_class_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
REQUIRE_THAT(puml, StartsWith("@startuml"));
|
||||
REQUIRE_THAT(puml, EndsWith("@enduml\n"));
|
||||
|
||||
REQUIRE_THAT(puml, IsClass(_A("A")));
|
||||
REQUIRE_THAT(puml, IsClass(_A("AA")));
|
||||
REQUIRE_THAT(puml, IsClass(_A("AAA")));
|
||||
REQUIRE_THAT(puml, IsClass(_A("ns2::AAAA")));
|
||||
|
||||
REQUIRE_THAT(puml, !IsClass(_A("B")));
|
||||
REQUIRE_THAT(puml, !IsClass(_A("ns1::BB")));
|
||||
|
||||
save_puml(
|
||||
"./" + config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
}
|
||||
@@ -22,16 +22,16 @@ TEST_CASE("t20001", "[test-case][sequence]")
|
||||
|
||||
auto diagram = config.diagrams["t20001_sequence"];
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t20001::A"));
|
||||
REQUIRE(!diagram->should_include("clanguml::t20001::detail::C"));
|
||||
REQUIRE(!diagram->should_include("std::vector"));
|
||||
|
||||
REQUIRE(diagram->name == "t20001_sequence");
|
||||
|
||||
auto model = generate_sequence_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t20001_sequence");
|
||||
|
||||
REQUIRE(model.should_include("clanguml::t20001::A"));
|
||||
REQUIRE(!model.should_include("clanguml::t20001::detail::C"));
|
||||
REQUIRE(!model.should_include("std::vector"));
|
||||
|
||||
auto puml = generate_sequence_puml(diagram, model);
|
||||
|
||||
REQUIRE_THAT(puml, StartsWith("@startuml"));
|
||||
|
||||
@@ -22,16 +22,16 @@ TEST_CASE("t30001", "[test-case][package]")
|
||||
|
||||
auto diagram = config.diagrams["t30001_package"];
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t30001::A"));
|
||||
REQUIRE(!diagram->should_include("clanguml::t30001::detail::C"));
|
||||
REQUIRE(!diagram->should_include("std::vector"));
|
||||
|
||||
REQUIRE(diagram->name == "t30001_package");
|
||||
|
||||
auto model = generate_package_diagram(db, diagram);
|
||||
|
||||
REQUIRE(model.name() == "t30001_package");
|
||||
|
||||
REQUIRE(model.should_include("clanguml::t30001::A"));
|
||||
REQUIRE(!model.should_include("clanguml::t30001::detail::C"));
|
||||
REQUIRE(!model.should_include("std::vector"));
|
||||
|
||||
auto puml = generate_package_puml(diagram, model);
|
||||
AliasMatcher _A(puml);
|
||||
|
||||
|
||||
@@ -22,10 +22,6 @@ TEST_CASE("t30002", "[test-case][package]")
|
||||
|
||||
auto diagram = config.diagrams["t30002_package"];
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t30002::A"));
|
||||
REQUIRE(!diagram->should_include("clanguml::t30002::detail::C"));
|
||||
REQUIRE(!diagram->should_include("std::vector"));
|
||||
|
||||
REQUIRE(diagram->name == "t30002_package");
|
||||
|
||||
auto model = generate_package_diagram(db, diagram);
|
||||
|
||||
@@ -22,10 +22,6 @@ TEST_CASE("t30003", "[test-case][package]")
|
||||
|
||||
auto diagram = config.diagrams["t30003_package"];
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t30003::A"));
|
||||
REQUIRE(diagram->should_include("clanguml::t30003::C"));
|
||||
REQUIRE(!diagram->should_include("std::vector"));
|
||||
|
||||
REQUIRE(diagram->name == "t30003_package");
|
||||
|
||||
auto model = generate_package_diagram(db, diagram);
|
||||
|
||||
@@ -22,10 +22,6 @@ TEST_CASE("t30004", "[test-case][package]")
|
||||
|
||||
auto diagram = config.diagrams["t30004_package"];
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t30004::A"));
|
||||
REQUIRE(diagram->should_include("clanguml::t30004::C"));
|
||||
REQUIRE(!diagram->should_include("std::vector"));
|
||||
|
||||
REQUIRE(diagram->name == "t30004_package");
|
||||
|
||||
auto model = generate_package_diagram(db, diagram);
|
||||
|
||||
@@ -22,10 +22,6 @@ TEST_CASE("t30005", "[test-case][package]")
|
||||
|
||||
auto diagram = config.diagrams["t30005_package"];
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t30005::A"));
|
||||
REQUIRE(diagram->should_include("clanguml::t30005::C"));
|
||||
REQUIRE(!diagram->should_include("std::vector"));
|
||||
|
||||
REQUIRE(diagram->name == "t30005_package");
|
||||
|
||||
auto model = generate_package_diagram(db, diagram);
|
||||
|
||||
@@ -22,10 +22,6 @@ TEST_CASE("t30006", "[test-case][package]")
|
||||
|
||||
auto diagram = config.diagrams["t30006_package"];
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t30006::A"));
|
||||
REQUIRE(diagram->should_include("clanguml::t30006::C"));
|
||||
REQUIRE(!diagram->should_include("std::vector"));
|
||||
|
||||
REQUIRE(diagram->name == "t30006_package");
|
||||
|
||||
auto model = generate_package_diagram(db, diagram);
|
||||
|
||||
@@ -22,10 +22,6 @@ TEST_CASE("t30007", "[test-case][package]")
|
||||
|
||||
auto diagram = config.diagrams["t30007_package"];
|
||||
|
||||
REQUIRE(diagram->should_include("clanguml::t30007::A"));
|
||||
REQUIRE(diagram->should_include("clanguml::t30007::C"));
|
||||
REQUIRE(!diagram->should_include("std::vector"));
|
||||
|
||||
REQUIRE(diagram->name == "t30007_package");
|
||||
|
||||
auto model = generate_package_diagram(db, diagram);
|
||||
|
||||
@@ -66,7 +66,7 @@ clanguml::sequence_diagram::model::diagram generate_sequence_diagram(
|
||||
diagram_config, diagram_visitor>(db, diagram->name,
|
||||
dynamic_cast<clanguml::config::sequence_diagram &>(*diagram));
|
||||
|
||||
return model;
|
||||
return std::move(model);
|
||||
}
|
||||
|
||||
clanguml::class_diagram::model::diagram generate_class_diagram(
|
||||
@@ -84,7 +84,7 @@ clanguml::class_diagram::model::diagram generate_class_diagram(
|
||||
diagram_config, diagram_visitor>(
|
||||
db, diagram->name, dynamic_cast<diagram_config &>(*diagram));
|
||||
|
||||
return model;
|
||||
return std::move(model);
|
||||
}
|
||||
|
||||
clanguml::package_diagram::model::diagram generate_package_diagram(
|
||||
@@ -197,6 +197,7 @@ using namespace clanguml::test::matchers;
|
||||
#include "t00036/test_case.h"
|
||||
#include "t00037/test_case.h"
|
||||
#include "t00038/test_case.h"
|
||||
#include "t00039/test_case.h"
|
||||
|
||||
//
|
||||
// Sequence diagram tests
|
||||
|
||||
@@ -111,6 +111,9 @@ test_cases:
|
||||
- name: t00038
|
||||
title: Template instantiation with unexposed nested templates
|
||||
description:
|
||||
- name: t00039
|
||||
title: Subclass class diagram filter test
|
||||
description:
|
||||
Sequence diagrams:
|
||||
- name: t20001
|
||||
title: Basic sequence diagram test case
|
||||
|
||||
Reference in New Issue
Block a user