Refactored class, include and package diagrams visitor to output filtered intermediate diagram (#289)
This commit is contained in:
@@ -158,26 +158,17 @@ void generator::generate_top_level_elements(nlohmann::json &parent) const
|
||||
{
|
||||
for (const auto &p : model()) {
|
||||
if (auto *pkg = dynamic_cast<package *>(p.get()); pkg) {
|
||||
if (!pkg->is_empty() &&
|
||||
!pkg->all_of([this](const common::model::element &e) {
|
||||
return !model().should_include(e);
|
||||
}))
|
||||
if (!pkg->is_empty())
|
||||
generate(*pkg, parent);
|
||||
}
|
||||
else if (auto *cls = dynamic_cast<class_ *>(p.get()); cls) {
|
||||
if (model().should_include(*cls)) {
|
||||
generate(*cls, parent);
|
||||
}
|
||||
generate(*cls, parent);
|
||||
}
|
||||
else if (auto *enm = dynamic_cast<enum_ *>(p.get()); enm) {
|
||||
if (model().should_include(*enm)) {
|
||||
generate(*enm, parent);
|
||||
}
|
||||
generate(*enm, parent);
|
||||
}
|
||||
else if (auto *cpt = dynamic_cast<concept_ *>(p.get()); cpt) {
|
||||
if (model().should_include(*cpt)) {
|
||||
generate(*cpt, parent);
|
||||
}
|
||||
generate(*cpt, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -203,10 +194,7 @@ void generator::generate(const package &p, nlohmann::json &parent) const
|
||||
for (const auto &subpackage : p) {
|
||||
if (dynamic_cast<package *>(subpackage.get()) != nullptr) {
|
||||
const auto &sp = dynamic_cast<package &>(*subpackage);
|
||||
if (!sp.is_empty() &&
|
||||
!sp.all_of([this](const common::model::element &e) {
|
||||
return !model().should_include(e);
|
||||
})) {
|
||||
if (!sp.is_empty()) {
|
||||
if (config().generate_packages())
|
||||
generate(sp, package_object);
|
||||
else
|
||||
@@ -214,28 +202,22 @@ void generator::generate(const package &p, nlohmann::json &parent) const
|
||||
}
|
||||
}
|
||||
else if (auto *cls = dynamic_cast<class_ *>(subpackage.get()); cls) {
|
||||
if (model().should_include(*cls)) {
|
||||
if (config().generate_packages())
|
||||
generate(*cls, package_object);
|
||||
else
|
||||
generate(*cls, parent);
|
||||
}
|
||||
if (config().generate_packages())
|
||||
generate(*cls, package_object);
|
||||
else
|
||||
generate(*cls, parent);
|
||||
}
|
||||
else if (auto *enm = dynamic_cast<enum_ *>(subpackage.get()); enm) {
|
||||
if (model().should_include(*enm)) {
|
||||
if (config().generate_packages())
|
||||
generate(*enm, package_object);
|
||||
else
|
||||
generate(*enm, parent);
|
||||
}
|
||||
if (config().generate_packages())
|
||||
generate(*enm, package_object);
|
||||
else
|
||||
generate(*enm, parent);
|
||||
}
|
||||
else if (auto *cpt = dynamic_cast<concept_ *>(subpackage.get()); cpt) {
|
||||
if (model().should_include(*cpt)) {
|
||||
if (config().generate_packages())
|
||||
generate(*cpt, package_object);
|
||||
else
|
||||
generate(*cpt, parent);
|
||||
}
|
||||
if (config().generate_packages())
|
||||
generate(*cpt, package_object);
|
||||
else
|
||||
generate(*cpt, parent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,19 +283,13 @@ void generator::generate_relationships(nlohmann::json &parent) const
|
||||
generate_relationships(*pkg, parent);
|
||||
}
|
||||
else if (auto *cls = dynamic_cast<class_ *>(p.get()); cls) {
|
||||
if (model().should_include(*cls)) {
|
||||
generate_relationships(*cls, parent);
|
||||
}
|
||||
generate_relationships(*cls, parent);
|
||||
}
|
||||
else if (auto *enm = dynamic_cast<enum_ *>(p.get()); enm) {
|
||||
if (model().should_include(*enm)) {
|
||||
generate_relationships(*enm, parent);
|
||||
}
|
||||
generate_relationships(*enm, parent);
|
||||
}
|
||||
else if (auto *cpt = dynamic_cast<concept_ *>(p.get()); cpt) {
|
||||
if (model().should_include(*cpt)) {
|
||||
generate_relationships(*cpt, parent);
|
||||
}
|
||||
generate_relationships(*cpt, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -322,9 +298,6 @@ void generator::generate_relationships(
|
||||
const class_ &c, nlohmann::json &parent) const
|
||||
{
|
||||
for (const auto &r : c.relationships()) {
|
||||
if (!model().should_include(r))
|
||||
continue;
|
||||
|
||||
auto target_element = model().get(r.destination());
|
||||
if (!target_element.has_value()) {
|
||||
LOG_DBG("Skipping {} relation from {} to {} due "
|
||||
@@ -353,9 +326,6 @@ void generator::generate_relationships(
|
||||
const enum_ &c, nlohmann::json &parent) const
|
||||
{
|
||||
for (const auto &r : c.relationships()) {
|
||||
if (!model().should_include(r))
|
||||
continue;
|
||||
|
||||
auto target_element = model().get(r.destination());
|
||||
if (!target_element.has_value()) {
|
||||
LOG_DBG("Skipping {} relation from {} to {} due "
|
||||
@@ -374,9 +344,6 @@ void generator::generate_relationships(
|
||||
const concept_ &c, nlohmann::json &parent) const
|
||||
{
|
||||
for (const auto &r : c.relationships()) {
|
||||
if (!model().should_include(r))
|
||||
continue;
|
||||
|
||||
auto target_element = model().get(r.destination());
|
||||
if (!target_element.has_value()) {
|
||||
LOG_DBG("Skipping {} relation from {} to {} due "
|
||||
|
||||
@@ -89,9 +89,6 @@ void generator::generate(const class_ &c, std::ostream &ostr) const
|
||||
|
||||
std::stringstream all_relations_str;
|
||||
for (const auto &r : c.relationships()) {
|
||||
if (!model().should_include(r.type()))
|
||||
continue;
|
||||
|
||||
try {
|
||||
generate_relationship(r, rendered_relations);
|
||||
}
|
||||
@@ -111,9 +108,6 @@ void generator::generate(const class_ &c, std::ostream &ostr) const
|
||||
sort_class_elements(members);
|
||||
|
||||
for (const auto &m : members) {
|
||||
if (!model().should_include(m))
|
||||
continue;
|
||||
|
||||
if (!config().include_relations_also_as_members() &&
|
||||
rendered_relations.find(m.name()) != rendered_relations.end())
|
||||
continue;
|
||||
@@ -156,11 +150,7 @@ void generator::generate_methods(
|
||||
sort_class_elements(sorted_methods);
|
||||
|
||||
for (const auto &m : sorted_methods) {
|
||||
if (!model().should_include(m))
|
||||
continue;
|
||||
|
||||
generate_method(m, ostr);
|
||||
|
||||
ostr << '\n';
|
||||
}
|
||||
}
|
||||
@@ -170,17 +160,11 @@ generator::method_groups_t generator::group_methods(
|
||||
{
|
||||
std::map<std::string, std::vector<class_method>> result;
|
||||
|
||||
// First get rid of methods which don't pass the filters
|
||||
std::vector<class_method> filtered_methods;
|
||||
std::copy_if(methods.cbegin(), methods.cend(),
|
||||
std::back_inserter(filtered_methods),
|
||||
[this](auto &m) { return model().should_include(m); });
|
||||
|
||||
for (const auto &g : method_groups_) {
|
||||
result[g] = {};
|
||||
}
|
||||
|
||||
for (const auto &m : filtered_methods) {
|
||||
for (const auto &m : methods) {
|
||||
if (m.is_constructor() || m.is_destructor()) {
|
||||
result["constructors"].push_back(m);
|
||||
}
|
||||
@@ -333,19 +317,13 @@ void generator::generate_relationships(std::ostream &ostr) const
|
||||
generate_relationships(*pkg, ostr);
|
||||
}
|
||||
else if (auto *cls = dynamic_cast<class_ *>(p.get()); cls) {
|
||||
if (model().should_include(*cls)) {
|
||||
generate_relationships(*cls, ostr);
|
||||
}
|
||||
generate_relationships(*cls, ostr);
|
||||
}
|
||||
else if (auto *enm = dynamic_cast<enum_ *>(p.get()); enm) {
|
||||
if (model().should_include(*enm)) {
|
||||
generate_relationships(*enm, ostr);
|
||||
}
|
||||
generate_relationships(*enm, ostr);
|
||||
}
|
||||
else if (auto *cpt = dynamic_cast<concept_ *>(p.get()); cpt) {
|
||||
if (model().should_include(*cpt)) {
|
||||
generate_relationships(*cpt, ostr);
|
||||
}
|
||||
generate_relationships(*cpt, ostr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -401,9 +379,6 @@ void generator::generate_relationships(
|
||||
std::set<std::string> unique_relations;
|
||||
|
||||
for (const auto &r : c.relationships()) {
|
||||
if (!model().should_include(r.type()))
|
||||
continue;
|
||||
|
||||
LOG_DBG("== Processing relationship {}", to_string(r.type()));
|
||||
|
||||
std::stringstream relstr;
|
||||
@@ -509,9 +484,6 @@ void generator::generate_relationships(
|
||||
std::set<std::string> unique_relations;
|
||||
|
||||
for (const auto &r : c.relationships()) {
|
||||
if (!model().should_include(r.type()))
|
||||
continue;
|
||||
|
||||
LOG_DBG("== Processing relationship {}", to_string(r.type()));
|
||||
|
||||
std::stringstream relstr;
|
||||
@@ -583,9 +555,6 @@ void generator::generate_relationships(
|
||||
void generator::generate_relationships(const enum_ &e, std::ostream &ostr) const
|
||||
{
|
||||
for (const auto &r : e.relationships()) {
|
||||
if (!model().should_include(r.type()))
|
||||
continue;
|
||||
|
||||
eid_t destination{};
|
||||
std::stringstream relstr;
|
||||
try {
|
||||
@@ -718,10 +687,7 @@ void generator::generate_relationships(
|
||||
// packages which do not contain anything but other
|
||||
// packages are skipped
|
||||
const auto &sp = dynamic_cast<package &>(*subpackage);
|
||||
if (!sp.is_empty() &&
|
||||
!sp.all_of([this](const common::model::element &e) {
|
||||
return !model().should_include(e);
|
||||
}))
|
||||
if (!sp.is_empty())
|
||||
generate_relationships(sp, ostr);
|
||||
}
|
||||
else if (dynamic_cast<class_ *>(subpackage.get()) != nullptr) {
|
||||
@@ -758,52 +724,43 @@ void generator::generate_top_level_elements(std::ostream &ostr) const
|
||||
{
|
||||
for (const auto &p : model()) {
|
||||
if (auto *pkg = dynamic_cast<package *>(p.get()); pkg) {
|
||||
if (!pkg->is_empty() &&
|
||||
!pkg->all_of([this](const common::model::element &e) {
|
||||
return !model().should_include(e);
|
||||
}))
|
||||
if (!pkg->is_empty())
|
||||
generate(*pkg, ostr);
|
||||
}
|
||||
else if (auto *cls = dynamic_cast<class_ *>(p.get()); cls) {
|
||||
if (model().should_include(*cls)) {
|
||||
auto together_group =
|
||||
config().get_together_group(cls->full_name(false));
|
||||
if (together_group) {
|
||||
together_group_stack_.group_together(
|
||||
together_group.value(), cls);
|
||||
}
|
||||
else {
|
||||
generate_alias(*cls, ostr);
|
||||
generate(*cls, ostr);
|
||||
}
|
||||
auto together_group =
|
||||
config().get_together_group(cls->full_name(false));
|
||||
if (together_group) {
|
||||
together_group_stack_.group_together(
|
||||
together_group.value(), cls);
|
||||
}
|
||||
else {
|
||||
generate_alias(*cls, ostr);
|
||||
generate(*cls, ostr);
|
||||
}
|
||||
}
|
||||
else if (auto *enm = dynamic_cast<enum_ *>(p.get()); enm) {
|
||||
if (model().should_include(*enm)) {
|
||||
auto together_group =
|
||||
config().get_together_group(enm->full_name(false));
|
||||
if (together_group) {
|
||||
together_group_stack_.group_together(
|
||||
together_group.value(), enm);
|
||||
}
|
||||
else {
|
||||
generate_alias(*enm, ostr);
|
||||
generate(*enm, ostr);
|
||||
}
|
||||
auto together_group =
|
||||
config().get_together_group(enm->full_name(false));
|
||||
if (together_group) {
|
||||
together_group_stack_.group_together(
|
||||
together_group.value(), enm);
|
||||
}
|
||||
else {
|
||||
generate_alias(*enm, ostr);
|
||||
generate(*enm, ostr);
|
||||
}
|
||||
}
|
||||
else if (auto *cpt = dynamic_cast<concept_ *>(p.get()); cpt) {
|
||||
if (model().should_include(*cpt)) {
|
||||
auto together_group =
|
||||
config().get_together_group(cpt->full_name(false));
|
||||
if (together_group) {
|
||||
together_group_stack_.group_together(
|
||||
together_group.value(), cpt);
|
||||
}
|
||||
else {
|
||||
generate_alias(*cpt, ostr);
|
||||
generate(*cpt, ostr);
|
||||
}
|
||||
auto together_group =
|
||||
config().get_together_group(cpt->full_name(false));
|
||||
if (together_group) {
|
||||
together_group_stack_.group_together(
|
||||
together_group.value(), cpt);
|
||||
}
|
||||
else {
|
||||
generate_alias(*cpt, ostr);
|
||||
generate(*cpt, ostr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,9 +157,6 @@ void generator::generate(const class_ &c, std::ostream &ostr) const
|
||||
|
||||
std::stringstream all_relations_str;
|
||||
for (const auto &r : c.relationships()) {
|
||||
if (!model().should_include(r.type()))
|
||||
continue;
|
||||
|
||||
try {
|
||||
generate_relationship(r, rendered_relations);
|
||||
}
|
||||
@@ -182,9 +179,6 @@ void generator::generate(const class_ &c, std::ostream &ostr) const
|
||||
ostr << "__\n";
|
||||
|
||||
for (const auto &m : members) {
|
||||
if (!model().should_include(m))
|
||||
continue;
|
||||
|
||||
if (!config().include_relations_also_as_members() &&
|
||||
rendered_relations.find(m.name()) != rendered_relations.end())
|
||||
continue;
|
||||
@@ -228,11 +222,7 @@ void generator::generate_methods(
|
||||
sort_class_elements(sorted_methods);
|
||||
|
||||
for (const auto &m : sorted_methods) {
|
||||
if (!model().should_include(m))
|
||||
continue;
|
||||
|
||||
generate_method(m, ostr);
|
||||
|
||||
ostr << '\n';
|
||||
}
|
||||
}
|
||||
@@ -242,17 +232,11 @@ generator::method_groups_t generator::group_methods(
|
||||
{
|
||||
std::map<std::string, std::vector<class_method>> result;
|
||||
|
||||
// First get rid of methods which don't pass the filters
|
||||
std::vector<class_method> filtered_methods;
|
||||
std::copy_if(methods.cbegin(), methods.cend(),
|
||||
std::back_inserter(filtered_methods),
|
||||
[this](auto &m) { return model().should_include(m); });
|
||||
|
||||
for (const auto &g : method_groups_) {
|
||||
result[g] = {};
|
||||
}
|
||||
|
||||
for (const auto &m : filtered_methods) {
|
||||
for (const auto &m : methods) {
|
||||
if (m.is_constructor() || m.is_destructor()) {
|
||||
result["constructors"].push_back(m);
|
||||
}
|
||||
@@ -417,19 +401,13 @@ void generator::generate_relationships(std::ostream &ostr) const
|
||||
generate_relationships(*pkg, ostr);
|
||||
}
|
||||
else if (auto *cls = dynamic_cast<class_ *>(p.get()); cls) {
|
||||
if (model().should_include(*cls)) {
|
||||
generate_relationships(*cls, ostr);
|
||||
}
|
||||
generate_relationships(*cls, ostr);
|
||||
}
|
||||
else if (auto *enm = dynamic_cast<enum_ *>(p.get()); enm) {
|
||||
if (model().should_include(*enm)) {
|
||||
generate_relationships(*enm, ostr);
|
||||
}
|
||||
generate_relationships(*enm, ostr);
|
||||
}
|
||||
else if (auto *cpt = dynamic_cast<concept_ *>(p.get()); cpt) {
|
||||
if (model().should_include(*cpt)) {
|
||||
generate_relationships(*cpt, ostr);
|
||||
}
|
||||
generate_relationships(*cpt, ostr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -481,9 +459,6 @@ void generator::generate_relationships(
|
||||
std::set<std::string> unique_relations;
|
||||
|
||||
for (const auto &r : c.relationships()) {
|
||||
if (!model().should_include(r.type()))
|
||||
continue;
|
||||
|
||||
LOG_DBG("== Processing relationship {}",
|
||||
plantuml_common::to_plantuml(r, config()));
|
||||
|
||||
@@ -661,9 +636,6 @@ void generator::generate(const enum_ &e, std::ostream &ostr) const
|
||||
void generator::generate_relationships(const enum_ &e, std::ostream &ostr) const
|
||||
{
|
||||
for (const auto &r : e.relationships()) {
|
||||
if (!model().should_include(r.type()))
|
||||
continue;
|
||||
|
||||
eid_t destination{};
|
||||
std::stringstream relstr;
|
||||
try {
|
||||
@@ -724,10 +696,7 @@ void generator::generate(const package &p, std::ostream &ostr) const
|
||||
if (dynamic_cast<package *>(subpackage.get()) != nullptr) {
|
||||
// TODO: add option - generate_empty_packages
|
||||
const auto &sp = dynamic_cast<package &>(*subpackage);
|
||||
if (!sp.is_empty() &&
|
||||
!sp.all_of([this](const common::model::element &e) {
|
||||
return !model().should_include(e);
|
||||
})) {
|
||||
if (!sp.is_empty()) {
|
||||
together_group_stack_.enter();
|
||||
|
||||
generate(sp, ostr);
|
||||
@@ -822,10 +791,7 @@ void generator::generate_relationships(
|
||||
// packages which do not contain anything but other
|
||||
// packages are skipped
|
||||
const auto &sp = dynamic_cast<package &>(*subpackage);
|
||||
if (!sp.is_empty() &&
|
||||
!sp.all_of([this](const common::model::element &e) {
|
||||
return !model().should_include(e);
|
||||
}))
|
||||
if (!sp.is_empty())
|
||||
generate_relationships(sp, ostr);
|
||||
}
|
||||
else if (dynamic_cast<class_ *>(subpackage.get()) != nullptr) {
|
||||
@@ -864,52 +830,43 @@ void generator::generate_top_level_elements(std::ostream &ostr) const
|
||||
{
|
||||
for (const auto &p : model()) {
|
||||
if (auto *pkg = dynamic_cast<package *>(p.get()); pkg) {
|
||||
if (!pkg->is_empty() &&
|
||||
!pkg->all_of([this](const common::model::element &e) {
|
||||
return !model().should_include(e);
|
||||
}))
|
||||
if (!pkg->is_empty())
|
||||
generate(*pkg, ostr);
|
||||
}
|
||||
else if (auto *cls = dynamic_cast<class_ *>(p.get()); cls) {
|
||||
if (model().should_include(*cls)) {
|
||||
auto together_group =
|
||||
config().get_together_group(cls->full_name(false));
|
||||
if (together_group) {
|
||||
together_group_stack_.group_together(
|
||||
together_group.value(), cls);
|
||||
}
|
||||
else {
|
||||
generate_alias(*cls, ostr);
|
||||
generate(*cls, ostr);
|
||||
}
|
||||
auto together_group =
|
||||
config().get_together_group(cls->full_name(false));
|
||||
if (together_group) {
|
||||
together_group_stack_.group_together(
|
||||
together_group.value(), cls);
|
||||
}
|
||||
else {
|
||||
generate_alias(*cls, ostr);
|
||||
generate(*cls, ostr);
|
||||
}
|
||||
}
|
||||
else if (auto *enm = dynamic_cast<enum_ *>(p.get()); enm) {
|
||||
if (model().should_include(*enm)) {
|
||||
auto together_group =
|
||||
config().get_together_group(enm->full_name(false));
|
||||
if (together_group) {
|
||||
together_group_stack_.group_together(
|
||||
together_group.value(), enm);
|
||||
}
|
||||
else {
|
||||
generate_alias(*enm, ostr);
|
||||
generate(*enm, ostr);
|
||||
}
|
||||
auto together_group =
|
||||
config().get_together_group(enm->full_name(false));
|
||||
if (together_group) {
|
||||
together_group_stack_.group_together(
|
||||
together_group.value(), enm);
|
||||
}
|
||||
else {
|
||||
generate_alias(*enm, ostr);
|
||||
generate(*enm, ostr);
|
||||
}
|
||||
}
|
||||
else if (auto *cpt = dynamic_cast<concept_ *>(p.get()); cpt) {
|
||||
if (model().should_include(*cpt)) {
|
||||
auto together_group =
|
||||
config().get_together_group(cpt->full_name(false));
|
||||
if (together_group) {
|
||||
together_group_stack_.group_together(
|
||||
together_group.value(), cpt);
|
||||
}
|
||||
else {
|
||||
generate_alias(*cpt, ostr);
|
||||
generate(*cpt, ostr);
|
||||
}
|
||||
auto together_group =
|
||||
config().get_together_group(cpt->full_name(false));
|
||||
if (together_group) {
|
||||
together_group_stack_.group_together(
|
||||
together_group.value(), cpt);
|
||||
}
|
||||
else {
|
||||
generate_alias(*cpt, ostr);
|
||||
generate(*cpt, ostr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "class.h"
|
||||
|
||||
#include "common/model/filters/diagram_filter.h"
|
||||
#include "util/util.h"
|
||||
|
||||
#include <sstream>
|
||||
@@ -63,6 +64,7 @@ const std::vector<class_member> &class_::members() const { return members_; }
|
||||
const std::vector<class_method> &class_::methods() const { return methods_; }
|
||||
|
||||
const std::vector<class_parent> &class_::parents() const { return bases_; }
|
||||
std::vector<class_parent> &class_::parents() { return bases_; }
|
||||
|
||||
bool operator==(const class_ &l, const class_ &r) { return l.id() == r.id(); }
|
||||
|
||||
@@ -111,6 +113,21 @@ bool class_::is_abstract() const
|
||||
[](const auto &method) { return method.is_pure_virtual(); });
|
||||
}
|
||||
|
||||
void class_::apply_filter(
|
||||
const common::model::diagram_filter &filter, const std::set<eid_t> &removed)
|
||||
{
|
||||
diagram_element::apply_filter(filter, removed);
|
||||
|
||||
common::model::apply_filter(members_, filter);
|
||||
common::model::apply_filter(methods_, filter);
|
||||
|
||||
// Remove class bases which are no longer in the diagram
|
||||
parents().erase(
|
||||
std::remove_if(parents().begin(), parents().end(),
|
||||
[&removed](auto &&p) { return removed.count(p.id()) > 0; }),
|
||||
parents().end());
|
||||
}
|
||||
|
||||
std::optional<std::string> class_::doxygen_link() const
|
||||
{
|
||||
const auto *type = is_struct() ? "struct" : "class";
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace clanguml::common::model {
|
||||
class diagram_filter;
|
||||
}
|
||||
|
||||
namespace clanguml::class_diagram::model {
|
||||
|
||||
/**
|
||||
@@ -126,6 +130,7 @@ public:
|
||||
* @return Reference to class parents.
|
||||
*/
|
||||
const std::vector<class_parent> &parents() const;
|
||||
std::vector<class_parent> &parents();
|
||||
|
||||
/**
|
||||
* @brief Get class full name.
|
||||
@@ -166,6 +171,9 @@ public:
|
||||
*/
|
||||
std::optional<std::string> doxygen_link() const override;
|
||||
|
||||
void apply_filter(const common::model::diagram_filter &filter,
|
||||
const std::set<eid_t> &removed) override;
|
||||
|
||||
private:
|
||||
bool is_struct_{false};
|
||||
bool is_union_{false};
|
||||
|
||||
@@ -256,6 +256,39 @@ void diagram::remove_redundant_dependencies()
|
||||
}
|
||||
}
|
||||
|
||||
void diagram::apply_filter()
|
||||
{
|
||||
// First find all element ids which should be removed
|
||||
std::set<eid_t> to_remove;
|
||||
|
||||
for (const auto &c : element_view<class_>::view())
|
||||
if (!filter().should_include(c.get()))
|
||||
to_remove.emplace(c.get().id());
|
||||
|
||||
for (const auto &e : element_view<enum_>::view())
|
||||
if (!filter().should_include(e.get()))
|
||||
to_remove.emplace(e.get().id());
|
||||
|
||||
for (const auto &c : element_view<concept_>::view())
|
||||
if (!filter().should_include(c.get()))
|
||||
to_remove.emplace(c.get().id());
|
||||
|
||||
nested_trait_ns::remove(to_remove);
|
||||
|
||||
element_view<class_>::remove(to_remove);
|
||||
element_view<enum_>::remove(to_remove);
|
||||
element_view<concept_>::remove(to_remove);
|
||||
|
||||
for (auto &c : element_view<class_>::view())
|
||||
c.get().apply_filter(filter(), to_remove);
|
||||
|
||||
for (auto &e : element_view<enum_>::view())
|
||||
e.get().apply_filter(filter(), to_remove);
|
||||
|
||||
for (auto &c : element_view<concept_>::view())
|
||||
c.get().apply_filter(filter(), to_remove);
|
||||
}
|
||||
|
||||
bool diagram::is_empty() const
|
||||
{
|
||||
return element_view<class_>::is_empty() &&
|
||||
|
||||
@@ -256,6 +256,8 @@ public:
|
||||
*/
|
||||
bool is_empty() const override;
|
||||
|
||||
void apply_filter() override;
|
||||
|
||||
private:
|
||||
template <typename ElementT>
|
||||
bool add_with_namespace_path(std::unique_ptr<ElementT> &&e);
|
||||
|
||||
@@ -941,12 +941,27 @@ bool parse_source_location(const std::string &location_str, std::string &file,
|
||||
clang::RawComment *get_expression_raw_comment(const clang::SourceManager &sm,
|
||||
const clang::ASTContext &context, const clang::Stmt *stmt)
|
||||
{
|
||||
// First get the first line of the expression
|
||||
auto expr_begin = stmt->getSourceRange().getBegin();
|
||||
return get_raw_comment(sm, context, stmt->getSourceRange());
|
||||
}
|
||||
|
||||
clang::RawComment *get_declaration_raw_comment(const clang::SourceManager &sm,
|
||||
const clang::ASTContext &context, const clang::Decl *decl)
|
||||
{
|
||||
return get_raw_comment(sm, context, decl->getSourceRange());
|
||||
}
|
||||
|
||||
clang::RawComment *get_raw_comment(const clang::SourceManager &sm,
|
||||
const clang::ASTContext &context, const clang::SourceRange &source_range)
|
||||
{
|
||||
auto expr_begin = source_range.getBegin();
|
||||
const auto expr_begin_line = sm.getSpellingLineNumber(expr_begin);
|
||||
|
||||
std::string file_Path = sm.getFilename(expr_begin).str();
|
||||
|
||||
auto file_id = sm.getFileID(expr_begin);
|
||||
|
||||
if (!context.Comments.empty() &&
|
||||
context.Comments.getCommentsInFile(sm.getFileID(expr_begin)) != nullptr)
|
||||
context.Comments.getCommentsInFile(file_id) != nullptr) {
|
||||
for (const auto [offset, raw_comment] :
|
||||
*context.Comments.getCommentsInFile(sm.getFileID(expr_begin))) {
|
||||
const auto comment_end_line = sm.getSpellingLineNumber(
|
||||
@@ -956,6 +971,7 @@ clang::RawComment *get_expression_raw_comment(const clang::SourceManager &sm,
|
||||
expr_begin_line == comment_end_line + 1)
|
||||
return raw_comment;
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -299,6 +299,12 @@ consume_type_context(clang::QualType type);
|
||||
clang::RawComment *get_expression_raw_comment(const clang::SourceManager &sm,
|
||||
const clang::ASTContext &context, const clang::Stmt *stmt);
|
||||
|
||||
clang::RawComment *get_declaration_raw_comment(const clang::SourceManager &sm,
|
||||
const clang::ASTContext &context, const clang::Decl *decl);
|
||||
|
||||
clang::RawComment *get_raw_comment(const clang::SourceManager &sm,
|
||||
const clang::ASTContext &context, const clang::SourceRange &source_range);
|
||||
|
||||
/**
|
||||
* Check if function or method declaration is a C++20 coroutine.
|
||||
*
|
||||
|
||||
@@ -59,10 +59,18 @@ void diagram::set_complete(bool complete) { complete_ = complete; }
|
||||
|
||||
bool diagram::complete() const { return complete_; }
|
||||
|
||||
void diagram::finalize() { }
|
||||
void diagram::finalize()
|
||||
{
|
||||
// Remove elements that do not match the filter
|
||||
apply_filter();
|
||||
filtered_ = true;
|
||||
}
|
||||
|
||||
bool diagram::should_include(const element &e) const
|
||||
{
|
||||
if (filtered_)
|
||||
return true;
|
||||
|
||||
if (filter_.get() == nullptr)
|
||||
return true;
|
||||
|
||||
@@ -77,6 +85,9 @@ bool diagram::should_include(const element &e) const
|
||||
|
||||
bool diagram::should_include(const namespace_ &ns) const
|
||||
{
|
||||
if (filtered_)
|
||||
return true;
|
||||
|
||||
if (filter_.get() == nullptr)
|
||||
return true;
|
||||
|
||||
|
||||
@@ -171,10 +171,13 @@ public:
|
||||
*/
|
||||
virtual bool is_empty() const = 0;
|
||||
|
||||
virtual void apply_filter() { }
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
std::unique_ptr<diagram_filter> filter_;
|
||||
bool complete_{false};
|
||||
bool filtered_{false};
|
||||
};
|
||||
|
||||
template <typename DiagramT> bool check_diagram_type(diagram_t t);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "diagram_element.h"
|
||||
|
||||
#include "common/model/filters/diagram_filter.h"
|
||||
#include "util/util.h"
|
||||
|
||||
#include <ostream>
|
||||
@@ -102,6 +103,19 @@ bool diagram_element::complete() const { return complete_; }
|
||||
|
||||
void diagram_element::complete(bool completed) { complete_ = completed; }
|
||||
|
||||
void diagram_element::apply_filter(
|
||||
const diagram_filter &filter, const std::set<eid_t> &removed)
|
||||
{
|
||||
common::model::apply_filter(relationships(), filter);
|
||||
|
||||
auto &rels = relationships();
|
||||
rels.erase(std::remove_if(std::begin(rels), std::end(rels),
|
||||
[&removed](auto &&r) {
|
||||
return removed.count(r.destination()) > 0;
|
||||
}),
|
||||
std::end(rels));
|
||||
}
|
||||
|
||||
bool operator==(const diagram_element &l, const diagram_element &r)
|
||||
{
|
||||
return l.id() == r.id();
|
||||
|
||||
@@ -26,11 +26,14 @@
|
||||
|
||||
#include <atomic>
|
||||
#include <exception>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace clanguml::common::model {
|
||||
|
||||
class diagram_filter;
|
||||
|
||||
/**
|
||||
* @brief Base class for standalone diagram elements.
|
||||
*
|
||||
@@ -184,6 +187,9 @@ public:
|
||||
*/
|
||||
void complete(bool completed);
|
||||
|
||||
virtual void apply_filter(
|
||||
const diagram_filter &filter, const std::set<eid_t> &removed);
|
||||
|
||||
private:
|
||||
eid_t id_{};
|
||||
std::optional<eid_t> parent_element_id_{};
|
||||
|
||||
@@ -78,6 +78,15 @@ public:
|
||||
*/
|
||||
bool is_empty() const { return elements_.empty(); }
|
||||
|
||||
void remove(const std::set<eid_t> &element_ids)
|
||||
{
|
||||
elements_.erase(std::remove_if(elements_.begin(), elements_.end(),
|
||||
[&element_ids](auto &&e) {
|
||||
return element_ids.count(e.get().id()) > 0;
|
||||
}),
|
||||
elements_.end());
|
||||
}
|
||||
|
||||
private:
|
||||
reference_vector<T> elements_;
|
||||
};
|
||||
|
||||
@@ -99,6 +99,12 @@ tvl::value_t filter_visitor::match(
|
||||
return {};
|
||||
}
|
||||
|
||||
tvl::value_t filter_visitor::match(
|
||||
const diagram &d, const common::model::relationship &r) const
|
||||
{
|
||||
return match(d, r.type());
|
||||
}
|
||||
|
||||
tvl::value_t filter_visitor::match(
|
||||
const diagram & /*d*/, const common::model::relationship_t & /*r*/) const
|
||||
{
|
||||
@@ -997,7 +1003,7 @@ tvl::value_t paths_filter::match(
|
||||
return {};
|
||||
}
|
||||
|
||||
// Matching source paths doesn't make sens if they are not absolute
|
||||
// Matching source paths doesn't make sense if they are not absolute
|
||||
if (!p.is_absolute()) {
|
||||
return {};
|
||||
}
|
||||
@@ -1071,7 +1077,7 @@ tvl::value_t class_member_filter::match(
|
||||
}
|
||||
|
||||
diagram_filter::diagram_filter(const common::model::diagram &d,
|
||||
const config::diagram &c, private_constructor_tag_t /*unused*/)
|
||||
const config::diagram & /*c*/, private_constructor_tag_t /*unused*/)
|
||||
: diagram_{d}
|
||||
{
|
||||
}
|
||||
|
||||
@@ -86,6 +86,9 @@ public:
|
||||
virtual tvl::value_t match(
|
||||
const diagram &d, const common::model::element &e) const;
|
||||
|
||||
virtual tvl::value_t match(
|
||||
const diagram &d, const common::model::relationship &r) const;
|
||||
|
||||
virtual tvl::value_t match(
|
||||
const diagram &d, const common::model::relationship_t &r) const;
|
||||
|
||||
@@ -815,15 +818,6 @@ public:
|
||||
friend class diagram_filter_factory;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Initialize filters.
|
||||
*
|
||||
* Some filters require initialization.
|
||||
*
|
||||
* @param c Diagram config.
|
||||
*/
|
||||
// void init_filters(const config::diagram &c);
|
||||
|
||||
/*! List of inclusive filters */
|
||||
std::vector<std::unique_ptr<filter_visitor>> inclusive_;
|
||||
|
||||
@@ -834,6 +828,27 @@ private:
|
||||
const common::model::diagram &diagram_;
|
||||
};
|
||||
|
||||
template <typename Collection>
|
||||
void apply_filter(Collection &col, const diagram_filter &filter)
|
||||
{
|
||||
col.erase(std::remove_if(col.begin(), col.end(),
|
||||
[&filter](auto &&element) {
|
||||
return !filter.should_include(element);
|
||||
}),
|
||||
col.end());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void apply_filter(
|
||||
std::vector<std::reference_wrapper<T>> &col, const diagram_filter &filter)
|
||||
{
|
||||
col.erase(std::remove_if(col.begin(), col.end(),
|
||||
[&filter](auto &&element) {
|
||||
return !filter.should_include(element.get());
|
||||
}),
|
||||
col.end());
|
||||
}
|
||||
|
||||
template <>
|
||||
bool diagram_filter::should_include<std::string>(const std::string &name) const;
|
||||
} // namespace clanguml::common::model
|
||||
@@ -253,8 +253,10 @@ template <>
|
||||
void advanced_diagram_filter_initializer::add_filter<
|
||||
source_file_dependency_filter_t>(const filter_t &filter_type,
|
||||
const std::vector<common::string_or_regex> &filter_config,
|
||||
std::vector<std::unique_ptr<filter_visitor>> &result, relationship_t &&rt,
|
||||
bool &&direction)
|
||||
std::vector<std::unique_ptr<filter_visitor>> &result,
|
||||
relationship_t &&rt, // NOLINT
|
||||
bool &&direction // NOLINT
|
||||
)
|
||||
{
|
||||
std::vector<std::string> deps;
|
||||
for (auto &&path : filter_config) {
|
||||
|
||||
@@ -51,6 +51,8 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~diagram_filter_initializer() = default;
|
||||
|
||||
virtual void initialize() = 0;
|
||||
|
||||
protected:
|
||||
@@ -62,6 +64,8 @@ class basic_diagram_filter_initializer : public diagram_filter_initializer {
|
||||
public:
|
||||
using diagram_filter_initializer::diagram_filter_initializer;
|
||||
|
||||
~basic_diagram_filter_initializer() override = default;
|
||||
|
||||
void initialize() override;
|
||||
};
|
||||
|
||||
@@ -69,6 +73,8 @@ class advanced_diagram_filter_initializer : public diagram_filter_initializer {
|
||||
public:
|
||||
using diagram_filter_initializer::diagram_filter_initializer;
|
||||
|
||||
~advanced_diagram_filter_initializer() override = default;
|
||||
|
||||
void initialize() override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -245,6 +246,23 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void remove(const std::set<eid_t> &element_ids)
|
||||
{
|
||||
// First remove all matching elements on this level
|
||||
elements_.erase(std::remove_if(elements_.begin(), elements_.end(),
|
||||
[&element_ids](auto &&e) {
|
||||
return element_ids.count(e->id()) > 0;
|
||||
}),
|
||||
elements_.end());
|
||||
|
||||
// Now recurse to any packages on this level
|
||||
for (auto &p : elements_) {
|
||||
if (dynamic_cast<nested_trait<T, Path> *>(p.get()))
|
||||
dynamic_cast<nested_trait<T, Path> *>(p.get())->remove(
|
||||
element_ids);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<T>> elements_;
|
||||
};
|
||||
|
||||
@@ -253,8 +253,12 @@ public:
|
||||
|
||||
comment_visitor_->visit(decl, e);
|
||||
|
||||
const auto *comment =
|
||||
decl.getASTContext().getRawCommentForDeclNoCache(&decl);
|
||||
auto *comment = decl.getASTContext().getRawCommentForDeclNoCache(&decl);
|
||||
|
||||
if (comment == nullptr) {
|
||||
comment = clanguml::common::get_declaration_raw_comment(
|
||||
source_manager(), decl.getASTContext(), &decl);
|
||||
}
|
||||
|
||||
process_comment(comment, decl.getASTContext().getDiagnostics(), e);
|
||||
}
|
||||
|
||||
@@ -39,14 +39,11 @@ void generator::generate_relationships(
|
||||
});
|
||||
}
|
||||
else {
|
||||
util::for_each_if(
|
||||
f.relationships(),
|
||||
[this](const auto &r) { return model().should_include(r.type()); },
|
||||
[&f, &parent](const auto &r) {
|
||||
nlohmann::json rel = r;
|
||||
rel["source"] = std::to_string(f.id().value());
|
||||
parent["relationships"].push_back(std::move(rel));
|
||||
});
|
||||
for (const auto &r : f.relationships()) {
|
||||
nlohmann::json rel = r;
|
||||
rel["source"] = std::to_string(f.id().value());
|
||||
parent["relationships"].push_back(std::move(rel));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,17 +70,15 @@ void generator::generate(const source_file &f, nlohmann::json &parent) const
|
||||
parent["elements"].push_back(std::move(j));
|
||||
}
|
||||
else {
|
||||
if (model().should_include(f)) {
|
||||
LOG_DBG("Generating file {}", f.name());
|
||||
LOG_DBG("Generating file {}", f.name());
|
||||
|
||||
j["type"] = "file";
|
||||
j["file_kind"] = to_string(f.type());
|
||||
if (f.type() == common::model::source_file_t::kHeader) {
|
||||
j["is_system"] = f.is_system_header();
|
||||
}
|
||||
|
||||
parent["elements"].push_back(std::move(j));
|
||||
j["type"] = "file";
|
||||
j["file_kind"] = to_string(f.type());
|
||||
if (f.type() == common::model::source_file_t::kHeader) {
|
||||
j["is_system"] = f.is_system_header();
|
||||
}
|
||||
|
||||
parent["elements"].push_back(std::move(j));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,21 +49,13 @@ void generator::generate_relationships(
|
||||
});
|
||||
}
|
||||
else {
|
||||
util::for_each_if(
|
||||
f.relationships(),
|
||||
[this](const auto &r) {
|
||||
return model().should_include(r.type()) &&
|
||||
util::contains(m_generated_aliases,
|
||||
model().get(r.destination()).value().alias());
|
||||
},
|
||||
[&f, &ostr, this](const auto &r) {
|
||||
ostr << indent(1) << f.alias() << " "
|
||||
<< (r.type() == common::model::relationship_t::kDependency
|
||||
? "-.->"
|
||||
: "-->")
|
||||
<< " " << model().get(r.destination()).value().alias()
|
||||
<< '\n';
|
||||
});
|
||||
for (const auto &r : f.relationships()) {
|
||||
ostr << indent(1) << f.alias() << " "
|
||||
<< (r.type() == common::model::relationship_t::kDependency
|
||||
? "-.->"
|
||||
: "-->")
|
||||
<< " " << model().get(r.destination()).value().alias() << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,11 +78,9 @@ void generator::generate(const source_file &f, std::ostream &ostr) const
|
||||
else {
|
||||
LOG_DBG("Generating file {}", f.name());
|
||||
|
||||
if (model().should_include(f)) {
|
||||
ostr << indent(1) << f.alias() << "[" << f.name() << "]\n";
|
||||
ostr << indent(1) << f.alias() << "[" << f.name() << "]\n";
|
||||
|
||||
m_generated_aliases.emplace(f.alias());
|
||||
}
|
||||
m_generated_aliases.emplace(f.alias());
|
||||
}
|
||||
|
||||
if (config().generate_links) {
|
||||
|
||||
@@ -44,18 +44,11 @@ void generator::generate_relationships(
|
||||
});
|
||||
}
|
||||
else {
|
||||
util::for_each_if(
|
||||
f.relationships(),
|
||||
[this](const auto &r) {
|
||||
return model().should_include(r.type()) &&
|
||||
util::contains(m_generated_aliases,
|
||||
model().get(r.destination()).value().alias());
|
||||
},
|
||||
[&f, &ostr, this](const auto &r) {
|
||||
ostr << f.alias() << " "
|
||||
<< plantuml_common::to_plantuml(r, config()) << " "
|
||||
<< model().get(r.destination()).value().alias() << '\n';
|
||||
});
|
||||
for (const auto &r : f.relationships()) {
|
||||
ostr << f.alias() << " "
|
||||
<< plantuml_common::to_plantuml(r, config()) << " "
|
||||
<< model().get(r.destination()).value().alias() << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,17 +72,15 @@ void generator::generate(const source_file &f, std::ostream &ostr) const
|
||||
else {
|
||||
LOG_DBG("Generating file {}", f.name());
|
||||
|
||||
if (model().should_include(f)) {
|
||||
ostr << "file \"" << f.name() << "\" as " << f.alias();
|
||||
ostr << "file \"" << f.name() << "\" as " << f.alias();
|
||||
|
||||
if (config().generate_links) {
|
||||
generate_link(ostr, f);
|
||||
}
|
||||
|
||||
ostr << '\n';
|
||||
|
||||
m_generated_aliases.emplace(f.alias());
|
||||
if (config().generate_links) {
|
||||
generate_link(ostr, f);
|
||||
}
|
||||
|
||||
ostr << '\n';
|
||||
|
||||
m_generated_aliases.emplace(f.alias());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "diagram.h"
|
||||
|
||||
#include "common/model/filters/diagram_filter.h"
|
||||
#include "util/error.h"
|
||||
#include "util/util.h"
|
||||
|
||||
@@ -53,8 +54,6 @@ void diagram::add_file(std::unique_ptr<common::model::source_file> &&f)
|
||||
assert(!ff.name().empty());
|
||||
assert(ff.id().value() != 0);
|
||||
|
||||
element_view<source_file>::add(ff);
|
||||
|
||||
auto p = ff.path();
|
||||
|
||||
if (!f->path().is_empty()) {
|
||||
@@ -86,7 +85,8 @@ void diagram::add_file(std::unique_ptr<common::model::source_file> &&f)
|
||||
|
||||
assert(p.type() == common::model::path_type::kFilesystem);
|
||||
|
||||
add_element(p, std::move(f));
|
||||
if (add_element(p, std::move(f)))
|
||||
element_view<source_file>::add(ff);
|
||||
}
|
||||
|
||||
const common::reference_vector<common::model::source_file> &
|
||||
@@ -133,6 +133,25 @@ inja::json diagram::context() const
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void diagram::apply_filter()
|
||||
{
|
||||
// First find all element ids which should be removed
|
||||
std::set<eid_t> to_remove;
|
||||
|
||||
for (auto &f : element_view<source_file>::view())
|
||||
if (f.get().type() != common::model::source_file_t::kDirectory &&
|
||||
!filter().should_include(f.get())) {
|
||||
to_remove.emplace(f.get().id());
|
||||
}
|
||||
|
||||
for (auto &sf : element_view<source_file>::view())
|
||||
sf.get().apply_filter(filter(), to_remove);
|
||||
|
||||
element_view<source_file>::remove(to_remove);
|
||||
|
||||
nested_trait_fspath::remove(to_remove);
|
||||
}
|
||||
|
||||
bool diagram::is_empty() const { return element_view<source_file>::is_empty(); }
|
||||
|
||||
} // namespace clanguml::include_diagram::model
|
||||
|
||||
@@ -33,13 +33,15 @@ using clanguml::common::opt_ref;
|
||||
using clanguml::common::model::diagram_element;
|
||||
using clanguml::common::model::source_file;
|
||||
|
||||
using nested_trait_fspath = clanguml::common::model::nested_trait<source_file,
|
||||
clanguml::common::model::filesystem_path>;
|
||||
|
||||
/**
|
||||
* @brief Class representing an include diagram model.
|
||||
*/
|
||||
class diagram : public clanguml::common::model::diagram,
|
||||
public clanguml::common::model::element_view<source_file>,
|
||||
public clanguml::common::model::nested_trait<source_file,
|
||||
clanguml::common::model::filesystem_path> {
|
||||
public nested_trait_fspath {
|
||||
public:
|
||||
diagram() = default;
|
||||
|
||||
@@ -128,6 +130,8 @@ public:
|
||||
* @return True, if diagram is empty
|
||||
*/
|
||||
bool is_empty() const override;
|
||||
|
||||
void apply_filter() override;
|
||||
};
|
||||
|
||||
template <typename ElementT>
|
||||
|
||||
@@ -39,9 +39,7 @@ void generator::generate_relationships(
|
||||
|
||||
auto destination_package = model().get(r.destination());
|
||||
|
||||
if (!destination_package ||
|
||||
!model().should_include(
|
||||
dynamic_cast<const package &>(*destination_package)))
|
||||
if (!destination_package)
|
||||
continue;
|
||||
|
||||
rel["source"] = std::to_string(p.id().value());
|
||||
@@ -88,9 +86,7 @@ void generator::generate(const package &p, nlohmann::json &parent) const
|
||||
|
||||
for (const auto &subpackage : p) {
|
||||
auto &pkg = dynamic_cast<package &>(*subpackage);
|
||||
if (model().should_include(pkg)) {
|
||||
generate(pkg, j);
|
||||
}
|
||||
generate(pkg, j);
|
||||
}
|
||||
|
||||
parent["elements"].push_back(std::move(j));
|
||||
@@ -98,9 +94,7 @@ void generator::generate(const package &p, nlohmann::json &parent) const
|
||||
else {
|
||||
for (const auto &subpackage : p) {
|
||||
auto &pkg = dynamic_cast<package &>(*subpackage);
|
||||
if (model().should_include(pkg)) {
|
||||
generate(pkg, parent);
|
||||
}
|
||||
generate(pkg, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,15 +114,12 @@ void generator::generate_diagram(nlohmann::json &parent) const
|
||||
|
||||
for (const auto &p : model()) {
|
||||
auto &pkg = dynamic_cast<package &>(*p);
|
||||
if (model().should_include(pkg)) {
|
||||
generate(pkg, parent);
|
||||
}
|
||||
generate(pkg, parent);
|
||||
}
|
||||
|
||||
// Process package relationships
|
||||
for (const auto &p : model()) {
|
||||
if (model().should_include(dynamic_cast<package &>(*p)))
|
||||
generate_relationships(dynamic_cast<package &>(*p), parent);
|
||||
generate_relationships(dynamic_cast<package &>(*p), parent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,9 +47,7 @@ void generator::generate_relationships(
|
||||
try {
|
||||
auto destination_package = model().get(r.destination());
|
||||
|
||||
if (!destination_package ||
|
||||
!model().should_include(
|
||||
dynamic_cast<const package &>(*destination_package)))
|
||||
if (!destination_package)
|
||||
continue;
|
||||
|
||||
auto destination_alias = model().to_alias(r.destination());
|
||||
@@ -94,16 +92,12 @@ void generator::generate(const package &p, std::ostream &ostr) const
|
||||
|
||||
for (const auto &subpackage : p) {
|
||||
auto &pkg = dynamic_cast<package &>(*subpackage);
|
||||
if (model().should_include(pkg)) {
|
||||
auto together_group =
|
||||
config().get_together_group(pkg.full_name(false));
|
||||
if (together_group) {
|
||||
together_group_stack_.group_together(
|
||||
together_group.value(), &pkg);
|
||||
}
|
||||
else {
|
||||
generate(pkg, ostr);
|
||||
}
|
||||
auto together_group = config().get_together_group(pkg.full_name(false));
|
||||
if (together_group) {
|
||||
together_group_stack_.group_together(together_group.value(), &pkg);
|
||||
}
|
||||
else {
|
||||
generate(pkg, ostr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,16 +153,12 @@ void generator::generate_diagram(std::ostream &ostr) const
|
||||
{
|
||||
for (const auto &p : model()) {
|
||||
auto &pkg = dynamic_cast<package &>(*p);
|
||||
if (model().should_include(pkg)) {
|
||||
auto together_group =
|
||||
config().get_together_group(pkg.full_name(false));
|
||||
if (together_group) {
|
||||
together_group_stack_.group_together(
|
||||
together_group.value(), &pkg);
|
||||
}
|
||||
else {
|
||||
generate(pkg, ostr);
|
||||
}
|
||||
auto together_group = config().get_together_group(pkg.full_name(false));
|
||||
if (together_group) {
|
||||
together_group_stack_.group_together(together_group.value(), &pkg);
|
||||
}
|
||||
else {
|
||||
generate(pkg, ostr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,8 +166,7 @@ void generator::generate_diagram(std::ostream &ostr) const
|
||||
|
||||
// Process package relationships
|
||||
for (const auto &p : model()) {
|
||||
if (model().should_include(dynamic_cast<package &>(*p)))
|
||||
generate_relationships(dynamic_cast<package &>(*p), ostr);
|
||||
generate_relationships(dynamic_cast<package &>(*p), ostr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,10 +39,7 @@ void generator::generate_relationships(
|
||||
std::stringstream relstr;
|
||||
try {
|
||||
auto destination_package = model().get(r.destination());
|
||||
|
||||
if (!destination_package ||
|
||||
!model().should_include(
|
||||
dynamic_cast<const package &>(*destination_package)))
|
||||
if (!destination_package)
|
||||
continue;
|
||||
|
||||
auto destination_alias = model().to_alias(r.destination());
|
||||
@@ -62,9 +59,8 @@ void generator::generate_relationships(
|
||||
|
||||
// Process it's subpackages relationships
|
||||
for (const auto &subpackage : p) {
|
||||
if (model().should_include(dynamic_cast<const package &>(*subpackage)))
|
||||
generate_relationships(
|
||||
dynamic_cast<const package &>(*subpackage), ostr);
|
||||
generate_relationships(
|
||||
dynamic_cast<const package &>(*subpackage), ostr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,16 +92,12 @@ void generator::generate(const package &p, std::ostream &ostr) const
|
||||
|
||||
for (const auto &subpackage : p) {
|
||||
auto &pkg = dynamic_cast<package &>(*subpackage);
|
||||
if (model().should_include(pkg)) {
|
||||
auto together_group =
|
||||
config().get_together_group(pkg.full_name(false));
|
||||
if (together_group) {
|
||||
together_group_stack_.group_together(
|
||||
together_group.value(), &pkg);
|
||||
}
|
||||
else {
|
||||
generate(pkg, ostr);
|
||||
}
|
||||
auto together_group = config().get_together_group(pkg.full_name(false));
|
||||
if (together_group) {
|
||||
together_group_stack_.group_together(together_group.value(), &pkg);
|
||||
}
|
||||
else {
|
||||
generate(pkg, ostr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,16 +130,12 @@ void generator::generate_diagram(std::ostream &ostr) const
|
||||
{
|
||||
for (const auto &p : model()) {
|
||||
auto &pkg = dynamic_cast<package &>(*p);
|
||||
if (model().should_include(pkg)) {
|
||||
auto together_group =
|
||||
config().get_together_group(pkg.full_name(false));
|
||||
if (together_group) {
|
||||
together_group_stack_.group_together(
|
||||
together_group.value(), &pkg);
|
||||
}
|
||||
else {
|
||||
generate(pkg, ostr);
|
||||
}
|
||||
auto together_group = config().get_together_group(pkg.full_name(false));
|
||||
if (together_group) {
|
||||
together_group_stack_.group_together(together_group.value(), &pkg);
|
||||
}
|
||||
else {
|
||||
generate(pkg, ostr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,8 +143,7 @@ void generator::generate_diagram(std::ostream &ostr) const
|
||||
|
||||
// Process package relationships
|
||||
for (const auto &p : model()) {
|
||||
if (model().should_include(dynamic_cast<package &>(*p)))
|
||||
generate_relationships(dynamic_cast<package &>(*p), ostr);
|
||||
generate_relationships(dynamic_cast<package &>(*p), ostr);
|
||||
}
|
||||
|
||||
generate_config_layout_hints(ostr);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "diagram.h"
|
||||
|
||||
#include "common/model/filters/diagram_filter.h"
|
||||
#include "util/error.h"
|
||||
#include "util/util.h"
|
||||
|
||||
@@ -74,6 +75,23 @@ inja::json diagram::context() const
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void diagram::apply_filter()
|
||||
{
|
||||
// First find all element ids which should be removed
|
||||
std::set<eid_t> to_remove;
|
||||
|
||||
for (const auto &c : packages())
|
||||
if (!filter().should_include(c.get()))
|
||||
to_remove.emplace(c.get().id());
|
||||
|
||||
nested_trait_ns::remove(to_remove);
|
||||
|
||||
element_view<package>::remove(to_remove);
|
||||
|
||||
for (auto &c : element_view<package>::view())
|
||||
c.get().apply_filter(filter(), to_remove);
|
||||
}
|
||||
|
||||
bool diagram::is_empty() const { return element_view<package>::is_empty(); }
|
||||
} // namespace clanguml::package_diagram::model
|
||||
|
||||
|
||||
@@ -32,14 +32,16 @@ using clanguml::common::model::diagram_element;
|
||||
using clanguml::common::model::package;
|
||||
using clanguml::common::model::path;
|
||||
|
||||
using nested_trait_ns =
|
||||
clanguml::common::model::nested_trait<clanguml::common::model::element,
|
||||
clanguml::common::model::namespace_>;
|
||||
|
||||
/**
|
||||
* @brief Package diagram model.
|
||||
*/
|
||||
class diagram : public clanguml::common::model::diagram,
|
||||
public clanguml::common::model::element_view<package>,
|
||||
public clanguml::common::model::nested_trait<
|
||||
clanguml::common::model::element,
|
||||
clanguml::common::model::namespace_> {
|
||||
public nested_trait_ns {
|
||||
public:
|
||||
diagram() = default;
|
||||
|
||||
@@ -165,6 +167,8 @@ public:
|
||||
*/
|
||||
bool is_empty() const override;
|
||||
|
||||
void apply_filter() override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Add element using module as diagram path
|
||||
|
||||
Reference in New Issue
Block a user