Skip to content

Commit

Permalink
Added context filter relationships option (#274)
Browse files Browse the repository at this point in the history
  • Loading branch information
bkryza committed Jun 13, 2024
1 parent db2bd04 commit 6952c32
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 4 deletions.
11 changes: 11 additions & 0 deletions src/common/model/diagram_filter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -724,13 +724,24 @@ void context_filter::initialize_effective_context(
}
}

bool context_filter::should_include(
const config::context_config &context_cfg, relationship_t r) const
{
return context_cfg.relationships.empty() ||
util::contains(context_cfg.relationships, r);
}

void context_filter::find_elements_inheritance_relationship(const diagram &d,
const config::context_config &context_cfg,
std::set<eid_t> &effective_context,
std::set<eid_t> &current_iteration_context) const
{
const auto &cd = dynamic_cast<const class_diagram::model::diagram &>(d);

if (!should_include(context_cfg, relationship_t::kExtension)) {
return;
}

for (const auto &c : cd.classes()) {
// Check if any of the elements parents are already in the
// effective context...
Expand Down
18 changes: 14 additions & 4 deletions src/common/model/diagram_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,10 @@ struct context_filter : public filter_visitor {
// which have a relationship to any of the effective_context
// elements
for (const relationship &rel : el.get().relationships()) {
if (!should_include(context_cfg, rel.type()) ||
!d.should_include(rel.type())) {
continue;
}
// At the moment aggregation and composition are added in the
// model in reverse direction, so we don't consider them here
if (context_cfg.direction ==
Expand All @@ -531,8 +535,7 @@ struct context_filter : public filter_visitor {
continue;
}
for (const auto &element_id : effective_context) {
if (d.should_include(rel.type()) &&
rel.destination() == element_id)
if (rel.destination() == element_id)
current_iteration_context.emplace(el.get().id());
}
}
Expand All @@ -548,6 +551,11 @@ struct context_filter : public filter_visitor {

for (const relationship &rel :
maybe_element.value().relationships()) {
if (!should_include(context_cfg, rel.type()) ||
!d.should_include(rel.type())) {
continue;
}

if ((context_cfg.direction ==
config::context_direction_t::inward) &&
(rel.type() != relationship_t::kAggregation &&
Expand All @@ -561,14 +569,16 @@ struct context_filter : public filter_visitor {
continue;
}

if (d.should_include(rel.type()) &&
rel.destination() == el.get().id())
if (rel.destination() == el.get().id())
current_iteration_context.emplace(el.get().id());
}
}
}
}

bool should_include(
const config::context_config &context_cfg, relationship_t r) const;

void find_elements_inheritance_relationship(const diagram &d,
const config::context_config &context_cfg,
std::set<eid_t> &effective_context,
Expand Down
1 change: 1 addition & 0 deletions src/config/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ struct context_config {
common::string_or_regex pattern;
unsigned radius{0};
context_direction_t direction{context_direction_t::any};
std::vector<common::model::relationship_t> relationships;
};

/**
Expand Down
13 changes: 13 additions & 0 deletions src/config/schema.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@ const std::string schema_str = R"(
- dependency
- constraint
- none
relationship_context_t: !variant
- extension
- inheritance
- composition
- aggregation
- containment
- ownership
- association
- instantiation
- friendship
- dependency
- constraint
access_filter_t: !variant
- public
- protected
Expand Down Expand Up @@ -123,6 +135,7 @@ const std::string schema_str = R"(
radius: int
pattern: regex_or_string_t
direction: !optional direction_t
relationships: !optional [relationship_context_t]
context_filter_t:
- regex_or_string_t
- context_filter_match_t
Expand Down
3 changes: 3 additions & 0 deletions src/config/yaml_decoders.cc
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,9 @@ template <> struct convert<context_config> {
rhs.pattern = match["pattern"].as<string_or_regex>();
if (has_key(match, "direction"))
rhs.direction = match["direction"].as<context_direction_t>();
if (has_key(match, "relationships"))
rhs.relationships =
match["relationships"].as<std::vector<relationship_t>>();
}
else {
rhs.radius = 1;
Expand Down
16 changes: 16 additions & 0 deletions tests/t00078/.clang-uml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
diagrams:
t00078_class:
type: class
glob:
- t00078.cc
include:
namespaces:
- clanguml::t00078
context:
- match:
radius: 1
pattern: clanguml::t00078::A
relationships:
- inheritance
- aggregation
using_namespace: clanguml::t00078
22 changes: 22 additions & 0 deletions tests/t00078/t00078.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace clanguml {
namespace t00078 {

struct Base { };

struct D { };
struct E { };
struct A : public Base {
D d;
E *e;
};

struct B {
A *a;
};

struct C {
A a;
};

}
}
36 changes: 36 additions & 0 deletions tests/t00078/test_case.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* tests/t00078/test_case.h
*
* Copyright (c) 2021-2024 Bartek Kryza <[email protected]>
*
* 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("t00078")
{
using namespace clanguml::test;
using namespace std::string_literals;

auto [config, db, diagram, model] =
CHECK_CLASS_MODEL("t00078", "t00078_class");

CHECK_CLASS_DIAGRAM(*config, diagram, *model, [](const auto &src) {
REQUIRE(IsClass(src, "Base"));
REQUIRE(IsClass(src, "A"));
REQUIRE(IsClass(src, "C"));
REQUIRE(IsClass(src, "D"));

REQUIRE(!IsClass(src, "B"));
REQUIRE(!IsClass(src, "E"));
});
}
1 change: 1 addition & 0 deletions tests/test_cases.cc
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,7 @@ void CHECK_INCLUDE_DIAGRAM(const clanguml::config::config &config,
#endif
#include "t00076/test_case.h"
#include "t00077/test_case.h"
#include "t00078/test_case.h"

///
/// Sequence diagram tests
Expand Down
3 changes: 3 additions & 0 deletions tests/test_cases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,9 @@ test_cases:
- name: t00077
title: Test case for context diagram with outward direction flag
description:
- name: t00078
title: Test case for context diagram with relationships option
description:
Sequence diagrams:
- name: t20001
title: Basic sequence diagram test case
Expand Down

0 comments on commit 6952c32

Please sign in to comment.