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,
|
void context_filter::find_elements_inheritance_relationship(const diagram &d,
|
||||||
const config::context_config &context_cfg,
|
const config::context_config &context_cfg,
|
||||||
std::set<eid_t> &effective_context,
|
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);
|
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()) {
|
for (const auto &c : cd.classes()) {
|
||||||
// Check if any of the elements parents are already in the
|
// Check if any of the elements parents are already in the
|
||||||
// effective context...
|
// effective context...
|
||||||
|
|||||||
@@ -516,6 +516,10 @@ private:
|
|||||||
// which have a relationship to any of the effective_context
|
// which have a relationship to any of the effective_context
|
||||||
// elements
|
// elements
|
||||||
for (const relationship &rel : el.get().relationships()) {
|
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
|
// At the moment aggregation and composition are added in the
|
||||||
// model in reverse direction, so we don't consider them here
|
// model in reverse direction, so we don't consider them here
|
||||||
if (context_cfg.direction ==
|
if (context_cfg.direction ==
|
||||||
@@ -531,8 +535,7 @@ private:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (const auto &element_id : effective_context) {
|
for (const auto &element_id : effective_context) {
|
||||||
if (d.should_include(rel.type()) &&
|
if (rel.destination() == element_id)
|
||||||
rel.destination() == element_id)
|
|
||||||
current_iteration_context.emplace(el.get().id());
|
current_iteration_context.emplace(el.get().id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -548,6 +551,11 @@ private:
|
|||||||
|
|
||||||
for (const relationship &rel :
|
for (const relationship &rel :
|
||||||
maybe_element.value().relationships()) {
|
maybe_element.value().relationships()) {
|
||||||
|
if (!should_include(context_cfg, rel.type()) ||
|
||||||
|
!d.should_include(rel.type())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ((context_cfg.direction ==
|
if ((context_cfg.direction ==
|
||||||
config::context_direction_t::inward) &&
|
config::context_direction_t::inward) &&
|
||||||
(rel.type() != relationship_t::kAggregation &&
|
(rel.type() != relationship_t::kAggregation &&
|
||||||
@@ -561,14 +569,16 @@ private:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d.should_include(rel.type()) &&
|
if (rel.destination() == el.get().id())
|
||||||
rel.destination() == el.get().id())
|
|
||||||
current_iteration_context.emplace(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,
|
void find_elements_inheritance_relationship(const diagram &d,
|
||||||
const config::context_config &context_cfg,
|
const config::context_config &context_cfg,
|
||||||
std::set<eid_t> &effective_context,
|
std::set<eid_t> &effective_context,
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ struct context_config {
|
|||||||
common::string_or_regex pattern;
|
common::string_or_regex pattern;
|
||||||
unsigned radius{0};
|
unsigned radius{0};
|
||||||
context_direction_t direction{context_direction_t::any};
|
context_direction_t direction{context_direction_t::any};
|
||||||
|
std::vector<common::model::relationship_t> relationships;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -87,6 +87,18 @@ types:
|
|||||||
- dependency
|
- dependency
|
||||||
- constraint
|
- constraint
|
||||||
- none
|
- none
|
||||||
|
relationship_context_t: !variant
|
||||||
|
- extension
|
||||||
|
- inheritance
|
||||||
|
- composition
|
||||||
|
- aggregation
|
||||||
|
- containment
|
||||||
|
- ownership
|
||||||
|
- association
|
||||||
|
- instantiation
|
||||||
|
- friendship
|
||||||
|
- dependency
|
||||||
|
- constraint
|
||||||
access_filter_t: !variant
|
access_filter_t: !variant
|
||||||
- public
|
- public
|
||||||
- protected
|
- protected
|
||||||
@@ -123,6 +135,7 @@ types:
|
|||||||
radius: int
|
radius: int
|
||||||
pattern: regex_or_string_t
|
pattern: regex_or_string_t
|
||||||
direction: !optional direction_t
|
direction: !optional direction_t
|
||||||
|
relationships: !optional [relationship_context_t]
|
||||||
context_filter_t:
|
context_filter_t:
|
||||||
- regex_or_string_t
|
- regex_or_string_t
|
||||||
- context_filter_match_t
|
- context_filter_match_t
|
||||||
|
|||||||
@@ -485,6 +485,9 @@ template <> struct convert<context_config> {
|
|||||||
rhs.pattern = match["pattern"].as<string_or_regex>();
|
rhs.pattern = match["pattern"].as<string_or_regex>();
|
||||||
if (has_key(match, "direction"))
|
if (has_key(match, "direction"))
|
||||||
rhs.direction = match["direction"].as<context_direction_t>();
|
rhs.direction = match["direction"].as<context_direction_t>();
|
||||||
|
if (has_key(match, "relationships"))
|
||||||
|
rhs.relationships =
|
||||||
|
match["relationships"].as<std::vector<relationship_t>>();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rhs.radius = 1;
|
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
|
#endif
|
||||||
#include "t00076/test_case.h"
|
#include "t00076/test_case.h"
|
||||||
#include "t00077/test_case.h"
|
#include "t00077/test_case.h"
|
||||||
|
#include "t00078/test_case.h"
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Sequence diagram tests
|
/// Sequence diagram tests
|
||||||
|
|||||||
@@ -228,6 +228,9 @@ test_cases:
|
|||||||
- name: t00077
|
- name: t00077
|
||||||
title: Test case for context diagram with outward direction flag
|
title: Test case for context diagram with outward direction flag
|
||||||
description:
|
description:
|
||||||
|
- name: t00078
|
||||||
|
title: Test case for context diagram with relationships option
|
||||||
|
description:
|
||||||
Sequence diagrams:
|
Sequence diagrams:
|
||||||
- name: t20001
|
- name: t20001
|
||||||
title: Basic sequence diagram test case
|
title: Basic sequence diagram test case
|
||||||
|
|||||||
Reference in New Issue
Block a user