From a8b57e4eb1a69f363e0c51a58dc15e45164126e8 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Wed, 30 Mar 2022 23:27:46 +0200 Subject: [PATCH] Changed scope_t to access_t and fixed friend access specifier handling --- docs/configuration_file.md | 14 +++--- examples/cppast/.clang-uml | 6 +-- .../plantuml/class_diagram_generator.cc | 10 ++-- .../plantuml/class_diagram_generator.h | 2 +- src/class_diagram/model/class_element.cc | 8 ++-- src/class_diagram/model/class_element.h | 6 +-- src/class_diagram/model/class_member.cc | 4 +- src/class_diagram/model/class_member.h | 2 +- src/class_diagram/model/class_method.cc | 4 +- src/class_diagram/model/class_method.h | 2 +- .../visitor/translation_unit_visitor.cc | 47 +++++++++---------- .../visitor/translation_unit_visitor.h | 3 +- src/common/generators/plantuml/generator.cc | 8 ++-- src/common/generators/plantuml/generator.h | 4 +- src/common/model/diagram.cc | 2 +- src/common/model/diagram.h | 2 +- src/common/model/diagram_filter.cc | 29 +++++++----- src/common/model/diagram_filter.h | 15 +++--- src/common/model/enums.cc | 16 ------- src/common/model/enums.h | 4 -- src/common/model/relationship.cc | 8 ++-- src/common/model/relationship.h | 8 ++-- src/config/config.cc | 19 ++++---- src/config/config.h | 2 +- .../plantuml/package_diagram_generator.h | 2 +- .../visitor/translation_unit_visitor.cc | 13 +++-- tests/t00011/test_case.h | 2 +- tests/t00040/.clang-uml | 2 +- tests/test_cases.h | 25 +++++++--- tests/test_cases.yaml | 2 +- 30 files changed, 134 insertions(+), 137 deletions(-) diff --git a/docs/configuration_file.md b/docs/configuration_file.md index ddd9dc82..087e2c8a 100644 --- a/docs/configuration_file.md +++ b/docs/configuration_file.md @@ -11,17 +11,19 @@ * `glob` - list of glob patterns to match source code files for analysis * `include_relations_also_as_members` - when set to `false`, class members for relationships are rendered in UML are skipped from class definition (default: `true`) * `generate_method_arguments` - determines whether the class diagrams methods contain full arguments (`full`), are abbreviated (`abbreviated`) or skipped (`none`) -* `using_namespace` - similar to C++ `using namespace`, a `A::B` value here will render a class `A::B::C::MyClass` in the diagram as `C::MyClass` +* `using_namespace` - similar to C++ `using namespace`, a `A::B` value here will render a class `A::B::C::MyClass` in the diagram as `C::MyClass`, at most 1 value is supported * `include` - definition of inclusion patterns: * `namespaces` - list of namespaces to include * `relationships` - list of relationships to include - * `entity_types` - list of entity types to include (e.g. `class`, `enum`) - * `scopes` - list of visibility scopes to include (e.g. `private`) + * `elements` - list of elements, i.e. specific classes, enums, templates to include + * `access` - list of visibility scopes to include (e.g. `private`) + * `subclasses` - include only subclasses of specified classes (and themselves) * `exclude` - definition of excqlusion patterns: * `namespaces` - list of namespaces to exclude * `relationships` - list of relationships to exclude - * `entity_types` - list of entity types to exclude (e.g. `class`, `enum`) - * `scopes` - list of visibility scopes to exclude (e.g. `private`) + * `elements` - list of elements, i.e. specific classes, enums, templates to exclude + * `access` - list of visibility scopes to exclude (e.g. `private`) + * `subclasses` - exclude subclasses of specified classes (and themselves) * `layout` - add layout hints for entities (classes, packages) * `plantuml` - verbatim PlantUML directives which should be added to a diagram * `before` - list of directives which will be added before the generated diagram @@ -81,7 +83,7 @@ diagrams: - clanguml::class_diagram::model exclude: # Do not include private members and methods in the diagram - scopes: + access: - private layout: # Add layout hints for PlantUML diff --git a/examples/cppast/.clang-uml b/examples/cppast/.clang-uml index 92e51154..63cb2b0f 100644 --- a/examples/cppast/.clang-uml +++ b/examples/cppast/.clang-uml @@ -25,7 +25,7 @@ diagrams: exclude: namespaces: - cppast::detail - scopes: + access: - public - protected - private @@ -73,7 +73,7 @@ diagrams: - cppast::detail entity_types: - enums - scopes: + access: - public - protected - private @@ -93,7 +93,7 @@ diagrams: exclude: namespaces: - cppast::detail - scopes: + access: - public - protected - private diff --git a/src/class_diagram/generators/plantuml/class_diagram_generator.cc b/src/class_diagram/generators/plantuml/class_diagram_generator.cc index d2a501aa..9b458fdb 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_model.should_include(m.scope())) + if (!m_model.should_include(m.access())) continue; if (m.is_pure_virtual()) @@ -121,7 +121,7 @@ void generator::generate( std::string type{m.type()}; - ostr << plantuml_common::to_plantuml(m.scope()) << m.name(); + ostr << plantuml_common::to_plantuml(m.access()) << m.name(); ostr << "("; if (m_config.generate_method_arguments() != @@ -195,7 +195,7 @@ void generator::generate( << m_model.to_alias(uns.relative(destination)); if (!r.label().empty()) { - relstr << " : " << plantuml_common::to_plantuml(r.scope()) + relstr << " : " << plantuml_common::to_plantuml(r.access()) << r.label(); rendered_relations.emplace(r.label()); } @@ -222,7 +222,7 @@ void generator::generate( // Process members // for (const auto &m : c.members()) { - if (!m_model.should_include(m.scope())) + if (!m_model.should_include(m.access())) continue; if (!m_config.include_relations_also_as_members() && @@ -232,7 +232,7 @@ void generator::generate( if (m.is_static()) ostr << "{static} "; - ostr << plantuml_common::to_plantuml(m.scope()) << m.name() << " : " + ostr << plantuml_common::to_plantuml(m.access()) << m.name() << " : " << uns.relative(m.type()); if (m_config.generate_links) { diff --git a/src/class_diagram/generators/plantuml/class_diagram_generator.h b/src/class_diagram/generators/plantuml/class_diagram_generator.h index 74119724..9b8ec30d 100644 --- a/src/class_diagram/generators/plantuml/class_diagram_generator.h +++ b/src/class_diagram/generators/plantuml/class_diagram_generator.h @@ -49,9 +49,9 @@ using common_generator = using clanguml::class_diagram::model::class_; using clanguml::class_diagram::model::enum_; +using clanguml::common::model::access_t; using clanguml::common::model::package; using clanguml::common::model::relationship_t; -using clanguml::common::model::scope_t; using namespace clanguml::util; diff --git a/src/class_diagram/model/class_element.cc b/src/class_diagram/model/class_element.cc index 65688e14..8c21456f 100644 --- a/src/class_diagram/model/class_element.cc +++ b/src/class_diagram/model/class_element.cc @@ -20,15 +20,15 @@ namespace clanguml::class_diagram::model { -class_element::class_element(common::model::scope_t scope, +class_element::class_element(common::model::access_t access, const std::string &name, const std::string &type) - : scope_{scope} + : access_{access} , name_{name} , type_{type} { } -common::model::scope_t class_element::scope() const { return scope_; } +common::model::access_t class_element::access() const { return access_; } std::string class_element::name() const { return name_; } @@ -39,7 +39,7 @@ inja::json class_element::context() const inja::json ctx; ctx["name"] = name(); ctx["type"] = type(); - ctx["scope"] = to_string(scope()); + ctx["access"] = to_string(access()); return ctx; } } diff --git a/src/class_diagram/model/class_element.h b/src/class_diagram/model/class_element.h index 765fce87..441c26c9 100644 --- a/src/class_diagram/model/class_element.h +++ b/src/class_diagram/model/class_element.h @@ -29,17 +29,17 @@ namespace clanguml::class_diagram::model { class class_element : public common::model::decorated_element, public common::model::source_location { public: - class_element(common::model::scope_t scope, const std::string &name, + class_element(common::model::access_t scope, const std::string &name, const std::string &type); - common::model::scope_t scope() const; + common::model::access_t access() const; std::string name() const; std::string type() const; virtual inja::json context() const; private: - common::model::scope_t scope_; + common::model::access_t access_; std::string name_; std::string type_; }; diff --git a/src/class_diagram/model/class_member.cc b/src/class_diagram/model/class_member.cc index 360f76b0..8bf041e6 100644 --- a/src/class_diagram/model/class_member.cc +++ b/src/class_diagram/model/class_member.cc @@ -20,9 +20,9 @@ namespace clanguml::class_diagram::model { -class_member::class_member(common::model::scope_t scope, +class_member::class_member(common::model::access_t access, const std::string &name, const std::string &type) - : class_element{scope, name, type} + : class_element{access, name, type} { } diff --git a/src/class_diagram/model/class_member.h b/src/class_diagram/model/class_member.h index f339d4cb..39b29983 100644 --- a/src/class_diagram/model/class_member.h +++ b/src/class_diagram/model/class_member.h @@ -25,7 +25,7 @@ namespace clanguml::class_diagram::model { class class_member : public class_element { public: - class_member(common::model::scope_t scope, const std::string &name, + class_member(common::model::access_t access, const std::string &name, const std::string &type); bool is_relationship() const; diff --git a/src/class_diagram/model/class_method.cc b/src/class_diagram/model/class_method.cc index 38f44bfe..cef773cd 100644 --- a/src/class_diagram/model/class_method.cc +++ b/src/class_diagram/model/class_method.cc @@ -20,9 +20,9 @@ namespace clanguml::class_diagram::model { -class_method::class_method(common::model::scope_t scope, +class_method::class_method(common::model::access_t access, const std::string &name, const std::string &type) - : class_element{scope, name, type} + : class_element{access, name, type} { } diff --git a/src/class_diagram/model/class_method.h b/src/class_diagram/model/class_method.h index 024fbac7..f35ad492 100644 --- a/src/class_diagram/model/class_method.h +++ b/src/class_diagram/model/class_method.h @@ -27,7 +27,7 @@ namespace clanguml::class_diagram::model { class class_method : public class_element { public: - class_method(common::model::scope_t scope, const std::string &name, + class_method(common::model::access_t access, const std::string &name, const std::string &type); bool is_pure_virtual() const; diff --git a/src/class_diagram/visitor/translation_unit_visitor.cc b/src/class_diagram/visitor/translation_unit_visitor.cc index 37636246..9320c680 100644 --- a/src/class_diagram/visitor/translation_unit_visitor.cc +++ b/src/class_diagram/visitor/translation_unit_visitor.cc @@ -46,28 +46,27 @@ using clanguml::class_diagram::model::type_alias; using clanguml::common::model::access_t; using clanguml::common::model::relationship; using clanguml::common::model::relationship_t; -using clanguml::common::model::scope_t; namespace detail { -scope_t cpp_access_specifier_to_scope( +access_t cpp_access_specifier_to_access( cppast::cpp_access_specifier_kind access_specifier) { - scope_t scope = scope_t::kPublic; + auto access = access_t::kPublic; switch (access_specifier) { case cppast::cpp_access_specifier_kind::cpp_public: - scope = scope_t::kPublic; + access = access_t::kPublic; break; case cppast::cpp_access_specifier_kind::cpp_private: - scope = scope_t::kPrivate; + access = access_t::kPrivate; break; case cppast::cpp_access_specifier_kind::cpp_protected: - scope = scope_t::kProtected; + access = access_t::kProtected; break; default: break; } - return scope; + return access; } } @@ -662,7 +661,7 @@ void translation_unit_visitor::process_class_children( child.scope_name() ? child.scope_name().value().name() : ""); - process_friend(fr, c); + process_friend(fr, c, last_access_specifier); } else if (cppast::is_friended(child)) { auto &fr = @@ -670,7 +669,7 @@ void translation_unit_visitor::process_class_children( LOG_DBG("Found friend template: {}", child.name()); - process_friend(fr, c); + process_friend(fr, c, last_access_specifier); } else { LOG_DBG("Found some other class child: {} ({})", child.name(), @@ -717,7 +716,7 @@ bool translation_unit_visitor::process_field_with_template_instantiation( relationship_type = relationship_t::kAggregation; relationship rr{relationship_type, tinst.full_name(), - detail::cpp_access_specifier_to_scope(as), mv.name()}; + detail::cpp_access_specifier_to_access(as), mv.name()}; rr.set_style(m.style_spec()); // Process field decorators @@ -765,7 +764,7 @@ void translation_unit_visitor::process_field( type_name = "<>"; class_member m{ - detail::cpp_access_specifier_to_scope(as), mv.name(), type_name}; + detail::cpp_access_specifier_to_access(as), mv.name(), type_name}; if (mv.location().has_value()) { m.set_file(mv.location().value().file); @@ -816,7 +815,7 @@ void translation_unit_visitor::process_field( for (const auto &[type, relationship_type] : relationships) { if (relationship_type != relationship_t::kNone) { - relationship r{relationship_type, type, m.scope(), m.name()}; + relationship r{relationship_type, type, m.access(), m.name()}; r.set_style(m.style_spec()); auto [decorator_rtype, decorator_rmult] = m.get_relationship(); @@ -848,7 +847,7 @@ void translation_unit_visitor::process_anonymous_enum( for (const auto &ev : en) { if (ev.kind() == cppast::cpp_entity_kind::enum_value_t) { class_member m{ - detail::cpp_access_specifier_to_scope(as), ev.name(), "enum"}; + detail::cpp_access_specifier_to_access(as), ev.name(), "enum"}; c.add_member(std::move(m)); } } @@ -858,7 +857,7 @@ void translation_unit_visitor::process_static_field( const cppast::cpp_variable &mv, class_ &c, cppast::cpp_access_specifier_kind as) { - class_member m{detail::cpp_access_specifier_to_scope(as), mv.name(), + class_member m{detail::cpp_access_specifier_to_access(as), mv.name(), cppast::to_string(mv.type())}; if (mv.location().has_value()) { @@ -881,7 +880,7 @@ void translation_unit_visitor::process_method( const cppast::cpp_member_function &mf, class_ &c, cppast::cpp_access_specifier_kind as) { - class_method m{detail::cpp_access_specifier_to_scope(as), + class_method m{detail::cpp_access_specifier_to_access(as), util::trim(mf.name()), cppast::to_string(mf.return_type())}; m.is_pure_virtual(cppast::is_pure(mf.virtual_info())); m.is_virtual(cppast::is_virtual(mf.virtual_info())); @@ -923,8 +922,8 @@ void translation_unit_visitor::process_template_method( static_cast(mf.function()) .return_type()); - class_method m{ - detail::cpp_access_specifier_to_scope(as), util::trim(mf.name()), type}; + class_method m{detail::cpp_access_specifier_to_access(as), + util::trim(mf.name()), type}; m.is_pure_virtual(false); m.is_virtual(false); m.is_const(cppast::is_const( @@ -964,7 +963,7 @@ void translation_unit_visitor::process_static_method( const cppast::cpp_function &mf, class_ &c, cppast::cpp_access_specifier_kind as) { - class_method m{detail::cpp_access_specifier_to_scope(as), + class_method m{detail::cpp_access_specifier_to_access(as), util::trim(mf.name()), cppast::to_string(mf.return_type())}; m.is_pure_virtual(false); m.is_virtual(false); @@ -998,7 +997,7 @@ void translation_unit_visitor::process_constructor( const cppast::cpp_constructor &mf, class_ &c, cppast::cpp_access_specifier_kind as) { - class_method m{detail::cpp_access_specifier_to_scope(as), + class_method m{detail::cpp_access_specifier_to_access(as), util::trim(mf.name()), "void"}; m.is_pure_virtual(false); m.is_virtual(false); @@ -1030,7 +1029,7 @@ void translation_unit_visitor::process_destructor( const cppast::cpp_destructor &mf, class_ &c, cppast::cpp_access_specifier_kind as) { - class_method m{detail::cpp_access_specifier_to_scope(as), + class_method m{detail::cpp_access_specifier_to_access(as), util::trim(mf.name()), "void"}; m.is_pure_virtual(false); m.is_virtual(cppast::is_virtual(mf.virtual_info())); @@ -1230,8 +1229,8 @@ void translation_unit_visitor::process_template_template_parameter( parent.add_template({"", t.name() + "<>"}); } -void translation_unit_visitor::process_friend( - const cppast::cpp_friend &f, class_ &parent) +void translation_unit_visitor::process_friend(const cppast::cpp_friend &f, + class_ &parent, cppast::cpp_access_specifier_kind as) { // Only process friends to other classes or class templates if (!f.entity() || @@ -1240,8 +1239,8 @@ void translation_unit_visitor::process_friend( cppast::cpp_entity_kind::class_template_t)) return; - relationship r{ - relationship_t::kFriendship, "", scope_t::kNone, "<>"}; + relationship r{relationship_t::kFriendship, "", + detail::cpp_access_specifier_to_access(as), "<>"}; if (f.comment().has_value()) r.add_decorators(decorators::parse(f.comment().value())); diff --git a/src/class_diagram/visitor/translation_unit_visitor.h b/src/class_diagram/visitor/translation_unit_visitor.h index 07bcc5e5..0a611b5b 100644 --- a/src/class_diagram/visitor/translation_unit_visitor.h +++ b/src/class_diagram/visitor/translation_unit_visitor.h @@ -124,7 +124,8 @@ public: clanguml::class_diagram::model::class_ &parent); void process_friend(const cppast::cpp_friend &t, - clanguml::class_diagram::model::class_ &parent); + clanguml::class_diagram::model::class_ &parent, + cppast::cpp_access_specifier_kind as); void process_namespace(const cppast::cpp_entity &e, const cppast::cpp_namespace &ns_declaration); diff --git a/src/common/generators/plantuml/generator.cc b/src/common/generators/plantuml/generator.cc index 139a04b8..eea26a9c 100644 --- a/src/common/generators/plantuml/generator.cc +++ b/src/common/generators/plantuml/generator.cc @@ -42,14 +42,14 @@ std::string to_plantuml(relationship_t r, std::string style) } } -std::string to_plantuml(scope_t scope) +std::string to_plantuml(access_t scope) { switch (scope) { - case scope_t::kPublic: + case access_t::kPublic: return "+"; - case scope_t::kProtected: + case access_t::kProtected: return "#"; - case scope_t::kPrivate: + case access_t::kPrivate: return "-"; default: return ""; diff --git a/src/common/generators/plantuml/generator.h b/src/common/generators/plantuml/generator.h index 1ff63d06..4d40604f 100644 --- a/src/common/generators/plantuml/generator.h +++ b/src/common/generators/plantuml/generator.h @@ -30,13 +30,13 @@ namespace clanguml::common::generators::plantuml { +using clanguml::common::model::access_t; using clanguml::common::model::element; using clanguml::common::model::message_t; using clanguml::common::model::relationship_t; -using clanguml::common::model::scope_t; std::string to_plantuml(relationship_t r, std::string style); -std::string to_plantuml(scope_t scope); +std::string to_plantuml(access_t scope); std::string to_plantuml(message_t r); template class generator { diff --git a/src/common/model/diagram.cc b/src/common/model/diagram.cc index 98e84f9d..7330236c 100644 --- a/src/common/model/diagram.cc +++ b/src/common/model/diagram.cc @@ -68,7 +68,7 @@ bool diagram::should_include(const relationship_t r) const return filter_->should_include(r); } -bool diagram::should_include(const scope_t s) const +bool diagram::should_include(const access_t s) const { if (filter_.get() == nullptr) return true; diff --git a/src/common/model/diagram.h b/src/common/model/diagram.h index eeefee27..8fb8aff0 100644 --- a/src/common/model/diagram.h +++ b/src/common/model/diagram.h @@ -52,7 +52,7 @@ public: 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 access_t s) const; bool should_include(const namespace_ &ns, const std::string &name) const; private: diff --git a/src/common/model/diagram_filter.cc b/src/common/model/diagram_filter.cc index 165b6347..2a801d87 100644 --- a/src/common/model/diagram_filter.cc +++ b/src/common/model/diagram_filter.cc @@ -20,6 +20,11 @@ namespace clanguml::common::model { +filter_visitor::filter_visitor(filter_t type) + : type_{type} +{ +} + std::optional filter_visitor::match( const diagram &d, const common::model::element &e) const { @@ -33,7 +38,7 @@ std::optional filter_visitor::match( } std::optional filter_visitor::match( - const diagram &d, const common::model::scope_t &r) const + const diagram &d, const common::model::access_t &a) const { return {}; } @@ -172,20 +177,20 @@ std::optional relationship_filter::match( [&r](const auto &rel) { return r == rel; }); } -scope_filter::scope_filter(filter_t type, std::vector scopes) +access_filter::access_filter(filter_t type, std::vector access) : filter_visitor{type} - , scopes_{scopes} + , access_{access} { } -std::optional scope_filter::match( - const diagram &d, const scope_t &s) const +std::optional access_filter::match( + const diagram &d, const access_t &a) const { - if (scopes_.empty()) + if (access_.empty()) return {}; - return std::any_of(scopes_.begin(), scopes_.end(), - [&s](const auto &scope) { return s == scope; }); + return std::any_of(access_.begin(), access_.end(), + [&a](const auto &access) { return a == access; }); } context_filter::context_filter(filter_t type, std::vector context) @@ -246,8 +251,8 @@ void diagram_filter::init_filters(const config::diagram &c) filter_t::kInclusive, c.include().namespaces)); 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().access)); inclusive_.emplace_back(std::make_unique( filter_t::kInclusive, c.include().elements)); inclusive_.emplace_back(std::make_unique( @@ -264,8 +269,8 @@ void diagram_filter::init_filters(const config::diagram &c) filter_t::kExclusive, c.exclude().elements)); exclusive_.emplace_back(std::make_unique( filter_t::kExclusive, c.exclude().relationships)); - exclusive_.emplace_back(std::make_unique( - filter_t::kExclusive, c.exclude().scopes)); + exclusive_.emplace_back(std::make_unique( + filter_t::kExclusive, c.exclude().access)); exclusive_.emplace_back(std::make_unique( filter_t::kExclusive, c.exclude().subclasses)); exclusive_.emplace_back(std::make_unique( diff --git a/src/common/model/diagram_filter.h b/src/common/model/diagram_filter.h index 8e97314f..ddc8ac5b 100644 --- a/src/common/model/diagram_filter.h +++ b/src/common/model/diagram_filter.h @@ -32,10 +32,7 @@ enum filter_t { kInclusive, kExclusive }; class filter_visitor { public: - filter_visitor(filter_t type) - : type_{type} - { - } + filter_visitor(filter_t type); virtual std::optional match( const diagram &d, const common::model::element &e) const; @@ -44,7 +41,7 @@ public: const diagram &d, const common::model::relationship_t &r) const; virtual std::optional match( - const diagram &d, const common::model::scope_t &r) const; + const diagram &d, const common::model::access_t &a) const; virtual std::optional match( const diagram &d, const common::model::namespace_ &ns) const; @@ -102,14 +99,14 @@ private: std::vector relationships_; }; -struct scope_filter : public filter_visitor { - scope_filter(filter_t type, std::vector scopes); +struct access_filter : public filter_visitor { + access_filter(filter_t type, std::vector access); std::optional match( - const diagram &d, const scope_t &s) const override; + const diagram &d, const access_t &a) const override; private: - std::vector scopes_; + std::vector access_; }; struct context_filter : public filter_visitor { diff --git a/src/common/model/enums.cc b/src/common/model/enums.cc index df734e6d..f1336fa6 100644 --- a/src/common/model/enums.cc +++ b/src/common/model/enums.cc @@ -49,22 +49,6 @@ std::string to_string(relationship_t r) } } -std::string to_string(scope_t s) -{ - switch (s) { - case scope_t::kPublic: - return "public"; - case scope_t::kProtected: - return "protected"; - case scope_t::kPrivate: - return "private"; - case scope_t::kNone: - return "none"; - default: - assert(false); - } -} - std::string to_string(access_t a) { switch (a) { diff --git a/src/common/model/enums.h b/src/common/model/enums.h index 2b553562..24748512 100644 --- a/src/common/model/enums.h +++ b/src/common/model/enums.h @@ -23,8 +23,6 @@ namespace clanguml::common::model { enum class access_t { kPublic, kProtected, kPrivate }; -enum class scope_t { kPublic, kProtected, kPrivate, kNone }; - enum class relationship_t { kNone, kExtension, @@ -42,8 +40,6 @@ enum class message_t { kCall, kReturn }; std::string to_string(relationship_t r); -std::string to_string(scope_t r); - std::string to_string(access_t r); std::string to_string(message_t r); diff --git a/src/common/model/relationship.cc b/src/common/model/relationship.cc index f384e40a..28b0d961 100644 --- a/src/common/model/relationship.cc +++ b/src/common/model/relationship.cc @@ -21,12 +21,12 @@ namespace clanguml::common::model { relationship::relationship(relationship_t type, const std::string &destination, - scope_t scope, const std::string &label, + access_t access, const std::string &label, const std::string &multiplicity_source, const std::string &multiplicity_destination) : type_{type} , destination_{destination} - , scope_{scope} + , access_{access} , label_{label} , multiplicity_source_{multiplicity_source} , multiplicity_destination_{multiplicity_destination} @@ -70,9 +70,9 @@ void relationship::set_label(const std::string &label) { label_ = label; } std::string relationship::label() const { return label_; } -void relationship::set_scope(scope_t scope) noexcept { scope_ = scope; } +void relationship::set_access(access_t access) noexcept { access_ = access; } -scope_t relationship::scope() const noexcept { return scope_; } +access_t relationship::access() const noexcept { return access_; } bool operator==(const relationship &l, const relationship &r) { diff --git a/src/common/model/relationship.h b/src/common/model/relationship.h index d75addf8..6a695528 100644 --- a/src/common/model/relationship.h +++ b/src/common/model/relationship.h @@ -28,7 +28,7 @@ class relationship : public common::model::decorated_element, public common::model::stylable_element { public: relationship(relationship_t type, const std::string &destination, - scope_t scope = scope_t::kNone, const std::string &label = "", + access_t access = access_t::kPublic, const std::string &label = "", const std::string &multiplicity_source = "", const std::string &multiplicity_destination = ""); @@ -50,8 +50,8 @@ public: void set_label(const std::string &label); std::string label() const; - void set_scope(scope_t scope) noexcept; - scope_t scope() const noexcept; + void set_access(access_t scope) noexcept; + access_t access() const noexcept; friend bool operator==(const relationship &l, const relationship &r); @@ -61,6 +61,6 @@ private: std::string multiplicity_source_; std::string multiplicity_destination_; std::string label_; - scope_t scope_{scope_t::kNone}; + access_t access_{access_t::kPublic}; }; } diff --git a/src/config/config.cc b/src/config/config.cc index 45c7d9f8..6084be63 100644 --- a/src/config/config.cc +++ b/src/config/config.cc @@ -151,8 +151,8 @@ template <> void append_value(plantuml &l, const plantuml &r) } namespace YAML { +using clanguml::common::model::access_t; using clanguml::common::model::relationship_t; -using clanguml::common::model::scope_t; using clanguml::config::class_diagram; using clanguml::config::config; using clanguml::config::filter; @@ -234,15 +234,18 @@ std::shared_ptr parse_diagram_config(const Node &d) return {}; } -template <> struct convert { - static bool decode(const Node &node, scope_t &rhs) +// +// config access_t decoder +// +template <> struct convert { + static bool decode(const Node &node, access_t &rhs) { if (node.as() == "public") - rhs = scope_t::kPublic; + rhs = access_t::kPublic; else if (node.as() == "protected") - rhs = scope_t::kProtected; + rhs = access_t::kProtected; else if (node.as() == "private") - rhs = scope_t::kPrivate; + rhs = access_t::kPrivate; else return false; @@ -368,8 +371,8 @@ template <> struct convert { if (node["elements"]) rhs.elements = node["elements"].as(); - if (node["scopes"]) - rhs.scopes = node["scopes"].as(); + if (node["access"]) + rhs.access = node["access"].as(); if (node["subclasses"]) rhs.subclasses = node["subclasses"].as(); diff --git a/src/config/config.h b/src/config/config.h index 482a52a4..11db75fe 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -60,7 +60,7 @@ struct filter { // - public // - protected // - private - std::vector scopes; + std::vector access; std::vector subclasses; diff --git a/src/package_diagram/generators/plantuml/package_diagram_generator.h b/src/package_diagram/generators/plantuml/package_diagram_generator.h index 075bcef0..bc416afa 100644 --- a/src/package_diagram/generators/plantuml/package_diagram_generator.h +++ b/src/package_diagram/generators/plantuml/package_diagram_generator.h @@ -46,9 +46,9 @@ template using common_generator = clanguml::common::generators::plantuml::generator; +using clanguml::common::model::access_t; using clanguml::common::model::package; using clanguml::common::model::relationship_t; -using clanguml::common::model::scope_t; using namespace clanguml::util; class generator : public common_generator { diff --git a/src/package_diagram/visitor/translation_unit_visitor.cc b/src/package_diagram/visitor/translation_unit_visitor.cc index 7bda748e..b0632fc9 100644 --- a/src/package_diagram/visitor/translation_unit_visitor.cc +++ b/src/package_diagram/visitor/translation_unit_visitor.cc @@ -42,29 +42,28 @@ using clanguml::common::model::access_t; using clanguml::common::model::package; using clanguml::common::model::relationship; using clanguml::common::model::relationship_t; -using clanguml::common::model::scope_t; using clanguml::package_diagram::model::diagram; namespace detail { -scope_t cpp_access_specifier_to_scope( +access_t cpp_access_specifier_to_access( cppast::cpp_access_specifier_kind access_specifier) { - scope_t scope = scope_t::kPublic; + access_t access = access_t::kPublic; switch (access_specifier) { case cppast::cpp_access_specifier_kind::cpp_public: - scope = scope_t::kPublic; + access = access_t::kPublic; break; case cppast::cpp_access_specifier_kind::cpp_private: - scope = scope_t::kPrivate; + access = access_t::kPrivate; break; case cppast::cpp_access_specifier_kind::cpp_protected: - scope = scope_t::kProtected; + access = access_t::kProtected; break; default: break; } - return scope; + return access; } } diff --git a/tests/t00011/test_case.h b/tests/t00011/test_case.h index 49465640..da15bf51 100644 --- a/tests/t00011/test_case.h +++ b/tests/t00011/test_case.h @@ -37,7 +37,7 @@ TEST_CASE("t00011", "[test-case][class]") REQUIRE_THAT(puml, IsClass(_A("B"))); REQUIRE_THAT(puml, IsClass(_A("D"))); - REQUIRE_THAT(puml, IsFriend(_A("A"), _A("B"))); + REQUIRE_THAT(puml, IsFriend(_A("A"), _A("B"))); // REQUIRE_THAT(puml, IsFriend(_A("A"), _A("D"))); save_puml( diff --git a/tests/t00040/.clang-uml b/tests/t00040/.clang-uml index 5e7a1213..20744d33 100644 --- a/tests/t00040/.clang-uml +++ b/tests/t00040/.clang-uml @@ -11,7 +11,7 @@ diagrams: include: namespaces: - clanguml::t00040 - scopes: + access: - public - protected exclude: diff --git a/tests/test_cases.h b/tests/test_cases.h index c7d07c69..030f9849 100644 --- a/tests/test_cases.h +++ b/tests/test_cases.h @@ -264,13 +264,6 @@ ContainsMatcher IsAssociation(std::string const &from, std::string const &to, fmt::format(format_string, from, to, label), caseSensitivity)); } -ContainsMatcher IsFriend(std::string const &from, std::string const &to, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString( - fmt::format("{} <.. {} : <>", from, to), caseSensitivity)); -} - ContainsMatcher IsComposition(std::string const &from, std::string const &to, std::string const &label, std::string multiplicity_source = "", std::string multiplicity_dest = "", @@ -424,6 +417,24 @@ ContainsMatcher IsField(std::string const &name, CasedString(pattern + " : " + type, caseSensitivity)); } +template +ContainsMatcher IsFriend(std::string const &from, std::string const &to, + CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) +{ + std::string pattern; + + if constexpr (has_type()) + pattern = "+"; + else if constexpr (has_type()) + pattern = "#"; + else + pattern = "-"; + + return ContainsMatcher( + CasedString(fmt::format("{} <.. {} : {}<>", from, to, pattern), + caseSensitivity)); +} + ContainsMatcher IsPackage(std::string const &str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) { diff --git a/tests/test_cases.yaml b/tests/test_cases.yaml index cef80515..bafd015a 100644 --- a/tests/test_cases.yaml +++ b/tests/test_cases.yaml @@ -115,7 +115,7 @@ test_cases: title: Subclass class diagram filter test description: - name: t00040 - title: Relationship and scope filter test + title: Relationship and access filter test description: Sequence diagrams: - name: t20001