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()) {
|
for (const auto &p : model()) {
|
||||||
if (auto *pkg = dynamic_cast<package *>(p.get()); pkg) {
|
if (auto *pkg = dynamic_cast<package *>(p.get()); pkg) {
|
||||||
if (!pkg->is_empty() &&
|
if (!pkg->is_empty())
|
||||||
!pkg->all_of([this](const common::model::element &e) {
|
|
||||||
return !model().should_include(e);
|
|
||||||
}))
|
|
||||||
generate(*pkg, parent);
|
generate(*pkg, parent);
|
||||||
}
|
}
|
||||||
else if (auto *cls = dynamic_cast<class_ *>(p.get()); cls) {
|
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) {
|
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) {
|
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) {
|
for (const auto &subpackage : p) {
|
||||||
if (dynamic_cast<package *>(subpackage.get()) != nullptr) {
|
if (dynamic_cast<package *>(subpackage.get()) != nullptr) {
|
||||||
const auto &sp = dynamic_cast<package &>(*subpackage);
|
const auto &sp = dynamic_cast<package &>(*subpackage);
|
||||||
if (!sp.is_empty() &&
|
if (!sp.is_empty()) {
|
||||||
!sp.all_of([this](const common::model::element &e) {
|
|
||||||
return !model().should_include(e);
|
|
||||||
})) {
|
|
||||||
if (config().generate_packages())
|
if (config().generate_packages())
|
||||||
generate(sp, package_object);
|
generate(sp, package_object);
|
||||||
else
|
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) {
|
else if (auto *cls = dynamic_cast<class_ *>(subpackage.get()); cls) {
|
||||||
if (model().should_include(*cls)) {
|
if (config().generate_packages())
|
||||||
if (config().generate_packages())
|
generate(*cls, package_object);
|
||||||
generate(*cls, package_object);
|
else
|
||||||
else
|
generate(*cls, parent);
|
||||||
generate(*cls, parent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (auto *enm = dynamic_cast<enum_ *>(subpackage.get()); enm) {
|
else if (auto *enm = dynamic_cast<enum_ *>(subpackage.get()); enm) {
|
||||||
if (model().should_include(*enm)) {
|
if (config().generate_packages())
|
||||||
if (config().generate_packages())
|
generate(*enm, package_object);
|
||||||
generate(*enm, package_object);
|
else
|
||||||
else
|
generate(*enm, parent);
|
||||||
generate(*enm, parent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (auto *cpt = dynamic_cast<concept_ *>(subpackage.get()); cpt) {
|
else if (auto *cpt = dynamic_cast<concept_ *>(subpackage.get()); cpt) {
|
||||||
if (model().should_include(*cpt)) {
|
if (config().generate_packages())
|
||||||
if (config().generate_packages())
|
generate(*cpt, package_object);
|
||||||
generate(*cpt, package_object);
|
else
|
||||||
else
|
generate(*cpt, parent);
|
||||||
generate(*cpt, parent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,19 +283,13 @@ void generator::generate_relationships(nlohmann::json &parent) const
|
|||||||
generate_relationships(*pkg, parent);
|
generate_relationships(*pkg, parent);
|
||||||
}
|
}
|
||||||
else if (auto *cls = dynamic_cast<class_ *>(p.get()); cls) {
|
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) {
|
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) {
|
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
|
const class_ &c, nlohmann::json &parent) const
|
||||||
{
|
{
|
||||||
for (const auto &r : c.relationships()) {
|
for (const auto &r : c.relationships()) {
|
||||||
if (!model().should_include(r))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto target_element = model().get(r.destination());
|
auto target_element = model().get(r.destination());
|
||||||
if (!target_element.has_value()) {
|
if (!target_element.has_value()) {
|
||||||
LOG_DBG("Skipping {} relation from {} to {} due "
|
LOG_DBG("Skipping {} relation from {} to {} due "
|
||||||
@@ -353,9 +326,6 @@ void generator::generate_relationships(
|
|||||||
const enum_ &c, nlohmann::json &parent) const
|
const enum_ &c, nlohmann::json &parent) const
|
||||||
{
|
{
|
||||||
for (const auto &r : c.relationships()) {
|
for (const auto &r : c.relationships()) {
|
||||||
if (!model().should_include(r))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto target_element = model().get(r.destination());
|
auto target_element = model().get(r.destination());
|
||||||
if (!target_element.has_value()) {
|
if (!target_element.has_value()) {
|
||||||
LOG_DBG("Skipping {} relation from {} to {} due "
|
LOG_DBG("Skipping {} relation from {} to {} due "
|
||||||
@@ -374,9 +344,6 @@ void generator::generate_relationships(
|
|||||||
const concept_ &c, nlohmann::json &parent) const
|
const concept_ &c, nlohmann::json &parent) const
|
||||||
{
|
{
|
||||||
for (const auto &r : c.relationships()) {
|
for (const auto &r : c.relationships()) {
|
||||||
if (!model().should_include(r))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto target_element = model().get(r.destination());
|
auto target_element = model().get(r.destination());
|
||||||
if (!target_element.has_value()) {
|
if (!target_element.has_value()) {
|
||||||
LOG_DBG("Skipping {} relation from {} to {} due "
|
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;
|
std::stringstream all_relations_str;
|
||||||
for (const auto &r : c.relationships()) {
|
for (const auto &r : c.relationships()) {
|
||||||
if (!model().should_include(r.type()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
generate_relationship(r, rendered_relations);
|
generate_relationship(r, rendered_relations);
|
||||||
}
|
}
|
||||||
@@ -111,9 +108,6 @@ void generator::generate(const class_ &c, std::ostream &ostr) const
|
|||||||
sort_class_elements(members);
|
sort_class_elements(members);
|
||||||
|
|
||||||
for (const auto &m : members) {
|
for (const auto &m : members) {
|
||||||
if (!model().should_include(m))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!config().include_relations_also_as_members() &&
|
if (!config().include_relations_also_as_members() &&
|
||||||
rendered_relations.find(m.name()) != rendered_relations.end())
|
rendered_relations.find(m.name()) != rendered_relations.end())
|
||||||
continue;
|
continue;
|
||||||
@@ -156,11 +150,7 @@ void generator::generate_methods(
|
|||||||
sort_class_elements(sorted_methods);
|
sort_class_elements(sorted_methods);
|
||||||
|
|
||||||
for (const auto &m : sorted_methods) {
|
for (const auto &m : sorted_methods) {
|
||||||
if (!model().should_include(m))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
generate_method(m, ostr);
|
generate_method(m, ostr);
|
||||||
|
|
||||||
ostr << '\n';
|
ostr << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -170,17 +160,11 @@ generator::method_groups_t generator::group_methods(
|
|||||||
{
|
{
|
||||||
std::map<std::string, std::vector<class_method>> result;
|
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_) {
|
for (const auto &g : method_groups_) {
|
||||||
result[g] = {};
|
result[g] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &m : filtered_methods) {
|
for (const auto &m : methods) {
|
||||||
if (m.is_constructor() || m.is_destructor()) {
|
if (m.is_constructor() || m.is_destructor()) {
|
||||||
result["constructors"].push_back(m);
|
result["constructors"].push_back(m);
|
||||||
}
|
}
|
||||||
@@ -333,19 +317,13 @@ void generator::generate_relationships(std::ostream &ostr) const
|
|||||||
generate_relationships(*pkg, ostr);
|
generate_relationships(*pkg, ostr);
|
||||||
}
|
}
|
||||||
else if (auto *cls = dynamic_cast<class_ *>(p.get()); cls) {
|
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) {
|
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) {
|
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;
|
std::set<std::string> unique_relations;
|
||||||
|
|
||||||
for (const auto &r : c.relationships()) {
|
for (const auto &r : c.relationships()) {
|
||||||
if (!model().should_include(r.type()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
LOG_DBG("== Processing relationship {}", to_string(r.type()));
|
LOG_DBG("== Processing relationship {}", to_string(r.type()));
|
||||||
|
|
||||||
std::stringstream relstr;
|
std::stringstream relstr;
|
||||||
@@ -509,9 +484,6 @@ void generator::generate_relationships(
|
|||||||
std::set<std::string> unique_relations;
|
std::set<std::string> unique_relations;
|
||||||
|
|
||||||
for (const auto &r : c.relationships()) {
|
for (const auto &r : c.relationships()) {
|
||||||
if (!model().should_include(r.type()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
LOG_DBG("== Processing relationship {}", to_string(r.type()));
|
LOG_DBG("== Processing relationship {}", to_string(r.type()));
|
||||||
|
|
||||||
std::stringstream relstr;
|
std::stringstream relstr;
|
||||||
@@ -583,9 +555,6 @@ void generator::generate_relationships(
|
|||||||
void generator::generate_relationships(const enum_ &e, std::ostream &ostr) const
|
void generator::generate_relationships(const enum_ &e, std::ostream &ostr) const
|
||||||
{
|
{
|
||||||
for (const auto &r : e.relationships()) {
|
for (const auto &r : e.relationships()) {
|
||||||
if (!model().should_include(r.type()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
eid_t destination{};
|
eid_t destination{};
|
||||||
std::stringstream relstr;
|
std::stringstream relstr;
|
||||||
try {
|
try {
|
||||||
@@ -718,10 +687,7 @@ void generator::generate_relationships(
|
|||||||
// packages which do not contain anything but other
|
// packages which do not contain anything but other
|
||||||
// packages are skipped
|
// packages are skipped
|
||||||
const auto &sp = dynamic_cast<package &>(*subpackage);
|
const auto &sp = dynamic_cast<package &>(*subpackage);
|
||||||
if (!sp.is_empty() &&
|
if (!sp.is_empty())
|
||||||
!sp.all_of([this](const common::model::element &e) {
|
|
||||||
return !model().should_include(e);
|
|
||||||
}))
|
|
||||||
generate_relationships(sp, ostr);
|
generate_relationships(sp, ostr);
|
||||||
}
|
}
|
||||||
else if (dynamic_cast<class_ *>(subpackage.get()) != nullptr) {
|
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()) {
|
for (const auto &p : model()) {
|
||||||
if (auto *pkg = dynamic_cast<package *>(p.get()); pkg) {
|
if (auto *pkg = dynamic_cast<package *>(p.get()); pkg) {
|
||||||
if (!pkg->is_empty() &&
|
if (!pkg->is_empty())
|
||||||
!pkg->all_of([this](const common::model::element &e) {
|
|
||||||
return !model().should_include(e);
|
|
||||||
}))
|
|
||||||
generate(*pkg, ostr);
|
generate(*pkg, ostr);
|
||||||
}
|
}
|
||||||
else if (auto *cls = dynamic_cast<class_ *>(p.get()); cls) {
|
else if (auto *cls = dynamic_cast<class_ *>(p.get()); cls) {
|
||||||
if (model().should_include(*cls)) {
|
auto together_group =
|
||||||
auto together_group =
|
config().get_together_group(cls->full_name(false));
|
||||||
config().get_together_group(cls->full_name(false));
|
if (together_group) {
|
||||||
if (together_group) {
|
together_group_stack_.group_together(
|
||||||
together_group_stack_.group_together(
|
together_group.value(), cls);
|
||||||
together_group.value(), cls);
|
}
|
||||||
}
|
else {
|
||||||
else {
|
generate_alias(*cls, ostr);
|
||||||
generate_alias(*cls, ostr);
|
generate(*cls, ostr);
|
||||||
generate(*cls, ostr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (auto *enm = dynamic_cast<enum_ *>(p.get()); enm) {
|
else if (auto *enm = dynamic_cast<enum_ *>(p.get()); enm) {
|
||||||
if (model().should_include(*enm)) {
|
auto together_group =
|
||||||
auto together_group =
|
config().get_together_group(enm->full_name(false));
|
||||||
config().get_together_group(enm->full_name(false));
|
if (together_group) {
|
||||||
if (together_group) {
|
together_group_stack_.group_together(
|
||||||
together_group_stack_.group_together(
|
together_group.value(), enm);
|
||||||
together_group.value(), enm);
|
}
|
||||||
}
|
else {
|
||||||
else {
|
generate_alias(*enm, ostr);
|
||||||
generate_alias(*enm, ostr);
|
generate(*enm, ostr);
|
||||||
generate(*enm, ostr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (auto *cpt = dynamic_cast<concept_ *>(p.get()); cpt) {
|
else if (auto *cpt = dynamic_cast<concept_ *>(p.get()); cpt) {
|
||||||
if (model().should_include(*cpt)) {
|
auto together_group =
|
||||||
auto together_group =
|
config().get_together_group(cpt->full_name(false));
|
||||||
config().get_together_group(cpt->full_name(false));
|
if (together_group) {
|
||||||
if (together_group) {
|
together_group_stack_.group_together(
|
||||||
together_group_stack_.group_together(
|
together_group.value(), cpt);
|
||||||
together_group.value(), cpt);
|
}
|
||||||
}
|
else {
|
||||||
else {
|
generate_alias(*cpt, ostr);
|
||||||
generate_alias(*cpt, ostr);
|
generate(*cpt, ostr);
|
||||||
generate(*cpt, ostr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,9 +157,6 @@ void generator::generate(const class_ &c, std::ostream &ostr) const
|
|||||||
|
|
||||||
std::stringstream all_relations_str;
|
std::stringstream all_relations_str;
|
||||||
for (const auto &r : c.relationships()) {
|
for (const auto &r : c.relationships()) {
|
||||||
if (!model().should_include(r.type()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
generate_relationship(r, rendered_relations);
|
generate_relationship(r, rendered_relations);
|
||||||
}
|
}
|
||||||
@@ -182,9 +179,6 @@ void generator::generate(const class_ &c, std::ostream &ostr) const
|
|||||||
ostr << "__\n";
|
ostr << "__\n";
|
||||||
|
|
||||||
for (const auto &m : members) {
|
for (const auto &m : members) {
|
||||||
if (!model().should_include(m))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!config().include_relations_also_as_members() &&
|
if (!config().include_relations_also_as_members() &&
|
||||||
rendered_relations.find(m.name()) != rendered_relations.end())
|
rendered_relations.find(m.name()) != rendered_relations.end())
|
||||||
continue;
|
continue;
|
||||||
@@ -228,11 +222,7 @@ void generator::generate_methods(
|
|||||||
sort_class_elements(sorted_methods);
|
sort_class_elements(sorted_methods);
|
||||||
|
|
||||||
for (const auto &m : sorted_methods) {
|
for (const auto &m : sorted_methods) {
|
||||||
if (!model().should_include(m))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
generate_method(m, ostr);
|
generate_method(m, ostr);
|
||||||
|
|
||||||
ostr << '\n';
|
ostr << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -242,17 +232,11 @@ generator::method_groups_t generator::group_methods(
|
|||||||
{
|
{
|
||||||
std::map<std::string, std::vector<class_method>> result;
|
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_) {
|
for (const auto &g : method_groups_) {
|
||||||
result[g] = {};
|
result[g] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &m : filtered_methods) {
|
for (const auto &m : methods) {
|
||||||
if (m.is_constructor() || m.is_destructor()) {
|
if (m.is_constructor() || m.is_destructor()) {
|
||||||
result["constructors"].push_back(m);
|
result["constructors"].push_back(m);
|
||||||
}
|
}
|
||||||
@@ -417,19 +401,13 @@ void generator::generate_relationships(std::ostream &ostr) const
|
|||||||
generate_relationships(*pkg, ostr);
|
generate_relationships(*pkg, ostr);
|
||||||
}
|
}
|
||||||
else if (auto *cls = dynamic_cast<class_ *>(p.get()); cls) {
|
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) {
|
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) {
|
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;
|
std::set<std::string> unique_relations;
|
||||||
|
|
||||||
for (const auto &r : c.relationships()) {
|
for (const auto &r : c.relationships()) {
|
||||||
if (!model().should_include(r.type()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
LOG_DBG("== Processing relationship {}",
|
LOG_DBG("== Processing relationship {}",
|
||||||
plantuml_common::to_plantuml(r, config()));
|
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
|
void generator::generate_relationships(const enum_ &e, std::ostream &ostr) const
|
||||||
{
|
{
|
||||||
for (const auto &r : e.relationships()) {
|
for (const auto &r : e.relationships()) {
|
||||||
if (!model().should_include(r.type()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
eid_t destination{};
|
eid_t destination{};
|
||||||
std::stringstream relstr;
|
std::stringstream relstr;
|
||||||
try {
|
try {
|
||||||
@@ -724,10 +696,7 @@ void generator::generate(const package &p, std::ostream &ostr) const
|
|||||||
if (dynamic_cast<package *>(subpackage.get()) != nullptr) {
|
if (dynamic_cast<package *>(subpackage.get()) != nullptr) {
|
||||||
// TODO: add option - generate_empty_packages
|
// TODO: add option - generate_empty_packages
|
||||||
const auto &sp = dynamic_cast<package &>(*subpackage);
|
const auto &sp = dynamic_cast<package &>(*subpackage);
|
||||||
if (!sp.is_empty() &&
|
if (!sp.is_empty()) {
|
||||||
!sp.all_of([this](const common::model::element &e) {
|
|
||||||
return !model().should_include(e);
|
|
||||||
})) {
|
|
||||||
together_group_stack_.enter();
|
together_group_stack_.enter();
|
||||||
|
|
||||||
generate(sp, ostr);
|
generate(sp, ostr);
|
||||||
@@ -822,10 +791,7 @@ void generator::generate_relationships(
|
|||||||
// packages which do not contain anything but other
|
// packages which do not contain anything but other
|
||||||
// packages are skipped
|
// packages are skipped
|
||||||
const auto &sp = dynamic_cast<package &>(*subpackage);
|
const auto &sp = dynamic_cast<package &>(*subpackage);
|
||||||
if (!sp.is_empty() &&
|
if (!sp.is_empty())
|
||||||
!sp.all_of([this](const common::model::element &e) {
|
|
||||||
return !model().should_include(e);
|
|
||||||
}))
|
|
||||||
generate_relationships(sp, ostr);
|
generate_relationships(sp, ostr);
|
||||||
}
|
}
|
||||||
else if (dynamic_cast<class_ *>(subpackage.get()) != nullptr) {
|
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()) {
|
for (const auto &p : model()) {
|
||||||
if (auto *pkg = dynamic_cast<package *>(p.get()); pkg) {
|
if (auto *pkg = dynamic_cast<package *>(p.get()); pkg) {
|
||||||
if (!pkg->is_empty() &&
|
if (!pkg->is_empty())
|
||||||
!pkg->all_of([this](const common::model::element &e) {
|
|
||||||
return !model().should_include(e);
|
|
||||||
}))
|
|
||||||
generate(*pkg, ostr);
|
generate(*pkg, ostr);
|
||||||
}
|
}
|
||||||
else if (auto *cls = dynamic_cast<class_ *>(p.get()); cls) {
|
else if (auto *cls = dynamic_cast<class_ *>(p.get()); cls) {
|
||||||
if (model().should_include(*cls)) {
|
auto together_group =
|
||||||
auto together_group =
|
config().get_together_group(cls->full_name(false));
|
||||||
config().get_together_group(cls->full_name(false));
|
if (together_group) {
|
||||||
if (together_group) {
|
together_group_stack_.group_together(
|
||||||
together_group_stack_.group_together(
|
together_group.value(), cls);
|
||||||
together_group.value(), cls);
|
}
|
||||||
}
|
else {
|
||||||
else {
|
generate_alias(*cls, ostr);
|
||||||
generate_alias(*cls, ostr);
|
generate(*cls, ostr);
|
||||||
generate(*cls, ostr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (auto *enm = dynamic_cast<enum_ *>(p.get()); enm) {
|
else if (auto *enm = dynamic_cast<enum_ *>(p.get()); enm) {
|
||||||
if (model().should_include(*enm)) {
|
auto together_group =
|
||||||
auto together_group =
|
config().get_together_group(enm->full_name(false));
|
||||||
config().get_together_group(enm->full_name(false));
|
if (together_group) {
|
||||||
if (together_group) {
|
together_group_stack_.group_together(
|
||||||
together_group_stack_.group_together(
|
together_group.value(), enm);
|
||||||
together_group.value(), enm);
|
}
|
||||||
}
|
else {
|
||||||
else {
|
generate_alias(*enm, ostr);
|
||||||
generate_alias(*enm, ostr);
|
generate(*enm, ostr);
|
||||||
generate(*enm, ostr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (auto *cpt = dynamic_cast<concept_ *>(p.get()); cpt) {
|
else if (auto *cpt = dynamic_cast<concept_ *>(p.get()); cpt) {
|
||||||
if (model().should_include(*cpt)) {
|
auto together_group =
|
||||||
auto together_group =
|
config().get_together_group(cpt->full_name(false));
|
||||||
config().get_together_group(cpt->full_name(false));
|
if (together_group) {
|
||||||
if (together_group) {
|
together_group_stack_.group_together(
|
||||||
together_group_stack_.group_together(
|
together_group.value(), cpt);
|
||||||
together_group.value(), cpt);
|
}
|
||||||
}
|
else {
|
||||||
else {
|
generate_alias(*cpt, ostr);
|
||||||
generate_alias(*cpt, ostr);
|
generate(*cpt, ostr);
|
||||||
generate(*cpt, ostr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "class.h"
|
#include "class.h"
|
||||||
|
|
||||||
|
#include "common/model/filters/diagram_filter.h"
|
||||||
#include "util/util.h"
|
#include "util/util.h"
|
||||||
|
|
||||||
#include <sstream>
|
#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_method> &class_::methods() const { return methods_; }
|
||||||
|
|
||||||
const std::vector<class_parent> &class_::parents() const { return bases_; }
|
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(); }
|
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(); });
|
[](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
|
std::optional<std::string> class_::doxygen_link() const
|
||||||
{
|
{
|
||||||
const auto *type = is_struct() ? "struct" : "class";
|
const auto *type = is_struct() ? "struct" : "class";
|
||||||
|
|||||||
@@ -30,6 +30,10 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
namespace clanguml::common::model {
|
||||||
|
class diagram_filter;
|
||||||
|
}
|
||||||
|
|
||||||
namespace clanguml::class_diagram::model {
|
namespace clanguml::class_diagram::model {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -126,6 +130,7 @@ public:
|
|||||||
* @return Reference to class parents.
|
* @return Reference to class parents.
|
||||||
*/
|
*/
|
||||||
const std::vector<class_parent> &parents() const;
|
const std::vector<class_parent> &parents() const;
|
||||||
|
std::vector<class_parent> &parents();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get class full name.
|
* @brief Get class full name.
|
||||||
@@ -166,6 +171,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
std::optional<std::string> doxygen_link() const override;
|
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:
|
private:
|
||||||
bool is_struct_{false};
|
bool is_struct_{false};
|
||||||
bool is_union_{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
|
bool diagram::is_empty() const
|
||||||
{
|
{
|
||||||
return element_view<class_>::is_empty() &&
|
return element_view<class_>::is_empty() &&
|
||||||
|
|||||||
@@ -256,6 +256,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool is_empty() const override;
|
bool is_empty() const override;
|
||||||
|
|
||||||
|
void apply_filter() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename ElementT>
|
template <typename ElementT>
|
||||||
bool add_with_namespace_path(std::unique_ptr<ElementT> &&e);
|
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,
|
clang::RawComment *get_expression_raw_comment(const clang::SourceManager &sm,
|
||||||
const clang::ASTContext &context, const clang::Stmt *stmt)
|
const clang::ASTContext &context, const clang::Stmt *stmt)
|
||||||
{
|
{
|
||||||
// First get the first line of the expression
|
return get_raw_comment(sm, context, stmt->getSourceRange());
|
||||||
auto expr_begin = stmt->getSourceRange().getBegin();
|
}
|
||||||
|
|
||||||
|
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);
|
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() &&
|
if (!context.Comments.empty() &&
|
||||||
context.Comments.getCommentsInFile(sm.getFileID(expr_begin)) != nullptr)
|
context.Comments.getCommentsInFile(file_id) != nullptr) {
|
||||||
for (const auto [offset, raw_comment] :
|
for (const auto [offset, raw_comment] :
|
||||||
*context.Comments.getCommentsInFile(sm.getFileID(expr_begin))) {
|
*context.Comments.getCommentsInFile(sm.getFileID(expr_begin))) {
|
||||||
const auto comment_end_line = sm.getSpellingLineNumber(
|
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)
|
expr_begin_line == comment_end_line + 1)
|
||||||
return raw_comment;
|
return raw_comment;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -299,6 +299,12 @@ consume_type_context(clang::QualType type);
|
|||||||
clang::RawComment *get_expression_raw_comment(const clang::SourceManager &sm,
|
clang::RawComment *get_expression_raw_comment(const clang::SourceManager &sm,
|
||||||
const clang::ASTContext &context, const clang::Stmt *stmt);
|
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.
|
* 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_; }
|
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
|
bool diagram::should_include(const element &e) const
|
||||||
{
|
{
|
||||||
|
if (filtered_)
|
||||||
|
return true;
|
||||||
|
|
||||||
if (filter_.get() == nullptr)
|
if (filter_.get() == nullptr)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -77,6 +85,9 @@ bool diagram::should_include(const element &e) const
|
|||||||
|
|
||||||
bool diagram::should_include(const namespace_ &ns) const
|
bool diagram::should_include(const namespace_ &ns) const
|
||||||
{
|
{
|
||||||
|
if (filtered_)
|
||||||
|
return true;
|
||||||
|
|
||||||
if (filter_.get() == nullptr)
|
if (filter_.get() == nullptr)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|||||||
@@ -171,10 +171,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual bool is_empty() const = 0;
|
virtual bool is_empty() const = 0;
|
||||||
|
|
||||||
|
virtual void apply_filter() { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string name_;
|
std::string name_;
|
||||||
std::unique_ptr<diagram_filter> filter_;
|
std::unique_ptr<diagram_filter> filter_;
|
||||||
bool complete_{false};
|
bool complete_{false};
|
||||||
|
bool filtered_{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename DiagramT> bool check_diagram_type(diagram_t t);
|
template <typename DiagramT> bool check_diagram_type(diagram_t t);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "diagram_element.h"
|
#include "diagram_element.h"
|
||||||
|
|
||||||
|
#include "common/model/filters/diagram_filter.h"
|
||||||
#include "util/util.h"
|
#include "util/util.h"
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
@@ -102,6 +103,19 @@ bool diagram_element::complete() const { return complete_; }
|
|||||||
|
|
||||||
void diagram_element::complete(bool completed) { complete_ = completed; }
|
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)
|
bool operator==(const diagram_element &l, const diagram_element &r)
|
||||||
{
|
{
|
||||||
return l.id() == r.id();
|
return l.id() == r.id();
|
||||||
|
|||||||
@@ -26,11 +26,14 @@
|
|||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace clanguml::common::model {
|
namespace clanguml::common::model {
|
||||||
|
|
||||||
|
class diagram_filter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Base class for standalone diagram elements.
|
* @brief Base class for standalone diagram elements.
|
||||||
*
|
*
|
||||||
@@ -184,6 +187,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
void complete(bool completed);
|
void complete(bool completed);
|
||||||
|
|
||||||
|
virtual void apply_filter(
|
||||||
|
const diagram_filter &filter, const std::set<eid_t> &removed);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
eid_t id_{};
|
eid_t id_{};
|
||||||
std::optional<eid_t> parent_element_id_{};
|
std::optional<eid_t> parent_element_id_{};
|
||||||
|
|||||||
@@ -78,6 +78,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool is_empty() const { return elements_.empty(); }
|
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:
|
private:
|
||||||
reference_vector<T> elements_;
|
reference_vector<T> elements_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -99,6 +99,12 @@ tvl::value_t filter_visitor::match(
|
|||||||
return {};
|
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(
|
tvl::value_t filter_visitor::match(
|
||||||
const diagram & /*d*/, const common::model::relationship_t & /*r*/) const
|
const diagram & /*d*/, const common::model::relationship_t & /*r*/) const
|
||||||
{
|
{
|
||||||
@@ -997,7 +1003,7 @@ tvl::value_t paths_filter::match(
|
|||||||
return {};
|
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()) {
|
if (!p.is_absolute()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -1071,7 +1077,7 @@ tvl::value_t class_member_filter::match(
|
|||||||
}
|
}
|
||||||
|
|
||||||
diagram_filter::diagram_filter(const common::model::diagram &d,
|
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}
|
: diagram_{d}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,6 +86,9 @@ public:
|
|||||||
virtual tvl::value_t match(
|
virtual tvl::value_t match(
|
||||||
const diagram &d, const common::model::element &e) const;
|
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(
|
virtual tvl::value_t match(
|
||||||
const diagram &d, const common::model::relationship_t &r) const;
|
const diagram &d, const common::model::relationship_t &r) const;
|
||||||
|
|
||||||
@@ -815,15 +818,6 @@ public:
|
|||||||
friend class diagram_filter_factory;
|
friend class diagram_filter_factory;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
|
||||||
* @brief Initialize filters.
|
|
||||||
*
|
|
||||||
* Some filters require initialization.
|
|
||||||
*
|
|
||||||
* @param c Diagram config.
|
|
||||||
*/
|
|
||||||
// void init_filters(const config::diagram &c);
|
|
||||||
|
|
||||||
/*! List of inclusive filters */
|
/*! List of inclusive filters */
|
||||||
std::vector<std::unique_ptr<filter_visitor>> inclusive_;
|
std::vector<std::unique_ptr<filter_visitor>> inclusive_;
|
||||||
|
|
||||||
@@ -834,6 +828,27 @@ private:
|
|||||||
const common::model::diagram &diagram_;
|
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 <>
|
template <>
|
||||||
bool diagram_filter::should_include<std::string>(const std::string &name) const;
|
bool diagram_filter::should_include<std::string>(const std::string &name) const;
|
||||||
} // namespace clanguml::common::model
|
} // namespace clanguml::common::model
|
||||||
@@ -253,8 +253,10 @@ template <>
|
|||||||
void advanced_diagram_filter_initializer::add_filter<
|
void advanced_diagram_filter_initializer::add_filter<
|
||||||
source_file_dependency_filter_t>(const filter_t &filter_type,
|
source_file_dependency_filter_t>(const filter_t &filter_type,
|
||||||
const std::vector<common::string_or_regex> &filter_config,
|
const std::vector<common::string_or_regex> &filter_config,
|
||||||
std::vector<std::unique_ptr<filter_visitor>> &result, relationship_t &&rt,
|
std::vector<std::unique_ptr<filter_visitor>> &result,
|
||||||
bool &&direction)
|
relationship_t &&rt, // NOLINT
|
||||||
|
bool &&direction // NOLINT
|
||||||
|
)
|
||||||
{
|
{
|
||||||
std::vector<std::string> deps;
|
std::vector<std::string> deps;
|
||||||
for (auto &&path : filter_config) {
|
for (auto &&path : filter_config) {
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual ~diagram_filter_initializer() = default;
|
||||||
|
|
||||||
virtual void initialize() = 0;
|
virtual void initialize() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -62,6 +64,8 @@ class basic_diagram_filter_initializer : public diagram_filter_initializer {
|
|||||||
public:
|
public:
|
||||||
using diagram_filter_initializer::diagram_filter_initializer;
|
using diagram_filter_initializer::diagram_filter_initializer;
|
||||||
|
|
||||||
|
~basic_diagram_filter_initializer() override = default;
|
||||||
|
|
||||||
void initialize() override;
|
void initialize() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -69,6 +73,8 @@ class advanced_diagram_filter_initializer : public diagram_filter_initializer {
|
|||||||
public:
|
public:
|
||||||
using diagram_filter_initializer::diagram_filter_initializer;
|
using diagram_filter_initializer::diagram_filter_initializer;
|
||||||
|
|
||||||
|
~advanced_diagram_filter_initializer() override = default;
|
||||||
|
|
||||||
void initialize() override;
|
void initialize() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#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:
|
private:
|
||||||
std::vector<std::unique_ptr<T>> elements_;
|
std::vector<std::unique_ptr<T>> elements_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -253,8 +253,12 @@ public:
|
|||||||
|
|
||||||
comment_visitor_->visit(decl, e);
|
comment_visitor_->visit(decl, e);
|
||||||
|
|
||||||
const auto *comment =
|
auto *comment = decl.getASTContext().getRawCommentForDeclNoCache(&decl);
|
||||||
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);
|
process_comment(comment, decl.getASTContext().getDiagnostics(), e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,14 +39,11 @@ void generator::generate_relationships(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
util::for_each_if(
|
for (const auto &r : f.relationships()) {
|
||||||
f.relationships(),
|
nlohmann::json rel = r;
|
||||||
[this](const auto &r) { return model().should_include(r.type()); },
|
rel["source"] = std::to_string(f.id().value());
|
||||||
[&f, &parent](const auto &r) {
|
parent["relationships"].push_back(std::move(rel));
|
||||||
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));
|
parent["elements"].push_back(std::move(j));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (model().should_include(f)) {
|
LOG_DBG("Generating file {}", f.name());
|
||||||
LOG_DBG("Generating file {}", f.name());
|
|
||||||
|
|
||||||
j["type"] = "file";
|
j["type"] = "file";
|
||||||
j["file_kind"] = to_string(f.type());
|
j["file_kind"] = to_string(f.type());
|
||||||
if (f.type() == common::model::source_file_t::kHeader) {
|
if (f.type() == common::model::source_file_t::kHeader) {
|
||||||
j["is_system"] = f.is_system_header();
|
j["is_system"] = f.is_system_header();
|
||||||
}
|
|
||||||
|
|
||||||
parent["elements"].push_back(std::move(j));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parent["elements"].push_back(std::move(j));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,21 +49,13 @@ void generator::generate_relationships(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
util::for_each_if(
|
for (const auto &r : f.relationships()) {
|
||||||
f.relationships(),
|
ostr << indent(1) << f.alias() << " "
|
||||||
[this](const auto &r) {
|
<< (r.type() == common::model::relationship_t::kDependency
|
||||||
return model().should_include(r.type()) &&
|
? "-.->"
|
||||||
util::contains(m_generated_aliases,
|
: "-->")
|
||||||
model().get(r.destination()).value().alias());
|
<< " " << model().get(r.destination()).value().alias() << '\n';
|
||||||
},
|
}
|
||||||
[&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';
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,11 +78,9 @@ void generator::generate(const source_file &f, std::ostream &ostr) const
|
|||||||
else {
|
else {
|
||||||
LOG_DBG("Generating file {}", f.name());
|
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) {
|
if (config().generate_links) {
|
||||||
|
|||||||
@@ -44,18 +44,11 @@ void generator::generate_relationships(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
util::for_each_if(
|
for (const auto &r : f.relationships()) {
|
||||||
f.relationships(),
|
ostr << f.alias() << " "
|
||||||
[this](const auto &r) {
|
<< plantuml_common::to_plantuml(r, config()) << " "
|
||||||
return model().should_include(r.type()) &&
|
<< model().get(r.destination()).value().alias() << '\n';
|
||||||
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';
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,17 +72,15 @@ void generator::generate(const source_file &f, std::ostream &ostr) const
|
|||||||
else {
|
else {
|
||||||
LOG_DBG("Generating file {}", f.name());
|
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) {
|
if (config().generate_links) {
|
||||||
generate_link(ostr, f);
|
generate_link(ostr, f);
|
||||||
}
|
|
||||||
|
|
||||||
ostr << '\n';
|
|
||||||
|
|
||||||
m_generated_aliases.emplace(f.alias());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ostr << '\n';
|
||||||
|
|
||||||
|
m_generated_aliases.emplace(f.alias());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "diagram.h"
|
#include "diagram.h"
|
||||||
|
|
||||||
|
#include "common/model/filters/diagram_filter.h"
|
||||||
#include "util/error.h"
|
#include "util/error.h"
|
||||||
#include "util/util.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.name().empty());
|
||||||
assert(ff.id().value() != 0);
|
assert(ff.id().value() != 0);
|
||||||
|
|
||||||
element_view<source_file>::add(ff);
|
|
||||||
|
|
||||||
auto p = ff.path();
|
auto p = ff.path();
|
||||||
|
|
||||||
if (!f->path().is_empty()) {
|
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);
|
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> &
|
const common::reference_vector<common::model::source_file> &
|
||||||
@@ -133,6 +133,25 @@ inja::json diagram::context() const
|
|||||||
return ctx;
|
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(); }
|
bool diagram::is_empty() const { return element_view<source_file>::is_empty(); }
|
||||||
|
|
||||||
} // namespace clanguml::include_diagram::model
|
} // namespace clanguml::include_diagram::model
|
||||||
|
|||||||
@@ -33,13 +33,15 @@ using clanguml::common::opt_ref;
|
|||||||
using clanguml::common::model::diagram_element;
|
using clanguml::common::model::diagram_element;
|
||||||
using clanguml::common::model::source_file;
|
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.
|
* @brief Class representing an include diagram model.
|
||||||
*/
|
*/
|
||||||
class diagram : public clanguml::common::model::diagram,
|
class diagram : public clanguml::common::model::diagram,
|
||||||
public clanguml::common::model::element_view<source_file>,
|
public clanguml::common::model::element_view<source_file>,
|
||||||
public clanguml::common::model::nested_trait<source_file,
|
public nested_trait_fspath {
|
||||||
clanguml::common::model::filesystem_path> {
|
|
||||||
public:
|
public:
|
||||||
diagram() = default;
|
diagram() = default;
|
||||||
|
|
||||||
@@ -128,6 +130,8 @@ public:
|
|||||||
* @return True, if diagram is empty
|
* @return True, if diagram is empty
|
||||||
*/
|
*/
|
||||||
bool is_empty() const override;
|
bool is_empty() const override;
|
||||||
|
|
||||||
|
void apply_filter() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename ElementT>
|
template <typename ElementT>
|
||||||
|
|||||||
@@ -39,9 +39,7 @@ void generator::generate_relationships(
|
|||||||
|
|
||||||
auto destination_package = model().get(r.destination());
|
auto destination_package = model().get(r.destination());
|
||||||
|
|
||||||
if (!destination_package ||
|
if (!destination_package)
|
||||||
!model().should_include(
|
|
||||||
dynamic_cast<const package &>(*destination_package)))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
rel["source"] = std::to_string(p.id().value());
|
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) {
|
for (const auto &subpackage : p) {
|
||||||
auto &pkg = dynamic_cast<package &>(*subpackage);
|
auto &pkg = dynamic_cast<package &>(*subpackage);
|
||||||
if (model().should_include(pkg)) {
|
generate(pkg, j);
|
||||||
generate(pkg, j);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parent["elements"].push_back(std::move(j));
|
parent["elements"].push_back(std::move(j));
|
||||||
@@ -98,9 +94,7 @@ void generator::generate(const package &p, nlohmann::json &parent) const
|
|||||||
else {
|
else {
|
||||||
for (const auto &subpackage : p) {
|
for (const auto &subpackage : p) {
|
||||||
auto &pkg = dynamic_cast<package &>(*subpackage);
|
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()) {
|
for (const auto &p : model()) {
|
||||||
auto &pkg = dynamic_cast<package &>(*p);
|
auto &pkg = dynamic_cast<package &>(*p);
|
||||||
if (model().should_include(pkg)) {
|
generate(pkg, parent);
|
||||||
generate(pkg, parent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process package relationships
|
// Process package relationships
|
||||||
for (const auto &p : model()) {
|
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 {
|
try {
|
||||||
auto destination_package = model().get(r.destination());
|
auto destination_package = model().get(r.destination());
|
||||||
|
|
||||||
if (!destination_package ||
|
if (!destination_package)
|
||||||
!model().should_include(
|
|
||||||
dynamic_cast<const package &>(*destination_package)))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto destination_alias = model().to_alias(r.destination());
|
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) {
|
for (const auto &subpackage : p) {
|
||||||
auto &pkg = dynamic_cast<package &>(*subpackage);
|
auto &pkg = dynamic_cast<package &>(*subpackage);
|
||||||
if (model().should_include(pkg)) {
|
auto together_group = config().get_together_group(pkg.full_name(false));
|
||||||
auto together_group =
|
if (together_group) {
|
||||||
config().get_together_group(pkg.full_name(false));
|
together_group_stack_.group_together(together_group.value(), &pkg);
|
||||||
if (together_group) {
|
}
|
||||||
together_group_stack_.group_together(
|
else {
|
||||||
together_group.value(), &pkg);
|
generate(pkg, ostr);
|
||||||
}
|
|
||||||
else {
|
|
||||||
generate(pkg, ostr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,16 +153,12 @@ void generator::generate_diagram(std::ostream &ostr) const
|
|||||||
{
|
{
|
||||||
for (const auto &p : model()) {
|
for (const auto &p : model()) {
|
||||||
auto &pkg = dynamic_cast<package &>(*p);
|
auto &pkg = dynamic_cast<package &>(*p);
|
||||||
if (model().should_include(pkg)) {
|
auto together_group = config().get_together_group(pkg.full_name(false));
|
||||||
auto together_group =
|
if (together_group) {
|
||||||
config().get_together_group(pkg.full_name(false));
|
together_group_stack_.group_together(together_group.value(), &pkg);
|
||||||
if (together_group) {
|
}
|
||||||
together_group_stack_.group_together(
|
else {
|
||||||
together_group.value(), &pkg);
|
generate(pkg, ostr);
|
||||||
}
|
|
||||||
else {
|
|
||||||
generate(pkg, ostr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,8 +166,7 @@ void generator::generate_diagram(std::ostream &ostr) const
|
|||||||
|
|
||||||
// Process package relationships
|
// Process package relationships
|
||||||
for (const auto &p : model()) {
|
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;
|
std::stringstream relstr;
|
||||||
try {
|
try {
|
||||||
auto destination_package = model().get(r.destination());
|
auto destination_package = model().get(r.destination());
|
||||||
|
if (!destination_package)
|
||||||
if (!destination_package ||
|
|
||||||
!model().should_include(
|
|
||||||
dynamic_cast<const package &>(*destination_package)))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto destination_alias = model().to_alias(r.destination());
|
auto destination_alias = model().to_alias(r.destination());
|
||||||
@@ -62,9 +59,8 @@ void generator::generate_relationships(
|
|||||||
|
|
||||||
// Process it's subpackages relationships
|
// Process it's subpackages relationships
|
||||||
for (const auto &subpackage : p) {
|
for (const auto &subpackage : p) {
|
||||||
if (model().should_include(dynamic_cast<const package &>(*subpackage)))
|
generate_relationships(
|
||||||
generate_relationships(
|
dynamic_cast<const package &>(*subpackage), ostr);
|
||||||
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) {
|
for (const auto &subpackage : p) {
|
||||||
auto &pkg = dynamic_cast<package &>(*subpackage);
|
auto &pkg = dynamic_cast<package &>(*subpackage);
|
||||||
if (model().should_include(pkg)) {
|
auto together_group = config().get_together_group(pkg.full_name(false));
|
||||||
auto together_group =
|
if (together_group) {
|
||||||
config().get_together_group(pkg.full_name(false));
|
together_group_stack_.group_together(together_group.value(), &pkg);
|
||||||
if (together_group) {
|
}
|
||||||
together_group_stack_.group_together(
|
else {
|
||||||
together_group.value(), &pkg);
|
generate(pkg, ostr);
|
||||||
}
|
|
||||||
else {
|
|
||||||
generate(pkg, ostr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,16 +130,12 @@ void generator::generate_diagram(std::ostream &ostr) const
|
|||||||
{
|
{
|
||||||
for (const auto &p : model()) {
|
for (const auto &p : model()) {
|
||||||
auto &pkg = dynamic_cast<package &>(*p);
|
auto &pkg = dynamic_cast<package &>(*p);
|
||||||
if (model().should_include(pkg)) {
|
auto together_group = config().get_together_group(pkg.full_name(false));
|
||||||
auto together_group =
|
if (together_group) {
|
||||||
config().get_together_group(pkg.full_name(false));
|
together_group_stack_.group_together(together_group.value(), &pkg);
|
||||||
if (together_group) {
|
}
|
||||||
together_group_stack_.group_together(
|
else {
|
||||||
together_group.value(), &pkg);
|
generate(pkg, ostr);
|
||||||
}
|
|
||||||
else {
|
|
||||||
generate(pkg, ostr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,8 +143,7 @@ void generator::generate_diagram(std::ostream &ostr) const
|
|||||||
|
|
||||||
// Process package relationships
|
// Process package relationships
|
||||||
for (const auto &p : model()) {
|
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);
|
generate_config_layout_hints(ostr);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "diagram.h"
|
#include "diagram.h"
|
||||||
|
|
||||||
|
#include "common/model/filters/diagram_filter.h"
|
||||||
#include "util/error.h"
|
#include "util/error.h"
|
||||||
#include "util/util.h"
|
#include "util/util.h"
|
||||||
|
|
||||||
@@ -74,6 +75,23 @@ inja::json diagram::context() const
|
|||||||
return ctx;
|
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(); }
|
bool diagram::is_empty() const { return element_view<package>::is_empty(); }
|
||||||
} // namespace clanguml::package_diagram::model
|
} // namespace clanguml::package_diagram::model
|
||||||
|
|
||||||
|
|||||||
@@ -32,14 +32,16 @@ using clanguml::common::model::diagram_element;
|
|||||||
using clanguml::common::model::package;
|
using clanguml::common::model::package;
|
||||||
using clanguml::common::model::path;
|
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.
|
* @brief Package diagram model.
|
||||||
*/
|
*/
|
||||||
class diagram : public clanguml::common::model::diagram,
|
class diagram : public clanguml::common::model::diagram,
|
||||||
public clanguml::common::model::element_view<package>,
|
public clanguml::common::model::element_view<package>,
|
||||||
public clanguml::common::model::nested_trait<
|
public nested_trait_ns {
|
||||||
clanguml::common::model::element,
|
|
||||||
clanguml::common::model::namespace_> {
|
|
||||||
public:
|
public:
|
||||||
diagram() = default;
|
diagram() = default;
|
||||||
|
|
||||||
@@ -165,6 +167,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool is_empty() const override;
|
bool is_empty() const override;
|
||||||
|
|
||||||
|
void apply_filter() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* @brief Add element using module as diagram path
|
* @brief Add element using module as diagram path
|
||||||
|
|||||||
Reference in New Issue
Block a user