diff --git a/src/class_diagram/model/diagram.h b/src/class_diagram/model/diagram.h index 3415e12e..dc023048 100644 --- a/src/class_diagram/model/diagram.h +++ b/src/class_diagram/model/diagram.h @@ -401,7 +401,10 @@ opt_ref diagram::find(const std::string &name) const for (const auto &element : element_view::view()) { const auto full_name = element.get().full_name(false); - if (full_name == name) { + auto full_name_escaped = full_name; + util::replace_all(full_name_escaped, "##", "::"); + + if (name == full_name || name == full_name_escaped) { return {element}; } } @@ -417,8 +420,10 @@ std::vector> diagram::find( for (const auto &element : element_view::view()) { const auto full_name = element.get().full_name(false); + auto full_name_escaped = full_name; + util::replace_all(full_name_escaped, "##", "::"); - if (pattern == full_name) { + if (pattern == full_name || pattern == full_name_escaped) { result.emplace_back(element); } } diff --git a/src/common/model/diagram_filter.cc b/src/common/model/diagram_filter.cc index 431fc2b5..d2406f60 100644 --- a/src/common/model/diagram_filter.cc +++ b/src/common/model/diagram_filter.cc @@ -669,6 +669,24 @@ void context_filter::initialize_effective_context( effective_context.emplace(maybe_match.value().id()); } + const auto &context_enum_matches = + dynamic_cast(d) + .find(context.pattern); + + for (const auto &maybe_match : context_enum_matches) { + if (maybe_match) + effective_context.emplace(maybe_match.value().id()); + } + + const auto &context_concept_matches = + dynamic_cast(d) + .find(context.pattern); + + for (const auto &maybe_match : context_concept_matches) { + if (maybe_match) + effective_context.emplace(maybe_match.value().id()); + } + // Now repeat radius times - extend the effective context with elements // matching in direct relationship to what is in context auto radius_counter = context.radius; @@ -688,14 +706,14 @@ void context_filter::initialize_effective_context( find_elements_inheritance_relationship( d, effective_context, current_iteration_context); - // For each enum in the model - find_elements_in_relationship_with_enum( - d, effective_context, current_iteration_context); - // For each concept in the model find_elements_in_direct_relationship( d, effective_context, current_iteration_context); + // For each enum in the model + find_elements_in_direct_relationship( + d, effective_context, current_iteration_context); + for (auto id : current_iteration_context) { if (effective_context.count(id) == 0) { // Found new element to add to context @@ -706,31 +724,6 @@ void context_filter::initialize_effective_context( } } -void context_filter::find_elements_in_relationship_with_enum(const diagram &d, - std::set &effective_context, - std::set ¤t_iteration_context) const -{ - - const auto &cd = dynamic_cast(d); - for (const auto &enm : cd.enums()) { - - for (const auto &ec : effective_context) { - const auto &maybe_class = cd.find(ec); - - if (!maybe_class) - continue; - - for (const relationship &rel : - maybe_class.value().relationships()) { - - if (d.should_include(rel.type()) && - rel.destination() == enm.get().id()) - current_iteration_context.emplace(enm.get().id()); - } - } - } -} - void context_filter::find_elements_inheritance_relationship(const diagram &d, std::set &effective_context, std::set ¤t_iteration_context) const diff --git a/src/common/model/diagram_filter.h b/src/common/model/diagram_filter.h index a3b868ae..6e86e0e6 100644 --- a/src/common/model/diagram_filter.h +++ b/src/common/model/diagram_filter.h @@ -496,27 +496,34 @@ private: std::set ¤t_iteration_context) const { static_assert(std::is_same_v || + std::is_same_v || std::is_same_v, - "ElementT must be either class_ or concept_"); + "ElementT must be either class_ or enum_ or concept_"); const auto &cd = dynamic_cast(d); for (const auto &el : cd.elements()) { + // First search all elements of type ElementT in the diagram + // which have a relationship to any of the effective_context + // elements for (const relationship &rel : el.get().relationships()) { - for (const auto &ec : effective_context) { - if (d.should_include(rel.type()) && rel.destination() == ec) + for (const auto &element_id : effective_context) { + if (d.should_include(rel.type()) && + rel.destination() == element_id) current_iteration_context.emplace(el.get().id()); } } - for (const auto &ec : effective_context) { - const auto &maybe_concept = cd.find(ec); + // Now search current effective_context elements and add any + // elements of any type in the diagram which to that element + for (const auto element_id : effective_context) { + const auto &maybe_element = cd.get(element_id); - if (!maybe_concept) + if (!maybe_element) continue; for (const relationship &rel : - maybe_concept.value().relationships()) { + maybe_element.value().relationships()) { if (d.should_include(rel.type()) && rel.destination() == el.get().id()) @@ -530,10 +537,6 @@ private: std::set &effective_context, std::set ¤t_iteration_context) const; - void find_elements_in_relationship_with_enum(const diagram &d, - std::set &effective_context, - std::set ¤t_iteration_context) const; - std::vector context_; /*! diff --git a/tests/t00041/.clang-uml b/tests/t00041/.clang-uml index b9b0068d..161f33b5 100644 --- a/tests/t00041/.clang-uml +++ b/tests/t00041/.clang-uml @@ -10,6 +10,8 @@ diagrams: - clanguml::t00041 context: - clanguml::t00041::RR + - clanguml::t00041::Color + - clanguml::t00041::T::Direction subclasses: - clanguml::t00041::ns1::N exclude: diff --git a/tests/t00041/t00041.cc b/tests/t00041/t00041.cc index b7373f6b..c89a192d 100644 --- a/tests/t00041/t00041.cc +++ b/tests/t00041/t00041.cc @@ -29,6 +29,10 @@ struct RR : public R { F *f; detail::G *g; + enum K { One, Two, Three }; + + K k; + void foo(H *h) { } }; @@ -42,4 +46,15 @@ struct NN : public N { }; struct NM : public N { }; } +enum class Color { Red, Green, Blue }; + +struct S { + Color c; +}; + +struct T { + enum class Direction { Left, Right }; + Direction d; +}; + } // namespace clanguml::t00041 diff --git a/tests/t00041/test_case.h b/tests/t00041/test_case.h index 2fbfd147..ddf10b23 100644 --- a/tests/t00041/test_case.h +++ b/tests/t00041/test_case.h @@ -40,10 +40,16 @@ TEST_CASE("t00041") REQUIRE(IsClass(src, "RRR")); REQUIRE(!IsClass(src, "detail::G")); REQUIRE(!IsClass(src, "H")); + REQUIRE(IsClass(src, "S")); + REQUIRE(IsClass(src, "T")); REQUIRE(IsBaseClass(src, "R", "RR")); REQUIRE(IsBaseClass(src, "RR", "RRR")); + REQUIRE(IsEnum(src, "RR::K")); + REQUIRE(IsEnum(src, "Color")); + REQUIRE(IsEnum(src, "T::Direction")); + REQUIRE(IsAssociation(src, "D", "RR", "rr")); REQUIRE(IsAssociation(src, "RR", "E", "e")); REQUIRE(IsAssociation(src, "RR", "F", "f")); @@ -54,5 +60,8 @@ TEST_CASE("t00041") REQUIRE(IsClass(src, {"ns1", "NM"})); REQUIRE(IsBaseClass(src, "ns1::N", "ns1::NN")); REQUIRE(IsBaseClass(src, "ns1::N", "ns1::NM")); + + REQUIRE(IsInnerClass(src, "T", "T::Direction")); + REQUIRE(IsAggregation(src, "S", "Color", "c")); }); } \ No newline at end of file