Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor relationships #311

Merged
merged 3 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,17 @@ Thanks for taking interest in `clang-uml`!
make tidy
```

* Compare generated diagrams in your branch against master using `util/test_case_browser.py` script, for instance:
```console
CC=/usr/bin/clang-18 CXX=/usr/bin/clang++-18 LLVM_VERSION=18 NUMPROC=16 CMAKE_GENERATOR=Ninja ENABLE_CXX_MODULES_TEST_CASES=ON ENABLE_CUDA_TEST_CASES=ON CLANG_UML_ENABLE_BACKTRACE=ON make test_diagrams
util/test_case_browser.py ../clang-uml-master/debug/tests/diagrams/plantuml debug/tests/diagrams/plantuml/
```

This will open your default web browser to a simple [NiceGUI](https://nicegui.io/) interface,
where diagrams generated from each test case can be compared side by side.
> The script only compares diagrams existing in both directories, so any
> new diagrams will not be included in this interface.

* Create a pull request from your branch to `master` branch

## If you would like to add a feature
Expand Down
8 changes: 2 additions & 6 deletions packaging/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
cd packaging
make DIST=focal deb
make DIST=jammy deb
make DIST=mantic deb
make DIST=noble deb

cd _BUILD/ubuntu/focal
Expand All @@ -18,9 +17,6 @@ dput ppa:bkryza/clang-uml *.changes
cd _BUILD/ubuntu/jammy
dput ppa:bkryza/clang-uml *.changes

cd _BUILD/ubuntu/mantic
dput ppa:bkryza/clang-uml *.changes

cd _BUILD/ubuntu/noble
dput ppa:bkryza/clang-uml *.changes
```
Expand All @@ -40,7 +36,7 @@ find packaging/_BUILD/fedora
```bash
docker run --rm -v $PWD:$PWD -it continuumio/miniconda3 bash
conda install conda-build make anaconda-client
cd packaging
cd /home/bartek/devel/clang-uml/packaging
git config --global --add safe.directory /home/bartek/devel/clang-uml
make CONDA_TOKEN=<TOKEN> conda
```
Expand All @@ -53,5 +49,5 @@ to the [documentation](../docs/installation.md#visual-studio-native-build).
```bash
cd packaging
.\make_installer.ps1
ls .\_BUILD\windows\clang-uml-0.5.2-win64.exe
ls .\_BUILD\windows\clang-uml-0.5.4-win64.exe
```
35 changes: 15 additions & 20 deletions src/class_diagram/generators/json/class_diagram_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,6 @@ void to_json(nlohmann::json &j, const class_method &c)
j["parameters"] = c.parameters();
}

void to_json(nlohmann::json &j, const class_parent &c)
{
j["is_virtual"] = c.is_virtual();
j["id"] = std::to_string(c.id().value());
if (c.access() != common::model::access_t::kNone)
j["access"] = to_string(c.access());
j["name"] = c.name();
}

void to_json(nlohmann::json &j, const class_ &c)
{
j = dynamic_cast<const common::model::element &>(c);
Expand All @@ -102,7 +93,21 @@ void to_json(nlohmann::json &j, const class_ &c)

j["members"] = c.members();
j["methods"] = c.methods();
j["bases"] = c.parents();
auto bases = nlohmann::json::array();

for (const auto &rel : c.relationships()) {
if (rel.type() != common::model::relationship_t::kExtension)
continue;

auto base = nlohmann::json::object();
base["is_virtual"] = rel.is_virtual();
base["id"] = std::to_string(rel.destination().value());
if (rel.access() != common::model::access_t::kNone)
base["access"] = to_string(rel.access());
base["name"] = c.name();
bases.push_back(std::move(base));
}
j["bases"] = std::move(bases);

set_module(j, c);

Expand Down Expand Up @@ -310,16 +315,6 @@ void generator::generate_relationships(
rel["source"] = std::to_string(c.id().value());
parent["relationships"].push_back(rel);
}

if (model().should_include(relationship_t::kExtension)) {
for (const auto &b : c.parents()) {
common::model::relationship r(
relationship_t::kExtension, b.id(), b.access());
nlohmann::json rel = r;
rel["source"] = std::to_string(c.id().value());
parent["relationships"].push_back(rel);
}
}
}

void generator::generate_relationships(
Expand Down
25 changes: 3 additions & 22 deletions src/class_diagram/generators/mermaid/class_diagram_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,9 @@ void generator::generate_relationships(
relstr << indent(1) << target_alias << " " << relation_str
<< " " << c.alias();
}
else if (r.type() == relationship_t::kExtension) {
relstr << indent(1) << target_alias << " <|-- " << c.alias();
}
else {
relstr << indent(1) << c.alias() << " " << relation_str << " "
<< target_alias;
Expand Down Expand Up @@ -445,28 +448,6 @@ void generator::generate_relationships(
}
}

if (model().should_include(relationship_t::kExtension)) {
for (const auto &b : c.parents()) {
std::stringstream relstr;
try {
auto target_alias = model().to_alias(b.id());

if (m_generated_aliases.find(target_alias) ==
m_generated_aliases.end())
continue;

relstr << indent(1) << target_alias << " <|-- " << c.alias()
<< '\n';
all_relations_str << relstr.str();
}
catch (error::uml_alias_missing &e) {
LOG_DBG("=== Skipping inheritance relation from {} to {} due "
"to: {}",
b.name(), c.name(), e.what());
}
}
}

ostr << all_relations_str.str();
}

Expand Down
27 changes: 5 additions & 22 deletions src/class_diagram/generators/plantuml/class_diagram_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,11 @@ void generator::generate_relationships(
m_generated_aliases.end())
continue;

relstr << c.alias() << " " << puml_relation << " " << target_alias;
if (r.type() != relationship_t::kExtension)
relstr << c.alias() << " " << puml_relation << " "
<< target_alias;
else
relstr << target_alias << " <|-- " << c.alias() << '\n';

if (!r.label().empty()) {
relstr << " : " << plantuml_common::to_plantuml(r.access())
Expand All @@ -522,27 +526,6 @@ void generator::generate_relationships(
}
}

if (model().should_include(relationship_t::kExtension)) {
for (const auto &b : c.parents()) {
std::stringstream relstr;
try {
auto target_alias = model().to_alias(b.id());

if (m_generated_aliases.find(target_alias) ==
m_generated_aliases.end())
continue;

relstr << target_alias << " <|-- " << c.alias() << '\n';
all_relations_str << relstr.str();
}
catch (error::uml_alias_missing &e) {
LOG_DBG("=== Skipping inheritance relation from {} to {} due "
"to: {}",
b.name(), c.name(), e.what());
}
}
}

ostr << all_relations_str.str();
}

Expand Down
20 changes: 0 additions & 20 deletions src/class_diagram/model/class.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,10 @@ void class_::add_method(class_method &&method)
methods_.emplace_back(std::move(method));
}

void class_::add_parent(class_parent &&parent)
{
for (const auto &p : bases_) {
if (p.id() == parent.id()) {
return;
}
}

bases_.emplace_back(std::move(parent));
}

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(); }

std::string class_::full_name_no_ns() const
Expand Down Expand Up @@ -120,12 +106,6 @@ void class_::apply_filter(

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
Expand Down
22 changes: 1 addition & 21 deletions src/class_diagram/model/class.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

#include "class_member.h"
#include "class_method.h"
#include "class_parent.h"
#include "common/model/enums.h"
#include "common/model/stylable_element.h"
#include "common/model/template_element.h"
Expand Down Expand Up @@ -100,16 +99,6 @@ class class_ : public common::model::template_element,
*/
void add_method(class_method &&method);

/**
* Add class parent (inheritance relationship).
*
* @todo Maybe it would be good to refactor this into a regular
* relationship. We could drop the 'class_parent' class completely...
*
* @param parent Class parent.
*/
void add_parent(class_parent &&parent);

/**
* Get reference to class member list.
*
Expand All @@ -124,14 +113,6 @@ class class_ : public common::model::template_element,
*/
const std::vector<class_method> &methods() const;

/**
* Get reference to class parent list.
*
* @return Reference to class parents.
*/
const std::vector<class_parent> &parents() const;
std::vector<class_parent> &parents();

/**
* @brief Get class full name.
*
Expand Down Expand Up @@ -172,14 +153,13 @@ class class_ : public common::model::template_element,
std::optional<std::string> doxygen_link() const override;

void apply_filter(const common::model::diagram_filter &filter,
const std::set<eid_t> &removed) override;
const std::set<common::model::eid_t> &removed) override;

private:
bool is_struct_{false};
bool is_union_{false};
std::vector<class_member> members_;
std::vector<class_method> methods_;
std::vector<class_parent> bases_;
std::string base_template_full_name_;
std::string full_name_;
};
Expand Down
42 changes: 0 additions & 42 deletions src/class_diagram/model/class_parent.cc

This file was deleted.

Loading
Loading