Changed scope_t to access_t and fixed friend access specifier handling

This commit is contained in:
Bartek Kryza
2022-03-30 23:27:46 +02:00
parent a216a81e19
commit a8b57e4eb1
30 changed files with 134 additions and 137 deletions

View File

@@ -11,17 +11,19 @@
* `glob` - list of glob patterns to match source code files for analysis * `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`) * `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`) * `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: * `include` - definition of inclusion patterns:
* `namespaces` - list of namespaces to include * `namespaces` - list of namespaces to include
* `relationships` - list of relationships to include * `relationships` - list of relationships to include
* `entity_types` - list of entity types to include (e.g. `class`, `enum`) * `elements` - list of elements, i.e. specific classes, enums, templates to include
* `scopes` - list of visibility scopes to include (e.g. `private`) * `access` - list of visibility scopes to include (e.g. `private`)
* `subclasses` - include only subclasses of specified classes (and themselves)
* `exclude` - definition of excqlusion patterns: * `exclude` - definition of excqlusion patterns:
* `namespaces` - list of namespaces to exclude * `namespaces` - list of namespaces to exclude
* `relationships` - list of relationships to exclude * `relationships` - list of relationships to exclude
* `entity_types` - list of entity types to exclude (e.g. `class`, `enum`) * `elements` - list of elements, i.e. specific classes, enums, templates to exclude
* `scopes` - list of visibility scopes to exclude (e.g. `private`) * `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) * `layout` - add layout hints for entities (classes, packages)
* `plantuml` - verbatim PlantUML directives which should be added to a diagram * `plantuml` - verbatim PlantUML directives which should be added to a diagram
* `before` - list of directives which will be added before the generated diagram * `before` - list of directives which will be added before the generated diagram
@@ -81,7 +83,7 @@ diagrams:
- clanguml::class_diagram::model - clanguml::class_diagram::model
exclude: exclude:
# Do not include private members and methods in the diagram # Do not include private members and methods in the diagram
scopes: access:
- private - private
layout: layout:
# Add layout hints for PlantUML # Add layout hints for PlantUML

View File

@@ -25,7 +25,7 @@ diagrams:
exclude: exclude:
namespaces: namespaces:
- cppast::detail - cppast::detail
scopes: access:
- public - public
- protected - protected
- private - private
@@ -73,7 +73,7 @@ diagrams:
- cppast::detail - cppast::detail
entity_types: entity_types:
- enums - enums
scopes: access:
- public - public
- protected - protected
- private - private
@@ -93,7 +93,7 @@ diagrams:
exclude: exclude:
namespaces: namespaces:
- cppast::detail - cppast::detail
scopes: access:
- public - public
- protected - protected
- private - private

View File

@@ -110,7 +110,7 @@ void generator::generate(
// Process methods // Process methods
// //
for (const auto &m : c.methods()) { for (const auto &m : c.methods()) {
if (!m_model.should_include(m.scope())) if (!m_model.should_include(m.access()))
continue; continue;
if (m.is_pure_virtual()) if (m.is_pure_virtual())
@@ -121,7 +121,7 @@ void generator::generate(
std::string type{m.type()}; std::string type{m.type()};
ostr << plantuml_common::to_plantuml(m.scope()) << m.name(); ostr << plantuml_common::to_plantuml(m.access()) << m.name();
ostr << "("; ostr << "(";
if (m_config.generate_method_arguments() != if (m_config.generate_method_arguments() !=
@@ -195,7 +195,7 @@ void generator::generate(
<< m_model.to_alias(uns.relative(destination)); << m_model.to_alias(uns.relative(destination));
if (!r.label().empty()) { if (!r.label().empty()) {
relstr << " : " << plantuml_common::to_plantuml(r.scope()) relstr << " : " << plantuml_common::to_plantuml(r.access())
<< r.label(); << r.label();
rendered_relations.emplace(r.label()); rendered_relations.emplace(r.label());
} }
@@ -222,7 +222,7 @@ void generator::generate(
// Process members // Process members
// //
for (const auto &m : c.members()) { for (const auto &m : c.members()) {
if (!m_model.should_include(m.scope())) if (!m_model.should_include(m.access()))
continue; continue;
if (!m_config.include_relations_also_as_members() && if (!m_config.include_relations_also_as_members() &&
@@ -232,7 +232,7 @@ void generator::generate(
if (m.is_static()) if (m.is_static())
ostr << "{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()); << uns.relative(m.type());
if (m_config.generate_links) { if (m_config.generate_links) {

View File

@@ -49,9 +49,9 @@ using common_generator =
using clanguml::class_diagram::model::class_; using clanguml::class_diagram::model::class_;
using clanguml::class_diagram::model::enum_; using clanguml::class_diagram::model::enum_;
using clanguml::common::model::access_t;
using clanguml::common::model::package; using clanguml::common::model::package;
using clanguml::common::model::relationship_t; using clanguml::common::model::relationship_t;
using clanguml::common::model::scope_t;
using namespace clanguml::util; using namespace clanguml::util;

View File

@@ -20,15 +20,15 @@
namespace clanguml::class_diagram::model { 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) const std::string &name, const std::string &type)
: scope_{scope} : access_{access}
, name_{name} , name_{name}
, type_{type} , 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_; } std::string class_element::name() const { return name_; }
@@ -39,7 +39,7 @@ inja::json class_element::context() const
inja::json ctx; inja::json ctx;
ctx["name"] = name(); ctx["name"] = name();
ctx["type"] = type(); ctx["type"] = type();
ctx["scope"] = to_string(scope()); ctx["access"] = to_string(access());
return ctx; return ctx;
} }
} }

View File

@@ -29,17 +29,17 @@ namespace clanguml::class_diagram::model {
class class_element : public common::model::decorated_element, class class_element : public common::model::decorated_element,
public common::model::source_location { public common::model::source_location {
public: 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); const std::string &type);
common::model::scope_t scope() const; common::model::access_t access() const;
std::string name() const; std::string name() const;
std::string type() const; std::string type() const;
virtual inja::json context() const; virtual inja::json context() const;
private: private:
common::model::scope_t scope_; common::model::access_t access_;
std::string name_; std::string name_;
std::string type_; std::string type_;
}; };

View File

@@ -20,9 +20,9 @@
namespace clanguml::class_diagram::model { 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) const std::string &name, const std::string &type)
: class_element{scope, name, type} : class_element{access, name, type}
{ {
} }

View File

@@ -25,7 +25,7 @@ namespace clanguml::class_diagram::model {
class class_member : public class_element { class class_member : public class_element {
public: 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); const std::string &type);
bool is_relationship() const; bool is_relationship() const;

View File

@@ -20,9 +20,9 @@
namespace clanguml::class_diagram::model { 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) const std::string &name, const std::string &type)
: class_element{scope, name, type} : class_element{access, name, type}
{ {
} }

View File

@@ -27,7 +27,7 @@ namespace clanguml::class_diagram::model {
class class_method : public class_element { class class_method : public class_element {
public: 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); const std::string &type);
bool is_pure_virtual() const; bool is_pure_virtual() const;

View File

@@ -46,28 +46,27 @@ using clanguml::class_diagram::model::type_alias;
using clanguml::common::model::access_t; using clanguml::common::model::access_t;
using clanguml::common::model::relationship; using clanguml::common::model::relationship;
using clanguml::common::model::relationship_t; using clanguml::common::model::relationship_t;
using clanguml::common::model::scope_t;
namespace detail { namespace detail {
scope_t cpp_access_specifier_to_scope( access_t cpp_access_specifier_to_access(
cppast::cpp_access_specifier_kind access_specifier) cppast::cpp_access_specifier_kind access_specifier)
{ {
scope_t scope = scope_t::kPublic; auto access = access_t::kPublic;
switch (access_specifier) { switch (access_specifier) {
case cppast::cpp_access_specifier_kind::cpp_public: case cppast::cpp_access_specifier_kind::cpp_public:
scope = scope_t::kPublic; access = access_t::kPublic;
break; break;
case cppast::cpp_access_specifier_kind::cpp_private: case cppast::cpp_access_specifier_kind::cpp_private:
scope = scope_t::kPrivate; access = access_t::kPrivate;
break; break;
case cppast::cpp_access_specifier_kind::cpp_protected: case cppast::cpp_access_specifier_kind::cpp_protected:
scope = scope_t::kProtected; access = access_t::kProtected;
break; break;
default: default:
break; break;
} }
return scope; return access;
} }
} }
@@ -662,7 +661,7 @@ void translation_unit_visitor::process_class_children(
child.scope_name() ? child.scope_name().value().name() child.scope_name() ? child.scope_name().value().name()
: "<no-scope>"); : "<no-scope>");
process_friend(fr, c); process_friend(fr, c, last_access_specifier);
} }
else if (cppast::is_friended(child)) { else if (cppast::is_friended(child)) {
auto &fr = auto &fr =
@@ -670,7 +669,7 @@ void translation_unit_visitor::process_class_children(
LOG_DBG("Found friend template: {}", child.name()); LOG_DBG("Found friend template: {}", child.name());
process_friend(fr, c); process_friend(fr, c, last_access_specifier);
} }
else { else {
LOG_DBG("Found some other class child: {} ({})", child.name(), 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_type = relationship_t::kAggregation;
relationship rr{relationship_type, tinst.full_name(), 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()); rr.set_style(m.style_spec());
// Process field decorators // Process field decorators
@@ -765,7 +764,7 @@ void translation_unit_visitor::process_field(
type_name = "<<anonymous>>"; type_name = "<<anonymous>>";
class_member m{ 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()) { if (mv.location().has_value()) {
m.set_file(mv.location().value().file); m.set_file(mv.location().value().file);
@@ -816,7 +815,7 @@ void translation_unit_visitor::process_field(
for (const auto &[type, relationship_type] : relationships) { for (const auto &[type, relationship_type] : relationships) {
if (relationship_type != relationship_t::kNone) { 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()); r.set_style(m.style_spec());
auto [decorator_rtype, decorator_rmult] = m.get_relationship(); auto [decorator_rtype, decorator_rmult] = m.get_relationship();
@@ -848,7 +847,7 @@ void translation_unit_visitor::process_anonymous_enum(
for (const auto &ev : en) { for (const auto &ev : en) {
if (ev.kind() == cppast::cpp_entity_kind::enum_value_t) { if (ev.kind() == cppast::cpp_entity_kind::enum_value_t) {
class_member m{ 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)); c.add_member(std::move(m));
} }
} }
@@ -858,7 +857,7 @@ void translation_unit_visitor::process_static_field(
const cppast::cpp_variable &mv, class_ &c, const cppast::cpp_variable &mv, class_ &c,
cppast::cpp_access_specifier_kind as) 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())}; cppast::to_string(mv.type())};
if (mv.location().has_value()) { if (mv.location().has_value()) {
@@ -881,7 +880,7 @@ void translation_unit_visitor::process_method(
const cppast::cpp_member_function &mf, class_ &c, const cppast::cpp_member_function &mf, class_ &c,
cppast::cpp_access_specifier_kind as) 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())}; util::trim(mf.name()), cppast::to_string(mf.return_type())};
m.is_pure_virtual(cppast::is_pure(mf.virtual_info())); m.is_pure_virtual(cppast::is_pure(mf.virtual_info()));
m.is_virtual(cppast::is_virtual(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<const cppast::cpp_member_function &>(mf.function()) static_cast<const cppast::cpp_member_function &>(mf.function())
.return_type()); .return_type());
class_method m{ class_method m{detail::cpp_access_specifier_to_access(as),
detail::cpp_access_specifier_to_scope(as), util::trim(mf.name()), type}; util::trim(mf.name()), type};
m.is_pure_virtual(false); m.is_pure_virtual(false);
m.is_virtual(false); m.is_virtual(false);
m.is_const(cppast::is_const( m.is_const(cppast::is_const(
@@ -964,7 +963,7 @@ void translation_unit_visitor::process_static_method(
const cppast::cpp_function &mf, class_ &c, const cppast::cpp_function &mf, class_ &c,
cppast::cpp_access_specifier_kind as) 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())}; util::trim(mf.name()), cppast::to_string(mf.return_type())};
m.is_pure_virtual(false); m.is_pure_virtual(false);
m.is_virtual(false); m.is_virtual(false);
@@ -998,7 +997,7 @@ void translation_unit_visitor::process_constructor(
const cppast::cpp_constructor &mf, class_ &c, const cppast::cpp_constructor &mf, class_ &c,
cppast::cpp_access_specifier_kind as) 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"}; util::trim(mf.name()), "void"};
m.is_pure_virtual(false); m.is_pure_virtual(false);
m.is_virtual(false); m.is_virtual(false);
@@ -1030,7 +1029,7 @@ void translation_unit_visitor::process_destructor(
const cppast::cpp_destructor &mf, class_ &c, const cppast::cpp_destructor &mf, class_ &c,
cppast::cpp_access_specifier_kind as) 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"}; util::trim(mf.name()), "void"};
m.is_pure_virtual(false); m.is_pure_virtual(false);
m.is_virtual(cppast::is_virtual(mf.virtual_info())); 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() + "<>"}); parent.add_template({"", t.name() + "<>"});
} }
void translation_unit_visitor::process_friend( void translation_unit_visitor::process_friend(const cppast::cpp_friend &f,
const cppast::cpp_friend &f, class_ &parent) class_ &parent, cppast::cpp_access_specifier_kind as)
{ {
// Only process friends to other classes or class templates // Only process friends to other classes or class templates
if (!f.entity() || if (!f.entity() ||
@@ -1240,8 +1239,8 @@ void translation_unit_visitor::process_friend(
cppast::cpp_entity_kind::class_template_t)) cppast::cpp_entity_kind::class_template_t))
return; return;
relationship r{ relationship r{relationship_t::kFriendship, "",
relationship_t::kFriendship, "", scope_t::kNone, "<<friend>>"}; detail::cpp_access_specifier_to_access(as), "<<friend>>"};
if (f.comment().has_value()) if (f.comment().has_value())
r.add_decorators(decorators::parse(f.comment().value())); r.add_decorators(decorators::parse(f.comment().value()));

View File

@@ -124,7 +124,8 @@ public:
clanguml::class_diagram::model::class_ &parent); clanguml::class_diagram::model::class_ &parent);
void process_friend(const cppast::cpp_friend &t, 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, void process_namespace(const cppast::cpp_entity &e,
const cppast::cpp_namespace &ns_declaration); const cppast::cpp_namespace &ns_declaration);

View File

@@ -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) { switch (scope) {
case scope_t::kPublic: case access_t::kPublic:
return "+"; return "+";
case scope_t::kProtected: case access_t::kProtected:
return "#"; return "#";
case scope_t::kPrivate: case access_t::kPrivate:
return "-"; return "-";
default: default:
return ""; return "";

View File

@@ -30,13 +30,13 @@
namespace clanguml::common::generators::plantuml { namespace clanguml::common::generators::plantuml {
using clanguml::common::model::access_t;
using clanguml::common::model::element; using clanguml::common::model::element;
using clanguml::common::model::message_t; using clanguml::common::model::message_t;
using clanguml::common::model::relationship_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(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); std::string to_plantuml(message_t r);
template <typename ConfigType, typename DiagramType> class generator { template <typename ConfigType, typename DiagramType> class generator {

View File

@@ -68,7 +68,7 @@ bool diagram::should_include(const relationship_t r) const
return filter_->should_include(r); 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) if (filter_.get() == nullptr)
return true; return true;

View File

@@ -52,7 +52,7 @@ public:
bool should_include(const std::string &e) const; bool should_include(const std::string &e) const;
bool should_include(const relationship r) const; bool should_include(const relationship r) const;
bool should_include(const relationship_t 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; bool should_include(const namespace_ &ns, const std::string &name) const;
private: private:

View File

@@ -20,6 +20,11 @@
namespace clanguml::common::model { namespace clanguml::common::model {
filter_visitor::filter_visitor(filter_t type)
: type_{type}
{
}
std::optional<bool> filter_visitor::match( std::optional<bool> filter_visitor::match(
const diagram &d, const common::model::element &e) const const diagram &d, const common::model::element &e) const
{ {
@@ -33,7 +38,7 @@ std::optional<bool> filter_visitor::match(
} }
std::optional<bool> filter_visitor::match( std::optional<bool> filter_visitor::match(
const diagram &d, const common::model::scope_t &r) const const diagram &d, const common::model::access_t &a) const
{ {
return {}; return {};
} }
@@ -172,20 +177,20 @@ std::optional<bool> relationship_filter::match(
[&r](const auto &rel) { return r == rel; }); [&r](const auto &rel) { return r == rel; });
} }
scope_filter::scope_filter(filter_t type, std::vector<scope_t> scopes) access_filter::access_filter(filter_t type, std::vector<access_t> access)
: filter_visitor{type} : filter_visitor{type}
, scopes_{scopes} , access_{access}
{ {
} }
std::optional<bool> scope_filter::match( std::optional<bool> access_filter::match(
const diagram &d, const scope_t &s) const const diagram &d, const access_t &a) const
{ {
if (scopes_.empty()) if (access_.empty())
return {}; return {};
return std::any_of(scopes_.begin(), scopes_.end(), return std::any_of(access_.begin(), access_.end(),
[&s](const auto &scope) { return s == scope; }); [&a](const auto &access) { return a == access; });
} }
context_filter::context_filter(filter_t type, std::vector<std::string> context) context_filter::context_filter(filter_t type, std::vector<std::string> context)
@@ -246,8 +251,8 @@ void diagram_filter::init_filters(const config::diagram &c)
filter_t::kInclusive, c.include().namespaces)); filter_t::kInclusive, c.include().namespaces));
inclusive_.emplace_back(std::make_unique<relationship_filter>( inclusive_.emplace_back(std::make_unique<relationship_filter>(
filter_t::kInclusive, c.include().relationships)); filter_t::kInclusive, c.include().relationships));
inclusive_.emplace_back(std::make_unique<scope_filter>( inclusive_.emplace_back(std::make_unique<access_filter>(
filter_t::kInclusive, c.include().scopes)); filter_t::kInclusive, c.include().access));
inclusive_.emplace_back(std::make_unique<element_filter>( inclusive_.emplace_back(std::make_unique<element_filter>(
filter_t::kInclusive, c.include().elements)); filter_t::kInclusive, c.include().elements));
inclusive_.emplace_back(std::make_unique<subclass_filter>( inclusive_.emplace_back(std::make_unique<subclass_filter>(
@@ -264,8 +269,8 @@ void diagram_filter::init_filters(const config::diagram &c)
filter_t::kExclusive, c.exclude().elements)); filter_t::kExclusive, c.exclude().elements));
exclusive_.emplace_back(std::make_unique<relationship_filter>( exclusive_.emplace_back(std::make_unique<relationship_filter>(
filter_t::kExclusive, c.exclude().relationships)); filter_t::kExclusive, c.exclude().relationships));
exclusive_.emplace_back(std::make_unique<scope_filter>( exclusive_.emplace_back(std::make_unique<access_filter>(
filter_t::kExclusive, c.exclude().scopes)); filter_t::kExclusive, c.exclude().access));
exclusive_.emplace_back(std::make_unique<subclass_filter>( exclusive_.emplace_back(std::make_unique<subclass_filter>(
filter_t::kExclusive, c.exclude().subclasses)); filter_t::kExclusive, c.exclude().subclasses));
exclusive_.emplace_back(std::make_unique<context_filter>( exclusive_.emplace_back(std::make_unique<context_filter>(

View File

@@ -32,10 +32,7 @@ enum filter_t { kInclusive, kExclusive };
class filter_visitor { class filter_visitor {
public: public:
filter_visitor(filter_t type) filter_visitor(filter_t type);
: type_{type}
{
}
virtual std::optional<bool> match( virtual std::optional<bool> match(
const diagram &d, const common::model::element &e) const; const diagram &d, const common::model::element &e) const;
@@ -44,7 +41,7 @@ public:
const diagram &d, const common::model::relationship_t &r) const; const diagram &d, const common::model::relationship_t &r) const;
virtual std::optional<bool> match( virtual std::optional<bool> match(
const diagram &d, const common::model::scope_t &r) const; const diagram &d, const common::model::access_t &a) const;
virtual std::optional<bool> match( virtual std::optional<bool> match(
const diagram &d, const common::model::namespace_ &ns) const; const diagram &d, const common::model::namespace_ &ns) const;
@@ -102,14 +99,14 @@ private:
std::vector<relationship_t> relationships_; std::vector<relationship_t> relationships_;
}; };
struct scope_filter : public filter_visitor { struct access_filter : public filter_visitor {
scope_filter(filter_t type, std::vector<scope_t> scopes); access_filter(filter_t type, std::vector<access_t> access);
std::optional<bool> match( std::optional<bool> match(
const diagram &d, const scope_t &s) const override; const diagram &d, const access_t &a) const override;
private: private:
std::vector<scope_t> scopes_; std::vector<access_t> access_;
}; };
struct context_filter : public filter_visitor { struct context_filter : public filter_visitor {

View File

@@ -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) std::string to_string(access_t a)
{ {
switch (a) { switch (a) {

View File

@@ -23,8 +23,6 @@ namespace clanguml::common::model {
enum class access_t { kPublic, kProtected, kPrivate }; enum class access_t { kPublic, kProtected, kPrivate };
enum class scope_t { kPublic, kProtected, kPrivate, kNone };
enum class relationship_t { enum class relationship_t {
kNone, kNone,
kExtension, kExtension,
@@ -42,8 +40,6 @@ enum class message_t { kCall, kReturn };
std::string to_string(relationship_t r); 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(access_t r);
std::string to_string(message_t r); std::string to_string(message_t r);

View File

@@ -21,12 +21,12 @@
namespace clanguml::common::model { namespace clanguml::common::model {
relationship::relationship(relationship_t type, const std::string &destination, 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_source,
const std::string &multiplicity_destination) const std::string &multiplicity_destination)
: type_{type} : type_{type}
, destination_{destination} , destination_{destination}
, scope_{scope} , access_{access}
, label_{label} , label_{label}
, multiplicity_source_{multiplicity_source} , multiplicity_source_{multiplicity_source}
, multiplicity_destination_{multiplicity_destination} , 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_; } 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) bool operator==(const relationship &l, const relationship &r)
{ {

View File

@@ -28,7 +28,7 @@ class relationship : public common::model::decorated_element,
public common::model::stylable_element { public common::model::stylable_element {
public: public:
relationship(relationship_t type, const std::string &destination, 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_source = "",
const std::string &multiplicity_destination = ""); const std::string &multiplicity_destination = "");
@@ -50,8 +50,8 @@ public:
void set_label(const std::string &label); void set_label(const std::string &label);
std::string label() const; std::string label() const;
void set_scope(scope_t scope) noexcept; void set_access(access_t scope) noexcept;
scope_t scope() const noexcept; access_t access() const noexcept;
friend bool operator==(const relationship &l, const relationship &r); friend bool operator==(const relationship &l, const relationship &r);
@@ -61,6 +61,6 @@ private:
std::string multiplicity_source_; std::string multiplicity_source_;
std::string multiplicity_destination_; std::string multiplicity_destination_;
std::string label_; std::string label_;
scope_t scope_{scope_t::kNone}; access_t access_{access_t::kPublic};
}; };
} }

View File

@@ -151,8 +151,8 @@ template <> void append_value<plantuml>(plantuml &l, const plantuml &r)
} }
namespace YAML { namespace YAML {
using clanguml::common::model::access_t;
using clanguml::common::model::relationship_t; using clanguml::common::model::relationship_t;
using clanguml::common::model::scope_t;
using clanguml::config::class_diagram; using clanguml::config::class_diagram;
using clanguml::config::config; using clanguml::config::config;
using clanguml::config::filter; using clanguml::config::filter;
@@ -234,15 +234,18 @@ std::shared_ptr<clanguml::config::diagram> parse_diagram_config(const Node &d)
return {}; return {};
} }
template <> struct convert<scope_t> { //
static bool decode(const Node &node, scope_t &rhs) // config access_t decoder
//
template <> struct convert<access_t> {
static bool decode(const Node &node, access_t &rhs)
{ {
if (node.as<std::string>() == "public") if (node.as<std::string>() == "public")
rhs = scope_t::kPublic; rhs = access_t::kPublic;
else if (node.as<std::string>() == "protected") else if (node.as<std::string>() == "protected")
rhs = scope_t::kProtected; rhs = access_t::kProtected;
else if (node.as<std::string>() == "private") else if (node.as<std::string>() == "private")
rhs = scope_t::kPrivate; rhs = access_t::kPrivate;
else else
return false; return false;
@@ -368,8 +371,8 @@ template <> struct convert<filter> {
if (node["elements"]) if (node["elements"])
rhs.elements = node["elements"].as<decltype(rhs.elements)>(); rhs.elements = node["elements"].as<decltype(rhs.elements)>();
if (node["scopes"]) if (node["access"])
rhs.scopes = node["scopes"].as<decltype(rhs.scopes)>(); rhs.access = node["access"].as<decltype(rhs.access)>();
if (node["subclasses"]) if (node["subclasses"])
rhs.subclasses = node["subclasses"].as<decltype(rhs.subclasses)>(); rhs.subclasses = node["subclasses"].as<decltype(rhs.subclasses)>();

View File

@@ -60,7 +60,7 @@ struct filter {
// - public // - public
// - protected // - protected
// - private // - private
std::vector<common::model::scope_t> scopes; std::vector<common::model::access_t> access;
std::vector<std::string> subclasses; std::vector<std::string> subclasses;

View File

@@ -46,9 +46,9 @@ template <typename C, typename D>
using common_generator = using common_generator =
clanguml::common::generators::plantuml::generator<C, D>; clanguml::common::generators::plantuml::generator<C, D>;
using clanguml::common::model::access_t;
using clanguml::common::model::package; using clanguml::common::model::package;
using clanguml::common::model::relationship_t; using clanguml::common::model::relationship_t;
using clanguml::common::model::scope_t;
using namespace clanguml::util; using namespace clanguml::util;
class generator : public common_generator<diagram_config, diagram_model> { class generator : public common_generator<diagram_config, diagram_model> {

View File

@@ -42,29 +42,28 @@ using clanguml::common::model::access_t;
using clanguml::common::model::package; using clanguml::common::model::package;
using clanguml::common::model::relationship; using clanguml::common::model::relationship;
using clanguml::common::model::relationship_t; using clanguml::common::model::relationship_t;
using clanguml::common::model::scope_t;
using clanguml::package_diagram::model::diagram; using clanguml::package_diagram::model::diagram;
namespace detail { namespace detail {
scope_t cpp_access_specifier_to_scope( access_t cpp_access_specifier_to_access(
cppast::cpp_access_specifier_kind access_specifier) cppast::cpp_access_specifier_kind access_specifier)
{ {
scope_t scope = scope_t::kPublic; access_t access = access_t::kPublic;
switch (access_specifier) { switch (access_specifier) {
case cppast::cpp_access_specifier_kind::cpp_public: case cppast::cpp_access_specifier_kind::cpp_public:
scope = scope_t::kPublic; access = access_t::kPublic;
break; break;
case cppast::cpp_access_specifier_kind::cpp_private: case cppast::cpp_access_specifier_kind::cpp_private:
scope = scope_t::kPrivate; access = access_t::kPrivate;
break; break;
case cppast::cpp_access_specifier_kind::cpp_protected: case cppast::cpp_access_specifier_kind::cpp_protected:
scope = scope_t::kProtected; access = access_t::kProtected;
break; break;
default: default:
break; break;
} }
return scope; return access;
} }
} }

View File

@@ -37,7 +37,7 @@ TEST_CASE("t00011", "[test-case][class]")
REQUIRE_THAT(puml, IsClass(_A("B"))); REQUIRE_THAT(puml, IsClass(_A("B")));
REQUIRE_THAT(puml, IsClass(_A("D<T>"))); REQUIRE_THAT(puml, IsClass(_A("D<T>")));
REQUIRE_THAT(puml, IsFriend(_A("A"), _A("B"))); REQUIRE_THAT(puml, IsFriend<Private>(_A("A"), _A("B")));
// REQUIRE_THAT(puml, IsFriend(_A("A"), _A("D<T>"))); // REQUIRE_THAT(puml, IsFriend(_A("A"), _A("D<T>")));
save_puml( save_puml(

View File

@@ -11,7 +11,7 @@ diagrams:
include: include:
namespaces: namespaces:
- clanguml::t00040 - clanguml::t00040
scopes: access:
- public - public
- protected - protected
exclude: exclude:

View File

@@ -264,13 +264,6 @@ ContainsMatcher IsAssociation(std::string const &from, std::string const &to,
fmt::format(format_string, from, to, label), caseSensitivity)); 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("{} <.. {} : <<friend>>", from, to), caseSensitivity));
}
ContainsMatcher IsComposition(std::string const &from, std::string const &to, ContainsMatcher IsComposition(std::string const &from, std::string const &to,
std::string const &label, std::string multiplicity_source = "", std::string const &label, std::string multiplicity_source = "",
std::string multiplicity_dest = "", std::string multiplicity_dest = "",
@@ -424,6 +417,24 @@ ContainsMatcher IsField(std::string const &name,
CasedString(pattern + " : " + type, caseSensitivity)); CasedString(pattern + " : " + type, caseSensitivity));
} }
template <typename... Ts>
ContainsMatcher IsFriend(std::string const &from, std::string const &to,
CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes)
{
std::string pattern;
if constexpr (has_type<Public, Ts...>())
pattern = "+";
else if constexpr (has_type<Protected, Ts...>())
pattern = "#";
else
pattern = "-";
return ContainsMatcher(
CasedString(fmt::format("{} <.. {} : {}<<friend>>", from, to, pattern),
caseSensitivity));
}
ContainsMatcher IsPackage(std::string const &str, ContainsMatcher IsPackage(std::string const &str,
CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes)
{ {

View File

@@ -115,7 +115,7 @@ test_cases:
title: Subclass class diagram filter test title: Subclass class diagram filter test
description: description:
- name: t00040 - name: t00040
title: Relationship and scope filter test title: Relationship and access filter test
description: description:
Sequence diagrams: Sequence diagrams:
- name: t20001 - name: t20001