diff --git a/src/class_diagram/generators/plantuml/class_diagram_generator.cc b/src/class_diagram/generators/plantuml/class_diagram_generator.cc index b90601fb..2a964218 100644 --- a/src/class_diagram/generators/plantuml/class_diagram_generator.cc +++ b/src/class_diagram/generators/plantuml/class_diagram_generator.cc @@ -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 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; diff --git a/src/class_diagram/visitor/translation_unit_context.cc b/src/class_diagram/visitor/translation_unit_context.cc index 0031d010..476e710a 100644 --- a/src/class_diagram/visitor/translation_unit_context.cc +++ b/src/class_diagram/visitor/translation_unit_context.cc @@ -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 p) { diff --git a/src/class_diagram/visitor/translation_unit_context.h b/src/class_diagram/visitor/translation_unit_context.h index 714f7eae..62cb7293 100644 --- a/src/class_diagram/visitor/translation_unit_context.h +++ b/src/class_diagram/visitor/translation_unit_context.h @@ -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 p); type_safe::optional_ref get_current_package() const; diff --git a/src/class_diagram/visitor/translation_unit_visitor.cc b/src/class_diagram/visitor/translation_unit_visitor.cc index aea10efe..bbf67617 100644 --- a/src/class_diagram/visitor/translation_unit_visitor.cc +++ b/src/class_diagram/visitor/translation_unit_visitor.cc @@ -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(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(usn); package_path = package_path.relative_to(usn); @@ -397,7 +397,8 @@ void translation_unit_visitor::process_class_declaration( fmt::ptr(reinterpret_cast(&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) { diff --git a/src/common/generators/plantuml/generator.h b/src/common/generators/plantuml/generator.h index 29aebf4e..f91a5788 100644 --- a/src/common/generators/plantuml/generator.h +++ b/src/common/generators/plantuml/generator.h @@ -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::generate_link( template 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(diagram, config)); // Get all translation units matching the glob from diagram // configuration std::vector 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 void generator::init_context() diff --git a/src/common/model/diagram.cc b/src/common/model/diagram.cc index 1f4263f5..97309561 100644 --- a/src/common/model/diagram.cc +++ b/src/common/model/diagram.cc @@ -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 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); +} + } \ No newline at end of file diff --git a/src/common/model/diagram.h b/src/common/model/diagram.h index 3e4f95b0..f6e3dcb0 100644 --- a/src/common/model/diagram.h +++ b/src/common/model/diagram.h @@ -17,18 +17,44 @@ */ #pragma once +#include "enums.h" + +#include #include 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 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 filter_; }; } diff --git a/src/common/model/diagram_filter.cc b/src/common/model/diagram_filter.cc new file mode 100644 index 00000000..5cd26c23 --- /dev/null +++ b/src/common/model/diagram_filter.cc @@ -0,0 +1,53 @@ +/** + * src/common/model/diagram_filter.h + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * 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(const std::string &name) +{ + auto [ns, n] = cx::util::split_ns(name); + + return should_include(ns, n); +} + +} diff --git a/src/common/model/diagram_filter.h b/src/common/model/diagram_filter.h new file mode 100644 index 00000000..1f185d76 --- /dev/null +++ b/src/common/model/diagram_filter.h @@ -0,0 +1,266 @@ +/** + * src/common/model/entity_filter.h + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * 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 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 namespaces_; +}; + +struct element_filter : public filter_visitor { + element_filter(filter_t type, std::vector 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 elements_; +}; + +struct subclass_filter : public filter_visitor { + subclass_filter(filter_t type, std::vector 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 roots_; +}; + +struct relationship_filter : public filter_visitor { + relationship_filter(filter_t type, std::vector 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 relationships_; +}; + +struct scope_filter : public filter_visitor { + scope_filter(filter_t type, std::vector 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 scopes_; +}; + +struct context_filter : public filter_visitor { + context_filter(filter_t type, std::vector 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 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 fv) + { + inclusive_.emplace_back(std::move(fv)); + } + + void add_exclusive_filter(std::unique_ptr 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 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( + filter_t::kInclusive, c.include().namespaces)); + inclusive_.emplace_back(std::make_unique( + filter_t::kInclusive, c.include().elements)); + inclusive_.emplace_back(std::make_unique( + filter_t::kInclusive, c.include().relationships)); + inclusive_.emplace_back(std::make_unique( + filter_t::kInclusive, c.include().scopes)); + inclusive_.emplace_back(std::make_unique( + filter_t::kInclusive, c.include().subclasses)); + inclusive_.emplace_back(std::make_unique( + filter_t::kInclusive, c.include().context)); + } + + // Process exclusive filters + if (c.exclude) { + exclusive_.emplace_back(std::make_unique( + filter_t::kExclusive, c.exclude().namespaces)); + exclusive_.emplace_back(std::make_unique( + filter_t::kExclusive, c.exclude().elements)); + exclusive_.emplace_back(std::make_unique( + filter_t::kExclusive, c.include().relationships)); + exclusive_.emplace_back(std::make_unique( + filter_t::kExclusive, c.include().scopes)); + exclusive_.emplace_back(std::make_unique( + filter_t::kExclusive, c.exclude().subclasses)); + exclusive_.emplace_back(std::make_unique( + filter_t::kExclusive, c.exclude().context)); + } + } + + std::vector> inclusive_; + std::vector> exclusive_; + const common::model::diagram &diagram_; +}; + +template <> +bool diagram_filter::should_include(const std::string &name); +} \ No newline at end of file diff --git a/src/config/config.cc b/src/config/config.cc index 9e7d00dd..c644d6b9 100644 --- a/src/config/config.cc +++ b/src/config/config.cc @@ -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 &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 { rhs.relationships = node["relationships"].as(); - if (node["entity_types"]) - rhs.entity_types = - node["entity_types"].as(); + if (node["elements"]) + rhs.elements = + node["elements"].as(); if (node["scopes"]) rhs.scopes = node["scopes"].as(); + if (node["subclasses"]) + rhs.subclasses = node["subclasses"].as(); + + if (node["context"]) + rhs.context = node["context"].as(); + return true; } }; diff --git a/src/config/config.h b/src/config/config.h index 3ebabf55..8f8caf1c 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -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 namespaces; - // Valid values are: + std::vector elements; + + // E.g.: // - inheritance // - dependency // - instantiation std::vector relationships; - // E.g.: - // - classes - // - enums - std::vector entity_types; - // E.g.: // - public + // - protected // - private - std::vector scopes; + std::vector scopes; + + std::vector subclasses; + + std::vector 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 &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; }; diff --git a/src/package_diagram/generators/plantuml/package_diagram_generator.cc b/src/package_diagram/generators/plantuml/package_diagram_generator.cc index cebe62d4..f03a5be7 100644 --- a/src/package_diagram/generators/plantuml/package_diagram_generator.cc +++ b/src/package_diagram/generators/plantuml/package_diagram_generator.cc @@ -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 { diff --git a/src/package_diagram/visitor/translation_unit_visitor.cc b/src/package_diagram/visitor/translation_unit_visitor.cc index ee15c3b7..09908fd9 100644 --- a/src/package_diagram/visitor/translation_unit_visitor.cc +++ b/src/package_diagram/visitor/translation_unit_visitor.cc @@ -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(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())); diff --git a/src/sequence_diagram/visitor/translation_unit_visitor.cc b/src/sequence_diagram/visitor/translation_unit_visitor.cc index e999fdd4..001de746 100644 --- a/src/sequence_diagram/visitor/translation_unit_visitor.cc +++ b/src/sequence_diagram/visitor/translation_unit_visitor.cc @@ -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; diff --git a/tests/t00002/test_case.h b/tests/t00002/test_case.h index 2b7856bf..c595f94d 100644 --- a/tests/t00002/test_case.h +++ b/tests/t00002/test_case.h @@ -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); diff --git a/tests/t00003/test_case.h b/tests/t00003/test_case.h index d5309310..843418fa 100644 --- a/tests/t00003/test_case.h +++ b/tests/t00003/test_case.h @@ -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); diff --git a/tests/t00004/test_case.h b/tests/t00004/test_case.h index daafd155..1a1798f4 100644 --- a/tests/t00004/test_case.h +++ b/tests/t00004/test_case.h @@ -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); diff --git a/tests/t00005/test_case.h b/tests/t00005/test_case.h index b1b9a6da..b17dc0cf 100644 --- a/tests/t00005/test_case.h +++ b/tests/t00005/test_case.h @@ -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); diff --git a/tests/t00006/test_case.h b/tests/t00006/test_case.h index fa6d7b4d..b7cd381b 100644 --- a/tests/t00006/test_case.h +++ b/tests/t00006/test_case.h @@ -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); diff --git a/tests/t00007/test_case.h b/tests/t00007/test_case.h index e3f8ce87..4c473a28 100644 --- a/tests/t00007/test_case.h +++ b/tests/t00007/test_case.h @@ -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"); diff --git a/tests/t00008/test_case.h b/tests/t00008/test_case.h index b2361adc..d9be705f 100644 --- a/tests/t00008/test_case.h +++ b/tests/t00008/test_case.h @@ -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"); diff --git a/tests/t00009/test_case.h b/tests/t00009/test_case.h index b63c7e87..7549eea5 100644 --- a/tests/t00009/test_case.h +++ b/tests/t00009/test_case.h @@ -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"); diff --git a/tests/t00010/test_case.h b/tests/t00010/test_case.h index 22754c08..77159904 100644 --- a/tests/t00010/test_case.h +++ b/tests/t00010/test_case.h @@ -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"); diff --git a/tests/t00011/test_case.h b/tests/t00011/test_case.h index 8fb39319..aa65f77d 100644 --- a/tests/t00011/test_case.h +++ b/tests/t00011/test_case.h @@ -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"); diff --git a/tests/t00012/test_case.h b/tests/t00012/test_case.h index 2f8e2057..59359155 100644 --- a/tests/t00012/test_case.h +++ b/tests/t00012/test_case.h @@ -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"); diff --git a/tests/t00013/test_case.h b/tests/t00013/test_case.h index ca91b368..bd5aa274 100644 --- a/tests/t00013/test_case.h +++ b/tests/t00013/test_case.h @@ -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); diff --git a/tests/t00014/test_case.h b/tests/t00014/test_case.h index ec4e5cd7..83627487 100644 --- a/tests/t00014/test_case.h +++ b/tests/t00014/test_case.h @@ -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); diff --git a/tests/t00015/test_case.h b/tests/t00015/test_case.h index 5ac0dbd3..b0287069 100644 --- a/tests/t00015/test_case.h +++ b/tests/t00015/test_case.h @@ -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); diff --git a/tests/t00016/test_case.h b/tests/t00016/test_case.h index 21232329..58a49181 100644 --- a/tests/t00016/test_case.h +++ b/tests/t00016/test_case.h @@ -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); diff --git a/tests/t00017/test_case.h b/tests/t00017/test_case.h index 2d5ecb47..71efe6de 100644 --- a/tests/t00017/test_case.h +++ b/tests/t00017/test_case.h @@ -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"); diff --git a/tests/t00018/test_case.h b/tests/t00018/test_case.h index 05e065d2..c2e16777 100644 --- a/tests/t00018/test_case.h +++ b/tests/t00018/test_case.h @@ -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); diff --git a/tests/t00019/test_case.h b/tests/t00019/test_case.h index fc9328b0..ec0c8ca6 100644 --- a/tests/t00019/test_case.h +++ b/tests/t00019/test_case.h @@ -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"); diff --git a/tests/t00020/test_case.h b/tests/t00020/test_case.h index 8a15d02b..43f82c39 100644 --- a/tests/t00020/test_case.h +++ b/tests/t00020/test_case.h @@ -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); diff --git a/tests/t00021/test_case.h b/tests/t00021/test_case.h index f956b6df..5e2d8ff1 100644 --- a/tests/t00021/test_case.h +++ b/tests/t00021/test_case.h @@ -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); diff --git a/tests/t00022/test_case.h b/tests/t00022/test_case.h index 3585d0ea..d4a0ae6e 100644 --- a/tests/t00022/test_case.h +++ b/tests/t00022/test_case.h @@ -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); diff --git a/tests/t00023/test_case.h b/tests/t00023/test_case.h index 90c381a5..f9d2d69c 100644 --- a/tests/t00023/test_case.h +++ b/tests/t00023/test_case.h @@ -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); diff --git a/tests/t00024/test_case.h b/tests/t00024/test_case.h index 1a9b5fa7..666b77e3 100644 --- a/tests/t00024/test_case.h +++ b/tests/t00024/test_case.h @@ -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); diff --git a/tests/t00025/test_case.h b/tests/t00025/test_case.h index f37bf07b..15751f2c 100644 --- a/tests/t00025/test_case.h +++ b/tests/t00025/test_case.h @@ -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); diff --git a/tests/t00026/test_case.h b/tests/t00026/test_case.h index d7509334..8d313dd5 100644 --- a/tests/t00026/test_case.h +++ b/tests/t00026/test_case.h @@ -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); diff --git a/tests/t00027/test_case.h b/tests/t00027/test_case.h index c9fe40f5..683d5467 100644 --- a/tests/t00027/test_case.h +++ b/tests/t00027/test_case.h @@ -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); diff --git a/tests/t00028/test_case.h b/tests/t00028/test_case.h index 89ef3fbb..21f57e05 100644 --- a/tests/t00028/test_case.h +++ b/tests/t00028/test_case.h @@ -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); diff --git a/tests/t00029/test_case.h b/tests/t00029/test_case.h index f4e02f56..d4ff282b 100644 --- a/tests/t00029/test_case.h +++ b/tests/t00029/test_case.h @@ -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); diff --git a/tests/t00030/test_case.h b/tests/t00030/test_case.h index 87aacb9b..e97303e1 100644 --- a/tests/t00030/test_case.h +++ b/tests/t00030/test_case.h @@ -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); diff --git a/tests/t00031/test_case.h b/tests/t00031/test_case.h index 25a6488e..70c8c9a1 100644 --- a/tests/t00031/test_case.h +++ b/tests/t00031/test_case.h @@ -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); diff --git a/tests/t00032/test_case.h b/tests/t00032/test_case.h index fc6b3abc..838bcd12 100644 --- a/tests/t00032/test_case.h +++ b/tests/t00032/test_case.h @@ -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); diff --git a/tests/t00033/test_case.h b/tests/t00033/test_case.h index 35025cc4..f58d062e 100644 --- a/tests/t00033/test_case.h +++ b/tests/t00033/test_case.h @@ -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); diff --git a/tests/t00034/test_case.h b/tests/t00034/test_case.h index affcb3a8..2dc3f7d2 100644 --- a/tests/t00034/test_case.h +++ b/tests/t00034/test_case.h @@ -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); diff --git a/tests/t00035/test_case.h b/tests/t00035/test_case.h index 7cbf4163..9aed7ede 100644 --- a/tests/t00035/test_case.h +++ b/tests/t00035/test_case.h @@ -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); diff --git a/tests/t00039/.clang-uml b/tests/t00039/.clang-uml new file mode 100644 index 00000000..b81fa27f --- /dev/null +++ b/tests/t00039/.clang-uml @@ -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 \ No newline at end of file diff --git a/tests/t00039/t00039.cc b/tests/t00039/t00039.cc new file mode 100644 index 00000000..3aa60938 --- /dev/null +++ b/tests/t00039/t00039.cc @@ -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 diff --git a/tests/t00039/test_case.h b/tests/t00039/test_case.h new file mode 100644 index 00000000..10e3bece --- /dev/null +++ b/tests/t00039/test_case.h @@ -0,0 +1,48 @@ +/** + * tests/t00039/test_case.cc + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * 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); +} diff --git a/tests/t20001/test_case.h b/tests/t20001/test_case.h index 66319027..ed85fe9f 100644 --- a/tests/t20001/test_case.h +++ b/tests/t20001/test_case.h @@ -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")); diff --git a/tests/t30001/test_case.h b/tests/t30001/test_case.h index 8ed7251f..1e46ad41 100644 --- a/tests/t30001/test_case.h +++ b/tests/t30001/test_case.h @@ -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); diff --git a/tests/t30002/test_case.h b/tests/t30002/test_case.h index 5cddd8ed..04b1d2dc 100644 --- a/tests/t30002/test_case.h +++ b/tests/t30002/test_case.h @@ -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); diff --git a/tests/t30003/test_case.h b/tests/t30003/test_case.h index 5d508026..1495c3c3 100644 --- a/tests/t30003/test_case.h +++ b/tests/t30003/test_case.h @@ -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); diff --git a/tests/t30004/test_case.h b/tests/t30004/test_case.h index fbc2a03c..60dda007 100644 --- a/tests/t30004/test_case.h +++ b/tests/t30004/test_case.h @@ -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); diff --git a/tests/t30005/test_case.h b/tests/t30005/test_case.h index d1186ef5..1c9e82c8 100644 --- a/tests/t30005/test_case.h +++ b/tests/t30005/test_case.h @@ -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); diff --git a/tests/t30006/test_case.h b/tests/t30006/test_case.h index 174d2612..16385c0e 100644 --- a/tests/t30006/test_case.h +++ b/tests/t30006/test_case.h @@ -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); diff --git a/tests/t30007/test_case.h b/tests/t30007/test_case.h index 130f1e96..5bc95e40 100644 --- a/tests/t30007/test_case.h +++ b/tests/t30007/test_case.h @@ -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); diff --git a/tests/test_cases.cc b/tests/test_cases.cc index f8a0c6cf..711e4d28 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -66,7 +66,7 @@ clanguml::sequence_diagram::model::diagram generate_sequence_diagram( diagram_config, diagram_visitor>(db, diagram->name, dynamic_cast(*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)); - 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 diff --git a/tests/test_cases.yaml b/tests/test_cases.yaml index d25f560b..eaaa6069 100644 --- a/tests/test_cases.yaml +++ b/tests/test_cases.yaml @@ -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