From 46e8885c41edade9881230efec791488008b05ee Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Mon, 4 Apr 2022 23:55:12 +0200 Subject: [PATCH 01/13] Added initial structure for include diagram generation --- src/class_diagram/model/diagram.cc | 6 +- src/class_diagram/model/diagram.h | 5 +- src/common/model/diagram.h | 5 +- src/common/model/diagram_element.cc | 99 +++++++++ src/common/model/diagram_element.h | 71 ++++++ src/common/model/element.cc | 37 ---- src/common/model/element.h | 36 +-- src/common/model/enums.h | 3 +- src/common/model/namespace.cc | 191 ---------------- src/common/model/namespace.h | 74 +------ src/common/model/nested_trait.h | 33 +-- src/common/model/package.h | 2 +- src/common/model/path.h | 207 ++++++++++++++++++ src/config/config.cc | 28 ++- src/config/config.h | 16 +- .../plantuml/include_diagram_generator.cc | 64 ++++++ .../plantuml/include_diagram_generator.h | 70 ++++++ src/include_diagram/model/diagram.cc | 65 ++++++ src/include_diagram/model/diagram.h | 59 +++++ src/include_diagram/model/source_file.cc | 19 ++ src/include_diagram/model/source_file.h | 95 ++++++++ .../visitor/element_visitor_context.cc | 43 ++++ .../visitor/element_visitor_context.h | 42 ++++ .../visitor/translation_unit_context.cc | 63 ++++++ .../visitor/translation_unit_context.h | 62 ++++++ .../visitor/translation_unit_visitor.cc | 53 +++++ .../visitor/translation_unit_visitor.h | 51 +++++ src/package_diagram/model/diagram.cc | 2 +- src/package_diagram/model/diagram.h | 5 +- src/sequence_diagram/model/diagram.cc | 2 +- src/sequence_diagram/model/diagram.h | 2 +- src/util/util.cc | 5 +- src/util/util.h | 5 +- tests/t40001/.clang-uml | 10 + tests/t40001/t40001.cc | 10 + tests/t40001/t40001_include1.h | 7 + tests/t40001/test_case.h | 40 ++++ tests/test_cases.cc | 35 +++ tests/test_cases.h | 2 + 39 files changed, 1268 insertions(+), 356 deletions(-) create mode 100644 src/common/model/diagram_element.cc create mode 100644 src/common/model/diagram_element.h create mode 100644 src/common/model/path.h create mode 100644 src/include_diagram/generators/plantuml/include_diagram_generator.cc create mode 100644 src/include_diagram/generators/plantuml/include_diagram_generator.h create mode 100644 src/include_diagram/model/diagram.cc create mode 100644 src/include_diagram/model/diagram.h create mode 100644 src/include_diagram/model/source_file.cc create mode 100644 src/include_diagram/model/source_file.h create mode 100644 src/include_diagram/visitor/element_visitor_context.cc create mode 100644 src/include_diagram/visitor/element_visitor_context.h create mode 100644 src/include_diagram/visitor/translation_unit_context.cc create mode 100644 src/include_diagram/visitor/translation_unit_context.h create mode 100644 src/include_diagram/visitor/translation_unit_visitor.cc create mode 100644 src/include_diagram/visitor/translation_unit_visitor.h create mode 100644 tests/t40001/.clang-uml create mode 100644 tests/t40001/t40001.cc create mode 100644 tests/t40001/t40001_include1.h create mode 100644 tests/t40001/test_case.h diff --git a/src/class_diagram/model/diagram.cc b/src/class_diagram/model/diagram.cc index 1f56f3a9..700e294e 100644 --- a/src/class_diagram/model/diagram.cc +++ b/src/class_diagram/model/diagram.cc @@ -41,10 +41,10 @@ common::model::diagram_t diagram::type() const return common::model::diagram_t::kClass; } -type_safe::optional_ref diagram::get( - const std::string &full_name) const +type_safe::optional_ref +diagram::get(const std::string &full_name) const { - type_safe::optional_ref res; + type_safe::optional_ref res; res = get_class(full_name); diff --git a/src/class_diagram/model/diagram.h b/src/class_diagram/model/diagram.h index 85fbe2b6..d27ad37b 100644 --- a/src/class_diagram/model/diagram.h +++ b/src/class_diagram/model/diagram.h @@ -32,7 +32,8 @@ namespace clanguml::class_diagram::model { class diagram : public clanguml::common::model::diagram, public clanguml::common::model::nested_trait< - clanguml::common::model::element> { + clanguml::common::model::element, + clanguml::common::model::namespace_> { public: diagram() = default; @@ -43,7 +44,7 @@ public: common::model::diagram_t type() const override; - type_safe::optional_ref get( + type_safe::optional_ref get( const std::string &full_name) const override; const std::vector> classes() const; diff --git a/src/common/model/diagram.h b/src/common/model/diagram.h index 3d71e2fd..dbcd9b52 100644 --- a/src/common/model/diagram.h +++ b/src/common/model/diagram.h @@ -17,7 +17,9 @@ */ #pragma once +#include "diagram_element.h" #include "enums.h" +#include "namespace.h" #include @@ -27,7 +29,6 @@ namespace clanguml::common::model { class diagram_filter; -class namespace_; class element; class relationship; @@ -38,7 +39,7 @@ public: virtual diagram_t type() const = 0; - virtual type_safe::optional_ref get( + virtual type_safe::optional_ref get( const std::string &full_name) const = 0; diagram(const diagram &) = delete; diff --git a/src/common/model/diagram_element.cc b/src/common/model/diagram_element.cc new file mode 100644 index 00000000..bd3179f3 --- /dev/null +++ b/src/common/model/diagram_element.cc @@ -0,0 +1,99 @@ +/** + * src/common/model/diagram_element.cc + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "diagram_element.h" + +#include "util/util.h" + +#include + +namespace clanguml::common::model { + +std::atomic_uint64_t diagram_element::m_nextId = 1; + +diagram_element::diagram_element() + : m_id{m_nextId++} +{ +} + +std::string diagram_element::alias() const +{ + return fmt::format("C_{:010}", m_id); +} + +void diagram_element::add_relationship(relationship &&cr) +{ + if (cr.destination().empty()) { + LOG_DBG("Skipping relationship '{}' - {} - '{}' due empty " + "destination", + cr.destination(), to_string(cr.type()), full_name(true)); + return; + } + + if ((cr.type() == relationship_t::kInstantiation) && + (cr.destination() == full_name(true))) { + LOG_DBG("Skipping self instantiation relationship for {}", + cr.destination()); + return; + } + + LOG_DBG("Adding relationship: '{}' - {} - '{}'", cr.destination(), + to_string(cr.type()), full_name(true)); + + if (!util::contains(relationships_, cr)) + relationships_.emplace_back(std::move(cr)); +} + +std::vector &diagram_element::relationships() +{ + return relationships_; +} + +const std::vector &diagram_element::relationships() const +{ + return relationships_; +} + +void diagram_element::append(const decorated_element &e) +{ + decorated_element::append(e); +} + +inja::json diagram_element::context() const +{ + inja::json ctx; + ctx["name"] = name(); + ctx["alias"] = alias(); + ctx["full_name"] = full_name(false); + + return ctx; +} + +bool operator==(const diagram_element &l, const diagram_element &r) +{ + return l.full_name(false) == r.full_name(false); +} + +std::ostream &operator<<(std::ostream &out, const diagram_element &rhs) +{ + out << "(" << rhs.name() << ", full_name=[" << rhs.full_name(false) << "])"; + + return out; +} + +} diff --git a/src/common/model/diagram_element.h b/src/common/model/diagram_element.h new file mode 100644 index 00000000..023cd90c --- /dev/null +++ b/src/common/model/diagram_element.h @@ -0,0 +1,71 @@ +/** + * src/common/model/diagram_element.h + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include "decorated_element.h" +#include "relationship.h" +#include "util/util.h" + +#include + +#include +#include +#include +#include + +namespace clanguml::common::model { + +class diagram_element : public decorated_element { +public: + diagram_element(); + + virtual ~diagram_element() = default; + + std::string alias() const; + + void set_name(const std::string &name) { name_ = name; } + + std::string name() const { return name_; } + + virtual std::string full_name(bool relative) const { return name(); } + + std::vector &relationships(); + + const std::vector &relationships() const; + + void add_relationship(relationship &&cr); + + void append(const decorated_element &e); + + friend bool operator==(const diagram_element &l, const diagram_element &r); + + friend std::ostream &operator<<( + std::ostream &out, const diagram_element &rhs); + + virtual inja::json context() const; + +protected: + const uint64_t m_id{0}; + +private: + std::string name_; + std::vector relationships_; + + static std::atomic_uint64_t m_nextId; +}; +} diff --git a/src/common/model/element.cc b/src/common/model/element.cc index 164d9292..dd789d92 100644 --- a/src/common/model/element.cc +++ b/src/common/model/element.cc @@ -24,39 +24,11 @@ namespace clanguml::common::model { -std::atomic_uint64_t element::m_nextId = 1; - element::element(const namespace_ &using_namespace) : using_namespace_{using_namespace} - , m_id{m_nextId++} { } -std::string element::alias() const { return fmt::format("C_{:010}", m_id); } - -void element::add_relationship(relationship &&cr) -{ - if (cr.destination().empty()) { - LOG_DBG("Skipping relationship '{}' - {} - '{}' due empty " - "destination", - cr.destination(), to_string(cr.type()), full_name(true)); - return; - } - - if ((cr.type() == relationship_t::kInstantiation) && - (cr.destination() == full_name(true))) { - LOG_DBG("Skipping self instantiation relationship for {}", - cr.destination()); - return; - } - - LOG_DBG("Adding relationship: '{}' - {} - '{}'", cr.destination(), - to_string(cr.type()), full_name(true)); - - if (!util::contains(relationships_, cr)) - relationships_.emplace_back(std::move(cr)); -} - void element::set_using_namespaces(const namespace_ &un) { using_namespace_ = un; @@ -64,15 +36,6 @@ void element::set_using_namespaces(const namespace_ &un) const namespace_ &element::using_namespace() const { return using_namespace_; } -std::vector &element::relationships() { return relationships_; } - -const std::vector &element::relationships() const -{ - return relationships_; -} - -void element::append(const element &e) { decorated_element::append(e); } - inja::json element::context() const { inja::json ctx; diff --git a/src/common/model/element.h b/src/common/model/element.h index 74173a89..881460bd 100644 --- a/src/common/model/element.h +++ b/src/common/model/element.h @@ -17,7 +17,7 @@ */ #pragma once -#include "decorated_element.h" +#include "diagram_element.h" #include "namespace.h" #include "relationship.h" #include "source_location.h" @@ -32,18 +32,12 @@ namespace clanguml::common::model { -class element : public decorated_element, public source_location { +class element : public diagram_element, public source_location { public: element(const namespace_ &using_namespace); virtual ~element() = default; - std::string alias() const; - - void set_name(const std::string &name) { name_ = name; } - - std::string name() const { return name_; } - std::string name_and_ns() const { auto ns = ns_ | name(); @@ -59,36 +53,26 @@ public: return ns_.relative_to(using_namespace_); } - virtual std::string full_name(bool relative) const { return name_and_ns(); } + const namespace_ &path() const { return ns_; } + + std::string full_name(bool relative) const override + { + return name_and_ns(); + } void set_using_namespaces(const namespace_ &un); const namespace_ &using_namespace() const; - std::vector &relationships(); - - const std::vector &relationships() const; - - void add_relationship(relationship &&cr); - - void append(const element &e); - friend bool operator==(const element &l, const element &r); friend std::ostream &operator<<(std::ostream &out, const element &rhs); - virtual inja::json context() const; - -protected: - const uint64_t m_id{0}; + inja::json context() const override; private: - std::string name_; namespace_ ns_; namespace_ using_namespace_; - std::vector relationships_; - type_safe::optional location_; - - static std::atomic_uint64_t m_nextId; + // type_safe::optional location_; }; } diff --git a/src/common/model/enums.h b/src/common/model/enums.h index e102a67c..fbbeb21f 100644 --- a/src/common/model/enums.h +++ b/src/common/model/enums.h @@ -35,7 +35,8 @@ enum class relationship_t { kAssociation, kInstantiation, kFriendship, - kDependency + kDependency, + kInclusion }; enum class message_t { kCall, kReturn }; diff --git a/src/common/model/namespace.cc b/src/common/model/namespace.cc index 2e6c6012..3039adb3 100644 --- a/src/common/model/namespace.cc +++ b/src/common/model/namespace.cc @@ -17,194 +17,3 @@ */ #include "namespace.h" - -#include "util/util.h" - -namespace clanguml::common::model { - -namespace_::namespace_(std::initializer_list ns) -{ - if ((ns.size() == 1) && util::contains(*ns.begin(), "::")) - namespace_path_ = util::split(*ns.begin(), "::"); - else - namespace_path_ = ns; -} - -namespace_::namespace_(const std::vector &ns) -{ - if ((ns.size() == 1) && util::contains(*ns.begin(), "::")) - namespace_path_ = util::split(*ns.begin(), "::"); - else - namespace_path_ = ns; -} - -namespace_::namespace_(const std::string &ns) -{ - namespace_path_ = util::split(ns, "::"); -} - -namespace_::namespace_( - container_type::const_iterator begin, container_type::const_iterator end) -{ - std::copy(begin, end, std::back_inserter(namespace_path_)); -} - -std::string namespace_::to_string() const -{ - return fmt::format("{}", fmt::join(namespace_path_, "::")); -} - -size_t namespace_::size() const { return namespace_path_.size(); } - -bool namespace_::is_empty() const { return namespace_path_.empty(); } - -namespace_::container_type::iterator namespace_::begin() -{ - return namespace_path_.begin(); -} -namespace_::container_type::iterator namespace_::end() -{ - return namespace_path_.end(); -} - -namespace_::container_type::const_iterator namespace_::cbegin() const -{ - return namespace_path_.cbegin(); -} -namespace_::container_type::const_iterator namespace_::cend() const -{ - return namespace_path_.cend(); -} - -namespace_::container_type::const_iterator namespace_::begin() const -{ - return namespace_path_.begin(); -} -namespace_::container_type::const_iterator namespace_::end() const -{ - return namespace_path_.end(); -} - -void namespace_::append(const std::string &ns) -{ - namespace_path_.push_back(ns); -} - -void namespace_::append(const namespace_ &ns) -{ - for (const auto &n : ns) { - append(n); - } -} - -void namespace_::pop_back() { namespace_path_.pop_back(); } - -type_safe::optional namespace_::parent() const -{ - if (size() <= 1) { - return {}; - } - - namespace_ res{*this}; - res.pop_back(); - return {std::move(res)}; -} - -namespace_ namespace_::operator|(const namespace_ &right) const -{ - namespace_ res{*this}; - res.append(right); - return res; -} - -void namespace_::operator|=(const namespace_ &right) { append(right); } - -namespace_ namespace_::operator|(const std::string &right) const -{ - namespace_ res{*this}; - res.append(right); - return res; -} - -void namespace_::operator|=(const std::string &right) { append(right); } - -std::string &namespace_::operator[](const int index) -{ - return namespace_path_[index]; -} - -const std::string &namespace_::operator[](const int index) const -{ - return namespace_path_[index]; -} - -bool namespace_::starts_with(const namespace_ &right) const -{ - return util::starts_with(namespace_path_, right.namespace_path_); -} - -bool namespace_::ends_with(const namespace_ &right) const -{ - return util::ends_with(namespace_path_, right.namespace_path_); -} - -namespace_ namespace_::common_path(const namespace_ &right) const -{ - namespace_ res{}; - for (auto i = 0U; i < std::min(size(), right.size()); i++) { - if (namespace_path_[i] == right[i]) - res |= namespace_path_[i]; - else - break; - } - return res; -} - -namespace_ namespace_::relative_to(const namespace_ &right) const -{ - namespace_ res{*this}; - - if (res.starts_with(right)) - util::remove_prefix(res.namespace_path_, right.namespace_path_); - - return res; -} - -std::string namespace_::relative(const std::string &name) const -{ - if (is_empty()) - return name; - - if (name == to_string()) - return name; - - auto res = name; - auto ns_prefix = to_string() + "::"; - - auto it = res.find(ns_prefix); - while (it != std::string::npos) { - res.erase(it, ns_prefix.size()); - it = res.find(ns_prefix); - } - - return res; -} - -bool operator==(const namespace_ &left, const namespace_ &right) -{ - return left.namespace_path_ == right.namespace_path_; -} - -bool operator<(const namespace_ &left, const namespace_ &right) -{ - return std::hash{}(left) < std::hash{}(right); -} - -std::string namespace_::name() const -{ - assert(size() > 0); - - return namespace_path_.back(); -} - -} \ No newline at end of file diff --git a/src/common/model/namespace.h b/src/common/model/namespace.h index 03d42bc9..9ba3faad 100644 --- a/src/common/model/namespace.h +++ b/src/common/model/namespace.h @@ -17,78 +17,20 @@ */ #pragma once +#include "path.h" + #include #include #include namespace clanguml::common::model { -class namespace_ { -public: - using container_type = std::vector; - - namespace_() = default; - - namespace_(const std::string &ns); - - namespace_(container_type::const_iterator begin, - container_type::const_iterator end); - - namespace_(const namespace_ &right) noexcept = default; - - namespace_ &operator=(const namespace_ &right) noexcept = default; - - namespace_(namespace_ &&right) noexcept = default; - - namespace_ &operator=(namespace_ &&right) noexcept = default; - - friend bool operator==(const namespace_ &left, const namespace_ &right); - friend bool operator<(const namespace_ &left, const namespace_ &right); - - namespace_(std::initializer_list ns); - - explicit namespace_(const std::vector &ns); - - std::string to_string() const; - - bool is_empty() const; - - size_t size() const; - - namespace_ operator|(const namespace_ &right) const; - void operator|=(const namespace_ &right); - namespace_ operator|(const std::string &right) const; - void operator|=(const std::string &right); - - std::string &operator[](const int index); - const std::string &operator[](const int index) const; - - void append(const std::string &ns); - - void append(const namespace_ &ns); - - void pop_back(); - - type_safe::optional parent() const; - - bool starts_with(const namespace_ &right) const; - bool ends_with(const namespace_ &right) const; - namespace_ common_path(const namespace_ &right) const; - namespace_ relative_to(const namespace_ &right) const; - std::string relative(const std::string &name) const; - std::string name() const; - - container_type::iterator begin(); - container_type::iterator end(); - container_type::const_iterator begin() const; - container_type::const_iterator end() const; - container_type::const_iterator cbegin() const; - container_type::const_iterator cend() const; - -private: - container_type namespace_path_; +struct ns_path_separator { + static constexpr std::string_view value = "::"; }; +using namespace_ = path; + } namespace std { @@ -96,7 +38,7 @@ namespace std { template <> struct hash { std::size_t operator()(const clanguml::common::model::namespace_ &key) const { - using clanguml::common::model::namespace_; + using clanguml::common::model::path; std::size_t seed = key.size(); for (const auto &ns : key) { @@ -108,4 +50,4 @@ template <> struct hash { } }; -} \ No newline at end of file +} diff --git a/src/common/model/nested_trait.h b/src/common/model/nested_trait.h index 91515d1f..d79d04b3 100644 --- a/src/common/model/nested_trait.h +++ b/src/common/model/nested_trait.h @@ -1,5 +1,5 @@ /** - * src/common/model/element.h + * src/common/model/nested_trait.h * * Copyright (c) 2021-2022 Bartek Kryza * @@ -26,7 +26,7 @@ #include namespace clanguml::common::model { -template class nested_trait { +template class nested_trait { public: nested_trait() = default; @@ -52,31 +52,31 @@ public: } template - void add_element(namespace_ ns, std::unique_ptr p) + void add_element(const Path &path, std::unique_ptr p) { assert(p); LOG_DBG( - "Adding nested element {} at path {}", p->name(), ns.to_string()); + "Adding nested element {} at path {}", p->name(), path.to_string()); - if (ns.is_empty()) { + if (path.is_empty()) { add_element(std::move(p)); return; } - auto parent = get_element(ns); + auto parent = get_element(path); - if (parent && dynamic_cast *>(&parent.value())) - dynamic_cast &>(parent.value()) + if (parent && dynamic_cast *>(&parent.value())) + dynamic_cast &>(parent.value()) .template add_element(std::move(p)); else { - spdlog::error("No parent element found at: {}", ns.to_string()); + spdlog::error("No parent element found at: {}", path.to_string()); throw std::runtime_error( - "No parent element found for " + ns.to_string()); + "No parent element found for " + path.to_string()); } } - template auto get_element(const namespace_ &path) const + template auto get_element(const Path &path) const { LOG_DBG("Getting nested element at path: {}", path.to_string()); @@ -93,9 +93,9 @@ public: if (!p) return type_safe::optional_ref{}; - if (dynamic_cast *>(&p.value())) - return dynamic_cast &>(p.value()).get_element( - namespace_{path.begin() + 1, path.end()}); + if (dynamic_cast *>(&p.value())) + return dynamic_cast &>(p.value()) + .get_element(Path{path.begin() + 1, path.end()}); return type_safe::optional_ref{}; } @@ -145,9 +145,10 @@ public: std::cout << "--- Printing tree:\n"; } for (const auto &e : d) { - if (dynamic_cast *>(e.get())) { + if (dynamic_cast *>(e.get())) { std::cout << std::string(level, ' ') << "[" << *e << "]\n"; - dynamic_cast *>(e.get())->print_tree(level + 1); + dynamic_cast *>(e.get())->print_tree( + level + 1); } else { std::cout << std::string(level, ' ') << "- " << *e << "]\n"; diff --git a/src/common/model/package.h b/src/common/model/package.h index 9b28893e..1fdac159 100644 --- a/src/common/model/package.h +++ b/src/common/model/package.h @@ -33,7 +33,7 @@ namespace clanguml::common::model { class package : public element, public stylable_element, - public nested_trait { + public nested_trait { public: package(const common::model::namespace_ &using_namespace); diff --git a/src/common/model/path.h b/src/common/model/path.h new file mode 100644 index 00000000..555b5085 --- /dev/null +++ b/src/common/model/path.h @@ -0,0 +1,207 @@ +/** + * src/common/model/path.h + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include "util/util.h" + +#include +#include +#include + +namespace clanguml::common::model { + +template class path { +public: + using container_type = std::vector; + + path() = default; + + path(const std::string &ns) { path_ = util::split(ns, Sep::value); } + + path(container_type::const_iterator begin, + container_type::const_iterator end) + { + std::copy(begin, end, std::back_inserter(path_)); + } + + path(const path &right) noexcept = default; + + path &operator=(const path &right) noexcept = default; + + path(path &&right) noexcept = default; + + path &operator=(path &&right) noexcept = default; + + path(std::initializer_list ns) + { + if ((ns.size() == 1) && util::contains(*ns.begin(), Sep::value)) + path_ = util::split(*ns.begin(), Sep::value); + else + path_ = ns; + } + + explicit path(const std::vector &ns) + { + if ((ns.size() == 1) && util::contains(*ns.begin(), Sep::value)) + path_ = util::split(*ns.begin(), Sep::value); + else + path_ = ns; + } + + friend bool operator==(const path &left, const path &right) + { + return left.path_ == right.path_; + } + + friend bool operator<(const path &left, const path &right) + { + return std::hash>{}(left) < std::hash>{}(right); + } + + std::string to_string() const + { + return fmt::format("{}", fmt::join(path_, Sep::value)); + } + + bool is_empty() const { return path_.empty(); } + + size_t size() const { return path_.size(); } + + path operator|(const path &right) const + { + path res{*this}; + res.append(right); + return res; + } + + void operator|=(const path &right) { append(right); } + + path operator|(const std::string &right) const + { + path res{*this}; + res.append(right); + return res; + } + + void operator|=(const std::string &right) { append(right); } + + std::string &operator[](const int index) { return path_[index]; } + + const std::string &operator[](const int index) const + { + return path_[index]; + } + + void append(const std::string &ns) { path_.push_back(ns); } + + void append(const path &ns) + { + for (const auto &n : ns) { + append(n); + } + } + + void pop_back() { path_.pop_back(); } + + type_safe::optional parent() const + { + if (size() <= 1) { + return {}; + } + + path res{*this}; + res.pop_back(); + return {std::move(res)}; + } + + bool starts_with(const path &right) const + { + return util::starts_with(path_, right.path_); + } + + bool ends_with(const path &right) const + { + return util::ends_with(path_, right.path_); + } + + path common_path(const path &right) const + { + path res{}; + for (auto i = 0U; i < std::min(size(), right.size()); i++) { + if (path_[i] == right[i]) + res |= path_[i]; + else + break; + } + return res; + } + + path relative_to(const path &right) const + { + path res{*this}; + + if (res.starts_with(right)) + util::remove_prefix(res.path_, right.path_); + + return res; + } + + std::string relative(const std::string &name) const + { + if (is_empty()) + return name; + + if (name == to_string()) + return name; + + auto res = name; + auto ns_prefix = to_string() + std::string{Sep::value}; + + auto it = res.find(ns_prefix); + while (it != std::string::npos) { + res.erase(it, ns_prefix.size()); + it = res.find(ns_prefix); + } + + return res; + } + + std::string name() const + { + assert(size() > 0); + + return path_.back(); + } + + path::container_type::iterator begin() { return path_.begin(); } + path::container_type::iterator end() { return path_.end(); } + + path::container_type::const_iterator cbegin() const + { + return path_.cbegin(); + } + path::container_type::const_iterator cend() const { return path_.cend(); } + + path::container_type::const_iterator begin() const { return path_.begin(); } + path::container_type::const_iterator end() const { return path_.end(); } + +private: + container_type path_; +}; + +} \ No newline at end of file diff --git a/src/config/config.cc b/src/config/config.cc index 6084be63..3138cc00 100644 --- a/src/config/config.cc +++ b/src/config/config.cc @@ -66,6 +66,8 @@ std::string to_string(const diagram_type t) return "sequence"; case diagram_type::package_diagram: return "package"; + case diagram_type::include_diagram: + return "include"; default: assert(false); } @@ -136,6 +138,11 @@ diagram_type package_diagram::type() const return diagram_type::package_diagram; } +diagram_type include_diagram::type() const +{ + return diagram_type::include_diagram; +} + template <> void append_value>( std::vector &l, const std::vector &r) @@ -159,6 +166,7 @@ using clanguml::config::filter; using clanguml::config::generate_links_config; using clanguml::config::git_config; using clanguml::config::hint_t; +using clanguml::config::include_diagram; using clanguml::config::layout_hint; using clanguml::config::method_arguments; using clanguml::config::package_diagram; @@ -228,6 +236,9 @@ std::shared_ptr parse_diagram_config(const Node &d) else if (diagram_type == "package") { return std::make_shared(d.as()); } + else if (diagram_type == "include") { + return std::make_shared(d.as()); + } LOG_ERROR("Diagrams of type {} are not supported... ", diagram_type); @@ -470,7 +481,7 @@ template <> struct convert { }; // -// class_diagram Yaml decoder +// package_diagram Yaml decoder // template <> struct convert { static bool decode(const Node &node, package_diagram &rhs) @@ -484,6 +495,21 @@ template <> struct convert { } }; +// +// include_diagram Yaml decoder +// +template <> struct convert { + static bool decode(const Node &node, include_diagram &rhs) + { + if (!decode_diagram(node, rhs)) + return false; + + get_option(node, rhs.layout); + + return true; + } +}; + // // layout_hint Yaml decoder // diff --git a/src/config/config.h b/src/config/config.h index 11db75fe..c598d774 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -35,7 +35,13 @@ namespace clanguml { namespace config { -enum class diagram_type { class_diagram, sequence_diagram, package_diagram }; +enum class diagram_type { + class_diagram, + sequence_diagram, + package_diagram, + include_diagram +}; + enum class method_arguments { full, abbreviated, none }; struct plantuml { @@ -149,6 +155,14 @@ struct package_diagram : public diagram { option layout{"layout"}; }; +struct include_diagram : public diagram { + virtual ~include_diagram() = default; + + diagram_type type() const override; + + option layout{"layout"}; +}; + struct config : public inheritable_diagram_options { // the glob list is additive and relative to the current // directory diff --git a/src/include_diagram/generators/plantuml/include_diagram_generator.cc b/src/include_diagram/generators/plantuml/include_diagram_generator.cc new file mode 100644 index 00000000..58ed09e4 --- /dev/null +++ b/src/include_diagram/generators/plantuml/include_diagram_generator.cc @@ -0,0 +1,64 @@ +/** + * src/package_diagram/generators/plantuml/package_diagram_generator.cc + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "include_diagram_generator.h" + +#include "util/error.h" + +namespace clanguml::include_diagram::generators::plantuml { + +generator::generator(diagram_config &config, diagram_model &model) + : common_generator{config, model} +{ +} + +void generator::generate_relationships( + const source_file &f, std::ostream &ostr) const +{ + LOG_DBG("Generating relationships for file {}", f.full_name(true)); +} + +void generator::generate(const source_file &f, std::ostream &ostr) const +{ + LOG_DBG("Generating source_file {}", f.name()); +} + +void generator::generate(std::ostream &ostr) const +{ + ostr << "@startuml" << '\n'; + + generate_plantuml_directives(ostr, m_config.puml().before); + + for (const auto &p : m_model) { + generate(dynamic_cast(*p), ostr); + ostr << '\n'; + } + + // Process package relationships + for (const auto &p : m_model) { + generate_relationships(dynamic_cast(*p), ostr); + ostr << '\n'; + } + + generate_config_layout_hints(ostr); + + generate_plantuml_directives(ostr, m_config.puml().after); + + ostr << "@enduml" << '\n'; +} +} diff --git a/src/include_diagram/generators/plantuml/include_diagram_generator.h b/src/include_diagram/generators/plantuml/include_diagram_generator.h new file mode 100644 index 00000000..8b2967c3 --- /dev/null +++ b/src/include_diagram/generators/plantuml/include_diagram_generator.h @@ -0,0 +1,70 @@ +/** + * src/include_diagram/generators/plantuml/include_diagram_generator.h + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include "common/generators/plantuml/generator.h" +#include "common/model/package.h" +#include "common/model/relationship.h" +#include "config/config.h" +#include "cx/compilation_database.h" +#include "include_diagram/model/diagram.h" +#include "include_diagram/model/source_file.h" +#include "include_diagram/visitor/translation_unit_visitor.h" +#include "util/util.h" + +#include +#include + +#include +#include +#include +#include + +namespace clanguml { +namespace include_diagram { +namespace generators { +namespace plantuml { + +using diagram_config = clanguml::config::include_diagram; +using diagram_model = clanguml::include_diagram::model::diagram; + +template +using common_generator = + clanguml::common::generators::plantuml::generator; + +using clanguml::common::model::access_t; +using clanguml::common::model::package; +using clanguml::common::model::relationship_t; +using clanguml::include_diagram::model::source_file; +using namespace clanguml::util; + +class generator : public common_generator { +public: + generator(diagram_config &config, diagram_model &model); + + void generate_relationships(const source_file &p, std::ostream &ostr) const; + + void generate(const source_file &e, std::ostream &ostr) const; + + void generate(std::ostream &ostr) const; +}; + +} +} +} +} diff --git a/src/include_diagram/model/diagram.cc b/src/include_diagram/model/diagram.cc new file mode 100644 index 00000000..3ad181f0 --- /dev/null +++ b/src/include_diagram/model/diagram.cc @@ -0,0 +1,65 @@ +/** + * src/include_diagram/model/diagram.cc + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "diagram.h" + +#include "util/error.h" +#include "util/util.h" + +namespace clanguml::include_diagram::model { + +common::model::diagram_t diagram::type() const +{ + return common::model::diagram_t::kPackage; +} + +type_safe::optional_ref diagram::get( + const std::string &full_name) const +{ + return get_file(full_name); +} + +void diagram::add_file(std::unique_ptr &&f) +{ + LOG_DBG("Adding source file: {}, {}", f->name(), f->full_name(true)); + + files_.emplace_back(*f); + + add_element(f->path(), std::move(f)); +} + +type_safe::optional_ref +diagram::get_file(const std::string &name) const +{ + for (const auto &p : files_) { + if (p.get().full_name(false) == name) { + return {p}; + } + } + + return type_safe::nullopt; +} + +std::string diagram::to_alias(const std::string &full_name) const +{ + LOG_DBG("Looking for alias for {}", full_name); + + return full_name; +} + +} diff --git a/src/include_diagram/model/diagram.h b/src/include_diagram/model/diagram.h new file mode 100644 index 00000000..8c71bcd7 --- /dev/null +++ b/src/include_diagram/model/diagram.h @@ -0,0 +1,59 @@ +/** + * src/include_diagram/model/diagram.h + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include "common/model/diagram.h" +#include "common/model/package.h" +#include "source_file.h" + +#include + +#include +#include + +namespace clanguml::include_diagram::model { + +class diagram : public clanguml::common::model::diagram, + public clanguml::common::model::nested_trait { +public: + diagram() = default; + + diagram(const diagram &) = delete; + diagram(diagram &&) = default; + diagram &operator=(const diagram &) = delete; + diagram &operator=(diagram &&) = default; + + common::model::diagram_t type() const override; + + type_safe::optional_ref get( + const std::string &full_name) const; + + void add_file(std::unique_ptr &&f); + + type_safe::optional_ref get_file( + const std::string &name) const; + + std::string to_alias(const std::string &full_name) const; + +private: + std::vector< + type_safe::object_ref> + files_; +}; +} diff --git a/src/include_diagram/model/source_file.cc b/src/include_diagram/model/source_file.cc new file mode 100644 index 00000000..3b596231 --- /dev/null +++ b/src/include_diagram/model/source_file.cc @@ -0,0 +1,19 @@ +/** + * src/include_diagram/model/source_file.cc + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "source_file.h" diff --git a/src/include_diagram/model/source_file.h b/src/include_diagram/model/source_file.h new file mode 100644 index 00000000..0e16835e --- /dev/null +++ b/src/include_diagram/model/source_file.h @@ -0,0 +1,95 @@ +/** + * src/include_diagram/model/source_file.h + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include "common/model/diagram_element.h" +#include "common/model/nested_trait.h" +#include "common/model/path.h" +#include "common/model/stylable_element.h" +#include "util/util.h" + +#include +#include + +#include +#include +#include + +namespace clanguml::include_diagram::model { + +enum class source_file_type { kDirectory, kHeader, kImplementation }; + +struct fs_path_sep { + static constexpr std::string_view value = "/"; +}; + +using filesystem_path = common::model::path; + +class source_file + : public common::model::diagram_element, + public common::model::stylable_element, + public common::model::nested_trait { +public: + source_file() = default; + + void set_path(const filesystem_path &p) { path_ = p; } + + source_file(const source_file &) = delete; + source_file(source_file &&) = default; + source_file &operator=(const source_file &) = delete; + source_file &operator=(source_file &&) = delete; + + const filesystem_path &path() const { return path_; } + + std::string full_name(bool relative) const override + { + return (path_ | name()).to_string(); + } + + void add_file(std::unique_ptr &&f) + { + LOG_DBG("Adding source file: {}, {}", f->name(), f->full_name(true)); + + add_element(f->path(), std::move(f)); + } + +private: + filesystem_path path_; +}; +} + +namespace std { + +template <> struct hash { + std::size_t operator()( + const clanguml::include_diagram::model::filesystem_path &key) const + { + using clanguml::common::model::path; + + std::size_t seed = key.size(); + for (const auto &ns : key) { + seed ^= std::hash{}(ns) + 0x6a3712b5 + (seed << 6) + + (seed >> 2); + } + + return seed; + } +}; + +} diff --git a/src/include_diagram/visitor/element_visitor_context.cc b/src/include_diagram/visitor/element_visitor_context.cc new file mode 100644 index 00000000..05118ab7 --- /dev/null +++ b/src/include_diagram/visitor/element_visitor_context.cc @@ -0,0 +1,43 @@ +/** + * src/include_diagram/model/visitor/element_visitor_context.cc + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "element_visitor_context.h" + +#include "translation_unit_context.h" + +namespace clanguml::include_diagram::visitor { + +template +element_visitor_context::element_visitor_context( + clanguml::include_diagram::model::diagram &diagram, T &element) + : element_{element} + , diagram_{diagram} +{ +} + +template T &element_visitor_context::element() +{ + return element_; +} + +template +clanguml::include_diagram::model::diagram &element_visitor_context::diagram() +{ + return diagram_; +} +} diff --git a/src/include_diagram/visitor/element_visitor_context.h b/src/include_diagram/visitor/element_visitor_context.h new file mode 100644 index 00000000..7dfc7e7a --- /dev/null +++ b/src/include_diagram/visitor/element_visitor_context.h @@ -0,0 +1,42 @@ +/** + * src/include_diagram/model/visitor/element_visitor_context.h + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include "include_diagram/model/diagram.h" + +namespace clanguml::include_diagram::visitor { + +class translation_unit_context; + +template class element_visitor_context { +public: + element_visitor_context( + clanguml::include_diagram::model::diagram &diagram, T &element); + + T &element(); + + clanguml::include_diagram::model::diagram &diagram(); + +private: + translation_unit_context *ctx_; + + T &element_; + clanguml::include_diagram::model::diagram &diagram_; +}; + +} diff --git a/src/include_diagram/visitor/translation_unit_context.cc b/src/include_diagram/visitor/translation_unit_context.cc new file mode 100644 index 00000000..a77e46aa --- /dev/null +++ b/src/include_diagram/visitor/translation_unit_context.cc @@ -0,0 +1,63 @@ +/** + * src/include_diagram/visitor/translation_unit_context.cc + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "translation_unit_context.h" + +#include "cx/util.h" + +namespace clanguml::include_diagram::visitor { + +translation_unit_context::translation_unit_context( + cppast::cpp_entity_index &idx, + clanguml::include_diagram::model::diagram &diagram, + const clanguml::config::include_diagram &config) + : entity_index_{idx} + , diagram_{diagram} + , config_{config} +{ +} + +const cppast::cpp_entity_index &translation_unit_context::entity_index() const +{ + return entity_index_; +} + +const clanguml::config::include_diagram & +translation_unit_context::config() const +{ + return config_; +} + +clanguml::include_diagram::model::diagram &translation_unit_context::diagram() +{ + return diagram_; +} + +void translation_unit_context::set_current_file( + type_safe::optional_ref f) +{ + current_file_ = f; +} + +type_safe::optional_ref +translation_unit_context::get_current_file() const +{ + return current_file_; +} + +} diff --git a/src/include_diagram/visitor/translation_unit_context.h b/src/include_diagram/visitor/translation_unit_context.h new file mode 100644 index 00000000..fe7cac41 --- /dev/null +++ b/src/include_diagram/visitor/translation_unit_context.h @@ -0,0 +1,62 @@ +/** + * src/include_diagram/visitor/translation_unit_context.h + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include "common/model/package.h" +#include "config/config.h" +#include "include_diagram/model/diagram.h" + +#include +#include +#include +#include + +namespace clanguml::include_diagram::visitor { + +class translation_unit_context { +public: + translation_unit_context(cppast::cpp_entity_index &idx, + clanguml::include_diagram::model::diagram &diagram, + const clanguml::config::include_diagram &config); + + const cppast::cpp_entity_index &entity_index() const; + + const clanguml::config::include_diagram &config() const; + + clanguml::include_diagram::model::diagram &diagram(); + + void set_current_file( + type_safe::optional_ref p); + + type_safe::optional_ref + get_current_file() const; + +private: + // Reference to the cppast entity index + cppast::cpp_entity_index &entity_index_; + + // Reference to the output diagram model + clanguml::include_diagram::model::diagram &diagram_; + + // Reference to class diagram config + const clanguml::config::include_diagram &config_; + + type_safe::optional_ref current_file_; +}; + +} diff --git a/src/include_diagram/visitor/translation_unit_visitor.cc b/src/include_diagram/visitor/translation_unit_visitor.cc new file mode 100644 index 00000000..d8c9ff2f --- /dev/null +++ b/src/include_diagram/visitor/translation_unit_visitor.cc @@ -0,0 +1,53 @@ +/** + * src/include_diagram/visitor/translation_unit_visitor.cc + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "translation_unit_visitor.h" + +#include +#include + +namespace clanguml::include_diagram::visitor { + +using clanguml::include_diagram::model::diagram; + +translation_unit_visitor::translation_unit_visitor( + cppast::cpp_entity_index &idx, + clanguml::include_diagram::model::diagram &diagram, + const clanguml::config::include_diagram &config) + : ctx{idx, diagram, config} +{ +} + +void translation_unit_visitor::operator()(const cppast::cpp_entity &file) +{ + cppast::visit(file, + [&, this](const cppast::cpp_entity &e, cppast::visitor_info info) { + if (e.kind() == cppast::cpp_entity_kind::include_directive_t) { + + const auto &inc = + static_cast(e); + + auto file_name = std::filesystem::path(inc.full_path()); + + auto f = std::make_unique(); + f->set_path(file_name.parent_path().string()); + f->set_name(file_name.filename().string()); + } + }); +} +} diff --git a/src/include_diagram/visitor/translation_unit_visitor.h b/src/include_diagram/visitor/translation_unit_visitor.h new file mode 100644 index 00000000..f0b1318f --- /dev/null +++ b/src/include_diagram/visitor/translation_unit_visitor.h @@ -0,0 +1,51 @@ +/** + * src/include_diagram/visitor/translation_unit_visitor.h + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include "config/config.h" +#include "cx/cursor.h" +#include "include_diagram/model/diagram.h" +#include "include_diagram/visitor/translation_unit_context.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace clanguml::include_diagram::visitor { + +class translation_unit_visitor { +public: + translation_unit_visitor(cppast::cpp_entity_index &idx, + clanguml::include_diagram::model::diagram &diagram, + const clanguml::config::include_diagram &config); + + void operator()(const cppast::cpp_entity &file); + +private: + // ctx allows to track current visitor context, e.g. current namespace + translation_unit_context ctx; +}; +} diff --git a/src/package_diagram/model/diagram.cc b/src/package_diagram/model/diagram.cc index 903609f4..21d469c9 100644 --- a/src/package_diagram/model/diagram.cc +++ b/src/package_diagram/model/diagram.cc @@ -51,7 +51,7 @@ type_safe::optional_ref diagram::get_package( return type_safe::nullopt; } -type_safe::optional_ref diagram::get( +type_safe::optional_ref diagram::get( const std::string &full_name) const { return get_package(full_name); diff --git a/src/package_diagram/model/diagram.h b/src/package_diagram/model/diagram.h index f8c92553..2a32826f 100644 --- a/src/package_diagram/model/diagram.h +++ b/src/package_diagram/model/diagram.h @@ -29,7 +29,8 @@ namespace clanguml::package_diagram::model { class diagram : public clanguml::common::model::diagram, public clanguml::common::model::nested_trait< - clanguml::common::model::element> { + clanguml::common::model::element, + clanguml::common::model::namespace_> { public: diagram() = default; @@ -40,7 +41,7 @@ public: common::model::diagram_t type() const override; - type_safe::optional_ref get( + type_safe::optional_ref get( const std::string &full_name) const; void add_package(std::unique_ptr &&p); diff --git a/src/sequence_diagram/model/diagram.cc b/src/sequence_diagram/model/diagram.cc index 27695aa8..0a7f1a88 100644 --- a/src/sequence_diagram/model/diagram.cc +++ b/src/sequence_diagram/model/diagram.cc @@ -28,7 +28,7 @@ common::model::diagram_t diagram::type() const return common::model::diagram_t::kSequence; } -type_safe::optional_ref diagram::get( +type_safe::optional_ref diagram::get( const std::string &full_name) const { return {}; diff --git a/src/sequence_diagram/model/diagram.h b/src/sequence_diagram/model/diagram.h index 0c917960..97c7f4f1 100644 --- a/src/sequence_diagram/model/diagram.h +++ b/src/sequence_diagram/model/diagram.h @@ -36,7 +36,7 @@ public: common::model::diagram_t type() const override; - type_safe::optional_ref get( + type_safe::optional_ref get( const std::string &full_name) const; std::string to_alias(const std::string &full_name) const; diff --git a/src/util/util.cc b/src/util/util.cc index 847155c8..55991c13 100644 --- a/src/util/util.cc +++ b/src/util/util.cc @@ -101,7 +101,7 @@ std::string rtrim(const std::string &s) std::string trim(const std::string &s) { return rtrim(ltrim(s)); } -std::vector split(std::string str, std::string delimiter) +std::vector split(std::string str, std::string_view delimiter) { std::vector result; @@ -124,7 +124,8 @@ std::vector split(std::string str, std::string delimiter) return result; } -std::string join(const std::vector &toks, std::string delimiter) +std::string join( + const std::vector &toks, std::string_view delimiter) { return fmt::format("{}", fmt::join(toks, delimiter)); } diff --git a/src/util/util.h b/src/util/util.h index 26ad5506..4208c5c4 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -83,9 +83,10 @@ std::string get_git_toplevel_dir(); * * @return Vector of string tokens. */ -std::vector split(std::string str, std::string delimiter); +std::vector split(std::string str, std::string_view delimiter); -std::string join(const std::vector &toks, std::string delimiter); +std::string join( + const std::vector &toks, std::string_view delimiter); /** * @brief Remove any qualifiers (e.g. const) from type. diff --git a/tests/t40001/.clang-uml b/tests/t40001/.clang-uml new file mode 100644 index 00000000..2ccf4457 --- /dev/null +++ b/tests/t40001/.clang-uml @@ -0,0 +1,10 @@ +compilation_database_dir: .. +output_directory: puml +diagrams: + t40001_include: + type: include + glob: + - ../../tests/t40001/t40001.cc + plantuml: + before: + - "' t40001 test include diagram" \ No newline at end of file diff --git a/tests/t40001/t40001.cc b/tests/t40001/t40001.cc new file mode 100644 index 00000000..fe07ee65 --- /dev/null +++ b/tests/t40001/t40001.cc @@ -0,0 +1,10 @@ +#include +#include + +#include "t40001_include1.h" + +namespace clanguml { +namespace t40001 { + +} // namespace t40001 +} // namespace clanguml diff --git a/tests/t40001/t40001_include1.h b/tests/t40001/t40001_include1.h new file mode 100644 index 00000000..94dcfa4a --- /dev/null +++ b/tests/t40001/t40001_include1.h @@ -0,0 +1,7 @@ +#pragma once + +namespace clanguml::t40001 { + +int foo() { return 0; } + +} \ No newline at end of file diff --git a/tests/t40001/test_case.h b/tests/t40001/test_case.h new file mode 100644 index 00000000..64fcaa7e --- /dev/null +++ b/tests/t40001/test_case.h @@ -0,0 +1,40 @@ +/** + * tests/t40001/test_case.cc + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +TEST_CASE("t40001", "[test-case][package]") +{ + auto [config, db] = load_config("t40001"); + + auto diagram = config.diagrams["t40001_include"]; + + REQUIRE(diagram->name == "t40001_include"); + + auto model = generate_include_diagram(db, diagram); + + REQUIRE(model->name() == "t40001_include"); + + auto puml = generate_include_puml(diagram, *model); + + AliasMatcher _A(puml); + + REQUIRE_THAT(puml, StartsWith("@startuml")); + REQUIRE_THAT(puml, EndsWith("@enduml\n")); + + save_puml( + "./" + config.output_directory() + "/" + diagram->name + ".puml", puml); +} diff --git a/tests/test_cases.cc b/tests/test_cases.cc index 3487f740..a782978c 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -103,6 +103,22 @@ generate_package_diagram(cppast::libclang_compilation_database &db, db, diagram->name, dynamic_cast(*diagram)); } +std::unique_ptr +generate_include_diagram(cppast::libclang_compilation_database &db, + std::shared_ptr diagram) +{ + using diagram_config = clanguml::config::include_diagram; + using diagram_model = clanguml::include_diagram::model::diagram; + using diagram_visitor = + clanguml::include_diagram::visitor::translation_unit_visitor; + + inject_diagram_options(diagram); + + return clanguml::common::generators::plantuml::generate( + db, diagram->name, dynamic_cast(*diagram)); +} + std::string generate_sequence_puml( std::shared_ptr config, clanguml::sequence_diagram::model::diagram &model) @@ -145,6 +161,20 @@ std::string generate_package_puml( return ss.str(); } +std::string generate_include_puml( + std::shared_ptr config, + clanguml::include_diagram::model::diagram &model) +{ + using namespace clanguml::include_diagram::generators::plantuml; + + std::stringstream ss; + + ss << generator( + dynamic_cast(*config), model); + + return ss.str(); +} + void save_puml(const std::string &path, const std::string &puml) { std::filesystem::path p{path}; @@ -218,6 +248,11 @@ using namespace clanguml::test::matchers; #include "t30006/test_case.h" #include "t30007/test_case.h" +// +// Include diagram tests +// +#include "t40001/test_case.h" + // // Other tests (e.g. configuration file) // diff --git a/tests/test_cases.h b/tests/test_cases.h index 030f9849..6d9a4a70 100644 --- a/tests/test_cases.h +++ b/tests/test_cases.h @@ -24,6 +24,8 @@ #include "class_diagram/visitor/translation_unit_visitor.h" #include "config/config.h" #include "cx/compilation_database.h" +#include "include_diagram/generators/plantuml/include_diagram_generator.h" +#include "include_diagram/visitor/translation_unit_visitor.h" #include "package_diagram/generators/plantuml/package_diagram_generator.h" #include "package_diagram/visitor/translation_unit_visitor.h" #include "sequence_diagram/generators/plantuml/sequence_diagram_generator.h" From ac624c9247f8019fe2d723d7cd72d73b1ca9648a Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 10 Apr 2022 13:32:59 +0200 Subject: [PATCH 02/13] Added initial support for include graph diagrams --- README.md | 4 +- src/common/model/diagram.cc | 8 ++ src/common/model/diagram.h | 3 + src/common/model/diagram_filter.cc | 45 ++++++++ src/common/model/diagram_filter.h | 22 +++- src/common/model/nested_trait.h | 3 +- .../model/source_file.cc | 2 +- .../model/source_file.h | 38 ++++-- src/config/config.cc | 48 +++++++- src/config/config.h | 4 + .../plantuml/include_diagram_generator.cc | 35 +++++- .../plantuml/include_diagram_generator.h | 4 +- src/include_diagram/model/diagram.cc | 8 +- src/include_diagram/model/diagram.h | 14 +-- .../visitor/translation_unit_context.cc | 4 +- .../visitor/translation_unit_context.h | 6 +- .../visitor/translation_unit_visitor.cc | 109 +++++++++++++++++- .../visitor/translation_unit_visitor.h | 8 +- src/util/util.cc | 32 +++++ src/util/util.h | 24 ++-- tests/t40001/include/t40001_include1.h | 9 ++ tests/t40001/{ => src}/t40001.cc | 2 +- tests/t40001/t40001_include1.h | 7 -- 23 files changed, 378 insertions(+), 61 deletions(-) rename src/{include_diagram => common}/model/source_file.cc (93%) rename src/{include_diagram => common}/model/source_file.h (69%) create mode 100644 tests/t40001/include/t40001_include1.h rename tests/t40001/{ => src}/t40001.cc (77%) delete mode 100644 tests/t40001/t40001_include1.h diff --git a/README.md b/README.md index 51bae82b..1144e315 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,9 @@ Main features supported so far include: * **Package diagram generation** * Generation of package diagram based on C++ namespaces * Interactive links to online code to packages - +* **Include graph diagram generation** + * Show include graph for selected files + To see what `clang-uml` can do so far, checkout the diagrams generated for unit test cases [here](./docs/test_cases.md). ## Installation diff --git a/src/common/model/diagram.cc b/src/common/model/diagram.cc index 7330236c..4f29e739 100644 --- a/src/common/model/diagram.cc +++ b/src/common/model/diagram.cc @@ -85,4 +85,12 @@ bool diagram::should_include( return filter_->should_include(ns, name); } +bool diagram::should_include(const common::model::source_file &f) const +{ + if (filter_.get() == nullptr) + return true; + + return filter_->should_include(f); +} + } \ No newline at end of file diff --git a/src/common/model/diagram.h b/src/common/model/diagram.h index dbcd9b52..579c2c1a 100644 --- a/src/common/model/diagram.h +++ b/src/common/model/diagram.h @@ -20,6 +20,7 @@ #include "diagram_element.h" #include "enums.h" #include "namespace.h" +#include "source_file.h" #include @@ -58,9 +59,11 @@ public: // TODO: refactor to a template method bool should_include(const element &e) const; bool should_include(const std::string &e) const; + bool should_include(const source_file &path) const; bool should_include(const relationship r) const; bool should_include(const relationship_t r) const; bool should_include(const access_t s) const; + bool should_include(const namespace_ &ns, const std::string &name) const; private: diff --git a/src/common/model/diagram_filter.cc b/src/common/model/diagram_filter.cc index 0d3d0d50..000a9cbb 100644 --- a/src/common/model/diagram_filter.cc +++ b/src/common/model/diagram_filter.cc @@ -49,6 +49,12 @@ tvl::value_t filter_visitor::match( return {}; } +tvl::value_t filter_visitor::match( + const diagram &d, const common::model::source_file &f) const +{ + return {}; +} + bool filter_visitor::is_inclusive() const { return type_ == filter_t::kInclusive; @@ -254,6 +260,40 @@ tvl::value_t context_filter::match(const diagram &d, const element &e) const }); } +paths_filter::paths_filter(filter_t type, const std::filesystem::path &root, + std::vector p) + : filter_visitor{type} + , root_{root} +{ + for (auto &&path : p) { + std::filesystem::path absolute_path; + + if (path.is_relative()) + absolute_path = root / path; + + absolute_path = absolute_path.lexically_normal(); + + paths_.emplace_back(std::move(absolute_path)); + } +} + +tvl::value_t paths_filter::match( + const diagram &d, const common::model::source_file &p) const +{ + + if (paths_.empty()) { + return {}; + } + + auto pp = p.fs_path(root_); + for (const auto &path : paths_) { + if (util::starts_with(pp, path)) + return true; + } + + return false; +} + diagram_filter::diagram_filter( const common::model::diagram &d, const config::diagram &c) : diagram_{d} @@ -295,6 +335,8 @@ void diagram_filter::init_filters(const config::diagram &c) filter_t::kInclusive, c.include().relationships)); inclusive_.emplace_back(std::make_unique( filter_t::kInclusive, c.include().access)); + inclusive_.emplace_back(std::make_unique( + filter_t::kInclusive, c.base_directory(), c.include().paths)); // Include any of these matches even if one them does not match std::vector> element_filters; @@ -305,6 +347,7 @@ void diagram_filter::init_filters(const config::diagram &c) element_filters.emplace_back(std::make_unique( filter_t::kInclusive, c.include().context)); + inclusive_.emplace_back(std::make_unique( filter_t::kInclusive, std::move(element_filters))); } @@ -323,6 +366,8 @@ void diagram_filter::init_filters(const config::diagram &c) filter_t::kExclusive, c.exclude().subclasses)); exclusive_.emplace_back(std::make_unique( filter_t::kExclusive, c.exclude().context)); + exclusive_.emplace_back(std::make_unique( + filter_t::kInclusive, c.base_directory(), c.exclude().paths)); } } diff --git a/src/common/model/diagram_filter.h b/src/common/model/diagram_filter.h index dfbc8886..b3df613e 100644 --- a/src/common/model/diagram_filter.h +++ b/src/common/model/diagram_filter.h @@ -25,8 +25,11 @@ #include "config/config.h" #include "cx/util.h" #include "diagram.h" +#include "source_file.h" #include "tvl.h" +#include + namespace clanguml::common::model { enum filter_t { kInclusive, kExclusive }; @@ -47,6 +50,9 @@ public: virtual tvl::value_t match( const diagram &d, const common::model::namespace_ &ns) const; + virtual tvl::value_t match( + const diagram &d, const common::model::source_file &f) const; + bool is_inclusive() const; bool is_exclusive() const; @@ -125,6 +131,18 @@ private: std::vector context_; }; +struct paths_filter : public filter_visitor { + paths_filter(filter_t type, const std::filesystem::path &root, + std::vector p); + + tvl::value_t match(const diagram &d, + const common::model::source_file &r) const override; + +private: + std::vector paths_; + std::filesystem::path root_; +}; + class diagram_filter { public: diagram_filter(const common::model::diagram &d, const config::diagram &c); @@ -144,7 +162,9 @@ public: return false; auto inc = tvl::all_of(inclusive_.begin(), inclusive_.end(), - [this, &e](const auto &in) { return in->match(diagram_, e); }); + [this, &e](const auto &in) { + return in->match(diagram_, e); + }); if (tvl::is_undefined(inc) || tvl::is_true(inc)) return true; diff --git a/src/common/model/nested_trait.h b/src/common/model/nested_trait.h index d79d04b3..8f083f39 100644 --- a/src/common/model/nested_trait.h +++ b/src/common/model/nested_trait.h @@ -52,7 +52,8 @@ public: } template - void add_element(const Path &path, std::unique_ptr p) + void add_element( + const Path &path, std::unique_ptr p) { assert(p); diff --git a/src/include_diagram/model/source_file.cc b/src/common/model/source_file.cc similarity index 93% rename from src/include_diagram/model/source_file.cc rename to src/common/model/source_file.cc index 3b596231..0a806652 100644 --- a/src/include_diagram/model/source_file.cc +++ b/src/common/model/source_file.cc @@ -1,5 +1,5 @@ /** - * src/include_diagram/model/source_file.cc + * src/common/model/source_file.cc * * Copyright (c) 2021-2022 Bartek Kryza * diff --git a/src/include_diagram/model/source_file.h b/src/common/model/source_file.h similarity index 69% rename from src/include_diagram/model/source_file.h rename to src/common/model/source_file.h index 0e16835e..99a2f1c7 100644 --- a/src/include_diagram/model/source_file.h +++ b/src/common/model/source_file.h @@ -1,5 +1,5 @@ /** - * src/include_diagram/model/source_file.h + * src/common/model/source_file.h * * Copyright (c) 2021-2022 Bartek Kryza * @@ -30,9 +30,9 @@ #include #include -namespace clanguml::include_diagram::model { +namespace clanguml::common::model { -enum class source_file_type { kDirectory, kHeader, kImplementation }; +enum class source_file_t { kDirectory, kHeader, kImplementation }; struct fs_path_sep { static constexpr std::string_view value = "/"; @@ -43,13 +43,19 @@ using filesystem_path = common::model::path; class source_file : public common::model::diagram_element, public common::model::stylable_element, - public common::model::nested_trait { public: source_file() = default; void set_path(const filesystem_path &p) { path_ = p; } + void set_absolute() { is_absolute_ = true; } + + void set_type(source_file_t type) { type_ = type; } + + source_file_t type() const { return type_; } + source_file(const source_file &) = delete; source_file(source_file &&) = default; source_file &operator=(const source_file &) = delete; @@ -62,23 +68,41 @@ public: return (path_ | name()).to_string(); } - void add_file(std::unique_ptr &&f) + void add_file(std::unique_ptr &&f) { LOG_DBG("Adding source file: {}, {}", f->name(), f->full_name(true)); add_element(f->path(), std::move(f)); } + std::filesystem::path fs_path(const std::filesystem::path &base = {}) const + { + std::filesystem::path res; + + for (const auto &pe : path_) { + res /= pe; + } + + if (is_absolute_) + res = "/" / res; + else + res = base / res; + + return res.lexically_normal(); + } + private: filesystem_path path_; + source_file_t type_{source_file_t::kDirectory}; + bool is_absolute_{false}; }; } namespace std { -template <> struct hash { +template <> struct hash { std::size_t operator()( - const clanguml::include_diagram::model::filesystem_path &key) const + const clanguml::common::model::filesystem_path &key) const { using clanguml::common::model::path; diff --git a/src/config/config.cc b/src/config/config.cc index 3138cc00..6764d069 100644 --- a/src/config/config.cc +++ b/src/config/config.cc @@ -15,7 +15,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include "config.h" + #include namespace clanguml { @@ -28,12 +30,13 @@ config load(const std::string &config_file) // Store the parent path of the config_file to properly resolve // the include files paths - auto config_file_path = std::filesystem::path{config_file}; + auto config_file_path = + std::filesystem::absolute(std::filesystem::path{config_file}); doc.force_insert( "__parent_path", config_file_path.parent_path().string()); // If the current directory is also a git repository, - // load some config values which can be included in the + // load some config values, which can be included in the // generated diagrams if (util::is_git_repository() && !doc["git"]) { YAML::Node git_config{YAML::NodeType::Map}; @@ -108,6 +111,8 @@ void inheritable_diagram_options::inherit( generate_method_arguments.override(parent.generate_method_arguments); generate_links.override(parent.generate_links); git.override(parent.git); + base_directory.override(parent.base_directory); + relative_to.override(parent.relative_to); } diagram_type class_diagram::type() const { return diagram_type::class_diagram; } @@ -245,6 +250,21 @@ std::shared_ptr parse_diagram_config(const Node &d) return {}; } +// +// config std::filesystem::path decoder +// +template <> struct convert { + static bool decode(const Node &node, std::filesystem::path &rhs) + { + if (!node.IsScalar()) + return false; + + rhs = std::filesystem::path{node.as()}; + + return true; + } +}; + // // config access_t decoder // @@ -391,6 +411,9 @@ template <> struct convert { if (node["context"]) rhs.context = node["context"].as(); + if (node["paths"]) + rhs.paths = node["paths"].as(); + return true; } }; @@ -505,6 +528,16 @@ template <> struct convert { return false; get_option(node, rhs.layout); + get_option(node, rhs.relative_to); + + // Convert the path in relative_to to an absolute path, with respect + // to the directory where the `.clang-uml` configuration file is located + if (rhs.relative_to) { + auto absolute_relative_to = + std::filesystem::path{node["__parent_path"].as()} / + rhs.relative_to(); + rhs.relative_to.set(absolute_relative_to.lexically_normal()); + } return true; } @@ -558,25 +591,29 @@ template <> struct convert { get_option(node, rhs.generate_packages); get_option(node, rhs.generate_links); get_option(node, rhs.git); + rhs.base_directory.set(node["__parent_path"].as()); + get_option(node, rhs.relative_to); auto diagrams = node["diagrams"]; assert(diagrams.Type() == NodeType::Map); - for (const auto &d : diagrams) { + for (auto d : diagrams) { auto name = d.first.as(); std::shared_ptr diagram_config{}; + auto parent_path = node["__parent_path"].as(); if (has_key(d.second, "include!")) { - auto parent_path = node["__parent_path"].as(); auto include_path = std::filesystem::path{parent_path}; include_path /= d.second["include!"].as(); YAML::Node node = YAML::LoadFile(include_path.string()); + node.force_insert("__parent_path", parent_path); diagram_config = parse_diagram_config(node); } else { + d.second.force_insert("__parent_path", parent_path); diagram_config = parse_diagram_config(d.second); } @@ -585,6 +622,9 @@ template <> struct convert { diagram_config->inherit(rhs); rhs.diagrams[name] = diagram_config; } + else { + return false; + } } return true; diff --git a/src/config/config.h b/src/config/config.h index c598d774..ce744e86 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -71,6 +71,8 @@ struct filter { std::vector subclasses; std::vector context; + + std::vector paths; }; enum class hint_t { up, down, left, right }; @@ -110,6 +112,8 @@ struct inheritable_diagram_options { option generate_packages{"generate_packages", false}; option generate_links{"generate_links"}; option git{"git"}; + option base_directory{"__parent_path"}; + option relative_to{"relative_to"}; void inherit(const inheritable_diagram_options &parent); }; diff --git a/src/include_diagram/generators/plantuml/include_diagram_generator.cc b/src/include_diagram/generators/plantuml/include_diagram_generator.cc index 58ed09e4..cf696df9 100644 --- a/src/include_diagram/generators/plantuml/include_diagram_generator.cc +++ b/src/include_diagram/generators/plantuml/include_diagram_generator.cc @@ -31,11 +31,41 @@ void generator::generate_relationships( const source_file &f, std::ostream &ostr) const { LOG_DBG("Generating relationships for file {}", f.full_name(true)); + + namespace plantuml_common = clanguml::common::generators::plantuml; + + if (f.type() == common::model::source_file_t::kDirectory) { + for (const auto &file : f) { + generate_relationships( + dynamic_cast(*file), ostr); + } + } + else { + for (const auto &r : f.relationships()) { + if (m_model.should_include(r.type())) { + ostr << f.alias() << " " + << plantuml_common::to_plantuml(r.type(), r.style()) << " " + << r.destination() << '\n'; + } + } + } } void generator::generate(const source_file &f, std::ostream &ostr) const { LOG_DBG("Generating source_file {}", f.name()); + + if (f.type() == common::model::source_file_t::kDirectory) { + ostr << "folder " << f.name(); + ostr << " as " << f.alias() << " {\n"; + for (const auto &file : f) { + generate(dynamic_cast(*file), ostr); + } + ostr << "}" << '\n'; + } + else { + ostr << "file " << f.name() << " as " << f.alias() << '\n'; + } } void generator::generate(std::ostream &ostr) const @@ -44,15 +74,14 @@ void generator::generate(std::ostream &ostr) const generate_plantuml_directives(ostr, m_config.puml().before); + // Generate files and folders for (const auto &p : m_model) { generate(dynamic_cast(*p), ostr); - ostr << '\n'; } - // Process package relationships + // Process file include relationships for (const auto &p : m_model) { generate_relationships(dynamic_cast(*p), ostr); - ostr << '\n'; } generate_config_layout_hints(ostr); diff --git a/src/include_diagram/generators/plantuml/include_diagram_generator.h b/src/include_diagram/generators/plantuml/include_diagram_generator.h index 8b2967c3..314bde18 100644 --- a/src/include_diagram/generators/plantuml/include_diagram_generator.h +++ b/src/include_diagram/generators/plantuml/include_diagram_generator.h @@ -20,10 +20,10 @@ #include "common/generators/plantuml/generator.h" #include "common/model/package.h" #include "common/model/relationship.h" +#include "common/model/source_file.h" #include "config/config.h" #include "cx/compilation_database.h" #include "include_diagram/model/diagram.h" -#include "include_diagram/model/source_file.h" #include "include_diagram/visitor/translation_unit_visitor.h" #include "util/util.h" @@ -50,7 +50,7 @@ using common_generator = using clanguml::common::model::access_t; using clanguml::common::model::package; using clanguml::common::model::relationship_t; -using clanguml::include_diagram::model::source_file; +using clanguml::common::model::source_file; using namespace clanguml::util; class generator : public common_generator { diff --git a/src/include_diagram/model/diagram.cc b/src/include_diagram/model/diagram.cc index 3ad181f0..58023d60 100644 --- a/src/include_diagram/model/diagram.cc +++ b/src/include_diagram/model/diagram.cc @@ -34,16 +34,18 @@ type_safe::optional_ref diagram::get( return get_file(full_name); } -void diagram::add_file(std::unique_ptr &&f) +void diagram::add_file(std::unique_ptr &&f) { LOG_DBG("Adding source file: {}, {}", f->name(), f->full_name(true)); files_.emplace_back(*f); - add_element(f->path(), std::move(f)); + auto p = f->path(); + + add_element(p, std::move(f)); } -type_safe::optional_ref +type_safe::optional_ref diagram::get_file(const std::string &name) const { for (const auto &p : files_) { diff --git a/src/include_diagram/model/diagram.h b/src/include_diagram/model/diagram.h index 8c71bcd7..58ed1581 100644 --- a/src/include_diagram/model/diagram.h +++ b/src/include_diagram/model/diagram.h @@ -19,7 +19,7 @@ #include "common/model/diagram.h" #include "common/model/package.h" -#include "source_file.h" +#include "common/model/source_file.h" #include @@ -29,8 +29,9 @@ namespace clanguml::include_diagram::model { class diagram : public clanguml::common::model::diagram, - public clanguml::common::model::nested_trait { + public clanguml::common::model::nested_trait< + clanguml::common::model::source_file, + clanguml::common::model::filesystem_path> { public: diagram() = default; @@ -44,16 +45,15 @@ public: type_safe::optional_ref get( const std::string &full_name) const; - void add_file(std::unique_ptr &&f); + void add_file(std::unique_ptr &&f); - type_safe::optional_ref get_file( + type_safe::optional_ref get_file( const std::string &name) const; std::string to_alias(const std::string &full_name) const; private: - std::vector< - type_safe::object_ref> + std::vector> files_; }; } diff --git a/src/include_diagram/visitor/translation_unit_context.cc b/src/include_diagram/visitor/translation_unit_context.cc index a77e46aa..4cff5297 100644 --- a/src/include_diagram/visitor/translation_unit_context.cc +++ b/src/include_diagram/visitor/translation_unit_context.cc @@ -49,12 +49,12 @@ clanguml::include_diagram::model::diagram &translation_unit_context::diagram() } void translation_unit_context::set_current_file( - type_safe::optional_ref f) + type_safe::optional_ref f) { current_file_ = f; } -type_safe::optional_ref +type_safe::optional_ref translation_unit_context::get_current_file() const { return current_file_; diff --git a/src/include_diagram/visitor/translation_unit_context.h b/src/include_diagram/visitor/translation_unit_context.h index fe7cac41..5d72912a 100644 --- a/src/include_diagram/visitor/translation_unit_context.h +++ b/src/include_diagram/visitor/translation_unit_context.h @@ -41,9 +41,9 @@ public: clanguml::include_diagram::model::diagram &diagram(); void set_current_file( - type_safe::optional_ref p); + type_safe::optional_ref p); - type_safe::optional_ref + type_safe::optional_ref get_current_file() const; private: @@ -56,7 +56,7 @@ private: // Reference to class diagram config const clanguml::config::include_diagram &config_; - type_safe::optional_ref current_file_; + type_safe::optional_ref current_file_; }; } diff --git a/src/include_diagram/visitor/translation_unit_visitor.cc b/src/include_diagram/visitor/translation_unit_visitor.cc index d8c9ff2f..c453b309 100644 --- a/src/include_diagram/visitor/translation_unit_visitor.cc +++ b/src/include_diagram/visitor/translation_unit_visitor.cc @@ -21,9 +21,9 @@ #include #include -namespace clanguml::include_diagram::visitor { +#include -using clanguml::include_diagram::model::diagram; +namespace clanguml::include_diagram::visitor { translation_unit_visitor::translation_unit_visitor( cppast::cpp_entity_index &idx, @@ -35,19 +35,116 @@ translation_unit_visitor::translation_unit_visitor( void translation_unit_visitor::operator()(const cppast::cpp_entity &file) { + assert(file.kind() == cppast::cpp_entity_kind::file_t); + + const auto &f = static_cast(file); + + auto file_path = f.name(); + + LOG_DBG("Processing source file {}", file_path); + + process_file(file_path, true); + cppast::visit(file, [&, this](const cppast::cpp_entity &e, cppast::visitor_info info) { if (e.kind() == cppast::cpp_entity_kind::include_directive_t) { + assert(ctx.get_current_file().has_value()); + + auto file_path_cpy = file.name(); const auto &inc = static_cast(e); - auto file_name = std::filesystem::path(inc.full_path()); + LOG_DBG("Processing include directive {} in file {}", + inc.full_path(), ctx.get_current_file().value().name()); - auto f = std::make_unique(); - f->set_path(file_name.parent_path().string()); - f->set_name(file_name.filename().string()); + process_file(inc.full_path(), false, inc.include_kind()); } }); } + +void translation_unit_visitor::process_file(const std::string &file, + bool register_as_current, + std::optional include_kind) +{ + auto include_path = std::filesystem::path(file); + + const std::filesystem::path base_directory{ctx.config().base_directory()}; + + if (include_path.is_relative()) { + include_path = ctx.config().base_directory() / include_path; + } + + include_path = include_path.lexically_normal(); + + auto f_abs = std::make_unique(); + + if (include_path.is_absolute()) + f_abs->set_absolute(); + + f_abs->set_path(include_path.parent_path().string()); + f_abs->set_name(include_path.filename().string()); + + if (ctx.diagram().should_include(*f_abs)) { + if (ctx.config().relative_to) { + const std::filesystem::path relative_to{ctx.config().relative_to()}; + + include_path = std::filesystem::relative(include_path, relative_to); + } + + auto f = std::make_unique(); + + auto parent_path_str = include_path.parent_path().string(); + if (!parent_path_str.empty()) + f->set_path(parent_path_str); + f->set_name(include_path.filename().string()); + f->set_type(common::model::source_file_t::kHeader); + + if (register_as_current && + ctx.diagram().get_element(f->path() | f->name()).has_value()) { + // This file is already in the diagram (e.g. it was added through an + // include directive before it was visited by the parser) + ctx.set_current_file( + ctx.diagram().get_element(f->path() | f->name())); + return; + } + + if (!f->path().is_empty()) { + // Ensure parent path directories source_files + // are in the diagram + common::model::filesystem_path parent_path_so_far; + for (const auto &directory : f->path()) { + auto dir = std::make_unique(); + if (!parent_path_so_far.is_empty()) + dir->set_path(parent_path_so_far); + dir->set_name(directory); + dir->set_type(common::model::source_file_t::kDirectory); + + if (!ctx.diagram() + .get_element(parent_path_so_far | directory) + .has_value()) + ctx.diagram().add_file(std::move(dir)); + + parent_path_so_far.append(directory); + } + } + + if (!register_as_current) { + auto relationship_type = + common::model::relationship_t::kAssociation; + if (include_kind.has_value() && + include_kind.value() == cppast::cpp_include_kind::system) + relationship_type = common::model::relationship_t::kDependency; + + ctx.get_current_file().value().add_relationship( + common::model::relationship{relationship_type, f->alias()}); + } + + if (!ctx.diagram().get_element(f->path() | f->name()).has_value()) { + ctx.set_current_file(type_safe::opt_ref(*f)); + ctx.diagram().add_file(std::move(f)); + } + } + +} } diff --git a/src/include_diagram/visitor/translation_unit_visitor.h b/src/include_diagram/visitor/translation_unit_visitor.h index f0b1318f..b9347a6f 100644 --- a/src/include_diagram/visitor/translation_unit_visitor.h +++ b/src/include_diagram/visitor/translation_unit_visitor.h @@ -21,14 +21,15 @@ #include "cx/cursor.h" #include "include_diagram/model/diagram.h" #include "include_diagram/visitor/translation_unit_context.h" +#include "common/model/enums.h" +#include "common/model/package.h" #include #include #include +#include #include -#include -#include #include #include #include @@ -45,6 +46,9 @@ public: void operator()(const cppast::cpp_entity &file); private: + void process_file(const std::string &file, bool register_as_current = false, + std::optional include_kind = {}); + // ctx allows to track current visitor context, e.g. current namespace translation_unit_context ctx; }; diff --git a/src/util/util.cc b/src/util/util.cc index 55991c13..08fc0415 100644 --- a/src/util/util.cc +++ b/src/util/util.cc @@ -198,5 +198,37 @@ bool replace_all( return replaced; } +template <> +bool starts_with( + const std::filesystem::path &path, const std::filesystem::path &prefix) +{ + if(path == prefix) + return true; + + const int path_length = std::distance(std::begin(path), std::end(path)); + + auto last_nonempty_prefix_element = std::prev(std::find_if( + prefix.begin(), prefix.end(), [](auto &&n) { return n.empty(); })); + + int prefix_length = + std::distance(std::begin(prefix), last_nonempty_prefix_element); + + // Empty prefix always matches + if (prefix_length == 0) + return true; + + // Prefix longer then path never matches + if (prefix_length >= path_length) + return false; + + auto path_compare_end = path.begin(); + std::advance(path_compare_end, prefix_length); + + std::vector pref(prefix.begin(), last_nonempty_prefix_element); + std::vector pat(path.begin(), path_compare_end); + + return pref == pat; +} + } } diff --git a/src/util/util.h b/src/util/util.h index 4208c5c4..d12ad9af 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -143,23 +144,26 @@ template void append(std::vector &l, const std::vector &r) } /** - * @brief Checks if vector starts with a prefix. + * @brief Checks if container starts with a prefix. * - * @tparam T - * @param col - * @param prefix - * @return + * @tparam T e.g. std::vector + * @param con Container to be checked against prefix + * @param prefix Container, which specifies the prefix + * @return true if first prefix.size() elements of con are equal to prefix */ -template -bool starts_with(const std::vector &col, const std::vector &prefix) +template bool starts_with(const T &con, const T &prefix) { - if (prefix.size() > col.size()) + if (prefix.size() > con.size()) return false; - return std::vector(prefix.begin(), prefix.end()) == - std::vector(col.begin(), col.begin() + prefix.size()); + return T(prefix.begin(), prefix.end()) == + T(con.begin(), con.begin() + prefix.size()); } +template <> +bool starts_with( + const std::filesystem::path &path, const std::filesystem::path &prefix); + template bool ends_with(const std::vector &col, const std::vector &suffix) { diff --git a/tests/t40001/include/t40001_include1.h b/tests/t40001/include/t40001_include1.h new file mode 100644 index 00000000..734f33d2 --- /dev/null +++ b/tests/t40001/include/t40001_include1.h @@ -0,0 +1,9 @@ +#pragma once + +#include "lib1/lib1.h" + +namespace clanguml::t40001 { + +int foo() { return lib1::foo2(); } + +} \ No newline at end of file diff --git a/tests/t40001/t40001.cc b/tests/t40001/src/t40001.cc similarity index 77% rename from tests/t40001/t40001.cc rename to tests/t40001/src/t40001.cc index fe07ee65..9c227217 100644 --- a/tests/t40001/t40001.cc +++ b/tests/t40001/src/t40001.cc @@ -1,7 +1,7 @@ #include #include -#include "t40001_include1.h" +#include "include/t40001_include1.h" namespace clanguml { namespace t40001 { diff --git a/tests/t40001/t40001_include1.h b/tests/t40001/t40001_include1.h deleted file mode 100644 index 94dcfa4a..00000000 --- a/tests/t40001/t40001_include1.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -namespace clanguml::t40001 { - -int foo() { return 0; } - -} \ No newline at end of file From f4d4633ecefa1cbf07c3c271646e2d12c4a8a43d Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 10 Apr 2022 13:33:16 +0200 Subject: [PATCH 03/13] Added basic include diagram test case --- tests/t40001/.clang-uml | 11 ++++++++++- tests/t40001/include/lib1/lib1.h | 7 +++++++ tests/t40001/src/t40001.cc | 2 +- tests/t40001/test_case.h | 8 ++++++++ tests/test_cases.cc | 4 ++++ tests/test_cases.h | 28 +++++++++++++++++++++++++--- tests/test_util.cc | 19 +++++++++++++++++++ 7 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 tests/t40001/include/lib1/lib1.h diff --git a/tests/t40001/.clang-uml b/tests/t40001/.clang-uml index 2ccf4457..6d55f301 100644 --- a/tests/t40001/.clang-uml +++ b/tests/t40001/.clang-uml @@ -3,8 +3,17 @@ output_directory: puml diagrams: t40001_include: type: include + # Provide the files to parse in order to look + # for #include directives glob: - - ../../tests/t40001/t40001.cc + - ../../tests/t40001/**/*.cc + - ../../tests/t40001/**/*.h + # Render the paths relative to this directory + relative_to: ../../tests/t40001 + include: + # Include only headers belonging to these paths + paths: + - ../../tests/t40001 plantuml: before: - "' t40001 test include diagram" \ No newline at end of file diff --git a/tests/t40001/include/lib1/lib1.h b/tests/t40001/include/lib1/lib1.h new file mode 100644 index 00000000..8d6d7d9b --- /dev/null +++ b/tests/t40001/include/lib1/lib1.h @@ -0,0 +1,7 @@ +#pragma once + +namespace clanguml::t40001::lib1 { + +int foo2() { return 0; } + +} \ No newline at end of file diff --git a/tests/t40001/src/t40001.cc b/tests/t40001/src/t40001.cc index 9c227217..d03a527c 100644 --- a/tests/t40001/src/t40001.cc +++ b/tests/t40001/src/t40001.cc @@ -1,7 +1,7 @@ #include #include -#include "include/t40001_include1.h" +#include "../include/t40001_include1.h" namespace clanguml { namespace t40001 { diff --git a/tests/t40001/test_case.h b/tests/t40001/test_case.h index 64fcaa7e..e2bf65ae 100644 --- a/tests/t40001/test_case.h +++ b/tests/t40001/test_case.h @@ -35,6 +35,14 @@ TEST_CASE("t40001", "[test-case][package]") REQUIRE_THAT(puml, StartsWith("@startuml")); REQUIRE_THAT(puml, EndsWith("@enduml\n")); + REQUIRE_THAT(puml, IsFolder("lib1")); + REQUIRE_THAT(puml, IsFile("lib1.h")); + REQUIRE_THAT(puml, IsFile("t40001.cc")); + REQUIRE_THAT(puml, IsFile("t40001_include1.h")); + + REQUIRE_THAT(puml, IsAssociation(_A("t40001.cc"), _A("t40001_include1.h"))); + REQUIRE_THAT(puml, IsAssociation(_A("t40001_include1.h"), _A("lib1.h"))); + save_puml( "./" + config.output_directory() + "/" + diagram->name + ".puml", puml); } diff --git a/tests/test_cases.cc b/tests/test_cases.cc index a782978c..422c806b 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -155,6 +155,8 @@ std::string generate_package_puml( std::stringstream ss; + assert(config.get() != nullptr); + ss << generator( dynamic_cast(*config), model); @@ -169,6 +171,8 @@ std::string generate_include_puml( std::stringstream ss; + assert(config.get() != nullptr); + ss << generator( dynamic_cast(*config), model); diff --git a/tests/test_cases.h b/tests/test_cases.h index 6d9a4a70..835fbb92 100644 --- a/tests/test_cases.h +++ b/tests/test_cases.h @@ -185,6 +185,10 @@ struct AliasMatcher { std::regex{"package\\s\"" + name + "\"\\sas\\s" + alias_regex}); patterns.push_back( std::regex{"package\\s\\[" + name + "\\]\\sas\\s" + alias_regex}); + patterns.push_back( + std::regex{"file\\s\"?" + name + "\"?\\sas\\s" + alias_regex}); + patterns.push_back( + std::regex{"folder\\s\"?" + name + "\"?\\sas\\s" + alias_regex}); std::smatch base_match; @@ -260,10 +264,16 @@ ContainsMatcher IsAssociation(std::string const &from, std::string const &to, if (!multiplicity_dest.empty()) format_string += " \"" + multiplicity_dest + "\""; - format_string += " {} : {}"; + format_string += " {}"; - return ContainsMatcher(CasedString( - fmt::format(format_string, from, to, label), caseSensitivity)); + if (!label.empty()) { + format_string += " : {}"; + return ContainsMatcher(CasedString( + fmt::format(format_string, from, to, label), caseSensitivity)); + } + else + return ContainsMatcher( + CasedString(fmt::format(format_string, from, to), caseSensitivity)); } ContainsMatcher IsComposition(std::string const &from, std::string const &to, @@ -444,6 +454,18 @@ ContainsMatcher IsPackage(std::string const &str, CasedString("package [" + str + "]", caseSensitivity)); } +ContainsMatcher IsFolder(std::string const &str, + CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) +{ + return ContainsMatcher(CasedString("folder " + str, caseSensitivity)); +} + +ContainsMatcher IsFile(std::string const &str, + CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) +{ + return ContainsMatcher(CasedString("file " + str, caseSensitivity)); +} + ContainsMatcher IsDeprecated(std::string const &str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) { diff --git a/tests/test_util.cc b/tests/test_util.cc index 6e9be6fd..d89ea994 100644 --- a/tests/test_util.cc +++ b/tests/test_util.cc @@ -20,6 +20,8 @@ #include "util/util.h" #include +#include + #include "catch.h" TEST_CASE("Test split", "[unit-test]") @@ -47,6 +49,23 @@ TEST_CASE("Test abbreviate", "[unit-test]") CHECK(abbreviate("abcdefg", 5) == "ab..."); } +TEST_CASE("Test starts_with", "[unit-test]") +{ + using clanguml::util::starts_with; + using std::filesystem::path; + + CHECK(starts_with(path{"/a/b/c/d"}, path{"/"})); + CHECK(!starts_with(path{"/a/b/c/d"}, path{"/a/b/c/d/e"})); + CHECK(starts_with(path{"/a/b/c/d/e"}, path{"/a/b/c/d"})); + CHECK(starts_with(path{"/a/b/c/d/e"}, path{"/a/b/c/d/"})); + CHECK(!starts_with(path{"/e/f/c/d/file.h"}, path{"/a/b"})); + CHECK(!starts_with(path{"/e/f/c/d/file.h"}, path{"/a/b/"})); + CHECK(starts_with(path{"/a/b/c/d/file.h"}, path{"/a/b/c"})); + CHECK(starts_with(path{"/a/b/c/file.h"}, path{"/a/b/c/file.h"})); + CHECK(starts_with(path{"c/file.h"}, path{"c"})); + CHECK(starts_with(path{"c/file.h"}, path{"c/"})); +} + TEST_CASE("Test replace_all", "[unit-test]") { using namespace clanguml::util; From 8e8945328eedbbe00cb22b2949157a849bc0bfd1 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 10 Apr 2022 13:33:36 +0200 Subject: [PATCH 04/13] Fixed formatting --- src/common/model/diagram_filter.cc | 1 - src/common/model/diagram_filter.h | 8 +++----- src/common/model/nested_trait.h | 3 +-- src/include_diagram/model/diagram.cc | 4 ++-- src/include_diagram/visitor/translation_unit_visitor.cc | 1 - src/include_diagram/visitor/translation_unit_visitor.h | 6 +++--- src/util/util.cc | 2 +- 7 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/common/model/diagram_filter.cc b/src/common/model/diagram_filter.cc index 000a9cbb..a1232308 100644 --- a/src/common/model/diagram_filter.cc +++ b/src/common/model/diagram_filter.cc @@ -347,7 +347,6 @@ void diagram_filter::init_filters(const config::diagram &c) element_filters.emplace_back(std::make_unique( filter_t::kInclusive, c.include().context)); - inclusive_.emplace_back(std::make_unique( filter_t::kInclusive, std::move(element_filters))); } diff --git a/src/common/model/diagram_filter.h b/src/common/model/diagram_filter.h index b3df613e..f1e3ad96 100644 --- a/src/common/model/diagram_filter.h +++ b/src/common/model/diagram_filter.h @@ -135,8 +135,8 @@ struct paths_filter : public filter_visitor { paths_filter(filter_t type, const std::filesystem::path &root, std::vector p); - tvl::value_t match(const diagram &d, - const common::model::source_file &r) const override; + tvl::value_t match( + const diagram &d, const common::model::source_file &r) const override; private: std::vector paths_; @@ -162,9 +162,7 @@ public: return false; auto inc = tvl::all_of(inclusive_.begin(), inclusive_.end(), - [this, &e](const auto &in) { - return in->match(diagram_, e); - }); + [this, &e](const auto &in) { return in->match(diagram_, e); }); if (tvl::is_undefined(inc) || tvl::is_true(inc)) return true; diff --git a/src/common/model/nested_trait.h b/src/common/model/nested_trait.h index 8f083f39..d79d04b3 100644 --- a/src/common/model/nested_trait.h +++ b/src/common/model/nested_trait.h @@ -52,8 +52,7 @@ public: } template - void add_element( - const Path &path, std::unique_ptr p) + void add_element(const Path &path, std::unique_ptr p) { assert(p); diff --git a/src/include_diagram/model/diagram.cc b/src/include_diagram/model/diagram.cc index 58023d60..77513703 100644 --- a/src/include_diagram/model/diagram.cc +++ b/src/include_diagram/model/diagram.cc @@ -45,8 +45,8 @@ void diagram::add_file(std::unique_ptr &&f) add_element(p, std::move(f)); } -type_safe::optional_ref -diagram::get_file(const std::string &name) const +type_safe::optional_ref diagram::get_file( + const std::string &name) const { for (const auto &p : files_) { if (p.get().full_name(false) == name) { diff --git a/src/include_diagram/visitor/translation_unit_visitor.cc b/src/include_diagram/visitor/translation_unit_visitor.cc index c453b309..c0cc675f 100644 --- a/src/include_diagram/visitor/translation_unit_visitor.cc +++ b/src/include_diagram/visitor/translation_unit_visitor.cc @@ -145,6 +145,5 @@ void translation_unit_visitor::process_file(const std::string &file, ctx.diagram().add_file(std::move(f)); } } - } } diff --git a/src/include_diagram/visitor/translation_unit_visitor.h b/src/include_diagram/visitor/translation_unit_visitor.h index b9347a6f..5b034882 100644 --- a/src/include_diagram/visitor/translation_unit_visitor.h +++ b/src/include_diagram/visitor/translation_unit_visitor.h @@ -17,17 +17,17 @@ */ #pragma once +#include "common/model/enums.h" +#include "common/model/package.h" #include "config/config.h" #include "cx/cursor.h" #include "include_diagram/model/diagram.h" #include "include_diagram/visitor/translation_unit_context.h" -#include "common/model/enums.h" -#include "common/model/package.h" #include #include -#include #include +#include #include #include diff --git a/src/util/util.cc b/src/util/util.cc index 08fc0415..88f108c0 100644 --- a/src/util/util.cc +++ b/src/util/util.cc @@ -202,7 +202,7 @@ template <> bool starts_with( const std::filesystem::path &path, const std::filesystem::path &prefix) { - if(path == prefix) + if (path == prefix) return true; const int path_length = std::distance(std::begin(path), std::end(path)); From 82bda3ed524cf5465d87914cbce78fccc8f4f30e Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 10 Apr 2022 13:36:59 +0200 Subject: [PATCH 05/13] Updated test cases documentation --- docs/test_cases.md | 2 + docs/test_cases/t00002.md | 8 +- docs/test_cases/t00002_class.svg | 228 +++++++++++++++-------------- docs/test_cases/t00003_class.svg | 110 +++++++------- docs/test_cases/t00004_class.svg | 26 ++-- docs/test_cases/t00005_class.svg | 110 +++++++------- docs/test_cases/t00006_class.svg | 132 ++++++++--------- docs/test_cases/t00007_class.svg | 30 ++-- docs/test_cases/t00008_class.svg | 60 ++++---- docs/test_cases/t00009_class.svg | 32 ++-- docs/test_cases/t00010_class.svg | 34 ++--- docs/test_cases/t00011_class.svg | 30 ++-- docs/test_cases/t00012_class.svg | 66 ++++----- docs/test_cases/t00013_class.svg | 112 +++++++------- docs/test_cases/t00014_class.svg | 72 ++++----- docs/test_cases/t00015_class.svg | 22 +-- docs/test_cases/t00016_class.svg | 22 +-- docs/test_cases/t00017_class.svg | 70 ++++----- docs/test_cases/t00018_class.svg | 66 ++++----- docs/test_cases/t00019_class.svg | 84 +++++------ docs/test_cases/t00020_class.svg | 94 ++++++------ docs/test_cases/t00021_class.svg | 82 +++++------ docs/test_cases/t00022_class.svg | 42 +++--- docs/test_cases/t00023_class.svg | 54 +++---- docs/test_cases/t00024_class.svg | 62 ++++---- docs/test_cases/t00025_class.svg | 62 ++++---- docs/test_cases/t00026_class.svg | 78 +++++----- docs/test_cases/t00027_class.svg | 82 +++++------ docs/test_cases/t00028_class.svg | 100 ++++++------- docs/test_cases/t00029_class.svg | 50 +++---- docs/test_cases/t00030_class.svg | 38 ++--- docs/test_cases/t00031_class.svg | 50 +++---- docs/test_cases/t00032_class.svg | 52 +++---- docs/test_cases/t00033_class.svg | 48 +++--- docs/test_cases/t00034_class.svg | 46 +++--- docs/test_cases/t00035_class.svg | 22 +-- docs/test_cases/t00036_class.svg | 38 ++--- docs/test_cases/t00037_class.svg | 42 +++--- docs/test_cases/t00038_class.svg | 54 +++---- docs/test_cases/t00039_class.svg | 54 +++---- docs/test_cases/t00040_class.svg | 38 ++--- docs/test_cases/t00041_class.svg | 50 +++---- docs/test_cases/t30001.md | 5 + docs/test_cases/t30001_package.svg | 100 +++++++------ docs/test_cases/t30002_package.svg | 74 +++++----- docs/test_cases/t30003_package.svg | 26 ++-- docs/test_cases/t30004_package.svg | 42 +++--- docs/test_cases/t30005_package.svg | 38 ++--- docs/test_cases/t30006_package.svg | 22 +-- docs/test_cases/t30007_package.svg | 26 ++-- docs/test_cases/t40001.md | 26 ++++ docs/test_cases/t40001_include.svg | 35 +++++ tests/test_cases.yaml | 4 + 53 files changed, 1522 insertions(+), 1430 deletions(-) create mode 100644 docs/test_cases/t40001.md create mode 100644 docs/test_cases/t40001_include.svg diff --git a/docs/test_cases.md b/docs/test_cases.md index 50a10212..4113a9fd 100644 --- a/docs/test_cases.md +++ b/docs/test_cases.md @@ -51,5 +51,7 @@ * [t30005](./test_cases/t30005.md) - Package namespace alias test case * [t30006](./test_cases/t30006.md) - Package split namespace test case * [t30007](./test_cases/t30007.md) - Package diagram layout hints test case +## Include diagrams + * [t40001](./test_cases/t40001.md) - Basic include graph diagram test case ## Configuration diagrams * [t90000](./test_cases/t90000.md) - Basic config test diff --git a/docs/test_cases/t00002.md b/docs/test_cases/t00002.md index 52b8ecbb..41d0b7b9 100644 --- a/docs/test_cases/t00002.md +++ b/docs/test_cases/t00002.md @@ -15,8 +15,12 @@ diagrams: - clanguml::t00002 plantuml: after: - - 'note left of @A(A) : Base abstract interface.' - + - 'note left of @A(A) : {{ comment("A") }}' + - 'note top of @A(B) : {{ comment("clanguml::t00002::B") }}' + - | + note right of {{ alias("D") }} + {{ comment("D") }} + end note ``` ## Source code File t00002.cc diff --git a/docs/test_cases/t00002_class.svg b/docs/test_cases/t00002_class.svg index 82e7b14d..e88f0fab 100644 --- a/docs/test_cases/t00002_class.svg +++ b/docs/test_cases/t00002_class.svg @@ -1,6 +1,6 @@ - + - + @@ -9,138 +9,146 @@ - - - - - A - - + + + + + A + + - - - + + + - - foo_a() = 0 : void + + foo_a() = 0 : void - - - + + + - - foo_c() = 0 : void + + foo_c() = 0 : void - - - - - B - - + + + + + B + + - - - + + + - - foo_a() : void + + foo_a() : void - - - - - C - - + + + + + C + + - - - + + + - - foo_c() : void + + foo_c() : void - - - - - D - + + + + + D + - - - + + + - - as : std::vector<A*> + + as : std::vector<A*> - - - - + + + + - - foo_a() : void + + foo_a() : void - - - + + + - - foo_c() : void + + foo_c() : void - - - - - E - + + + + + E + - - - + + + - - as : std::vector<A*> + + as : std::vector<A*> - - - - + + + + - - foo_a() : void + + foo_a() : void - - - + + + - - foo_c() : void + + foo_c() : void - - - Base abstract interface. - - - - - - - - as - - - - - - - - as - - - - + + + This is class A + + + This is class B + + + This is class D + which is a little like B + and a little like C + + + + + + + + as + + + + + + + + as + + + + diff --git a/docs/test_cases/t00003_class.svg b/docs/test_cases/t00003_class.svg index 8b07705b..c3699adc 100644 --- a/docs/test_cases/t00003_class.svg +++ b/docs/test_cases/t00003_class.svg @@ -1,6 +1,6 @@ - + @@ -9,194 +9,194 @@ - - + + A - + - + public_member : int - + - + static_int : int - + - + static_const_int : int const - + - + auto_member : unsigned long const - + - + protected_member : int - + - + private_member : int - + - + a : int - + - + b : int - + - + c : int - + - + A() : void - + - + A(int i) : void - + - + A(A&& ) : void - + - + A(A const& ) : void - + - + ~A() : void - + - + basic_method() : void - + - + static_method() : int - + - + const_method() const : void - + - + auto_method() : int - + - + double_int(int const i) : int - + - + sum(double const a, double const b) : double - + - + default_int(int i = 12) : int - + - + default_string(int i, std::string s = "abc") : std::string - + - + create_from_int(int i) : A - + - + protected_method() : void - + - + private_method() : void - + - + compare : std::function<bool(int const)> diff --git a/docs/test_cases/t00004_class.svg b/docs/test_cases/t00004_class.svg index f8195895..acfb62e9 100644 --- a/docs/test_cases/t00004_class.svg +++ b/docs/test_cases/t00004_class.svg @@ -1,6 +1,6 @@ - + @@ -9,38 +9,38 @@ - - + + A - + - + foo() const : void - + - + foo2() const : void - - + + AA - - + + Lights @@ -50,8 +50,8 @@ Red - - + + AAA diff --git a/docs/test_cases/t00005_class.svg b/docs/test_cases/t00005_class.svg index 0f3ddaeb..23192e5d 100644 --- a/docs/test_cases/t00005_class.svg +++ b/docs/test_cases/t00005_class.svg @@ -1,6 +1,6 @@ - + @@ -9,204 +9,204 @@ - - + + A - - + + B - - + + C - - + + D - - + + E - - + + F - - + + G - - + + H - - + + I - - + + J - - + + K - - + + R - + - + some_int : int - + - + some_int_pointer : int* - + - + some_int_pointer_pointer : int** - + - + some_int_reference : int& - + - + a : A - + - + b : B* - + - + c : C& - + - + d : D const* - + - + e : E const& - + - + f : F&& - + - + g : G** - + - + h : H*** - + - + i : I*& - + - + j : J volatile* - + - + k : K* diff --git a/docs/test_cases/t00006_class.svg b/docs/test_cases/t00006_class.svg index 6d655087..e24a7784 100644 --- a/docs/test_cases/t00006_class.svg +++ b/docs/test_cases/t00006_class.svg @@ -1,6 +1,6 @@ - + @@ -9,136 +9,136 @@ - - + + A - - + + B - - + + C - - + + D - - + + E - - + + F - - + + G - - + + H - - + + I - - + + J - - + + K - - + + L - - + + M - - + + N - - + + NN - - + + NNN - - + + custom_container @@ -146,15 +146,15 @@ T - + - + data : std::vector<T> - + custom_container @@ -162,102 +162,102 @@ E - - + + R - + - + a : std::vector<A> - + - + b : std::vector<B*> - + - + c : std::map<int,C> - + - + d : std::map<int,D*> - + - + e : custom_container<E> - + - + f : std::vector<std::vector<F>> - + - + g : std::map<int,std::vector<G*>> - + - + h : std::array<H,10> - + - + i : std::array<I*,5> - + - + j : J[10] - + - + k : K*[20] - + - + lm : std::vector<std::pair<L,M>> - + - + ns : std::tuple<N,NN,NNN> diff --git a/docs/test_cases/t00007_class.svg b/docs/test_cases/t00007_class.svg index f6fa6e5d..8ad67e1b 100644 --- a/docs/test_cases/t00007_class.svg +++ b/docs/test_cases/t00007_class.svg @@ -1,6 +1,6 @@ - + @@ -9,56 +9,56 @@ - - + + A - - + + B - - + + C - - + + R - + - + a : std::unique_ptr<A> - + - + b : std::shared_ptr<B> - + - + c : std::weak_ptr<C> diff --git a/docs/test_cases/t00008_class.svg b/docs/test_cases/t00008_class.svg index 32db5eb7..89876df7 100644 --- a/docs/test_cases/t00008_class.svg +++ b/docs/test_cases/t00008_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + A @@ -18,51 +18,51 @@ T,P,CMP,int N - + - + value : T - + - + pointer : T* - + - + reference : T& - + - + values : std::vector<P> - + - + ints : std::array<int,N> - + - + comparator : CMP - - + + Vector @@ -70,16 +70,16 @@ T - + - + values : std::vector<T> - - + + B @@ -87,15 +87,15 @@ T,C<> - + - + template_template : C<T> - + B @@ -103,26 +103,26 @@ int,Vector - - + + D - + - + ints : B<int,Vector> - + - + add(int i) : void diff --git a/docs/test_cases/t00009_class.svg b/docs/test_cases/t00009_class.svg index 13d224e2..aff8f76b 100644 --- a/docs/test_cases/t00009_class.svg +++ b/docs/test_cases/t00009_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + A @@ -18,15 +18,15 @@ T - + - + value : T - + A @@ -34,7 +34,7 @@ int - + A @@ -42,7 +42,7 @@ std::string - + A @@ -50,32 +50,32 @@ std::vector<std::string> - - + + B - + - + aint : A<int> - + - + astring : A<std::string>* - + - + avector : A<std::vector<std::string>>& diff --git a/docs/test_cases/t00010_class.svg b/docs/test_cases/t00010_class.svg index bbc31508..3cfa3ab2 100644 --- a/docs/test_cases/t00010_class.svg +++ b/docs/test_cases/t00010_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + A @@ -18,22 +18,22 @@ T,P - + - + first : T - + - + second : P - + A @@ -41,8 +41,8 @@ T,std::string - - + + B @@ -50,15 +50,15 @@ T - + - + astring : A<T,std::string> - + B @@ -66,18 +66,18 @@ int - - + + C - + - + aintstring : B<int> diff --git a/docs/test_cases/t00011_class.svg b/docs/test_cases/t00011_class.svg index 78537d30..e5aa388c 100644 --- a/docs/test_cases/t00011_class.svg +++ b/docs/test_cases/t00011_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + D @@ -18,49 +18,49 @@ T - + - + value : T - - + + A - + - + foo() : void - - + + B - + - + m_a : A* - + - + foo() : void diff --git a/docs/test_cases/t00012_class.svg b/docs/test_cases/t00012_class.svg index fcd8a4c2..fbf4bd12 100644 --- a/docs/test_cases/t00012_class.svg +++ b/docs/test_cases/t00012_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + A @@ -18,23 +18,23 @@ T,Ts... - + - + value : T - + - + values : int - - + + B @@ -43,15 +43,15 @@ - + - + ints : std::array<int,sizeof...(Is)> - - + + C @@ -60,14 +60,14 @@ - + - + ints : std::array<T,sizeof...(Is)> - + A @@ -75,7 +75,7 @@ int,std::string,float - + A @@ -83,7 +83,7 @@ int,std::string,bool - + B @@ -91,7 +91,7 @@ 3,2,1 - + B @@ -99,7 +99,7 @@ 1,1,1,1 - + C @@ -107,50 +107,50 @@ std::map<int,std::vector<std::vector<std::vector<std::string>>>>,3,3,3 - - + + R - + - + a1 : A<int,std::string,float> - + - + a2 : A<int,std::string,bool> - + - + b1 : B<3,2,1> - + - + b2 : B<1,1,1,1> - + - + c1 : C<std::map<int,std::vector<std::vector<std::vector<std::string>>>>,3,3,3> - + Long template annotation diff --git a/docs/test_cases/t00013_class.svg b/docs/test_cases/t00013_class.svg index 00d045e5..7762ab1b 100644 --- a/docs/test_cases/t00013_class.svg +++ b/docs/test_cases/t00013_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + ABCD::F @@ -18,83 +18,83 @@ T - + - + f : T - - + + A - + - + a : int - - + + B - + - + b : int - - + + C - + - + c : int - - + + D - + - + d : int - + - + print(R* r) : void - - + + E @@ -102,15 +102,15 @@ T - + - + e : T - + E @@ -118,7 +118,7 @@ int - + F @@ -126,7 +126,7 @@ int - + E @@ -134,96 +134,96 @@ std::string - - + + R - + - + estring : E<std::string> - + - + get_a(A* a) : int - + - + get_b(B& b) : int - + - + get_const_b(B const& b) : int - + - + get_c(C c) : int - + - + get_d(D&& d) : int - + - + get_d2(D&& d) : int - + - + get_e(E<T> e) : T - + - + get_int_e(E<int> const& e) : int - + - + get_int_e2(E<int>& e) : int - + - + get_f(F<T> const& f) : T - + - + get_int_f(F<int> const& f) : int diff --git a/docs/test_cases/t00014_class.svg b/docs/test_cases/t00014_class.svg index d07ffa4b..2cdce411 100644 --- a/docs/test_cases/t00014_class.svg +++ b/docs/test_cases/t00014_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + A @@ -18,22 +18,22 @@ T,P - + - + t : T - + - + p : P - + A @@ -41,22 +41,22 @@ T,std::string - - + + B - + - + value : std::string - + A @@ -64,7 +64,7 @@ bool,std::string - + AString @@ -72,7 +72,7 @@ float - + AString @@ -80,7 +80,7 @@ int - + AString @@ -88,7 +88,7 @@ std::string - + GeneralCallback @@ -96,73 +96,73 @@ AIntString - + GeneralCallback - - + + R - + - + boolstring : A<bool,std::string> - + - + floatstring : AString<float> - + - + intstring : AIntString - + - + stringstring : AStringString - + - + bs : BVector - + - + bs2 : BVector2 - + - + cb : GeneralCallback<AIntString> - + - + vcb : VoidCallback diff --git a/docs/test_cases/t00015_class.svg b/docs/test_cases/t00015_class.svg index 832850d6..b6aa21e6 100644 --- a/docs/test_cases/t00015_class.svg +++ b/docs/test_cases/t00015_class.svg @@ -1,6 +1,6 @@ - + @@ -9,40 +9,40 @@ - - + + ns1::A - - + + ns1::ns2_v0_9_0::A - - + + ns1::Anon - - + + ns3::ns1::ns2::Anon - - + + ns3::B diff --git a/docs/test_cases/t00016_class.svg b/docs/test_cases/t00016_class.svg index 9e19bcdd..b3e52145 100644 --- a/docs/test_cases/t00016_class.svg +++ b/docs/test_cases/t00016_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + is_numeric<> @@ -19,8 +19,8 @@ value : enum - - + + is_numeric @@ -31,8 +31,8 @@ value : enum - - + + is_numeric @@ -43,8 +43,8 @@ value : enum - - + + is_numeric @@ -55,8 +55,8 @@ value : enum - - + + is_numeric diff --git a/docs/test_cases/t00017_class.svg b/docs/test_cases/t00017_class.svg index dbd3e31f..ebd0f21a 100644 --- a/docs/test_cases/t00017_class.svg +++ b/docs/test_cases/t00017_class.svg @@ -1,6 +1,6 @@ - + @@ -9,135 +9,135 @@ - - + + A - - + + B - - + + C - - + + D - - + + E - - + + F - - + + G - - + + H - - + + I - - + + J - - + + K - - + + R - + - + some_int : int - + - + some_int_pointer : int* - + - + some_int_pointer_pointer : int** - + - + some_int_reference : int& - + - + R(int& some_int, C& cc, E const& ee, F&& ff, I*& ii) : void diff --git a/docs/test_cases/t00018_class.svg b/docs/test_cases/t00018_class.svg index cf056069..3f811f31 100644 --- a/docs/test_cases/t00018_class.svg +++ b/docs/test_cases/t00018_class.svg @@ -1,6 +1,6 @@ - + @@ -9,118 +9,118 @@ - - + + impl::widget - + - + n : int - + - + draw(widget const& w) const : void - + - + draw(widget const& w) : void - + - + widget(int n) : void - - + + widget - + - + pImpl : std::unique_ptr<impl::widget> - + - + draw() const : void - + - + draw() : void - + - + shown() const : bool - + - + widget(int ) : void - + - + ~widget() : void - + - + widget(widget&& ) : void - + - + widget(widget const& ) : void - + - + operator=(widget&& ) : widget& - + - + operator=(widget const& ) : widget& diff --git a/docs/test_cases/t00019_class.svg b/docs/test_cases/t00019_class.svg index d2ec0e29..d58b7023 100644 --- a/docs/test_cases/t00019_class.svg +++ b/docs/test_cases/t00019_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + Layer2 @@ -19,51 +19,51 @@ - + - + all_calls_count() const : int - - + + Base - + - + Base() : void - + - + ~Base() : void - + - + m1() : int - + - + m2() : std::string - - + + Layer1 @@ -72,22 +72,22 @@ - + - + m1() : int - + - + m2() : std::string - - + + Layer3 @@ -95,50 +95,50 @@ LowerLayer - + - + m_m1_calls : int - + - + m_m2_calls : int - + - + m1() : int - + - + m2() : std::string - + - + m1_calls() const : int - + - + m2_calls() const : int - + Layer3 @@ -146,7 +146,7 @@ Base - + Layer2 @@ -154,7 +154,7 @@ Layer3<Base> - + Layer1 @@ -162,18 +162,18 @@ Layer2<Layer3<Base>> - - + + A - + - + layers : std::unique_ptr<Layer1<Layer2<Layer3<Base>>>> diff --git a/docs/test_cases/t00020_class.svg b/docs/test_cases/t00020_class.svg index 23d91945..096591f8 100644 --- a/docs/test_cases/t00020_class.svg +++ b/docs/test_cases/t00020_class.svg @@ -1,6 +1,6 @@ - + @@ -9,174 +9,174 @@ - - + + ProductA - + - + ~ProductA() : void - + - + sell(int price) const = 0 : bool - - + + ProductA1 - + - + sell(int price) const : bool - - + + ProductA2 - + - + sell(int price) const : bool - - + + ProductB - + - + ~ProductB() : void - + - + buy(int price) const = 0 : bool - - + + ProductB1 - + - + buy(int price) const : bool - - + + ProductB2 - + - + buy(int price) const : bool - - + + AbstractFactory - + - + make_a() const = 0 : std::unique_ptr<ProductA> - + - + make_b() const = 0 : std::unique_ptr<ProductB> - - + + Factory1 - + - + make_a() const : std::unique_ptr<ProductA> - + - + make_b() const : std::unique_ptr<ProductB> - - + + Factory2 - + - + make_a() const : std::unique_ptr<ProductA> - + - + make_b() const : std::unique_ptr<ProductB> diff --git a/docs/test_cases/t00021_class.svg b/docs/test_cases/t00021_class.svg index 38801577..3f736a44 100644 --- a/docs/test_cases/t00021_class.svg +++ b/docs/test_cases/t00021_class.svg @@ -1,6 +1,6 @@ - + @@ -9,151 +9,151 @@ - - + + Visitor - + - + ~Visitor() : void - + - + visit_A(A const& item) const = 0 : void - + - + visit_B(B const& item) const = 0 : void - - + + Visitor1 - + - + visit_A(A const& item) const : void - + - + visit_B(B const& item) const : void - - + + Visitor2 - + - + visit_A(A const& item) const : void - + - + visit_B(B const& item) const : void - - + + Visitor3 - + - + visit_A(A const& item) const : void - + - + visit_B(B const& item) const : void - - + + Item - + - + ~Item() : void - + - + accept(Visitor const& visitor) const = 0 : void - - + + A - + - + accept(Visitor const& visitor) const : void - - + + B - + - + accept(Visitor const& visitor) const : void diff --git a/docs/test_cases/t00022_class.svg b/docs/test_cases/t00022_class.svg index 451e4c6e..6c871f13 100644 --- a/docs/test_cases/t00022_class.svg +++ b/docs/test_cases/t00022_class.svg @@ -1,6 +1,6 @@ - + @@ -9,77 +9,77 @@ - - + + A - + - + template_method() : void - + - + method1() = 0 : void - + - + method2() = 0 : void - - + + A1 - + - + method1() : void - + - + method2() : void - - + + A2 - + - + method1() : void - + - + method2() : void diff --git a/docs/test_cases/t00023_class.svg b/docs/test_cases/t00023_class.svg index 7c837b84..1bbf4a87 100644 --- a/docs/test_cases/t00023_class.svg +++ b/docs/test_cases/t00023_class.svg @@ -1,6 +1,6 @@ - + @@ -9,100 +9,100 @@ - - + + Strategy - + - + ~Strategy() : void - + - + algorithm() = 0 : void - - + + StrategyA - + - + algorithm() : void - - + + StrategyB - + - + algorithm() : void - - + + StrategyC - + - + algorithm() : void - - + + Context - + - + m_strategy : std::unique_ptr<Strategy> - + - + Context(std::unique_ptr<Strategy> strategy) : void - + - + apply() : void diff --git a/docs/test_cases/t00024_class.svg b/docs/test_cases/t00024_class.svg index 8c7101a2..7f7ca652 100644 --- a/docs/test_cases/t00024_class.svg +++ b/docs/test_cases/t00024_class.svg @@ -1,6 +1,6 @@ - + @@ -9,113 +9,113 @@ - - + + Target - + - + ~Target() : void - + - + m1() = 0 : void - + - + m2() = 0 : void - - + + Target1 - + - + m1() : void - + - + m2() : void - - + + Target2 - + - + m1() : void - + - + m2() : void - - + + Proxy - + - + m_target : std::shared_ptr<Target> - + - + Proxy(std::shared_ptr<Target> target) : void - + - + m1() : void - + - + m2() : void diff --git a/docs/test_cases/t00025_class.svg b/docs/test_cases/t00025_class.svg index 9731d133..7bbf911b 100644 --- a/docs/test_cases/t00025_class.svg +++ b/docs/test_cases/t00025_class.svg @@ -1,6 +1,6 @@ - + @@ -9,52 +9,52 @@ - - + + Target1 - + - + m1() : void - + - + m2() : void - - + + Target2 - + - + m1() : void - + - + m2() : void - - + + Proxy @@ -62,36 +62,36 @@ T - + - + m_target : std::shared_ptr<T> - + - + Proxy(std::shared_ptr<T> target) : void - + - + m1() : void - + - + m2() : void - + Proxy @@ -99,7 +99,7 @@ Target1 - + Proxy @@ -107,25 +107,25 @@ Target2 - - + + ProxyHolder - + - + proxy1 : Proxy<Target1> - + - + proxy2 : Proxy<Target2> diff --git a/docs/test_cases/t00026_class.svg b/docs/test_cases/t00026_class.svg index 4107e405..3bdd4690 100644 --- a/docs/test_cases/t00026_class.svg +++ b/docs/test_cases/t00026_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + Memento @@ -18,30 +18,30 @@ T - + - + m_value : T - + - + Memento(T&& v) : void - + - + value() const : T - - + + Originator @@ -49,51 +49,51 @@ T - + - + m_value : T - + - + Originator(T&& v) : void - + - + memoize_value() const : Memento<T> - + - + load(Memento<T> const& m) : void - + - + print() const : void - + - + set(T&& v) : void - - + + Caretaker @@ -101,29 +101,29 @@ T - + - + m_mementos : std::unordered_map<std::string,Memento<T>> - + - + state(std::string const& n) : Memento<T>& - + - + set_state(std::string const& s, Memento<T>&& m) : void - + Caretaker @@ -131,7 +131,7 @@ std::string - + Originator @@ -139,25 +139,25 @@ std::string - - + + StringMemento - + - + caretaker : Caretaker<std::string> - + - + originator : Originator<std::string> diff --git a/docs/test_cases/t00027_class.svg b/docs/test_cases/t00027_class.svg index 825c00ac..9c561d79 100644 --- a/docs/test_cases/t00027_class.svg +++ b/docs/test_cases/t00027_class.svg @@ -1,6 +1,6 @@ - + @@ -9,30 +9,30 @@ - - + + Shape - + - + display() = 0 : void - + - + ~Shape() : void - - + + Line @@ -41,15 +41,15 @@ - + - + display() : void - - + + Text @@ -58,30 +58,30 @@ - + - + display() : void - - + + ShapeDecorator - + - + display() = 0 : void - - + + Color @@ -90,15 +90,15 @@ - + - + display() : void - - + + Weight @@ -107,14 +107,14 @@ - + - + display() : void - + Line @@ -122,7 +122,7 @@ Color,Weight - + Line @@ -130,7 +130,7 @@ Color - + Text @@ -138,7 +138,7 @@ Color,Weight - + Text @@ -146,39 +146,39 @@ Color - - + + Window - + - + border : Line<Color,Weight> - + - + divider : Line<Color> - + - + title : Text<Color,Weight> - + - + description : Text<Color> diff --git a/docs/test_cases/t00028_class.svg b/docs/test_cases/t00028_class.svg index e6ba4850..eac2feba 100644 --- a/docs/test_cases/t00028_class.svg +++ b/docs/test_cases/t00028_class.svg @@ -1,6 +1,6 @@ - + @@ -9,68 +9,68 @@ - - + + A - + A class note. - + A class note. - - + + B - + B class note. - + B class note. - - + + C - + C class note. - + C class note. - - + + D - + D class note. - + D class note. - - + + E @@ -78,27 +78,27 @@ T - + - + param : T - + E template class note. - - + + G - - + + F @@ -108,13 +108,13 @@ three - + F enum note. - + F enum note. - + E @@ -122,72 +122,72 @@ int - - + + R - + - + aaa : A - + - + bbb : B* - + - + ccc : C& - + - + ddd : std::vector<std::shared_ptr<D>> - + - + eee : E<int> - + - + ggg : G** - + - + R(C& c) : void - + R class note. - + R class note. - - - + + + diff --git a/docs/test_cases/t00029_class.svg b/docs/test_cases/t00029_class.svg index cb589208..c8403d42 100644 --- a/docs/test_cases/t00029_class.svg +++ b/docs/test_cases/t00029_class.svg @@ -1,6 +1,6 @@ - + @@ -9,16 +9,16 @@ - - + + A - - + + C @@ -26,16 +26,16 @@ T - + - + param : T - - + + E @@ -45,64 +45,64 @@ three - - + + G1 - - + + G2 - - + + G3 - - + + G4 - - + + R - + - + g1 : G1 - + - + g3 : G3& - + - + g4 : std::shared_ptr<G4> diff --git a/docs/test_cases/t00030_class.svg b/docs/test_cases/t00030_class.svg index 59a90a82..b59a36c7 100644 --- a/docs/test_cases/t00030_class.svg +++ b/docs/test_cases/t00030_class.svg @@ -1,6 +1,6 @@ - + @@ -9,71 +9,71 @@ - - + + A - - + + B - - + + C - - + + D - - + + R - + - + aaa : A - + - + bbb : std::vector<B> - + - + ccc : std::vector<C> - + - + ddd : D diff --git a/docs/test_cases/t00031_class.svg b/docs/test_cases/t00031_class.svg index 0dba7e6b..0d03efdf 100644 --- a/docs/test_cases/t00031_class.svg +++ b/docs/test_cases/t00031_class.svg @@ -1,33 +1,33 @@ - + - + - + - - - + + + A - - + + B @@ -37,8 +37,8 @@ three - - + + @@ -47,23 +47,23 @@ T - + - + ttt : T - - + + D - + C @@ -71,39 +71,39 @@ int - - + + R - + - + aaa : A* - + - + bbb : std::vector<B> - + - + ccc : C<int> - + - + ddd : D* diff --git a/docs/test_cases/t00032_class.svg b/docs/test_cases/t00032_class.svg index 1a02ffed..ecd85b57 100644 --- a/docs/test_cases/t00032_class.svg +++ b/docs/test_cases/t00032_class.svg @@ -1,6 +1,6 @@ - + @@ -9,69 +9,69 @@ - - + + Base - - + + TBase - - + + A - + - + operator()() : void - - + + B - + - + operator()() : void - - + + C - + - + operator()() : void - - + + Overload @@ -79,15 +79,15 @@ T,L,Ts... - + - + counter : L - + Overload @@ -95,18 +95,18 @@ TBase,int,A,B,C - - + + R - + - + overload : Overload<TBase,int,A,B,C> diff --git a/docs/test_cases/t00033_class.svg b/docs/test_cases/t00033_class.svg index 1fc558ff..d51ce2db 100644 --- a/docs/test_cases/t00033_class.svg +++ b/docs/test_cases/t00033_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + A @@ -18,16 +18,16 @@ T - + - + aaa : T - - + + B @@ -35,16 +35,16 @@ T - + - + bbb : T - - + + C @@ -52,30 +52,30 @@ T - + - + ccc : T - - + + D - + - + ddd : int - + C @@ -83,7 +83,7 @@ D - + B @@ -91,7 +91,7 @@ std::unique_ptr<C<D>> - + A @@ -99,18 +99,18 @@ B<std::unique_ptr<C<D>>> - - + + R - + - + abc : A<B<std::unique_ptr<C<D>>>> diff --git a/docs/test_cases/t00034_class.svg b/docs/test_cases/t00034_class.svg index c30b7c8d..8f10212e 100644 --- a/docs/test_cases/t00034_class.svg +++ b/docs/test_cases/t00034_class.svg @@ -1,6 +1,6 @@ - + @@ -9,30 +9,30 @@ - - + + Void - + - + operator==(Void const& ) const : bool - + - + operator!=(Void const& ) const : bool - - + + lift_void @@ -41,8 +41,8 @@ - - + + lift_void @@ -51,8 +51,8 @@ - - + + drop_void @@ -61,8 +61,8 @@ - - + + drop_void @@ -71,33 +71,33 @@ - - + + A - - + + R - + - + la : lift_void_t<A>* - + - + lv : lift_void_t<void>* diff --git a/docs/test_cases/t00035_class.svg b/docs/test_cases/t00035_class.svg index 69058bc7..0b40c6e1 100644 --- a/docs/test_cases/t00035_class.svg +++ b/docs/test_cases/t00035_class.svg @@ -1,6 +1,6 @@ - + @@ -9,40 +9,40 @@ - - + + Top - - + + Left - - + + Center - - + + Bottom - - + + Right diff --git a/docs/test_cases/t00036_class.svg b/docs/test_cases/t00036_class.svg index 56a28096..9a372d78 100644 --- a/docs/test_cases/t00036_class.svg +++ b/docs/test_cases/t00036_class.svg @@ -1,6 +1,6 @@ - + @@ -9,23 +9,23 @@ - + ns1 - + ns11 - + ns111 - + ns2 - + ns22 - - + + E @@ -34,8 +34,8 @@ yellow - - + + A @@ -43,15 +43,15 @@ T - + - + a : T - + A @@ -59,23 +59,23 @@ int - - + + B - + - + a_int : A<int> - - + + C diff --git a/docs/test_cases/t00037_class.svg b/docs/test_cases/t00037_class.svg index 167ee043..b29f76fe 100644 --- a/docs/test_cases/t00037_class.svg +++ b/docs/test_cases/t00037_class.svg @@ -1,6 +1,6 @@ - + @@ -9,77 +9,77 @@ - - + + ST - + - + dimensions : «anonymous» - - + + <<anonymous>> - + - + t : double - + - + x : double - + - + y : double - + - + z : double - - + + A - + - + st : ST - + - + A() : void diff --git a/docs/test_cases/t00038_class.svg b/docs/test_cases/t00038_class.svg index ed262556..dee7ae25 100644 --- a/docs/test_cases/t00038_class.svg +++ b/docs/test_cases/t00038_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + thirdparty::ns1::color_t @@ -20,16 +20,16 @@ blue - - + + thirdparty::ns1::E - - + + property_t @@ -39,47 +39,47 @@ property_c - - + + A - - + + B - - + + C - - + + key_t - + - + key : std::string - - + + map @@ -88,8 +88,8 @@ - - + + map @@ -98,8 +98,8 @@ - - + + map @@ -108,8 +108,8 @@ - - + + map @@ -118,8 +118,8 @@ - - + + map diff --git a/docs/test_cases/t00039_class.svg b/docs/test_cases/t00039_class.svg index 8117f628..484d5c3d 100644 --- a/docs/test_cases/t00039_class.svg +++ b/docs/test_cases/t00039_class.svg @@ -1,6 +1,6 @@ - + @@ -9,47 +9,47 @@ - - + + A - - + + AA - - + + AAA - + - + b : B* - - + + ns2::AAAA - - + + ns3::F @@ -57,16 +57,16 @@ T - + - + t : T* - - + + ns3::FF @@ -74,16 +74,16 @@ T,M - + - + m : M* - - + + ns3::FE @@ -91,16 +91,16 @@ T,M - + - + m : M* - - + + ns3::FFF @@ -108,11 +108,11 @@ T,M,N - + - + n : N* diff --git a/docs/test_cases/t00040_class.svg b/docs/test_cases/t00040_class.svg index f2f2460c..20167371 100644 --- a/docs/test_cases/t00040_class.svg +++ b/docs/test_cases/t00040_class.svg @@ -1,6 +1,6 @@ - + @@ -9,71 +9,71 @@ - - + + A - + - + ii_ : int - + - + get_a() : int - - + + AA - - + + AAA - + - + b : B* - + - + get_aaa() : int - - + + R - + - + foo(A* a) : void diff --git a/docs/test_cases/t00041_class.svg b/docs/test_cases/t00041_class.svg index e00c3a92..dc6a997c 100644 --- a/docs/test_cases/t00041_class.svg +++ b/docs/test_cases/t00041_class.svg @@ -1,6 +1,6 @@ - + @@ -9,93 +9,93 @@ - - + + R - - + + D - + - + rr : RR* - - + + E - - + + F - - + + RR - + - + e : E* - + - + f : F* - - + + RRR - - + + ns1::N - - + + ns1::NN - - + + ns1::NM diff --git a/docs/test_cases/t30001.md b/docs/test_cases/t30001.md index 531e6265..e99d9129 100644 --- a/docs/test_cases/t30001.md +++ b/docs/test_cases/t30001.md @@ -21,6 +21,9 @@ diagrams: - "' t30001 test package diagram" after: - 'note right of {{ alias("A::AA::AAA") }}: A AAA note...' + - 'note top of {{ alias("A::AA") }} : {{ comment("A::AA") }}' + - 'note top of {{ alias("B::AA") }} : {{ comment("B::AA") }}' + ``` ## Source code File t30001.cc @@ -28,6 +31,7 @@ File t30001.cc namespace clanguml { namespace t30001 { namespace A { +/// This is namespace AA in namespace A namespace AA { namespace AAA { } // namespace AAA @@ -38,6 +42,7 @@ namespace BB { } // namespace BB } // namespace A namespace B { +/// This is namespace AA in namespace B namespace AA { namespace AAA { } // namespace AAA diff --git a/docs/test_cases/t30001_package.svg b/docs/test_cases/t30001_package.svg index 19cfccfc..d9291a8a 100644 --- a/docs/test_cases/t30001_package.svg +++ b/docs/test_cases/t30001_package.svg @@ -1,6 +1,6 @@ - + - + @@ -9,59 +9,67 @@ - - - - A + + + + A - - - - AA + + + + AA - - - - B + + + + B - - - - AA + + + + AA - - - - AAA + + + + AAA - - - - BBB + + + + BBB - - - - BB + + + + BB - - - - AAA + + + + AAA - - - - BBB + + + + BBB - - - - BB + + + + BB - - - A AAA note... - + + + A AAA note... + + + This is namespace AA in namespace A + + + This is namespace AA in namespace B + + + diff --git a/docs/test_cases/t30002_package.svg b/docs/test_cases/t30002_package.svg index 2f90ac61..ebd3e65b 100644 --- a/docs/test_cases/t30002_package.svg +++ b/docs/test_cases/t30002_package.svg @@ -1,6 +1,6 @@ - + @@ -9,93 +9,93 @@ - - + + A - - + + AA - - + + B - - + + BB - - + + A1 - - + + A2 - - + + A3 - - + + A4 - - + + A5 - - + + A6 - - + + A7 - - + + A8 - - + + A9 - - + + A10 - - + + A11 - - + + A12 - - + + A13 - - + + BBB diff --git a/docs/test_cases/t30003_package.svg b/docs/test_cases/t30003_package.svg index abfcdeaa..193d9dcd 100644 --- a/docs/test_cases/t30003_package.svg +++ b/docs/test_cases/t30003_package.svg @@ -1,6 +1,6 @@ - + @@ -9,35 +9,35 @@ - - + + ns1 - - + + ns3 «deprecated» - - + + ns1 - - + + ns2_v1_0_0 - - + + ns2_v0_9_0 «deprecated» - - + + ns2 diff --git a/docs/test_cases/t30004_package.svg b/docs/test_cases/t30004_package.svg index 0a766e61..6fc675bf 100644 --- a/docs/test_cases/t30004_package.svg +++ b/docs/test_cases/t30004_package.svg @@ -1,6 +1,6 @@ - + @@ -9,50 +9,50 @@ - - + + A - + Package AAA. - + Package BBB. - + CCCC package note. - + Another CCC note. - + We skipped DDD. - - + + AAA - - + + BBB - - + + CCC - - + + EEE - - - - - + + + + + diff --git a/docs/test_cases/t30005_package.svg b/docs/test_cases/t30005_package.svg index aefc641c..10ba4e30 100644 --- a/docs/test_cases/t30005_package.svg +++ b/docs/test_cases/t30005_package.svg @@ -1,6 +1,6 @@ - + @@ -9,48 +9,48 @@ - - + + A - - + + AA - - + + B - - + + BB - - + + C - - + + CC - - + + AAA - - + + BBB - - + + CCC diff --git a/docs/test_cases/t30006_package.svg b/docs/test_cases/t30006_package.svg index 7eced5db..b9b75270 100644 --- a/docs/test_cases/t30006_package.svg +++ b/docs/test_cases/t30006_package.svg @@ -1,6 +1,6 @@ - + @@ -9,29 +9,29 @@ - - + + B - - + + A - - + + C - + Top A note. - + Bottom A note. - - + + diff --git a/docs/test_cases/t30007_package.svg b/docs/test_cases/t30007_package.svg index 59f9ad5b..1303f65c 100644 --- a/docs/test_cases/t30007_package.svg +++ b/docs/test_cases/t30007_package.svg @@ -1,6 +1,6 @@ - + @@ -9,34 +9,34 @@ - - + + A - - + + B - - + + AA - - + + C - + Compare layout with t30006. - + Bottom A note. - - + + diff --git a/docs/test_cases/t40001.md b/docs/test_cases/t40001.md new file mode 100644 index 00000000..f3152546 --- /dev/null +++ b/docs/test_cases/t40001.md @@ -0,0 +1,26 @@ +# t40001 - Basic include graph diagram test case +## Config +```yaml +compilation_database_dir: .. +output_directory: puml +diagrams: + t40001_include: + type: include + # Provide the files to parse in order to look + # for #include directives + glob: + - ../../tests/t40001/**/*.cc + - ../../tests/t40001/**/*.h + # Render the paths relative to this directory + relative_to: ../../tests/t40001 + include: + # Include only headers belonging to these paths + paths: + - ../../tests/t40001 + plantuml: + before: + - "' t40001 test include diagram" +``` +## Source code +## Generated UML diagrams +![t40001_include](./t40001_include.svg "Basic include graph diagram test case") diff --git a/docs/test_cases/t40001_include.svg b/docs/test_cases/t40001_include.svg new file mode 100644 index 00000000..59538809 --- /dev/null +++ b/docs/test_cases/t40001_include.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + src + + + include + + + lib1 + + + t40001.cc + + + t40001_include1.h + + + lib1.h + + + + + + diff --git a/tests/test_cases.yaml b/tests/test_cases.yaml index ab6edccd..5713d322 100644 --- a/tests/test_cases.yaml +++ b/tests/test_cases.yaml @@ -149,6 +149,10 @@ test_cases: - name: t30007 title: Package diagram layout hints test case description: + Include diagrams: + - name: t40001 + title: Basic include graph diagram test case + description: Configuration diagrams: - name: t90000 title: Basic config test From 7c8e41a714a639da457919654c1dd1243c4bf150 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 10 Apr 2022 13:43:37 +0200 Subject: [PATCH 06/13] Updated readme with include diagram section --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index 1144e315..b756e0c7 100644 --- a/README.md +++ b/README.md @@ -302,6 +302,26 @@ generates the following diagram (via PlantUML): ![package_diagram_example](docs/test_cases/t30003_package.svg) +### Include diagrams + +#### Example + +The following C++ code structure: + +``` +tests/t40001 +├── include +│ ├── lib1 +│ │ └── lib1.h +│ └── t40001_include1.h +└── src + └── t40001.cc + +``` + +generates the following diagram (via PlantUML) based on include directives in the code: + +![package_diagram_example](docs/test_cases/t40001_include.svg) ### Default mappings @@ -314,6 +334,8 @@ generates the following diagram (via PlantUML): | Composition | ![composition](docs/img/puml_composition.png) | | Template specialization/instantiation | ![specialization](docs/img/puml_instantiation.png) | | Nesting (inner class/enum) | ![nesting](docs/img/puml_nested.png) | +| Include (local) | ![association](docs/img/puml_association.png) | +| Include (system) | ![dependency](docs/img/puml_dependency.png) | ### Diagram content filtering For typical code bases, generating a single diagram from entire code or even a single namespace can be too big to From 1c7edea9ad24fd0420491208ad23a329f38cee61 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 10 Apr 2022 16:18:04 +0200 Subject: [PATCH 07/13] Added alias resolution in include diagrams --- src/include_diagram/model/diagram.cc | 14 +++++++++++++- tests/t40001/.clang-uml | 5 ++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/include_diagram/model/diagram.cc b/src/include_diagram/model/diagram.cc index 77513703..5f1bcf7d 100644 --- a/src/include_diagram/model/diagram.cc +++ b/src/include_diagram/model/diagram.cc @@ -61,7 +61,19 @@ std::string diagram::to_alias(const std::string &full_name) const { LOG_DBG("Looking for alias for {}", full_name); - return full_name; + auto path = common::model::filesystem_path{full_name}; + + if (path.is_empty()) + throw error::uml_alias_missing( + fmt::format("Missing alias for '{}'", path.to_string())); + + auto source_file = get_element(path); + + if (!source_file) + throw error::uml_alias_missing( + fmt::format("Missing alias for '{}'", path.to_string())); + + return source_file.value().alias(); } } diff --git a/tests/t40001/.clang-uml b/tests/t40001/.clang-uml index 6d55f301..660a1e13 100644 --- a/tests/t40001/.clang-uml +++ b/tests/t40001/.clang-uml @@ -16,4 +16,7 @@ diagrams: - ../../tests/t40001 plantuml: before: - - "' t40001 test include diagram" \ No newline at end of file + - "' t40001 test include diagram" + after: + - 'note right of {{ alias("include/lib1") }}: This is a lib1 include dir' + - 'note right of {{ alias("include/t40001_include1.h") }}: This is a t40001_include1.h include file' \ No newline at end of file From 49874df5331d19a8836a4b7cb136790ac0c64d3f Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 10 Apr 2022 21:24:36 +0200 Subject: [PATCH 08/13] Added include diagram hyperlink generation --- src/common/generators/plantuml/generator.h | 11 ++++++----- src/common/model/element.h | 1 - src/common/model/source_file.h | 2 ++ .../plantuml/include_diagram_generator.cc | 13 ++++++++++--- .../visitor/translation_unit_visitor.cc | 5 +++++ 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/common/generators/plantuml/generator.h b/src/common/generators/plantuml/generator.h index c8556aa1..fac0f8d3 100644 --- a/src/common/generators/plantuml/generator.h +++ b/src/common/generators/plantuml/generator.h @@ -64,7 +64,8 @@ public: void generate_notes( std::ostream &ostr, const model::element &element) const; - void generate_link(std::ostream &ostr, const model::element &e) const; + template + void generate_link(std::ostream &ostr, const E &e) const; protected: const inja::json &context() const; @@ -114,9 +115,9 @@ inja::json generator::element_context(const E &e) const if (!e.file().empty()) { std::filesystem::path file{e.file()}; - std::string relative_path = std::filesystem::relative(file); + std::string relative_path = file.string(); - if (ctx.template contains("git")) + if (file.is_absolute() && ctx.template contains("git")) relative_path = std::filesystem::relative(file, ctx["git"]["toplevel"]); @@ -200,8 +201,8 @@ void generator::generate_notes( } template -void generator::generate_link( - std::ostream &ostr, const model::element &e) const +template +void generator::generate_link(std::ostream &ostr, const E &e) const { if (e.file().empty()) return; diff --git a/src/common/model/element.h b/src/common/model/element.h index 881460bd..4fda5918 100644 --- a/src/common/model/element.h +++ b/src/common/model/element.h @@ -73,6 +73,5 @@ public: private: namespace_ ns_; namespace_ using_namespace_; - // type_safe::optional location_; }; } diff --git a/src/common/model/source_file.h b/src/common/model/source_file.h index 99a2f1c7..47ad6629 100644 --- a/src/common/model/source_file.h +++ b/src/common/model/source_file.h @@ -20,6 +20,7 @@ #include "common/model/diagram_element.h" #include "common/model/nested_trait.h" #include "common/model/path.h" +#include "common/model/source_location.h" #include "common/model/stylable_element.h" #include "util/util.h" @@ -43,6 +44,7 @@ using filesystem_path = common::model::path; class source_file : public common::model::diagram_element, public common::model::stylable_element, + public source_location, public common::model::nested_trait { public: diff --git a/src/include_diagram/generators/plantuml/include_diagram_generator.cc b/src/include_diagram/generators/plantuml/include_diagram_generator.cc index cf696df9..91e7c3df 100644 --- a/src/include_diagram/generators/plantuml/include_diagram_generator.cc +++ b/src/include_diagram/generators/plantuml/include_diagram_generator.cc @@ -1,5 +1,5 @@ /** - * src/package_diagram/generators/plantuml/package_diagram_generator.cc + * src/include_diagram/generators/plantuml/include_diagram_generator.cc * * Copyright (c) 2021-2022 Bartek Kryza * @@ -57,14 +57,21 @@ void generator::generate(const source_file &f, std::ostream &ostr) const if (f.type() == common::model::source_file_t::kDirectory) { ostr << "folder " << f.name(); - ostr << " as " << f.alias() << " {\n"; + ostr << " as " << f.alias(); + ostr << " {\n"; for (const auto &file : f) { generate(dynamic_cast(*file), ostr); } ostr << "}" << '\n'; } else { - ostr << "file " << f.name() << " as " << f.alias() << '\n'; + ostr << "file " << f.name() << " as " << f.alias(); + + if (m_config.generate_links) { + generate_link(ostr, f); + } + + ostr << '\n'; } } diff --git a/src/include_diagram/visitor/translation_unit_visitor.cc b/src/include_diagram/visitor/translation_unit_visitor.cc index c0cc675f..f91cdd28 100644 --- a/src/include_diagram/visitor/translation_unit_visitor.cc +++ b/src/include_diagram/visitor/translation_unit_visitor.cc @@ -77,6 +77,7 @@ void translation_unit_visitor::process_file(const std::string &file, include_path = include_path.lexically_normal(); + std::string full_file_path = include_path; auto f_abs = std::make_unique(); if (include_path.is_absolute()) @@ -138,6 +139,10 @@ void translation_unit_visitor::process_file(const std::string &file, ctx.get_current_file().value().add_relationship( common::model::relationship{relationship_type, f->alias()}); + + auto fp = std::filesystem::absolute(file).lexically_normal(); + f->set_file(fp.string()); + f->set_line(0); } if (!ctx.diagram().get_element(f->path() | f->name()).has_value()) { From c033879b016d6811fcbdec6d3cf9407c4fc2e640 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 10 Apr 2022 22:42:57 +0200 Subject: [PATCH 09/13] Added cyclic dependency include diagram test case --- .../visitor/translation_unit_visitor.cc | 21 +++++--- tests/t40002/.clang-uml | 19 +++++++ tests/t40002/include/lib1/lib1.h | 13 +++++ tests/t40002/include/lib2/lib2.h | 13 +++++ tests/t40002/src/lib1/lib1.cc | 11 ++++ tests/t40002/src/lib2/lib2.cc | 11 ++++ tests/t40002/src/t40002.cc | 8 +++ tests/t40002/test_case.h | 53 +++++++++++++++++++ tests/test_cases.cc | 1 + tests/test_cases.yaml | 3 ++ 10 files changed, 146 insertions(+), 7 deletions(-) create mode 100644 tests/t40002/.clang-uml create mode 100644 tests/t40002/include/lib1/lib1.h create mode 100644 tests/t40002/include/lib2/lib2.h create mode 100644 tests/t40002/src/lib1/lib1.cc create mode 100644 tests/t40002/src/lib2/lib2.cc create mode 100644 tests/t40002/src/t40002.cc create mode 100644 tests/t40002/test_case.h diff --git a/src/include_diagram/visitor/translation_unit_visitor.cc b/src/include_diagram/visitor/translation_unit_visitor.cc index f91cdd28..4037900b 100644 --- a/src/include_diagram/visitor/translation_unit_visitor.cc +++ b/src/include_diagram/visitor/translation_unit_visitor.cc @@ -130,6 +130,15 @@ void translation_unit_visitor::process_file(const std::string &file, } } + auto diagram_file_path = f->path() | f->name(); + + if (!ctx.diagram().get_element(diagram_file_path).has_value()) { + ctx.diagram().add_file(std::move(f)); + } + + auto &diagram_source_file = + ctx.diagram().get_element(diagram_file_path).value(); + if (!register_as_current) { auto relationship_type = common::model::relationship_t::kAssociation; @@ -138,17 +147,15 @@ void translation_unit_visitor::process_file(const std::string &file, relationship_type = common::model::relationship_t::kDependency; ctx.get_current_file().value().add_relationship( - common::model::relationship{relationship_type, f->alias()}); + common::model::relationship{ + relationship_type, diagram_source_file.alias()}); auto fp = std::filesystem::absolute(file).lexically_normal(); - f->set_file(fp.string()); - f->set_line(0); + diagram_source_file.set_file(fp.string()); + diagram_source_file.set_line(0); } - if (!ctx.diagram().get_element(f->path() | f->name()).has_value()) { - ctx.set_current_file(type_safe::opt_ref(*f)); - ctx.diagram().add_file(std::move(f)); - } + ctx.set_current_file(type_safe::opt_ref(diagram_source_file)); } } } diff --git a/tests/t40002/.clang-uml b/tests/t40002/.clang-uml new file mode 100644 index 00000000..accff299 --- /dev/null +++ b/tests/t40002/.clang-uml @@ -0,0 +1,19 @@ +compilation_database_dir: .. +output_directory: puml +diagrams: + t40002_include: + type: include + # Provide the files to parse in order to look + # for #include directives + glob: + - ../../tests/t40002/**/*.cc + - ../../tests/t40002/**/*.h + # Render the paths relative to this directory + relative_to: ../../tests/t40002 + include: + # Include only files belonging to these paths + paths: + - ../../tests/t40002 + plantuml: + before: + - "' t40002 test include diagram" \ No newline at end of file diff --git a/tests/t40002/include/lib1/lib1.h b/tests/t40002/include/lib1/lib1.h new file mode 100644 index 00000000..250e3389 --- /dev/null +++ b/tests/t40002/include/lib1/lib1.h @@ -0,0 +1,13 @@ +#pragma once + +#include "../lib2/lib2.h" + +namespace clanguml::t40002::lib1 { + +int foo0(); + +int foo1(); + +int foo(); + +} \ No newline at end of file diff --git a/tests/t40002/include/lib2/lib2.h b/tests/t40002/include/lib2/lib2.h new file mode 100644 index 00000000..dc7b5dba --- /dev/null +++ b/tests/t40002/include/lib2/lib2.h @@ -0,0 +1,13 @@ +#pragma once + +#include "../lib1/lib1.h" + +namespace clanguml::t40002::lib2 { + +int foo2(); + +int foo3(); + +int foo(); + +} \ No newline at end of file diff --git a/tests/t40002/src/lib1/lib1.cc b/tests/t40002/src/lib1/lib1.cc new file mode 100644 index 00000000..de88c7b5 --- /dev/null +++ b/tests/t40002/src/lib1/lib1.cc @@ -0,0 +1,11 @@ +#include "../../include/lib1/lib1.h" + +namespace clanguml::t40002::lib1 { + +int foo0() { return 0; } + +int foo1() { return 1; } + +int foo() { return foo1(); } + +} \ No newline at end of file diff --git a/tests/t40002/src/lib2/lib2.cc b/tests/t40002/src/lib2/lib2.cc new file mode 100644 index 00000000..a4d06231 --- /dev/null +++ b/tests/t40002/src/lib2/lib2.cc @@ -0,0 +1,11 @@ +#include "../../include/lib2/lib2.h" + +namespace clanguml::t40002::lib2 { + +int foo0() { return 0; } + +int foo1() { return 1; } + +int foo() { return foo1(); } + +} \ No newline at end of file diff --git a/tests/t40002/src/t40002.cc b/tests/t40002/src/t40002.cc new file mode 100644 index 00000000..7ea55fc8 --- /dev/null +++ b/tests/t40002/src/t40002.cc @@ -0,0 +1,8 @@ +#include "../include/lib1/lib1.h" +#include "../include/lib2/lib2.h" + +namespace clanguml::t40002 { + +int foo() { return lib1::foo() + lib2::foo(); } + +} \ No newline at end of file diff --git a/tests/t40002/test_case.h b/tests/t40002/test_case.h new file mode 100644 index 00000000..ef752157 --- /dev/null +++ b/tests/t40002/test_case.h @@ -0,0 +1,53 @@ +/** + * tests/t40002/test_case.cc + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +TEST_CASE("t40002", "[test-case][package]") +{ + auto [config, db] = load_config("t40002"); + + auto diagram = config.diagrams["t40002_include"]; + + REQUIRE(diagram->name == "t40002_include"); + + auto model = generate_include_diagram(db, diagram); + + REQUIRE(model->name() == "t40002_include"); + + auto puml = generate_include_puml(diagram, *model); + + AliasMatcher _A(puml); + + REQUIRE_THAT(puml, StartsWith("@startuml")); + REQUIRE_THAT(puml, EndsWith("@enduml\n")); + + REQUIRE_THAT(puml, IsFolder("lib1")); + REQUIRE_THAT(puml, IsFolder("lib2")); + REQUIRE_THAT(puml, IsFile("lib1.h")); + REQUIRE_THAT(puml, IsFile("lib2.h")); + REQUIRE_THAT(puml, IsFile("t40002.cc")); + REQUIRE_THAT(puml, IsFile("lib1.cc")); + REQUIRE_THAT(puml, IsFile("lib2.cc")); + + REQUIRE_THAT(puml, IsAssociation(_A("t40002.cc"), _A("lib1.h"))); + REQUIRE_THAT(puml, IsAssociation(_A("lib1.h"), _A("lib2.h"))); + REQUIRE_THAT(puml, IsAssociation(_A("lib1.cc"), _A("lib1.h"))); + REQUIRE_THAT(puml, IsAssociation(_A("lib2.cc"), _A("lib2.h"))); + + save_puml( + "./" + config.output_directory() + "/" + diagram->name + ".puml", puml); +} diff --git a/tests/test_cases.cc b/tests/test_cases.cc index 422c806b..2a88894e 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -256,6 +256,7 @@ using namespace clanguml::test::matchers; // Include diagram tests // #include "t40001/test_case.h" +#include "t40002/test_case.h" // // Other tests (e.g. configuration file) diff --git a/tests/test_cases.yaml b/tests/test_cases.yaml index 5713d322..08962477 100644 --- a/tests/test_cases.yaml +++ b/tests/test_cases.yaml @@ -153,6 +153,9 @@ test_cases: - name: t40001 title: Basic include graph diagram test case description: + - name: t40002 + title: Cyclic include graph diagram test case + description: Configuration diagrams: - name: t90000 title: Basic config test From 3ed26ab6bb157658d5b0a3576d5836ef2fabe039 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 10 Apr 2022 22:48:16 +0200 Subject: [PATCH 10/13] Updated test cases documentation --- docs/test_cases.md | 1 + docs/test_cases/t00002_class.svg | 68 +++++++-------- docs/test_cases/t00003_class.svg | 110 ++++++++++++------------ docs/test_cases/t00004_class.svg | 26 +++--- docs/test_cases/t00005_class.svg | 110 ++++++++++++------------ docs/test_cases/t00006_class.svg | 132 ++++++++++++++--------------- docs/test_cases/t00007_class.svg | 30 +++---- docs/test_cases/t00008_class.svg | 60 ++++++------- docs/test_cases/t00009_class.svg | 32 +++---- docs/test_cases/t00010_class.svg | 34 ++++---- docs/test_cases/t00011_class.svg | 30 +++---- docs/test_cases/t00012_class.svg | 66 +++++++-------- docs/test_cases/t00013_class.svg | 112 ++++++++++++------------ docs/test_cases/t00014_class.svg | 72 ++++++++-------- docs/test_cases/t00015_class.svg | 22 ++--- docs/test_cases/t00016_class.svg | 22 ++--- docs/test_cases/t00017_class.svg | 70 +++++++-------- docs/test_cases/t00018_class.svg | 66 +++++++-------- docs/test_cases/t00019_class.svg | 84 +++++++++--------- docs/test_cases/t00020_class.svg | 94 ++++++++++---------- docs/test_cases/t00021_class.svg | 82 +++++++++--------- docs/test_cases/t00022_class.svg | 42 ++++----- docs/test_cases/t00023_class.svg | 54 ++++++------ docs/test_cases/t00024_class.svg | 62 +++++++------- docs/test_cases/t00025_class.svg | 62 +++++++------- docs/test_cases/t00026_class.svg | 78 ++++++++--------- docs/test_cases/t00027_class.svg | 82 +++++++++--------- docs/test_cases/t00028_class.svg | 94 ++++++++++---------- docs/test_cases/t00029_class.svg | 50 +++++------ docs/test_cases/t00030_class.svg | 38 ++++----- docs/test_cases/t00031_class.svg | 50 +++++------ docs/test_cases/t00032_class.svg | 52 ++++++------ docs/test_cases/t00033_class.svg | 48 +++++------ docs/test_cases/t00034_class.svg | 46 +++++----- docs/test_cases/t00035_class.svg | 22 ++--- docs/test_cases/t00036_class.svg | 38 ++++----- docs/test_cases/t00037_class.svg | 42 ++++----- docs/test_cases/t00038_class.svg | 54 ++++++------ docs/test_cases/t00039_class.svg | 54 ++++++------ docs/test_cases/t00040_class.svg | 38 ++++----- docs/test_cases/t00041_class.svg | 50 +++++------ docs/test_cases/t30001_package.svg | 48 +++++------ docs/test_cases/t30002_package.svg | 74 ++++++++-------- docs/test_cases/t30003_package.svg | 26 +++--- docs/test_cases/t30004_package.svg | 32 +++---- docs/test_cases/t30005_package.svg | 38 ++++----- docs/test_cases/t30006_package.svg | 18 ++-- docs/test_cases/t30007_package.svg | 22 ++--- docs/test_cases/t40001.md | 3 + docs/test_cases/t40001_include.svg | 55 +++++++----- docs/test_cases/t40002.md | 26 ++++++ docs/test_cases/t40002_include.svg | 58 +++++++++++++ 52 files changed, 1439 insertions(+), 1340 deletions(-) create mode 100644 docs/test_cases/t40002.md create mode 100644 docs/test_cases/t40002_include.svg diff --git a/docs/test_cases.md b/docs/test_cases.md index 4113a9fd..6ca3d4c1 100644 --- a/docs/test_cases.md +++ b/docs/test_cases.md @@ -53,5 +53,6 @@ * [t30007](./test_cases/t30007.md) - Package diagram layout hints test case ## Include diagrams * [t40001](./test_cases/t40001.md) - Basic include graph diagram test case + * [t40002](./test_cases/t40002.md) - Cyclic include graph diagram test case ## Configuration diagrams * [t90000](./test_cases/t90000.md) - Basic config test diff --git a/docs/test_cases/t00002_class.svg b/docs/test_cases/t00002_class.svg index e88f0fab..49b0ce8f 100644 --- a/docs/test_cases/t00002_class.svg +++ b/docs/test_cases/t00002_class.svg @@ -1,6 +1,6 @@ - + @@ -9,123 +9,123 @@ - - + + A - + - + foo_a() = 0 : void - + - + foo_c() = 0 : void - - + + B - + - + foo_a() : void - - + + C - + - + foo_c() : void - - + + D - + - + as : std::vector<A*> - + - + foo_a() : void - + - + foo_c() : void - - + + E - + - + as : std::vector<A*> - + - + foo_a() : void - + - + foo_c() : void - + This is class A - + This is class B - + This is class D which is a little like B diff --git a/docs/test_cases/t00003_class.svg b/docs/test_cases/t00003_class.svg index c3699adc..7554acd7 100644 --- a/docs/test_cases/t00003_class.svg +++ b/docs/test_cases/t00003_class.svg @@ -1,6 +1,6 @@ - + @@ -9,194 +9,194 @@ - - + + A - + - + public_member : int - + - + static_int : int - + - + static_const_int : int const - + - + auto_member : unsigned long const - + - + protected_member : int - + - + private_member : int - + - + a : int - + - + b : int - + - + c : int - + - + A() : void - + - + A(int i) : void - + - + A(A&& ) : void - + - + A(A const& ) : void - + - + ~A() : void - + - + basic_method() : void - + - + static_method() : int - + - + const_method() const : void - + - + auto_method() : int - + - + double_int(int const i) : int - + - + sum(double const a, double const b) : double - + - + default_int(int i = 12) : int - + - + default_string(int i, std::string s = "abc") : std::string - + - + create_from_int(int i) : A - + - + protected_method() : void - + - + private_method() : void - + - + compare : std::function<bool(int const)> diff --git a/docs/test_cases/t00004_class.svg b/docs/test_cases/t00004_class.svg index acfb62e9..a83a7612 100644 --- a/docs/test_cases/t00004_class.svg +++ b/docs/test_cases/t00004_class.svg @@ -1,6 +1,6 @@ - + @@ -9,38 +9,38 @@ - - + + A - + - + foo() const : void - + - + foo2() const : void - - + + AA - - + + Lights @@ -50,8 +50,8 @@ Red - - + + AAA diff --git a/docs/test_cases/t00005_class.svg b/docs/test_cases/t00005_class.svg index 23192e5d..7a135c13 100644 --- a/docs/test_cases/t00005_class.svg +++ b/docs/test_cases/t00005_class.svg @@ -1,6 +1,6 @@ - + @@ -9,204 +9,204 @@ - - + + A - - + + B - - + + C - - + + D - - + + E - - + + F - - + + G - - + + H - - + + I - - + + J - - + + K - - + + R - + - + some_int : int - + - + some_int_pointer : int* - + - + some_int_pointer_pointer : int** - + - + some_int_reference : int& - + - + a : A - + - + b : B* - + - + c : C& - + - + d : D const* - + - + e : E const& - + - + f : F&& - + - + g : G** - + - + h : H*** - + - + i : I*& - + - + j : J volatile* - + - + k : K* diff --git a/docs/test_cases/t00006_class.svg b/docs/test_cases/t00006_class.svg index e24a7784..d2866b4b 100644 --- a/docs/test_cases/t00006_class.svg +++ b/docs/test_cases/t00006_class.svg @@ -1,6 +1,6 @@ - + @@ -9,136 +9,136 @@ - - + + A - - + + B - - + + C - - + + D - - + + E - - + + F - - + + G - - + + H - - + + I - - + + J - - + + K - - + + L - - + + M - - + + N - - + + NN - - + + NNN - - + + custom_container @@ -146,15 +146,15 @@ T - + - + data : std::vector<T> - + custom_container @@ -162,102 +162,102 @@ E - - + + R - + - + a : std::vector<A> - + - + b : std::vector<B*> - + - + c : std::map<int,C> - + - + d : std::map<int,D*> - + - + e : custom_container<E> - + - + f : std::vector<std::vector<F>> - + - + g : std::map<int,std::vector<G*>> - + - + h : std::array<H,10> - + - + i : std::array<I*,5> - + - + j : J[10] - + - + k : K*[20] - + - + lm : std::vector<std::pair<L,M>> - + - + ns : std::tuple<N,NN,NNN> diff --git a/docs/test_cases/t00007_class.svg b/docs/test_cases/t00007_class.svg index 8ad67e1b..e02c056e 100644 --- a/docs/test_cases/t00007_class.svg +++ b/docs/test_cases/t00007_class.svg @@ -1,6 +1,6 @@ - + @@ -9,56 +9,56 @@ - - + + A - - + + B - - + + C - - + + R - + - + a : std::unique_ptr<A> - + - + b : std::shared_ptr<B> - + - + c : std::weak_ptr<C> diff --git a/docs/test_cases/t00008_class.svg b/docs/test_cases/t00008_class.svg index 89876df7..d607c545 100644 --- a/docs/test_cases/t00008_class.svg +++ b/docs/test_cases/t00008_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + A @@ -18,51 +18,51 @@ T,P,CMP,int N - + - + value : T - + - + pointer : T* - + - + reference : T& - + - + values : std::vector<P> - + - + ints : std::array<int,N> - + - + comparator : CMP - - + + Vector @@ -70,16 +70,16 @@ T - + - + values : std::vector<T> - - + + B @@ -87,15 +87,15 @@ T,C<> - + - + template_template : C<T> - + B @@ -103,26 +103,26 @@ int,Vector - - + + D - + - + ints : B<int,Vector> - + - + add(int i) : void diff --git a/docs/test_cases/t00009_class.svg b/docs/test_cases/t00009_class.svg index aff8f76b..61511c6a 100644 --- a/docs/test_cases/t00009_class.svg +++ b/docs/test_cases/t00009_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + A @@ -18,15 +18,15 @@ T - + - + value : T - + A @@ -34,7 +34,7 @@ int - + A @@ -42,7 +42,7 @@ std::string - + A @@ -50,32 +50,32 @@ std::vector<std::string> - - + + B - + - + aint : A<int> - + - + astring : A<std::string>* - + - + avector : A<std::vector<std::string>>& diff --git a/docs/test_cases/t00010_class.svg b/docs/test_cases/t00010_class.svg index 3cfa3ab2..6cc22cc2 100644 --- a/docs/test_cases/t00010_class.svg +++ b/docs/test_cases/t00010_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + A @@ -18,22 +18,22 @@ T,P - + - + first : T - + - + second : P - + A @@ -41,8 +41,8 @@ T,std::string - - + + B @@ -50,15 +50,15 @@ T - + - + astring : A<T,std::string> - + B @@ -66,18 +66,18 @@ int - - + + C - + - + aintstring : B<int> diff --git a/docs/test_cases/t00011_class.svg b/docs/test_cases/t00011_class.svg index e5aa388c..2cdcf0cd 100644 --- a/docs/test_cases/t00011_class.svg +++ b/docs/test_cases/t00011_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + D @@ -18,49 +18,49 @@ T - + - + value : T - - + + A - + - + foo() : void - - + + B - + - + m_a : A* - + - + foo() : void diff --git a/docs/test_cases/t00012_class.svg b/docs/test_cases/t00012_class.svg index fbf4bd12..3e6de596 100644 --- a/docs/test_cases/t00012_class.svg +++ b/docs/test_cases/t00012_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + A @@ -18,23 +18,23 @@ T,Ts... - + - + value : T - + - + values : int - - + + B @@ -43,15 +43,15 @@ - + - + ints : std::array<int,sizeof...(Is)> - - + + C @@ -60,14 +60,14 @@ - + - + ints : std::array<T,sizeof...(Is)> - + A @@ -75,7 +75,7 @@ int,std::string,float - + A @@ -83,7 +83,7 @@ int,std::string,bool - + B @@ -91,7 +91,7 @@ 3,2,1 - + B @@ -99,7 +99,7 @@ 1,1,1,1 - + C @@ -107,50 +107,50 @@ std::map<int,std::vector<std::vector<std::vector<std::string>>>>,3,3,3 - - + + R - + - + a1 : A<int,std::string,float> - + - + a2 : A<int,std::string,bool> - + - + b1 : B<3,2,1> - + - + b2 : B<1,1,1,1> - + - + c1 : C<std::map<int,std::vector<std::vector<std::vector<std::string>>>>,3,3,3> - + Long template annotation diff --git a/docs/test_cases/t00013_class.svg b/docs/test_cases/t00013_class.svg index 7762ab1b..a3948085 100644 --- a/docs/test_cases/t00013_class.svg +++ b/docs/test_cases/t00013_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + ABCD::F @@ -18,83 +18,83 @@ T - + - + f : T - - + + A - + - + a : int - - + + B - + - + b : int - - + + C - + - + c : int - - + + D - + - + d : int - + - + print(R* r) : void - - + + E @@ -102,15 +102,15 @@ T - + - + e : T - + E @@ -118,7 +118,7 @@ int - + F @@ -126,7 +126,7 @@ int - + E @@ -134,96 +134,96 @@ std::string - - + + R - + - + estring : E<std::string> - + - + get_a(A* a) : int - + - + get_b(B& b) : int - + - + get_const_b(B const& b) : int - + - + get_c(C c) : int - + - + get_d(D&& d) : int - + - + get_d2(D&& d) : int - + - + get_e(E<T> e) : T - + - + get_int_e(E<int> const& e) : int - + - + get_int_e2(E<int>& e) : int - + - + get_f(F<T> const& f) : T - + - + get_int_f(F<int> const& f) : int diff --git a/docs/test_cases/t00014_class.svg b/docs/test_cases/t00014_class.svg index 2cdce411..f89aaf70 100644 --- a/docs/test_cases/t00014_class.svg +++ b/docs/test_cases/t00014_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + A @@ -18,22 +18,22 @@ T,P - + - + t : T - + - + p : P - + A @@ -41,22 +41,22 @@ T,std::string - - + + B - + - + value : std::string - + A @@ -64,7 +64,7 @@ bool,std::string - + AString @@ -72,7 +72,7 @@ float - + AString @@ -80,7 +80,7 @@ int - + AString @@ -88,7 +88,7 @@ std::string - + GeneralCallback @@ -96,73 +96,73 @@ AIntString - + GeneralCallback - - + + R - + - + boolstring : A<bool,std::string> - + - + floatstring : AString<float> - + - + intstring : AIntString - + - + stringstring : AStringString - + - + bs : BVector - + - + bs2 : BVector2 - + - + cb : GeneralCallback<AIntString> - + - + vcb : VoidCallback diff --git a/docs/test_cases/t00015_class.svg b/docs/test_cases/t00015_class.svg index b6aa21e6..b5a7d970 100644 --- a/docs/test_cases/t00015_class.svg +++ b/docs/test_cases/t00015_class.svg @@ -1,6 +1,6 @@ - + @@ -9,40 +9,40 @@ - - + + ns1::A - - + + ns1::ns2_v0_9_0::A - - + + ns1::Anon - - + + ns3::ns1::ns2::Anon - - + + ns3::B diff --git a/docs/test_cases/t00016_class.svg b/docs/test_cases/t00016_class.svg index b3e52145..ff382a18 100644 --- a/docs/test_cases/t00016_class.svg +++ b/docs/test_cases/t00016_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + is_numeric<> @@ -19,8 +19,8 @@ value : enum - - + + is_numeric @@ -31,8 +31,8 @@ value : enum - - + + is_numeric @@ -43,8 +43,8 @@ value : enum - - + + is_numeric @@ -55,8 +55,8 @@ value : enum - - + + is_numeric diff --git a/docs/test_cases/t00017_class.svg b/docs/test_cases/t00017_class.svg index ebd0f21a..fd70a53d 100644 --- a/docs/test_cases/t00017_class.svg +++ b/docs/test_cases/t00017_class.svg @@ -1,6 +1,6 @@ - + @@ -9,135 +9,135 @@ - - + + A - - + + B - - + + C - - + + D - - + + E - - + + F - - + + G - - + + H - - + + I - - + + J - - + + K - - + + R - + - + some_int : int - + - + some_int_pointer : int* - + - + some_int_pointer_pointer : int** - + - + some_int_reference : int& - + - + R(int& some_int, C& cc, E const& ee, F&& ff, I*& ii) : void diff --git a/docs/test_cases/t00018_class.svg b/docs/test_cases/t00018_class.svg index 3f811f31..6545709f 100644 --- a/docs/test_cases/t00018_class.svg +++ b/docs/test_cases/t00018_class.svg @@ -1,6 +1,6 @@ - + @@ -9,118 +9,118 @@ - - + + impl::widget - + - + n : int - + - + draw(widget const& w) const : void - + - + draw(widget const& w) : void - + - + widget(int n) : void - - + + widget - + - + pImpl : std::unique_ptr<impl::widget> - + - + draw() const : void - + - + draw() : void - + - + shown() const : bool - + - + widget(int ) : void - + - + ~widget() : void - + - + widget(widget&& ) : void - + - + widget(widget const& ) : void - + - + operator=(widget&& ) : widget& - + - + operator=(widget const& ) : widget& diff --git a/docs/test_cases/t00019_class.svg b/docs/test_cases/t00019_class.svg index d58b7023..c5a5eba9 100644 --- a/docs/test_cases/t00019_class.svg +++ b/docs/test_cases/t00019_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + Layer2 @@ -19,51 +19,51 @@ - + - + all_calls_count() const : int - - + + Base - + - + Base() : void - + - + ~Base() : void - + - + m1() : int - + - + m2() : std::string - - + + Layer1 @@ -72,22 +72,22 @@ - + - + m1() : int - + - + m2() : std::string - - + + Layer3 @@ -95,50 +95,50 @@ LowerLayer - + - + m_m1_calls : int - + - + m_m2_calls : int - + - + m1() : int - + - + m2() : std::string - + - + m1_calls() const : int - + - + m2_calls() const : int - + Layer3 @@ -146,7 +146,7 @@ Base - + Layer2 @@ -154,7 +154,7 @@ Layer3<Base> - + Layer1 @@ -162,18 +162,18 @@ Layer2<Layer3<Base>> - - + + A - + - + layers : std::unique_ptr<Layer1<Layer2<Layer3<Base>>>> diff --git a/docs/test_cases/t00020_class.svg b/docs/test_cases/t00020_class.svg index 096591f8..90ea61b8 100644 --- a/docs/test_cases/t00020_class.svg +++ b/docs/test_cases/t00020_class.svg @@ -1,6 +1,6 @@ - + @@ -9,174 +9,174 @@ - - + + ProductA - + - + ~ProductA() : void - + - + sell(int price) const = 0 : bool - - + + ProductA1 - + - + sell(int price) const : bool - - + + ProductA2 - + - + sell(int price) const : bool - - + + ProductB - + - + ~ProductB() : void - + - + buy(int price) const = 0 : bool - - + + ProductB1 - + - + buy(int price) const : bool - - + + ProductB2 - + - + buy(int price) const : bool - - + + AbstractFactory - + - + make_a() const = 0 : std::unique_ptr<ProductA> - + - + make_b() const = 0 : std::unique_ptr<ProductB> - - + + Factory1 - + - + make_a() const : std::unique_ptr<ProductA> - + - + make_b() const : std::unique_ptr<ProductB> - - + + Factory2 - + - + make_a() const : std::unique_ptr<ProductA> - + - + make_b() const : std::unique_ptr<ProductB> diff --git a/docs/test_cases/t00021_class.svg b/docs/test_cases/t00021_class.svg index 3f736a44..6320d7bb 100644 --- a/docs/test_cases/t00021_class.svg +++ b/docs/test_cases/t00021_class.svg @@ -1,6 +1,6 @@ - + @@ -9,151 +9,151 @@ - - + + Visitor - + - + ~Visitor() : void - + - + visit_A(A const& item) const = 0 : void - + - + visit_B(B const& item) const = 0 : void - - + + Visitor1 - + - + visit_A(A const& item) const : void - + - + visit_B(B const& item) const : void - - + + Visitor2 - + - + visit_A(A const& item) const : void - + - + visit_B(B const& item) const : void - - + + Visitor3 - + - + visit_A(A const& item) const : void - + - + visit_B(B const& item) const : void - - + + Item - + - + ~Item() : void - + - + accept(Visitor const& visitor) const = 0 : void - - + + A - + - + accept(Visitor const& visitor) const : void - - + + B - + - + accept(Visitor const& visitor) const : void diff --git a/docs/test_cases/t00022_class.svg b/docs/test_cases/t00022_class.svg index 6c871f13..850cc6a7 100644 --- a/docs/test_cases/t00022_class.svg +++ b/docs/test_cases/t00022_class.svg @@ -1,6 +1,6 @@ - + @@ -9,77 +9,77 @@ - - + + A - + - + template_method() : void - + - + method1() = 0 : void - + - + method2() = 0 : void - - + + A1 - + - + method1() : void - + - + method2() : void - - + + A2 - + - + method1() : void - + - + method2() : void diff --git a/docs/test_cases/t00023_class.svg b/docs/test_cases/t00023_class.svg index 1bbf4a87..1dbeecf6 100644 --- a/docs/test_cases/t00023_class.svg +++ b/docs/test_cases/t00023_class.svg @@ -1,6 +1,6 @@ - + @@ -9,100 +9,100 @@ - - + + Strategy - + - + ~Strategy() : void - + - + algorithm() = 0 : void - - + + StrategyA - + - + algorithm() : void - - + + StrategyB - + - + algorithm() : void - - + + StrategyC - + - + algorithm() : void - - + + Context - + - + m_strategy : std::unique_ptr<Strategy> - + - + Context(std::unique_ptr<Strategy> strategy) : void - + - + apply() : void diff --git a/docs/test_cases/t00024_class.svg b/docs/test_cases/t00024_class.svg index 7f7ca652..5d2e5767 100644 --- a/docs/test_cases/t00024_class.svg +++ b/docs/test_cases/t00024_class.svg @@ -1,6 +1,6 @@ - + @@ -9,113 +9,113 @@ - - + + Target - + - + ~Target() : void - + - + m1() = 0 : void - + - + m2() = 0 : void - - + + Target1 - + - + m1() : void - + - + m2() : void - - + + Target2 - + - + m1() : void - + - + m2() : void - - + + Proxy - + - + m_target : std::shared_ptr<Target> - + - + Proxy(std::shared_ptr<Target> target) : void - + - + m1() : void - + - + m2() : void diff --git a/docs/test_cases/t00025_class.svg b/docs/test_cases/t00025_class.svg index 7bbf911b..564c7a48 100644 --- a/docs/test_cases/t00025_class.svg +++ b/docs/test_cases/t00025_class.svg @@ -1,6 +1,6 @@ - + @@ -9,52 +9,52 @@ - - + + Target1 - + - + m1() : void - + - + m2() : void - - + + Target2 - + - + m1() : void - + - + m2() : void - - + + Proxy @@ -62,36 +62,36 @@ T - + - + m_target : std::shared_ptr<T> - + - + Proxy(std::shared_ptr<T> target) : void - + - + m1() : void - + - + m2() : void - + Proxy @@ -99,7 +99,7 @@ Target1 - + Proxy @@ -107,25 +107,25 @@ Target2 - - + + ProxyHolder - + - + proxy1 : Proxy<Target1> - + - + proxy2 : Proxy<Target2> diff --git a/docs/test_cases/t00026_class.svg b/docs/test_cases/t00026_class.svg index 3bdd4690..9cb5a176 100644 --- a/docs/test_cases/t00026_class.svg +++ b/docs/test_cases/t00026_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + Memento @@ -18,30 +18,30 @@ T - + - + m_value : T - + - + Memento(T&& v) : void - + - + value() const : T - - + + Originator @@ -49,51 +49,51 @@ T - + - + m_value : T - + - + Originator(T&& v) : void - + - + memoize_value() const : Memento<T> - + - + load(Memento<T> const& m) : void - + - + print() const : void - + - + set(T&& v) : void - - + + Caretaker @@ -101,29 +101,29 @@ T - + - + m_mementos : std::unordered_map<std::string,Memento<T>> - + - + state(std::string const& n) : Memento<T>& - + - + set_state(std::string const& s, Memento<T>&& m) : void - + Caretaker @@ -131,7 +131,7 @@ std::string - + Originator @@ -139,25 +139,25 @@ std::string - - + + StringMemento - + - + caretaker : Caretaker<std::string> - + - + originator : Originator<std::string> diff --git a/docs/test_cases/t00027_class.svg b/docs/test_cases/t00027_class.svg index 9c561d79..3b0bd553 100644 --- a/docs/test_cases/t00027_class.svg +++ b/docs/test_cases/t00027_class.svg @@ -1,6 +1,6 @@ - + @@ -9,30 +9,30 @@ - - + + Shape - + - + display() = 0 : void - + - + ~Shape() : void - - + + Line @@ -41,15 +41,15 @@ - + - + display() : void - - + + Text @@ -58,30 +58,30 @@ - + - + display() : void - - + + ShapeDecorator - + - + display() = 0 : void - - + + Color @@ -90,15 +90,15 @@ - + - + display() : void - - + + Weight @@ -107,14 +107,14 @@ - + - + display() : void - + Line @@ -122,7 +122,7 @@ Color,Weight - + Line @@ -130,7 +130,7 @@ Color - + Text @@ -138,7 +138,7 @@ Color,Weight - + Text @@ -146,39 +146,39 @@ Color - - + + Window - + - + border : Line<Color,Weight> - + - + divider : Line<Color> - + - + title : Text<Color,Weight> - + - + description : Text<Color> diff --git a/docs/test_cases/t00028_class.svg b/docs/test_cases/t00028_class.svg index eac2feba..cdb232b8 100644 --- a/docs/test_cases/t00028_class.svg +++ b/docs/test_cases/t00028_class.svg @@ -1,6 +1,6 @@ - + @@ -9,68 +9,68 @@ - - + + A - + A class note. - + A class note. - - + + B - + B class note. - + B class note. - - + + C - + C class note. - + C class note. - - + + D - + D class note. - + D class note. - - + + E @@ -78,27 +78,27 @@ T - + - + param : T - + E template class note. - - + + G - - + + F @@ -108,13 +108,13 @@ three - + F enum note. - + F enum note. - + E @@ -122,67 +122,67 @@ int - - + + R - + - + aaa : A - + - + bbb : B* - + - + ccc : C& - + - + ddd : std::vector<std::shared_ptr<D>> - + - + eee : E<int> - + - + ggg : G** - + - + R(C& c) : void - + R class note. - + R class note. diff --git a/docs/test_cases/t00029_class.svg b/docs/test_cases/t00029_class.svg index c8403d42..f3ae1a8a 100644 --- a/docs/test_cases/t00029_class.svg +++ b/docs/test_cases/t00029_class.svg @@ -1,6 +1,6 @@ - + @@ -9,16 +9,16 @@ - - + + A - - + + C @@ -26,16 +26,16 @@ T - + - + param : T - - + + E @@ -45,64 +45,64 @@ three - - + + G1 - - + + G2 - - + + G3 - - + + G4 - - + + R - + - + g1 : G1 - + - + g3 : G3& - + - + g4 : std::shared_ptr<G4> diff --git a/docs/test_cases/t00030_class.svg b/docs/test_cases/t00030_class.svg index b59a36c7..af9d89af 100644 --- a/docs/test_cases/t00030_class.svg +++ b/docs/test_cases/t00030_class.svg @@ -1,6 +1,6 @@ - + @@ -9,71 +9,71 @@ - - + + A - - + + B - - + + C - - + + D - - + + R - + - + aaa : A - + - + bbb : std::vector<B> - + - + ccc : std::vector<C> - + - + ddd : D diff --git a/docs/test_cases/t00031_class.svg b/docs/test_cases/t00031_class.svg index 0d03efdf..5c933b5e 100644 --- a/docs/test_cases/t00031_class.svg +++ b/docs/test_cases/t00031_class.svg @@ -1,33 +1,33 @@ - + - + - + - - - + + + A - - + + B @@ -37,8 +37,8 @@ three - - + + @@ -47,23 +47,23 @@ T - + - + ttt : T - - + + D - + C @@ -71,39 +71,39 @@ int - - + + R - + - + aaa : A* - + - + bbb : std::vector<B> - + - + ccc : C<int> - + - + ddd : D* diff --git a/docs/test_cases/t00032_class.svg b/docs/test_cases/t00032_class.svg index ecd85b57..f2d726ee 100644 --- a/docs/test_cases/t00032_class.svg +++ b/docs/test_cases/t00032_class.svg @@ -1,6 +1,6 @@ - + @@ -9,69 +9,69 @@ - - + + Base - - + + TBase - - + + A - + - + operator()() : void - - + + B - + - + operator()() : void - - + + C - + - + operator()() : void - - + + Overload @@ -79,15 +79,15 @@ T,L,Ts... - + - + counter : L - + Overload @@ -95,18 +95,18 @@ TBase,int,A,B,C - - + + R - + - + overload : Overload<TBase,int,A,B,C> diff --git a/docs/test_cases/t00033_class.svg b/docs/test_cases/t00033_class.svg index d51ce2db..dbdf2188 100644 --- a/docs/test_cases/t00033_class.svg +++ b/docs/test_cases/t00033_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + A @@ -18,16 +18,16 @@ T - + - + aaa : T - - + + B @@ -35,16 +35,16 @@ T - + - + bbb : T - - + + C @@ -52,30 +52,30 @@ T - + - + ccc : T - - + + D - + - + ddd : int - + C @@ -83,7 +83,7 @@ D - + B @@ -91,7 +91,7 @@ std::unique_ptr<C<D>> - + A @@ -99,18 +99,18 @@ B<std::unique_ptr<C<D>>> - - + + R - + - + abc : A<B<std::unique_ptr<C<D>>>> diff --git a/docs/test_cases/t00034_class.svg b/docs/test_cases/t00034_class.svg index 8f10212e..2cbbbd93 100644 --- a/docs/test_cases/t00034_class.svg +++ b/docs/test_cases/t00034_class.svg @@ -1,6 +1,6 @@ - + @@ -9,30 +9,30 @@ - - + + Void - + - + operator==(Void const& ) const : bool - + - + operator!=(Void const& ) const : bool - - + + lift_void @@ -41,8 +41,8 @@ - - + + lift_void @@ -51,8 +51,8 @@ - - + + drop_void @@ -61,8 +61,8 @@ - - + + drop_void @@ -71,33 +71,33 @@ - - + + A - - + + R - + - + la : lift_void_t<A>* - + - + lv : lift_void_t<void>* diff --git a/docs/test_cases/t00035_class.svg b/docs/test_cases/t00035_class.svg index 0b40c6e1..f51a2ba0 100644 --- a/docs/test_cases/t00035_class.svg +++ b/docs/test_cases/t00035_class.svg @@ -1,6 +1,6 @@ - + @@ -9,40 +9,40 @@ - - + + Top - - + + Left - - + + Center - - + + Bottom - - + + Right diff --git a/docs/test_cases/t00036_class.svg b/docs/test_cases/t00036_class.svg index 9a372d78..a0aa491c 100644 --- a/docs/test_cases/t00036_class.svg +++ b/docs/test_cases/t00036_class.svg @@ -1,6 +1,6 @@ - + @@ -9,23 +9,23 @@ - + ns1 - + ns11 - + ns111 - + ns2 - + ns22 - - + + E @@ -34,8 +34,8 @@ yellow - - + + A @@ -43,15 +43,15 @@ T - + - + a : T - + A @@ -59,23 +59,23 @@ int - - + + B - + - + a_int : A<int> - - + + C diff --git a/docs/test_cases/t00037_class.svg b/docs/test_cases/t00037_class.svg index b29f76fe..b29a5ba4 100644 --- a/docs/test_cases/t00037_class.svg +++ b/docs/test_cases/t00037_class.svg @@ -1,6 +1,6 @@ - + @@ -9,77 +9,77 @@ - - + + ST - + - + dimensions : «anonymous» - - + + <<anonymous>> - + - + t : double - + - + x : double - + - + y : double - + - + z : double - - + + A - + - + st : ST - + - + A() : void diff --git a/docs/test_cases/t00038_class.svg b/docs/test_cases/t00038_class.svg index dee7ae25..93172c6d 100644 --- a/docs/test_cases/t00038_class.svg +++ b/docs/test_cases/t00038_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + thirdparty::ns1::color_t @@ -20,16 +20,16 @@ blue - - + + thirdparty::ns1::E - - + + property_t @@ -39,47 +39,47 @@ property_c - - + + A - - + + B - - + + C - - + + key_t - + - + key : std::string - - + + map @@ -88,8 +88,8 @@ - - + + map @@ -98,8 +98,8 @@ - - + + map @@ -108,8 +108,8 @@ - - + + map @@ -118,8 +118,8 @@ - - + + map diff --git a/docs/test_cases/t00039_class.svg b/docs/test_cases/t00039_class.svg index 484d5c3d..30106449 100644 --- a/docs/test_cases/t00039_class.svg +++ b/docs/test_cases/t00039_class.svg @@ -1,6 +1,6 @@ - + @@ -9,47 +9,47 @@ - - + + A - - + + AA - - + + AAA - + - + b : B* - - + + ns2::AAAA - - + + ns3::F @@ -57,16 +57,16 @@ T - + - + t : T* - - + + ns3::FF @@ -74,16 +74,16 @@ T,M - + - + m : M* - - + + ns3::FE @@ -91,16 +91,16 @@ T,M - + - + m : M* - - + + ns3::FFF @@ -108,11 +108,11 @@ T,M,N - + - + n : N* diff --git a/docs/test_cases/t00040_class.svg b/docs/test_cases/t00040_class.svg index 20167371..520597b9 100644 --- a/docs/test_cases/t00040_class.svg +++ b/docs/test_cases/t00040_class.svg @@ -1,6 +1,6 @@ - + @@ -9,71 +9,71 @@ - - + + A - + - + ii_ : int - + - + get_a() : int - - + + AA - - + + AAA - + - + b : B* - + - + get_aaa() : int - - + + R - + - + foo(A* a) : void diff --git a/docs/test_cases/t00041_class.svg b/docs/test_cases/t00041_class.svg index dc6a997c..665f3981 100644 --- a/docs/test_cases/t00041_class.svg +++ b/docs/test_cases/t00041_class.svg @@ -1,6 +1,6 @@ - + @@ -9,93 +9,93 @@ - - + + R - - + + D - + - + rr : RR* - - + + E - - + + F - - + + RR - + - + e : E* - + - + f : F* - - + + RRR - - + + ns1::N - - + + ns1::NN - - + + ns1::NM diff --git a/docs/test_cases/t30001_package.svg b/docs/test_cases/t30001_package.svg index d9291a8a..c23d95fc 100644 --- a/docs/test_cases/t30001_package.svg +++ b/docs/test_cases/t30001_package.svg @@ -1,6 +1,6 @@ - + @@ -9,63 +9,63 @@ - - + + A - - + + AA - - + + B - - + + AA - - + + AAA - - + + BBB - - + + BB - - + + AAA - - + + BBB - - + + BB - + A AAA note... - + This is namespace AA in namespace A - + This is namespace AA in namespace B diff --git a/docs/test_cases/t30002_package.svg b/docs/test_cases/t30002_package.svg index ebd3e65b..f1d68178 100644 --- a/docs/test_cases/t30002_package.svg +++ b/docs/test_cases/t30002_package.svg @@ -1,6 +1,6 @@ - + @@ -9,93 +9,93 @@ - - + + A - - + + AA - - + + B - - + + BB - - + + A1 - - + + A2 - - + + A3 - - + + A4 - - + + A5 - - + + A6 - - + + A7 - - + + A8 - - + + A9 - - + + A10 - - + + A11 - - + + A12 - - + + A13 - - + + BBB diff --git a/docs/test_cases/t30003_package.svg b/docs/test_cases/t30003_package.svg index 193d9dcd..655eb5a6 100644 --- a/docs/test_cases/t30003_package.svg +++ b/docs/test_cases/t30003_package.svg @@ -1,6 +1,6 @@ - + @@ -9,35 +9,35 @@ - - + + ns1 - - + + ns3 «deprecated» - - + + ns1 - - + + ns2_v1_0_0 - - + + ns2_v0_9_0 «deprecated» - - + + ns2 diff --git a/docs/test_cases/t30004_package.svg b/docs/test_cases/t30004_package.svg index 6fc675bf..9cded5f3 100644 --- a/docs/test_cases/t30004_package.svg +++ b/docs/test_cases/t30004_package.svg @@ -1,6 +1,6 @@ - + @@ -9,43 +9,43 @@ - - + + A - + Package AAA. - + Package BBB. - + CCCC package note. - + Another CCC note. - + We skipped DDD. - - + + AAA - - + + BBB - - + + CCC - - + + EEE diff --git a/docs/test_cases/t30005_package.svg b/docs/test_cases/t30005_package.svg index 10ba4e30..54d2e4e0 100644 --- a/docs/test_cases/t30005_package.svg +++ b/docs/test_cases/t30005_package.svg @@ -1,6 +1,6 @@ - + @@ -9,48 +9,48 @@ - - + + A - - + + AA - - + + B - - + + BB - - + + C - - + + CC - - + + AAA - - + + BBB - - + + CCC diff --git a/docs/test_cases/t30006_package.svg b/docs/test_cases/t30006_package.svg index b9b75270..065686d5 100644 --- a/docs/test_cases/t30006_package.svg +++ b/docs/test_cases/t30006_package.svg @@ -1,6 +1,6 @@ - + @@ -9,25 +9,25 @@ - - + + B - - + + A - - + + C - + Top A note. - + Bottom A note. diff --git a/docs/test_cases/t30007_package.svg b/docs/test_cases/t30007_package.svg index 1303f65c..acd169f2 100644 --- a/docs/test_cases/t30007_package.svg +++ b/docs/test_cases/t30007_package.svg @@ -1,6 +1,6 @@ - + @@ -9,30 +9,30 @@ - - + + A - - + + B - - + + AA - - + + C - + Compare layout with t30006. - + Bottom A note. diff --git a/docs/test_cases/t40001.md b/docs/test_cases/t40001.md index f3152546..f3611e82 100644 --- a/docs/test_cases/t40001.md +++ b/docs/test_cases/t40001.md @@ -20,6 +20,9 @@ diagrams: plantuml: before: - "' t40001 test include diagram" + after: + - 'note right of {{ alias("include/lib1") }}: This is a lib1 include dir' + - 'note right of {{ alias("include/t40001_include1.h") }}: This is a t40001_include1.h include file' ``` ## Source code ## Generated UML diagrams diff --git a/docs/test_cases/t40001_include.svg b/docs/test_cases/t40001_include.svg index 59538809..a483772f 100644 --- a/docs/test_cases/t40001_include.svg +++ b/docs/test_cases/t40001_include.svg @@ -1,6 +1,6 @@ - + - + @@ -9,27 +9,38 @@ - - - src - + + + src + include - - - lib1 - - - t40001.cc - - - t40001_include1.h - - - lib1.h - - - - + + + lib1 + + + t40001.cc + + + + t40001_include1.h + + + + + lib1.h + + + + This is a lib1 include dir + + + This is a t40001_include1.h include file + + + + + diff --git a/docs/test_cases/t40002.md b/docs/test_cases/t40002.md new file mode 100644 index 00000000..602e4e53 --- /dev/null +++ b/docs/test_cases/t40002.md @@ -0,0 +1,26 @@ +# t40002 - Cyclic include graph diagram test case +## Config +```yaml +compilation_database_dir: .. +output_directory: puml +diagrams: + t40002_include: + type: include + # Provide the files to parse in order to look + # for #include directives + glob: + - ../../tests/t40002/**/*.cc + - ../../tests/t40002/**/*.h + # Render the paths relative to this directory + relative_to: ../../tests/t40002 + include: + # Include only files belonging to these paths + paths: + - ../../tests/t40002 + plantuml: + before: + - "' t40002 test include diagram" +``` +## Source code +## Generated UML diagrams +![t40002_include](./t40002_include.svg "Cyclic include graph diagram test case") diff --git a/docs/test_cases/t40002_include.svg b/docs/test_cases/t40002_include.svg new file mode 100644 index 00000000..23d0e084 --- /dev/null +++ b/docs/test_cases/t40002_include.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + src + + + lib1 + + + lib2 + + + include + + + lib1 + + + lib2 + + + t40002.cc + + + lib1.cc + + + lib2.cc + + + + lib1.h + + + + + lib2.h + + + + + + + + + + + From 21cb9be0342b9dcf19c0a991b2f2bd5e8f79e69a Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 10 Apr 2022 23:06:01 +0200 Subject: [PATCH 11/13] Added clang-uml include diagram config --- .clang-uml | 4 ++-- src/main.cc | 16 ++++++++++++++++ uml/include_diagram.yml | 11 +++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 uml/include_diagram.yml diff --git a/.clang-uml b/.clang-uml index af55e480..8ac1a229 100644 --- a/.clang-uml +++ b/.clang-uml @@ -18,5 +18,5 @@ diagrams: include!: uml/sequence_model_class_diagram.yml package_model_class: include!: uml/package_model_class_diagram.yml - diagram_model_class: - include!: uml/diagram_model_class_diagram.yml + include_graph: + include!: uml/include_diagram.yml diff --git a/src/main.cc b/src/main.cc index d7a4d1c8..a4238119 100644 --- a/src/main.cc +++ b/src/main.cc @@ -19,6 +19,7 @@ #include "class_diagram/generators/plantuml/class_diagram_generator.h" #include "config/config.h" #include "cx/compilation_database.h" +#include "include_diagram/generators/plantuml/include_diagram_generator.h" #include "package_diagram/generators/plantuml/package_diagram_generator.h" #include "sequence_diagram/generators/plantuml/sequence_diagram_generator.h" @@ -133,6 +134,7 @@ void generate_diagram(const std::string &od, const std::string &name, { using clanguml::config::class_diagram; using clanguml::config::diagram_type; + using clanguml::config::include_diagram; using clanguml::config::package_diagram; using clanguml::config::sequence_diagram; @@ -183,6 +185,20 @@ void generate_diagram(const std::string &od, const std::string &name, ofs << clanguml::package_diagram::generators::plantuml::generator( dynamic_cast(*diagram), *model); } + else if (diagram->type() == diagram_type::include_diagram) { + using diagram_config = include_diagram; + using diagram_model = clanguml::include_diagram::model::diagram; + using diagram_visitor = + clanguml::include_diagram::visitor::translation_unit_visitor; + + auto model = + clanguml::common::generators::plantuml::generate(db, diagram->name, + dynamic_cast(*diagram), verbose); + + ofs << clanguml::include_diagram::generators::plantuml::generator( + dynamic_cast(*diagram), *model); + } LOG_INFO("Written {} diagram to {}", name, path.string()); diff --git a/uml/include_diagram.yml b/uml/include_diagram.yml new file mode 100644 index 00000000..d7a686db --- /dev/null +++ b/uml/include_diagram.yml @@ -0,0 +1,11 @@ +type: include +glob: + - src/**/*.h + - src/**/*.cc +relative_to: . +include: + paths: + - src +plantuml: + before: + - "title clang-uml include graph diagram" \ No newline at end of file From 4d4f18d0521ff61ab494ecfc9ceeb005e53ce762 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 10 Apr 2022 23:07:42 +0200 Subject: [PATCH 12/13] Updated test cases documentation --- docs/test_cases/t00002_class.svg | 68 +++++++-------- docs/test_cases/t00003_class.svg | 110 ++++++++++++------------ docs/test_cases/t00004_class.svg | 26 +++--- docs/test_cases/t00005_class.svg | 110 ++++++++++++------------ docs/test_cases/t00006_class.svg | 132 ++++++++++++++--------------- docs/test_cases/t00007_class.svg | 30 +++---- docs/test_cases/t00008_class.svg | 60 ++++++------- docs/test_cases/t00009_class.svg | 32 +++---- docs/test_cases/t00010_class.svg | 34 ++++---- docs/test_cases/t00011_class.svg | 30 +++---- docs/test_cases/t00012_class.svg | 66 +++++++-------- docs/test_cases/t00013_class.svg | 112 ++++++++++++------------ docs/test_cases/t00014_class.svg | 72 ++++++++-------- docs/test_cases/t00015_class.svg | 22 ++--- docs/test_cases/t00016_class.svg | 22 ++--- docs/test_cases/t00017_class.svg | 70 +++++++-------- docs/test_cases/t00018_class.svg | 66 +++++++-------- docs/test_cases/t00019_class.svg | 84 +++++++++--------- docs/test_cases/t00020_class.svg | 94 ++++++++++---------- docs/test_cases/t00021_class.svg | 82 +++++++++--------- docs/test_cases/t00022_class.svg | 42 ++++----- docs/test_cases/t00023_class.svg | 54 ++++++------ docs/test_cases/t00024_class.svg | 62 +++++++------- docs/test_cases/t00025_class.svg | 62 +++++++------- docs/test_cases/t00026_class.svg | 78 ++++++++--------- docs/test_cases/t00027_class.svg | 82 +++++++++--------- docs/test_cases/t00028_class.svg | 94 ++++++++++---------- docs/test_cases/t00029_class.svg | 50 +++++------ docs/test_cases/t00030_class.svg | 38 ++++----- docs/test_cases/t00031_class.svg | 50 +++++------ docs/test_cases/t00032_class.svg | 52 ++++++------ docs/test_cases/t00033_class.svg | 48 +++++------ docs/test_cases/t00034_class.svg | 46 +++++----- docs/test_cases/t00035_class.svg | 22 ++--- docs/test_cases/t00036_class.svg | 38 ++++----- docs/test_cases/t00037_class.svg | 42 ++++----- docs/test_cases/t00038_class.svg | 54 ++++++------ docs/test_cases/t00039_class.svg | 54 ++++++------ docs/test_cases/t00040_class.svg | 38 ++++----- docs/test_cases/t00041_class.svg | 50 +++++------ docs/test_cases/t30001_package.svg | 48 +++++------ docs/test_cases/t30002_package.svg | 74 ++++++++-------- docs/test_cases/t30003_package.svg | 26 +++--- docs/test_cases/t30004_package.svg | 32 +++---- docs/test_cases/t30005_package.svg | 38 ++++----- docs/test_cases/t30006_package.svg | 18 ++-- docs/test_cases/t30007_package.svg | 22 ++--- docs/test_cases/t40001_include.svg | 22 ++--- docs/test_cases/t40002_include.svg | 28 +++--- 49 files changed, 1343 insertions(+), 1343 deletions(-) diff --git a/docs/test_cases/t00002_class.svg b/docs/test_cases/t00002_class.svg index 49b0ce8f..ecd8d046 100644 --- a/docs/test_cases/t00002_class.svg +++ b/docs/test_cases/t00002_class.svg @@ -1,6 +1,6 @@ - + @@ -9,123 +9,123 @@ - - + + A - + - + foo_a() = 0 : void - + - + foo_c() = 0 : void - - + + B - + - + foo_a() : void - - + + C - + - + foo_c() : void - - + + D - + - + as : std::vector<A*> - + - + foo_a() : void - + - + foo_c() : void - - + + E - + - + as : std::vector<A*> - + - + foo_a() : void - + - + foo_c() : void - + This is class A - + This is class B - + This is class D which is a little like B diff --git a/docs/test_cases/t00003_class.svg b/docs/test_cases/t00003_class.svg index 7554acd7..ffd83d12 100644 --- a/docs/test_cases/t00003_class.svg +++ b/docs/test_cases/t00003_class.svg @@ -1,6 +1,6 @@ - + @@ -9,194 +9,194 @@ - - + + A - + - + public_member : int - + - + static_int : int - + - + static_const_int : int const - + - + auto_member : unsigned long const - + - + protected_member : int - + - + private_member : int - + - + a : int - + - + b : int - + - + c : int - + - + A() : void - + - + A(int i) : void - + - + A(A&& ) : void - + - + A(A const& ) : void - + - + ~A() : void - + - + basic_method() : void - + - + static_method() : int - + - + const_method() const : void - + - + auto_method() : int - + - + double_int(int const i) : int - + - + sum(double const a, double const b) : double - + - + default_int(int i = 12) : int - + - + default_string(int i, std::string s = "abc") : std::string - + - + create_from_int(int i) : A - + - + protected_method() : void - + - + private_method() : void - + - + compare : std::function<bool(int const)> diff --git a/docs/test_cases/t00004_class.svg b/docs/test_cases/t00004_class.svg index a83a7612..a39b9d9f 100644 --- a/docs/test_cases/t00004_class.svg +++ b/docs/test_cases/t00004_class.svg @@ -1,6 +1,6 @@ - + @@ -9,38 +9,38 @@ - - + + A - + - + foo() const : void - + - + foo2() const : void - - + + AA - - + + Lights @@ -50,8 +50,8 @@ Red - - + + AAA diff --git a/docs/test_cases/t00005_class.svg b/docs/test_cases/t00005_class.svg index 7a135c13..a77e806a 100644 --- a/docs/test_cases/t00005_class.svg +++ b/docs/test_cases/t00005_class.svg @@ -1,6 +1,6 @@ - + @@ -9,204 +9,204 @@ - - + + A - - + + B - - + + C - - + + D - - + + E - - + + F - - + + G - - + + H - - + + I - - + + J - - + + K - - + + R - + - + some_int : int - + - + some_int_pointer : int* - + - + some_int_pointer_pointer : int** - + - + some_int_reference : int& - + - + a : A - + - + b : B* - + - + c : C& - + - + d : D const* - + - + e : E const& - + - + f : F&& - + - + g : G** - + - + h : H*** - + - + i : I*& - + - + j : J volatile* - + - + k : K* diff --git a/docs/test_cases/t00006_class.svg b/docs/test_cases/t00006_class.svg index d2866b4b..50019ba5 100644 --- a/docs/test_cases/t00006_class.svg +++ b/docs/test_cases/t00006_class.svg @@ -1,6 +1,6 @@ - + @@ -9,136 +9,136 @@ - - + + A - - + + B - - + + C - - + + D - - + + E - - + + F - - + + G - - + + H - - + + I - - + + J - - + + K - - + + L - - + + M - - + + N - - + + NN - - + + NNN - - + + custom_container @@ -146,15 +146,15 @@ T - + - + data : std::vector<T> - + custom_container @@ -162,102 +162,102 @@ E - - + + R - + - + a : std::vector<A> - + - + b : std::vector<B*> - + - + c : std::map<int,C> - + - + d : std::map<int,D*> - + - + e : custom_container<E> - + - + f : std::vector<std::vector<F>> - + - + g : std::map<int,std::vector<G*>> - + - + h : std::array<H,10> - + - + i : std::array<I*,5> - + - + j : J[10] - + - + k : K*[20] - + - + lm : std::vector<std::pair<L,M>> - + - + ns : std::tuple<N,NN,NNN> diff --git a/docs/test_cases/t00007_class.svg b/docs/test_cases/t00007_class.svg index e02c056e..309e212d 100644 --- a/docs/test_cases/t00007_class.svg +++ b/docs/test_cases/t00007_class.svg @@ -1,6 +1,6 @@ - + @@ -9,56 +9,56 @@ - - + + A - - + + B - - + + C - - + + R - + - + a : std::unique_ptr<A> - + - + b : std::shared_ptr<B> - + - + c : std::weak_ptr<C> diff --git a/docs/test_cases/t00008_class.svg b/docs/test_cases/t00008_class.svg index d607c545..ec70da4d 100644 --- a/docs/test_cases/t00008_class.svg +++ b/docs/test_cases/t00008_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + A @@ -18,51 +18,51 @@ T,P,CMP,int N - + - + value : T - + - + pointer : T* - + - + reference : T& - + - + values : std::vector<P> - + - + ints : std::array<int,N> - + - + comparator : CMP - - + + Vector @@ -70,16 +70,16 @@ T - + - + values : std::vector<T> - - + + B @@ -87,15 +87,15 @@ T,C<> - + - + template_template : C<T> - + B @@ -103,26 +103,26 @@ int,Vector - - + + D - + - + ints : B<int,Vector> - + - + add(int i) : void diff --git a/docs/test_cases/t00009_class.svg b/docs/test_cases/t00009_class.svg index 61511c6a..a19dedf7 100644 --- a/docs/test_cases/t00009_class.svg +++ b/docs/test_cases/t00009_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + A @@ -18,15 +18,15 @@ T - + - + value : T - + A @@ -34,7 +34,7 @@ int - + A @@ -42,7 +42,7 @@ std::string - + A @@ -50,32 +50,32 @@ std::vector<std::string> - - + + B - + - + aint : A<int> - + - + astring : A<std::string>* - + - + avector : A<std::vector<std::string>>& diff --git a/docs/test_cases/t00010_class.svg b/docs/test_cases/t00010_class.svg index 6cc22cc2..9fafdd61 100644 --- a/docs/test_cases/t00010_class.svg +++ b/docs/test_cases/t00010_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + A @@ -18,22 +18,22 @@ T,P - + - + first : T - + - + second : P - + A @@ -41,8 +41,8 @@ T,std::string - - + + B @@ -50,15 +50,15 @@ T - + - + astring : A<T,std::string> - + B @@ -66,18 +66,18 @@ int - - + + C - + - + aintstring : B<int> diff --git a/docs/test_cases/t00011_class.svg b/docs/test_cases/t00011_class.svg index 2cdcf0cd..1bea2e2b 100644 --- a/docs/test_cases/t00011_class.svg +++ b/docs/test_cases/t00011_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + D @@ -18,49 +18,49 @@ T - + - + value : T - - + + A - + - + foo() : void - - + + B - + - + m_a : A* - + - + foo() : void diff --git a/docs/test_cases/t00012_class.svg b/docs/test_cases/t00012_class.svg index 3e6de596..cfa762c1 100644 --- a/docs/test_cases/t00012_class.svg +++ b/docs/test_cases/t00012_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + A @@ -18,23 +18,23 @@ T,Ts... - + - + value : T - + - + values : int - - + + B @@ -43,15 +43,15 @@ - + - + ints : std::array<int,sizeof...(Is)> - - + + C @@ -60,14 +60,14 @@ - + - + ints : std::array<T,sizeof...(Is)> - + A @@ -75,7 +75,7 @@ int,std::string,float - + A @@ -83,7 +83,7 @@ int,std::string,bool - + B @@ -91,7 +91,7 @@ 3,2,1 - + B @@ -99,7 +99,7 @@ 1,1,1,1 - + C @@ -107,50 +107,50 @@ std::map<int,std::vector<std::vector<std::vector<std::string>>>>,3,3,3 - - + + R - + - + a1 : A<int,std::string,float> - + - + a2 : A<int,std::string,bool> - + - + b1 : B<3,2,1> - + - + b2 : B<1,1,1,1> - + - + c1 : C<std::map<int,std::vector<std::vector<std::vector<std::string>>>>,3,3,3> - + Long template annotation diff --git a/docs/test_cases/t00013_class.svg b/docs/test_cases/t00013_class.svg index a3948085..d27d2eee 100644 --- a/docs/test_cases/t00013_class.svg +++ b/docs/test_cases/t00013_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + ABCD::F @@ -18,83 +18,83 @@ T - + - + f : T - - + + A - + - + a : int - - + + B - + - + b : int - - + + C - + - + c : int - - + + D - + - + d : int - + - + print(R* r) : void - - + + E @@ -102,15 +102,15 @@ T - + - + e : T - + E @@ -118,7 +118,7 @@ int - + F @@ -126,7 +126,7 @@ int - + E @@ -134,96 +134,96 @@ std::string - - + + R - + - + estring : E<std::string> - + - + get_a(A* a) : int - + - + get_b(B& b) : int - + - + get_const_b(B const& b) : int - + - + get_c(C c) : int - + - + get_d(D&& d) : int - + - + get_d2(D&& d) : int - + - + get_e(E<T> e) : T - + - + get_int_e(E<int> const& e) : int - + - + get_int_e2(E<int>& e) : int - + - + get_f(F<T> const& f) : T - + - + get_int_f(F<int> const& f) : int diff --git a/docs/test_cases/t00014_class.svg b/docs/test_cases/t00014_class.svg index f89aaf70..de38f61a 100644 --- a/docs/test_cases/t00014_class.svg +++ b/docs/test_cases/t00014_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + A @@ -18,22 +18,22 @@ T,P - + - + t : T - + - + p : P - + A @@ -41,22 +41,22 @@ T,std::string - - + + B - + - + value : std::string - + A @@ -64,7 +64,7 @@ bool,std::string - + AString @@ -72,7 +72,7 @@ float - + AString @@ -80,7 +80,7 @@ int - + AString @@ -88,7 +88,7 @@ std::string - + GeneralCallback @@ -96,73 +96,73 @@ AIntString - + GeneralCallback - - + + R - + - + boolstring : A<bool,std::string> - + - + floatstring : AString<float> - + - + intstring : AIntString - + - + stringstring : AStringString - + - + bs : BVector - + - + bs2 : BVector2 - + - + cb : GeneralCallback<AIntString> - + - + vcb : VoidCallback diff --git a/docs/test_cases/t00015_class.svg b/docs/test_cases/t00015_class.svg index b5a7d970..141f0096 100644 --- a/docs/test_cases/t00015_class.svg +++ b/docs/test_cases/t00015_class.svg @@ -1,6 +1,6 @@ - + @@ -9,40 +9,40 @@ - - + + ns1::A - - + + ns1::ns2_v0_9_0::A - - + + ns1::Anon - - + + ns3::ns1::ns2::Anon - - + + ns3::B diff --git a/docs/test_cases/t00016_class.svg b/docs/test_cases/t00016_class.svg index ff382a18..0c7660ac 100644 --- a/docs/test_cases/t00016_class.svg +++ b/docs/test_cases/t00016_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + is_numeric<> @@ -19,8 +19,8 @@ value : enum - - + + is_numeric @@ -31,8 +31,8 @@ value : enum - - + + is_numeric @@ -43,8 +43,8 @@ value : enum - - + + is_numeric @@ -55,8 +55,8 @@ value : enum - - + + is_numeric diff --git a/docs/test_cases/t00017_class.svg b/docs/test_cases/t00017_class.svg index fd70a53d..19b79364 100644 --- a/docs/test_cases/t00017_class.svg +++ b/docs/test_cases/t00017_class.svg @@ -1,6 +1,6 @@ - + @@ -9,135 +9,135 @@ - - + + A - - + + B - - + + C - - + + D - - + + E - - + + F - - + + G - - + + H - - + + I - - + + J - - + + K - - + + R - + - + some_int : int - + - + some_int_pointer : int* - + - + some_int_pointer_pointer : int** - + - + some_int_reference : int& - + - + R(int& some_int, C& cc, E const& ee, F&& ff, I*& ii) : void diff --git a/docs/test_cases/t00018_class.svg b/docs/test_cases/t00018_class.svg index 6545709f..9b513dc0 100644 --- a/docs/test_cases/t00018_class.svg +++ b/docs/test_cases/t00018_class.svg @@ -1,6 +1,6 @@ - + @@ -9,118 +9,118 @@ - - + + impl::widget - + - + n : int - + - + draw(widget const& w) const : void - + - + draw(widget const& w) : void - + - + widget(int n) : void - - + + widget - + - + pImpl : std::unique_ptr<impl::widget> - + - + draw() const : void - + - + draw() : void - + - + shown() const : bool - + - + widget(int ) : void - + - + ~widget() : void - + - + widget(widget&& ) : void - + - + widget(widget const& ) : void - + - + operator=(widget&& ) : widget& - + - + operator=(widget const& ) : widget& diff --git a/docs/test_cases/t00019_class.svg b/docs/test_cases/t00019_class.svg index c5a5eba9..4c7fa645 100644 --- a/docs/test_cases/t00019_class.svg +++ b/docs/test_cases/t00019_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + Layer2 @@ -19,51 +19,51 @@ - + - + all_calls_count() const : int - - + + Base - + - + Base() : void - + - + ~Base() : void - + - + m1() : int - + - + m2() : std::string - - + + Layer1 @@ -72,22 +72,22 @@ - + - + m1() : int - + - + m2() : std::string - - + + Layer3 @@ -95,50 +95,50 @@ LowerLayer - + - + m_m1_calls : int - + - + m_m2_calls : int - + - + m1() : int - + - + m2() : std::string - + - + m1_calls() const : int - + - + m2_calls() const : int - + Layer3 @@ -146,7 +146,7 @@ Base - + Layer2 @@ -154,7 +154,7 @@ Layer3<Base> - + Layer1 @@ -162,18 +162,18 @@ Layer2<Layer3<Base>> - - + + A - + - + layers : std::unique_ptr<Layer1<Layer2<Layer3<Base>>>> diff --git a/docs/test_cases/t00020_class.svg b/docs/test_cases/t00020_class.svg index 90ea61b8..f948cebc 100644 --- a/docs/test_cases/t00020_class.svg +++ b/docs/test_cases/t00020_class.svg @@ -1,6 +1,6 @@ - + @@ -9,174 +9,174 @@ - - + + ProductA - + - + ~ProductA() : void - + - + sell(int price) const = 0 : bool - - + + ProductA1 - + - + sell(int price) const : bool - - + + ProductA2 - + - + sell(int price) const : bool - - + + ProductB - + - + ~ProductB() : void - + - + buy(int price) const = 0 : bool - - + + ProductB1 - + - + buy(int price) const : bool - - + + ProductB2 - + - + buy(int price) const : bool - - + + AbstractFactory - + - + make_a() const = 0 : std::unique_ptr<ProductA> - + - + make_b() const = 0 : std::unique_ptr<ProductB> - - + + Factory1 - + - + make_a() const : std::unique_ptr<ProductA> - + - + make_b() const : std::unique_ptr<ProductB> - - + + Factory2 - + - + make_a() const : std::unique_ptr<ProductA> - + - + make_b() const : std::unique_ptr<ProductB> diff --git a/docs/test_cases/t00021_class.svg b/docs/test_cases/t00021_class.svg index 6320d7bb..974ee020 100644 --- a/docs/test_cases/t00021_class.svg +++ b/docs/test_cases/t00021_class.svg @@ -1,6 +1,6 @@ - + @@ -9,151 +9,151 @@ - - + + Visitor - + - + ~Visitor() : void - + - + visit_A(A const& item) const = 0 : void - + - + visit_B(B const& item) const = 0 : void - - + + Visitor1 - + - + visit_A(A const& item) const : void - + - + visit_B(B const& item) const : void - - + + Visitor2 - + - + visit_A(A const& item) const : void - + - + visit_B(B const& item) const : void - - + + Visitor3 - + - + visit_A(A const& item) const : void - + - + visit_B(B const& item) const : void - - + + Item - + - + ~Item() : void - + - + accept(Visitor const& visitor) const = 0 : void - - + + A - + - + accept(Visitor const& visitor) const : void - - + + B - + - + accept(Visitor const& visitor) const : void diff --git a/docs/test_cases/t00022_class.svg b/docs/test_cases/t00022_class.svg index 850cc6a7..2a2656fd 100644 --- a/docs/test_cases/t00022_class.svg +++ b/docs/test_cases/t00022_class.svg @@ -1,6 +1,6 @@ - + @@ -9,77 +9,77 @@ - - + + A - + - + template_method() : void - + - + method1() = 0 : void - + - + method2() = 0 : void - - + + A1 - + - + method1() : void - + - + method2() : void - - + + A2 - + - + method1() : void - + - + method2() : void diff --git a/docs/test_cases/t00023_class.svg b/docs/test_cases/t00023_class.svg index 1dbeecf6..3aab5ee9 100644 --- a/docs/test_cases/t00023_class.svg +++ b/docs/test_cases/t00023_class.svg @@ -1,6 +1,6 @@ - + @@ -9,100 +9,100 @@ - - + + Strategy - + - + ~Strategy() : void - + - + algorithm() = 0 : void - - + + StrategyA - + - + algorithm() : void - - + + StrategyB - + - + algorithm() : void - - + + StrategyC - + - + algorithm() : void - - + + Context - + - + m_strategy : std::unique_ptr<Strategy> - + - + Context(std::unique_ptr<Strategy> strategy) : void - + - + apply() : void diff --git a/docs/test_cases/t00024_class.svg b/docs/test_cases/t00024_class.svg index 5d2e5767..06a76965 100644 --- a/docs/test_cases/t00024_class.svg +++ b/docs/test_cases/t00024_class.svg @@ -1,6 +1,6 @@ - + @@ -9,113 +9,113 @@ - - + + Target - + - + ~Target() : void - + - + m1() = 0 : void - + - + m2() = 0 : void - - + + Target1 - + - + m1() : void - + - + m2() : void - - + + Target2 - + - + m1() : void - + - + m2() : void - - + + Proxy - + - + m_target : std::shared_ptr<Target> - + - + Proxy(std::shared_ptr<Target> target) : void - + - + m1() : void - + - + m2() : void diff --git a/docs/test_cases/t00025_class.svg b/docs/test_cases/t00025_class.svg index 564c7a48..126468e9 100644 --- a/docs/test_cases/t00025_class.svg +++ b/docs/test_cases/t00025_class.svg @@ -1,6 +1,6 @@ - + @@ -9,52 +9,52 @@ - - + + Target1 - + - + m1() : void - + - + m2() : void - - + + Target2 - + - + m1() : void - + - + m2() : void - - + + Proxy @@ -62,36 +62,36 @@ T - + - + m_target : std::shared_ptr<T> - + - + Proxy(std::shared_ptr<T> target) : void - + - + m1() : void - + - + m2() : void - + Proxy @@ -99,7 +99,7 @@ Target1 - + Proxy @@ -107,25 +107,25 @@ Target2 - - + + ProxyHolder - + - + proxy1 : Proxy<Target1> - + - + proxy2 : Proxy<Target2> diff --git a/docs/test_cases/t00026_class.svg b/docs/test_cases/t00026_class.svg index 9cb5a176..3391ad52 100644 --- a/docs/test_cases/t00026_class.svg +++ b/docs/test_cases/t00026_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + Memento @@ -18,30 +18,30 @@ T - + - + m_value : T - + - + Memento(T&& v) : void - + - + value() const : T - - + + Originator @@ -49,51 +49,51 @@ T - + - + m_value : T - + - + Originator(T&& v) : void - + - + memoize_value() const : Memento<T> - + - + load(Memento<T> const& m) : void - + - + print() const : void - + - + set(T&& v) : void - - + + Caretaker @@ -101,29 +101,29 @@ T - + - + m_mementos : std::unordered_map<std::string,Memento<T>> - + - + state(std::string const& n) : Memento<T>& - + - + set_state(std::string const& s, Memento<T>&& m) : void - + Caretaker @@ -131,7 +131,7 @@ std::string - + Originator @@ -139,25 +139,25 @@ std::string - - + + StringMemento - + - + caretaker : Caretaker<std::string> - + - + originator : Originator<std::string> diff --git a/docs/test_cases/t00027_class.svg b/docs/test_cases/t00027_class.svg index 3b0bd553..12831261 100644 --- a/docs/test_cases/t00027_class.svg +++ b/docs/test_cases/t00027_class.svg @@ -1,6 +1,6 @@ - + @@ -9,30 +9,30 @@ - - + + Shape - + - + display() = 0 : void - + - + ~Shape() : void - - + + Line @@ -41,15 +41,15 @@ - + - + display() : void - - + + Text @@ -58,30 +58,30 @@ - + - + display() : void - - + + ShapeDecorator - + - + display() = 0 : void - - + + Color @@ -90,15 +90,15 @@ - + - + display() : void - - + + Weight @@ -107,14 +107,14 @@ - + - + display() : void - + Line @@ -122,7 +122,7 @@ Color,Weight - + Line @@ -130,7 +130,7 @@ Color - + Text @@ -138,7 +138,7 @@ Color,Weight - + Text @@ -146,39 +146,39 @@ Color - - + + Window - + - + border : Line<Color,Weight> - + - + divider : Line<Color> - + - + title : Text<Color,Weight> - + - + description : Text<Color> diff --git a/docs/test_cases/t00028_class.svg b/docs/test_cases/t00028_class.svg index cdb232b8..1054ecd0 100644 --- a/docs/test_cases/t00028_class.svg +++ b/docs/test_cases/t00028_class.svg @@ -1,6 +1,6 @@ - + @@ -9,68 +9,68 @@ - - + + A - + A class note. - + A class note. - - + + B - + B class note. - + B class note. - - + + C - + C class note. - + C class note. - - + + D - + D class note. - + D class note. - - + + E @@ -78,27 +78,27 @@ T - + - + param : T - + E template class note. - - + + G - - + + F @@ -108,13 +108,13 @@ three - + F enum note. - + F enum note. - + E @@ -122,67 +122,67 @@ int - - + + R - + - + aaa : A - + - + bbb : B* - + - + ccc : C& - + - + ddd : std::vector<std::shared_ptr<D>> - + - + eee : E<int> - + - + ggg : G** - + - + R(C& c) : void - + R class note. - + R class note. diff --git a/docs/test_cases/t00029_class.svg b/docs/test_cases/t00029_class.svg index f3ae1a8a..e2ad1b25 100644 --- a/docs/test_cases/t00029_class.svg +++ b/docs/test_cases/t00029_class.svg @@ -1,6 +1,6 @@ - + @@ -9,16 +9,16 @@ - - + + A - - + + C @@ -26,16 +26,16 @@ T - + - + param : T - - + + E @@ -45,64 +45,64 @@ three - - + + G1 - - + + G2 - - + + G3 - - + + G4 - - + + R - + - + g1 : G1 - + - + g3 : G3& - + - + g4 : std::shared_ptr<G4> diff --git a/docs/test_cases/t00030_class.svg b/docs/test_cases/t00030_class.svg index af9d89af..dbfa902b 100644 --- a/docs/test_cases/t00030_class.svg +++ b/docs/test_cases/t00030_class.svg @@ -1,6 +1,6 @@ - + @@ -9,71 +9,71 @@ - - + + A - - + + B - - + + C - - + + D - - + + R - + - + aaa : A - + - + bbb : std::vector<B> - + - + ccc : std::vector<C> - + - + ddd : D diff --git a/docs/test_cases/t00031_class.svg b/docs/test_cases/t00031_class.svg index 5c933b5e..4901b3cc 100644 --- a/docs/test_cases/t00031_class.svg +++ b/docs/test_cases/t00031_class.svg @@ -1,33 +1,33 @@ - + - + - + - - - + + + A - - + + B @@ -37,8 +37,8 @@ three - - + + @@ -47,23 +47,23 @@ T - + - + ttt : T - - + + D - + C @@ -71,39 +71,39 @@ int - - + + R - + - + aaa : A* - + - + bbb : std::vector<B> - + - + ccc : C<int> - + - + ddd : D* diff --git a/docs/test_cases/t00032_class.svg b/docs/test_cases/t00032_class.svg index f2d726ee..61172e64 100644 --- a/docs/test_cases/t00032_class.svg +++ b/docs/test_cases/t00032_class.svg @@ -1,6 +1,6 @@ - + @@ -9,69 +9,69 @@ - - + + Base - - + + TBase - - + + A - + - + operator()() : void - - + + B - + - + operator()() : void - - + + C - + - + operator()() : void - - + + Overload @@ -79,15 +79,15 @@ T,L,Ts... - + - + counter : L - + Overload @@ -95,18 +95,18 @@ TBase,int,A,B,C - - + + R - + - + overload : Overload<TBase,int,A,B,C> diff --git a/docs/test_cases/t00033_class.svg b/docs/test_cases/t00033_class.svg index dbdf2188..df6692e4 100644 --- a/docs/test_cases/t00033_class.svg +++ b/docs/test_cases/t00033_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + A @@ -18,16 +18,16 @@ T - + - + aaa : T - - + + B @@ -35,16 +35,16 @@ T - + - + bbb : T - - + + C @@ -52,30 +52,30 @@ T - + - + ccc : T - - + + D - + - + ddd : int - + C @@ -83,7 +83,7 @@ D - + B @@ -91,7 +91,7 @@ std::unique_ptr<C<D>> - + A @@ -99,18 +99,18 @@ B<std::unique_ptr<C<D>>> - - + + R - + - + abc : A<B<std::unique_ptr<C<D>>>> diff --git a/docs/test_cases/t00034_class.svg b/docs/test_cases/t00034_class.svg index 2cbbbd93..6c26e233 100644 --- a/docs/test_cases/t00034_class.svg +++ b/docs/test_cases/t00034_class.svg @@ -1,6 +1,6 @@ - + @@ -9,30 +9,30 @@ - - + + Void - + - + operator==(Void const& ) const : bool - + - + operator!=(Void const& ) const : bool - - + + lift_void @@ -41,8 +41,8 @@ - - + + lift_void @@ -51,8 +51,8 @@ - - + + drop_void @@ -61,8 +61,8 @@ - - + + drop_void @@ -71,33 +71,33 @@ - - + + A - - + + R - + - + la : lift_void_t<A>* - + - + lv : lift_void_t<void>* diff --git a/docs/test_cases/t00035_class.svg b/docs/test_cases/t00035_class.svg index f51a2ba0..4c9d4a66 100644 --- a/docs/test_cases/t00035_class.svg +++ b/docs/test_cases/t00035_class.svg @@ -1,6 +1,6 @@ - + @@ -9,40 +9,40 @@ - - + + Top - - + + Left - - + + Center - - + + Bottom - - + + Right diff --git a/docs/test_cases/t00036_class.svg b/docs/test_cases/t00036_class.svg index a0aa491c..6d4f1f55 100644 --- a/docs/test_cases/t00036_class.svg +++ b/docs/test_cases/t00036_class.svg @@ -1,6 +1,6 @@ - + @@ -9,23 +9,23 @@ - + ns1 - + ns11 - + ns111 - + ns2 - + ns22 - - + + E @@ -34,8 +34,8 @@ yellow - - + + A @@ -43,15 +43,15 @@ T - + - + a : T - + A @@ -59,23 +59,23 @@ int - - + + B - + - + a_int : A<int> - - + + C diff --git a/docs/test_cases/t00037_class.svg b/docs/test_cases/t00037_class.svg index b29a5ba4..5931282f 100644 --- a/docs/test_cases/t00037_class.svg +++ b/docs/test_cases/t00037_class.svg @@ -1,6 +1,6 @@ - + @@ -9,77 +9,77 @@ - - + + ST - + - + dimensions : «anonymous» - - + + <<anonymous>> - + - + t : double - + - + x : double - + - + y : double - + - + z : double - - + + A - + - + st : ST - + - + A() : void diff --git a/docs/test_cases/t00038_class.svg b/docs/test_cases/t00038_class.svg index 93172c6d..46e21455 100644 --- a/docs/test_cases/t00038_class.svg +++ b/docs/test_cases/t00038_class.svg @@ -1,6 +1,6 @@ - + @@ -9,8 +9,8 @@ - - + + thirdparty::ns1::color_t @@ -20,16 +20,16 @@ blue - - + + thirdparty::ns1::E - - + + property_t @@ -39,47 +39,47 @@ property_c - - + + A - - + + B - - + + C - - + + key_t - + - + key : std::string - - + + map @@ -88,8 +88,8 @@ - - + + map @@ -98,8 +98,8 @@ - - + + map @@ -108,8 +108,8 @@ - - + + map @@ -118,8 +118,8 @@ - - + + map diff --git a/docs/test_cases/t00039_class.svg b/docs/test_cases/t00039_class.svg index 30106449..176237c0 100644 --- a/docs/test_cases/t00039_class.svg +++ b/docs/test_cases/t00039_class.svg @@ -1,6 +1,6 @@ - + @@ -9,47 +9,47 @@ - - + + A - - + + AA - - + + AAA - + - + b : B* - - + + ns2::AAAA - - + + ns3::F @@ -57,16 +57,16 @@ T - + - + t : T* - - + + ns3::FF @@ -74,16 +74,16 @@ T,M - + - + m : M* - - + + ns3::FE @@ -91,16 +91,16 @@ T,M - + - + m : M* - - + + ns3::FFF @@ -108,11 +108,11 @@ T,M,N - + - + n : N* diff --git a/docs/test_cases/t00040_class.svg b/docs/test_cases/t00040_class.svg index 520597b9..447e7497 100644 --- a/docs/test_cases/t00040_class.svg +++ b/docs/test_cases/t00040_class.svg @@ -1,6 +1,6 @@ - + @@ -9,71 +9,71 @@ - - + + A - + - + ii_ : int - + - + get_a() : int - - + + AA - - + + AAA - + - + b : B* - + - + get_aaa() : int - - + + R - + - + foo(A* a) : void diff --git a/docs/test_cases/t00041_class.svg b/docs/test_cases/t00041_class.svg index 665f3981..f2f9e43a 100644 --- a/docs/test_cases/t00041_class.svg +++ b/docs/test_cases/t00041_class.svg @@ -1,6 +1,6 @@ - + @@ -9,93 +9,93 @@ - - + + R - - + + D - + - + rr : RR* - - + + E - - + + F - - + + RR - + - + e : E* - + - + f : F* - - + + RRR - - + + ns1::N - - + + ns1::NN - - + + ns1::NM diff --git a/docs/test_cases/t30001_package.svg b/docs/test_cases/t30001_package.svg index c23d95fc..52affbf4 100644 --- a/docs/test_cases/t30001_package.svg +++ b/docs/test_cases/t30001_package.svg @@ -1,6 +1,6 @@ - + @@ -9,63 +9,63 @@ - - + + A - - + + AA - - + + B - - + + AA - - + + AAA - - + + BBB - - + + BB - - + + AAA - - + + BBB - - + + BB - + A AAA note... - + This is namespace AA in namespace A - + This is namespace AA in namespace B diff --git a/docs/test_cases/t30002_package.svg b/docs/test_cases/t30002_package.svg index f1d68178..97c234b8 100644 --- a/docs/test_cases/t30002_package.svg +++ b/docs/test_cases/t30002_package.svg @@ -1,6 +1,6 @@ - + @@ -9,93 +9,93 @@ - - + + A - - + + AA - - + + B - - + + BB - - + + A1 - - + + A2 - - + + A3 - - + + A4 - - + + A5 - - + + A6 - - + + A7 - - + + A8 - - + + A9 - - + + A10 - - + + A11 - - + + A12 - - + + A13 - - + + BBB diff --git a/docs/test_cases/t30003_package.svg b/docs/test_cases/t30003_package.svg index 655eb5a6..013ca6db 100644 --- a/docs/test_cases/t30003_package.svg +++ b/docs/test_cases/t30003_package.svg @@ -1,6 +1,6 @@ - + @@ -9,35 +9,35 @@ - - + + ns1 - - + + ns3 «deprecated» - - + + ns1 - - + + ns2_v1_0_0 - - + + ns2_v0_9_0 «deprecated» - - + + ns2 diff --git a/docs/test_cases/t30004_package.svg b/docs/test_cases/t30004_package.svg index 9cded5f3..5b085e3a 100644 --- a/docs/test_cases/t30004_package.svg +++ b/docs/test_cases/t30004_package.svg @@ -1,6 +1,6 @@ - + @@ -9,43 +9,43 @@ - - + + A - + Package AAA. - + Package BBB. - + CCCC package note. - + Another CCC note. - + We skipped DDD. - - + + AAA - - + + BBB - - + + CCC - - + + EEE diff --git a/docs/test_cases/t30005_package.svg b/docs/test_cases/t30005_package.svg index 54d2e4e0..fb46ad34 100644 --- a/docs/test_cases/t30005_package.svg +++ b/docs/test_cases/t30005_package.svg @@ -1,6 +1,6 @@ - + @@ -9,48 +9,48 @@ - - + + A - - + + AA - - + + B - - + + BB - - + + C - - + + CC - - + + AAA - - + + BBB - - + + CCC diff --git a/docs/test_cases/t30006_package.svg b/docs/test_cases/t30006_package.svg index 065686d5..bfe4f59c 100644 --- a/docs/test_cases/t30006_package.svg +++ b/docs/test_cases/t30006_package.svg @@ -1,6 +1,6 @@ - + @@ -9,25 +9,25 @@ - - + + B - - + + A - - + + C - + Top A note. - + Bottom A note. diff --git a/docs/test_cases/t30007_package.svg b/docs/test_cases/t30007_package.svg index acd169f2..d0ffe0e5 100644 --- a/docs/test_cases/t30007_package.svg +++ b/docs/test_cases/t30007_package.svg @@ -1,6 +1,6 @@ - + @@ -9,30 +9,30 @@ - - + + A - - + + B - - + + AA - - + + C - + Compare layout with t30006. - + Bottom A note. diff --git a/docs/test_cases/t40001_include.svg b/docs/test_cases/t40001_include.svg index a483772f..44961c1a 100644 --- a/docs/test_cases/t40001_include.svg +++ b/docs/test_cases/t40001_include.svg @@ -1,6 +1,6 @@ - + @@ -9,32 +9,32 @@ - + src - + include - + lib1 - + t40001.cc - - + + t40001_include1.h - - + + lib1.h - + This is a lib1 include dir - + This is a t40001_include1.h include file diff --git a/docs/test_cases/t40002_include.svg b/docs/test_cases/t40002_include.svg index 23d0e084..f79cc15a 100644 --- a/docs/test_cases/t40002_include.svg +++ b/docs/test_cases/t40002_include.svg @@ -1,6 +1,6 @@ - + @@ -9,40 +9,40 @@ - + src - + lib1 - + lib2 - + include - + lib1 - + lib2 - + t40002.cc - + lib1.cc - + lib2.cc - - + + lib1.h - - + + lib2.h From 2d284b4f7068256a9feb2d1f102c7dc82060a73f Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 10 Apr 2022 23:11:26 +0200 Subject: [PATCH 13/13] Updated config file description --- docs/configuration_file.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration_file.md b/docs/configuration_file.md index d8c1914a..c3cbaf7e 100644 --- a/docs/configuration_file.md +++ b/docs/configuration_file.md @@ -7,7 +7,7 @@ the key of the diagram YAML node ### Diagram options -* `type` - type of diagram, one of [`class`, `sequence`, `package`] +* `type` - type of diagram, one of [`class`, `sequence`, `package`, `include`] * `glob` - list of glob patterns to match source code files for analysis * `include_relations_also_as_members` - when set to `false`, class members for relationships are rendered in UML are skipped from class definition (default: `true`) * `generate_method_arguments` - determines whether the class diagrams methods contain full arguments (`full`), are abbreviated (`abbreviated`) or skipped (`none`)