Fixed handling of enums in class diagram context filter (#275)
This commit is contained in:
@@ -401,7 +401,10 @@ opt_ref<ElementT> diagram::find(const std::string &name) const
|
||||
for (const auto &element : element_view<ElementT>::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<opt_ref<ElementT>> diagram::find(
|
||||
|
||||
for (const auto &element : element_view<ElementT>::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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -669,6 +669,24 @@ void context_filter::initialize_effective_context(
|
||||
effective_context.emplace(maybe_match.value().id());
|
||||
}
|
||||
|
||||
const auto &context_enum_matches =
|
||||
dynamic_cast<const class_diagram::model::diagram &>(d)
|
||||
.find<class_diagram::model::enum_>(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<const class_diagram::model::diagram &>(d)
|
||||
.find<class_diagram::model::concept_>(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<class_diagram::model::concept_>(
|
||||
d, effective_context, current_iteration_context);
|
||||
|
||||
// For each enum in the model
|
||||
find_elements_in_direct_relationship<class_diagram::model::enum_>(
|
||||
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<id_t> &effective_context,
|
||||
std::set<clanguml::common::id_t> ¤t_iteration_context) const
|
||||
{
|
||||
|
||||
const auto &cd = dynamic_cast<const class_diagram::model::diagram &>(d);
|
||||
for (const auto &enm : cd.enums()) {
|
||||
|
||||
for (const auto &ec : effective_context) {
|
||||
const auto &maybe_class = cd.find<class_diagram::model::class_>(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<id_t> &effective_context,
|
||||
std::set<clanguml::common::id_t> ¤t_iteration_context) const
|
||||
|
||||
@@ -496,27 +496,34 @@ private:
|
||||
std::set<clanguml::common::id_t> ¤t_iteration_context) const
|
||||
{
|
||||
static_assert(std::is_same_v<ElementT, class_diagram::model::class_> ||
|
||||
std::is_same_v<ElementT, class_diagram::model::enum_> ||
|
||||
std::is_same_v<ElementT, class_diagram::model::concept_>,
|
||||
"ElementT must be either class_ or concept_");
|
||||
"ElementT must be either class_ or enum_ or concept_");
|
||||
|
||||
const auto &cd = dynamic_cast<const class_diagram::model::diagram &>(d);
|
||||
|
||||
for (const auto &el : cd.elements<ElementT>()) {
|
||||
// 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<ElementT>(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<id_t> &effective_context,
|
||||
std::set<clanguml::common::id_t> ¤t_iteration_context) const;
|
||||
|
||||
void find_elements_in_relationship_with_enum(const diagram &d,
|
||||
std::set<id_t> &effective_context,
|
||||
std::set<clanguml::common::id_t> ¤t_iteration_context) const;
|
||||
|
||||
std::vector<config::context_config> context_;
|
||||
|
||||
/*!
|
||||
|
||||
@@ -10,6 +10,8 @@ diagrams:
|
||||
- clanguml::t00041
|
||||
context:
|
||||
- clanguml::t00041::RR
|
||||
- clanguml::t00041::Color
|
||||
- clanguml::t00041::T::Direction
|
||||
subclasses:
|
||||
- clanguml::t00041::ns1::N
|
||||
exclude:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<Public>(src, "D", "RR", "rr"));
|
||||
REQUIRE(IsAssociation<Public>(src, "RR", "E", "e"));
|
||||
REQUIRE(IsAssociation<Public>(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<Public>(src, "S", "Color", "c"));
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user