Added context filter relationships option (#274)
This commit is contained in:
@@ -724,6 +724,13 @@ 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,
|
||||
@@ -731,6 +738,10 @@ void context_filter::find_elements_inheritance_relationship(const diagram &d,
|
||||
{
|
||||
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...
|
||||
|
||||
@@ -516,6 +516,10 @@ private:
|
||||
// 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 ==
|
||||
@@ -531,8 +535,7 @@ private:
|
||||
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());
|
||||
}
|
||||
}
|
||||
@@ -548,6 +551,11 @@ private:
|
||||
|
||||
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 &&
|
||||
@@ -561,14 +569,16 @@ private:
|
||||
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,
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -87,6 +87,18 @@ types:
|
||||
- dependency
|
||||
- constraint
|
||||
- none
|
||||
relationship_context_t: !variant
|
||||
- extension
|
||||
- inheritance
|
||||
- composition
|
||||
- aggregation
|
||||
- containment
|
||||
- ownership
|
||||
- association
|
||||
- instantiation
|
||||
- friendship
|
||||
- dependency
|
||||
- constraint
|
||||
access_filter_t: !variant
|
||||
- public
|
||||
- protected
|
||||
@@ -123,6 +135,7 @@ types:
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
|
||||
16
tests/t00078/.clang-uml
Normal file
16
tests/t00078/.clang-uml
Normal file
@@ -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
tests/t00078/t00078.cc
Normal file
22
tests/t00078/t00078.cc
Normal file
@@ -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
tests/t00078/test_case.h
Normal file
36
tests/t00078/test_case.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* tests/t00078/test_case.h
|
||||
*
|
||||
* Copyright (c) 2021-2024 Bartek Kryza <bkryza@gmail.com>
|
||||
*
|
||||
* 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"));
|
||||
});
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user