From cf79b3184c1c646b926bf1fe92e6d5fe248e5578 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Tue, 4 Jun 2024 00:03:26 +0200 Subject: [PATCH 1/8] Initial refactor of id_t to a separate class --- .../json/class_diagram_generator.cc | 10 +- .../mermaid/class_diagram_generator.cc | 6 +- .../plantuml/class_diagram_generator.cc | 6 +- src/class_diagram/model/class.h | 2 +- .../visitor/translation_unit_visitor.cc | 72 ++++++------ src/common/clang_utils.cc | 22 ++-- src/common/clang_utils.h | 22 ++-- src/common/generators/json/generator.cc | 4 +- src/common/model/diagram_element.cc | 6 +- src/common/model/diagram_element.h | 6 +- src/common/model/diagram_filter.h | 3 +- src/common/model/package.h | 2 +- src/common/model/relationship.cc | 4 +- src/common/model/relationship.h | 4 +- src/common/model/source_file.h | 2 +- src/common/model/template_parameter.cc | 2 +- src/common/model/template_parameter.h | 9 +- src/common/types.h | 94 +++++++++++++++- src/common/visitor/ast_id_mapper.cc | 11 +- src/common/visitor/ast_id_mapper.h | 2 +- src/common/visitor/template_builder.h | 9 +- .../json/include_diagram_generator.cc | 4 +- src/include_diagram/model/diagram.cc | 2 +- .../json/package_diagram_generator.cc | 4 +- .../visitor/translation_unit_visitor.cc | 4 +- .../json/sequence_diagram_generator.cc | 98 +++++++++-------- .../json/sequence_diagram_generator.h | 2 +- .../mermaid/sequence_diagram_generator.cc | 25 ++--- .../plantuml/sequence_diagram_generator.cc | 20 ++-- src/sequence_diagram/model/diagram.cc | 14 +-- src/sequence_diagram/model/diagram.h | 4 +- src/sequence_diagram/model/participant.cc | 4 +- src/sequence_diagram/model/participant.h | 2 +- .../visitor/call_expression_context.cc | 18 +-- .../visitor/call_expression_context.h | 12 +- .../visitor/translation_unit_visitor.cc | 103 ++++++++++-------- .../visitor/translation_unit_visitor.h | 8 +- 37 files changed, 374 insertions(+), 248 deletions(-) diff --git a/src/class_diagram/generators/json/class_diagram_generator.cc b/src/class_diagram/generators/json/class_diagram_generator.cc index 69b00950..464b8772 100644 --- a/src/class_diagram/generators/json/class_diagram_generator.cc +++ b/src/class_diagram/generators/json/class_diagram_generator.cc @@ -85,7 +85,7 @@ void to_json(nlohmann::json &j, const class_method &c) void to_json(nlohmann::json &j, const class_parent &c) { j["is_virtual"] = c.is_virtual(); - j["id"] = std::to_string(c.id()); + j["id"] = std::to_string(c.id().value()); if (c.access() != common::model::access_t::kNone) j["access"] = to_string(c.access()); j["name"] = c.name(); @@ -331,7 +331,7 @@ void generator::generate_relationships( } nlohmann::json rel = r; - rel["source"] = std::to_string(c.id()); + rel["source"] = std::to_string(c.id().value()); parent["relationships"].push_back(rel); } @@ -340,7 +340,7 @@ void generator::generate_relationships( common::model::relationship r( relationship_t::kExtension, b.id(), b.access()); nlohmann::json rel = r; - rel["source"] = std::to_string(c.id()); + rel["source"] = std::to_string(c.id().value()); parent["relationships"].push_back(rel); } } @@ -362,7 +362,7 @@ void generator::generate_relationships( } nlohmann::json rel = r; - rel["source"] = std::to_string(c.id()); + rel["source"] = std::to_string(c.id().value()); parent["relationships"].push_back(rel); } } @@ -383,7 +383,7 @@ void generator::generate_relationships( } nlohmann::json rel = r; - rel["source"] = std::to_string(c.id()); + rel["source"] = std::to_string(c.id().value()); parent["relationships"].push_back(rel); } } diff --git a/src/class_diagram/generators/mermaid/class_diagram_generator.cc b/src/class_diagram/generators/mermaid/class_diagram_generator.cc index 436d60b4..b37c0c0a 100644 --- a/src/class_diagram/generators/mermaid/class_diagram_generator.cc +++ b/src/class_diagram/generators/mermaid/class_diagram_generator.cc @@ -405,7 +405,7 @@ void generator::generate_relationships( LOG_DBG("== Processing relationship {}", to_string(r.type())); std::stringstream relstr; - clanguml::common::id_t destination{0}; + clanguml::common::id_t destination{}; try { destination = r.destination(); @@ -513,7 +513,7 @@ void generator::generate_relationships( LOG_DBG("== Processing relationship {}", to_string(r.type())); std::stringstream relstr; - clanguml::common::id_t destination{0}; + clanguml::common::id_t destination{}; try { destination = r.destination(); @@ -584,7 +584,7 @@ void generator::generate_relationships(const enum_ &e, std::ostream &ostr) const if (!model().should_include(r.type())) continue; - clanguml::common::id_t destination{0}; + clanguml::common::id_t destination{}; std::stringstream relstr; try { destination = r.destination(); diff --git a/src/class_diagram/generators/plantuml/class_diagram_generator.cc b/src/class_diagram/generators/plantuml/class_diagram_generator.cc index 67016667..11bdbc78 100644 --- a/src/class_diagram/generators/plantuml/class_diagram_generator.cc +++ b/src/class_diagram/generators/plantuml/class_diagram_generator.cc @@ -488,7 +488,7 @@ void generator::generate_relationships( plantuml_common::to_plantuml(r, config())); std::stringstream relstr; - clanguml::common::id_t destination{0}; + clanguml::common::id_t destination{}; try { destination = r.destination(); @@ -583,7 +583,7 @@ void generator::generate_relationships( LOG_DBG("== Processing relationship {}", to_string(r.type())); std::stringstream relstr; - clanguml::common::id_t destination{0}; + clanguml::common::id_t destination{}; try { destination = r.destination(); @@ -664,7 +664,7 @@ void generator::generate_relationships(const enum_ &e, std::ostream &ostr) const if (!model().should_include(r.type())) continue; - clanguml::common::id_t destination{0}; + clanguml::common::id_t destination{}; std::stringstream relstr; try { destination = r.destination(); diff --git a/src/class_diagram/model/class.h b/src/class_diagram/model/class.h index b8375aec..5e20990c 100644 --- a/src/class_diagram/model/class.h +++ b/src/class_diagram/model/class.h @@ -187,7 +187,7 @@ struct hash> { { using clanguml::common::id_t; - return std::hash{}(key.get().id()); + return std::hash{}(key.get().id().value()); } }; } // namespace std diff --git a/src/class_diagram/visitor/translation_unit_visitor.cc b/src/class_diagram/visitor/translation_unit_visitor.cc index 8431a81a..9dbd3d3e 100644 --- a/src/class_diagram/visitor/translation_unit_visitor.cc +++ b/src/class_diagram/visitor/translation_unit_visitor.cc @@ -130,7 +130,7 @@ bool translation_unit_visitor::VisitEnumDecl(clang::EnumDecl *enm) clang::dyn_cast(parent); if (parent_record_decl != nullptr) { - int64_t local_id = parent_record_decl->getID(); + common::id_t local_id{parent_record_decl->getID()}; // First check if the parent has been added to the diagram as // regular class @@ -222,8 +222,8 @@ bool translation_unit_visitor::VisitClassTemplateSpecializationDecl( if (!template_specialization.template_specialization_found()) { // Only do this if we haven't found a better specialization during // construction of the template specialization - const auto maybe_id = - id_mapper().get_global_id(cls->getSpecializedTemplate()->getID()); + const common::id_t ast_id{cls->getSpecializedTemplate()->getID()}; + const auto maybe_id = id_mapper().get_global_id(ast_id); if (maybe_id.has_value()) template_specialization.add_relationship( {relationship_t::kInstantiation, maybe_id.value()}); @@ -621,8 +621,8 @@ void translation_unit_visitor::process_concept_specialization_relationships( should_include(cpt)) { const auto cpt_name = cpt->getNameAsString(); - - const auto maybe_id = id_mapper().get_global_id(cpt->getID()); + const common::id_t ast_id{cpt->getID()}; + const auto maybe_id = id_mapper().get_global_id(ast_id); if (!maybe_id) return; @@ -707,7 +707,8 @@ bool translation_unit_visitor::VisitCXXRecordDecl(clang::CXXRecordDecl *cls) if (cls->isTemplated() && (cls->getDescribedTemplate() != nullptr)) { // If the described templated of this class is already in the model // skip it: - if (id_mapper().get_global_id(cls->getDescribedTemplate()->getID())) + const common::id_t ast_id{cls->getDescribedTemplate()->getID()}; + if (id_mapper().get_global_id(ast_id)) return true; } @@ -878,19 +879,19 @@ void translation_unit_visitor::process_record_parent( if (parent_record_decl != nullptr) { parent_ns = common::get_tag_namespace(*parent_record_decl); - int64_t local_id = parent_record_decl->getID(); + common::id_t ast_id{parent_record_decl->getID()}; // First check if the parent has been added to the diagram as // regular class - id_opt = id_mapper().get_global_id(local_id); + id_opt = id_mapper().get_global_id(ast_id); // If not, check if the parent template declaration is in the // model if (!id_opt) { if (parent_record_decl->getDescribedTemplate() != nullptr) { - local_id = + ast_id = parent_record_decl->getDescribedTemplate()->getID(); - id_opt = id_mapper().get_global_id(local_id); + id_opt = id_mapper().get_global_id(ast_id); } } } @@ -1993,34 +1994,43 @@ void translation_unit_visitor::resolve_local_to_global_ids() // to elements for (const auto &cls : diagram().classes()) { for (auto &rel : cls.get().relationships()) { - const auto maybe_id = id_mapper().get_global_id(rel.destination()); - if (maybe_id) { - LOG_DBG("= Resolved instantiation destination from local " - "id {} to global id {}", - rel.destination(), *maybe_id); - rel.set_destination(*maybe_id); + if (!rel.destination().is_global()) { + const auto maybe_id = + id_mapper().get_global_id(rel.destination()); + if (maybe_id) { + LOG_DBG("= Resolved instantiation destination from local " + "id {} to global id {}", + rel.destination(), *maybe_id); + rel.set_destination(*maybe_id); + } } } } for (const auto &cpt : diagram().concepts()) { for (auto &rel : cpt.get().relationships()) { - const auto maybe_id = id_mapper().get_global_id(rel.destination()); - if (maybe_id) { - LOG_DBG("= Resolved instantiation destination from local " - "id {} to global id {}", - rel.destination(), *maybe_id); - rel.set_destination(*maybe_id); + if (!rel.destination().is_global()) { + const auto maybe_id = + id_mapper().get_global_id(rel.destination()); + if (maybe_id) { + LOG_DBG("= Resolved instantiation destination from local " + "id {} to global id {}", + rel.destination(), *maybe_id); + rel.set_destination(*maybe_id); + } } } } for (const auto &enm : diagram().enums()) { for (auto &rel : enm.get().relationships()) { - const auto maybe_id = id_mapper().get_global_id(rel.destination()); - if (maybe_id) { - LOG_DBG("= Resolved instantiation destination from local " - "id {} to global id {}", - rel.destination(), *maybe_id); - rel.set_destination(*maybe_id); + if (!rel.destination().is_global()) { + const auto maybe_id = + id_mapper().get_global_id(rel.destination()); + if (maybe_id) { + LOG_DBG("= Resolved instantiation destination from local " + "id {} to global id {}", + rel.destination(), *maybe_id); + rel.set_destination(*maybe_id); + } } } } @@ -2177,7 +2187,7 @@ void translation_unit_visitor::find_instantiation_relationships( std::string best_match_full_name{}; auto full_template_name = template_instantiation.full_name(false); int best_match{}; - common::id_t best_match_id{0}; + common::id_t best_match_id{}; for (const auto templ : diagram().classes()) { if (templ.get() == template_instantiation) @@ -2196,9 +2206,9 @@ void translation_unit_visitor::find_instantiation_relationships( } auto templated_decl_global_id = - id_mapper().get_global_id(templated_decl_id).value_or(0); + id_mapper().get_global_id(templated_decl_id).value_or(common::id_t{}); - if (best_match_id > 0) { + if (best_match_id.value() > 0) { destination = best_match_full_name; template_instantiation.add_relationship( {common::model::relationship_t::kInstantiation, best_match_id}); diff --git a/src/common/clang_utils.cc b/src/common/clang_utils.cc index c02ff514..66631685 100644 --- a/src/common/clang_utils.cc +++ b/src/common/clang_utils.cc @@ -415,49 +415,49 @@ bool is_subexpr_of(const clang::Stmt *parent_stmt, const clang::Stmt *sub_stmt) [sub_stmt](const auto *e) { return is_subexpr_of(e, sub_stmt); }); } -template <> id_t to_id(const std::string &full_name) +template <> common::id_t to_id(const std::string &full_name) { - return static_cast(std::hash{}(full_name) >> 3U); + return static_cast(std::hash{}(full_name)); } -id_t to_id(const clang::QualType &type, const clang::ASTContext &ctx) +common::id_t to_id(const clang::QualType &type, const clang::ASTContext &ctx) { return to_id(common::to_string(type, ctx)); } -template <> id_t to_id(const clang::NamespaceDecl &declaration) +template <> common::id_t to_id(const clang::NamespaceDecl &declaration) { return to_id(get_qualified_name(declaration)); } -template <> id_t to_id(const clang::RecordDecl &declaration) +template <> common::id_t to_id(const clang::RecordDecl &declaration) { return to_id(get_qualified_name(declaration)); } -template <> id_t to_id(const clang::EnumDecl &declaration) +template <> common::id_t to_id(const clang::EnumDecl &declaration) { return to_id(get_qualified_name(declaration)); } -template <> id_t to_id(const clang::TagDecl &declaration) +template <> common::id_t to_id(const clang::TagDecl &declaration) { return to_id(get_qualified_name(declaration)); } -template <> id_t to_id(const clang::CXXRecordDecl &declaration) +template <> common::id_t to_id(const clang::CXXRecordDecl &declaration) { return to_id(get_qualified_name(declaration)); } -template <> id_t to_id(const clang::EnumType &t) { return to_id(*t.getDecl()); } +template <> common::id_t to_id(const clang::EnumType &t) { return to_id(*t.getDecl()); } -template <> id_t to_id(const std::filesystem::path &file) +template <> common::id_t to_id(const std::filesystem::path &file) { return to_id(file.lexically_normal().string()); } -template <> id_t to_id(const clang::TemplateArgument &template_argument) +template <> common::id_t to_id(const clang::TemplateArgument &template_argument) { if (template_argument.getKind() == clang::TemplateArgument::Type) { if (const auto *enum_type = diff --git a/src/common/clang_utils.h b/src/common/clang_utils.h index 25be8986..80f4c7db 100644 --- a/src/common/clang_utils.h +++ b/src/common/clang_utils.h @@ -178,27 +178,27 @@ bool is_subexpr_of(const clang::Stmt *parent_stmt, const clang::Stmt *sub_stmt); * * @{ */ -template id_t to_id(const T &declaration); +template common::id_t to_id(const T &declaration); -template <> id_t to_id(const std::string &full_name); +template <> common::id_t to_id(const std::string &full_name); -id_t to_id(const clang::QualType &type, const clang::ASTContext &ctx); +common::id_t to_id(const clang::QualType &type, const clang::ASTContext &ctx); -template <> id_t to_id(const clang::NamespaceDecl &declaration); +template <> common::id_t to_id(const clang::NamespaceDecl &declaration); -template <> id_t to_id(const clang::CXXRecordDecl &declaration); +template <> common::id_t to_id(const clang::CXXRecordDecl &declaration); -template <> id_t to_id(const clang::RecordDecl &declaration); +template <> common::id_t to_id(const clang::RecordDecl &declaration); -template <> id_t to_id(const clang::EnumDecl &declaration); +template <> common::id_t to_id(const clang::EnumDecl &declaration); -template <> id_t to_id(const clang::TagDecl &declaration); +template <> common::id_t to_id(const clang::TagDecl &declaration); -template <> id_t to_id(const clang::EnumType &type); +template <> common::id_t to_id(const clang::EnumType &type); -template <> id_t to_id(const clang::TemplateSpecializationType &type); +template <> common::id_t to_id(const clang::TemplateSpecializationType &type); -template <> id_t to_id(const std::filesystem::path &type); +template <> common::id_t to_id(const std::filesystem::path &type); /** @} */ // end of to_id /** diff --git a/src/common/generators/json/generator.cc b/src/common/generators/json/generator.cc index 79622391..aec3cd27 100644 --- a/src/common/generators/json/generator.cc +++ b/src/common/generators/json/generator.cc @@ -31,7 +31,7 @@ void to_json(nlohmann::json &j, const source_location &sl) void to_json(nlohmann::json &j, const element &c) { - j = json{{"id", std::to_string(c.id())}, + j = json{{"id", std::to_string(c.id().value())}, {"name", common::generators::json::render_name(c.name())}, {"namespace", c.get_namespace().to_string()}, {"type", c.type_name()}, {"display_name", @@ -62,7 +62,7 @@ void to_json(nlohmann::json &j, const template_parameter &c) void to_json(nlohmann::json &j, const relationship &c) { j["type"] = to_string(c.type()); - j["destination"] = std::to_string(c.destination()); + j["destination"] = std::to_string(c.destination().value()); if (!c.multiplicity_source().empty()) j["multiplicity_source"] = c.multiplicity_source(); if (!c.multiplicity_destination().empty()) diff --git a/src/common/model/diagram_element.cc b/src/common/model/diagram_element.cc index 8e307fc0..97ab0ff4 100644 --- a/src/common/model/diagram_element.cc +++ b/src/common/model/diagram_element.cc @@ -26,7 +26,7 @@ namespace clanguml::common::model { diagram_element::diagram_element() = default; -common::id_t diagram_element::id() const { return id_; } +const common::id_t & diagram_element::id() const { return id_; } void diagram_element::set_id(common::id_t id) { id_ = id; } @@ -42,9 +42,9 @@ void diagram_element::set_parent_element_id(common::id_t id) std::string diagram_element::alias() const { - assert(id_ >= 0); + assert(id_.value() >= 0); - return fmt::format("C_{:022}", id_); + return fmt::format("C_{:022}", id_.value()); } void diagram_element::add_relationship(relationship &&cr) diff --git a/src/common/model/diagram_element.h b/src/common/model/diagram_element.h index 224181af..3074dffe 100644 --- a/src/common/model/diagram_element.h +++ b/src/common/model/diagram_element.h @@ -53,7 +53,7 @@ public: * * @return Elements id. */ - common::id_t id() const; + const common::id_t& id() const; /** * Set elements id. @@ -185,8 +185,8 @@ public: void complete(bool completed); private: - id_t id_{0}; - std::optional parent_element_id_{0}; + id_t id_{}; + std::optional parent_element_id_{}; std::string name_; std::vector relationships_; bool nested_{false}; diff --git a/src/common/model/diagram_filter.h b/src/common/model/diagram_filter.h index 6e86e0e6..2176e13a 100644 --- a/src/common/model/diagram_filter.h +++ b/src/common/model/diagram_filter.h @@ -55,7 +55,8 @@ template const clanguml::common::optional_ref get( const DiagramT &d, const std::string &full_name); -template int64_t destination_comparator(const ElementT &e) +template +common::id_t destination_comparator(const ElementT &e) { return e.id(); } diff --git a/src/common/model/package.h b/src/common/model/package.h index 353b5cf1..981ad5ae 100644 --- a/src/common/model/package.h +++ b/src/common/model/package.h @@ -91,7 +91,7 @@ struct hash> { { using clanguml::common::id_t; - return std::hash{}(key.get().id()); + return std::hash{}(key.get().id().value()); } }; } // namespace std \ No newline at end of file diff --git a/src/common/model/relationship.cc b/src/common/model/relationship.cc index 00800c5d..fa02676e 100644 --- a/src/common/model/relationship.cc +++ b/src/common/model/relationship.cc @@ -22,7 +22,7 @@ namespace clanguml::common::model { -relationship::relationship(relationship_t type, int64_t destination, +relationship::relationship(relationship_t type, common::id_t destination, access_t access, std::string label, std::string multiplicity_source, std::string multiplicity_destination) : type_{type} @@ -38,7 +38,7 @@ void relationship::set_type(relationship_t type) noexcept { type_ = type; } relationship_t relationship::type() const noexcept { return type_; } -void relationship::set_destination(int64_t destination) +void relationship::set_destination(common::id_t destination) { destination_ = destination; } diff --git a/src/common/model/relationship.h b/src/common/model/relationship.h index db282908..400ff663 100644 --- a/src/common/model/relationship.h +++ b/src/common/model/relationship.h @@ -74,14 +74,14 @@ public: * * @param destination Target element id. */ - void set_destination(int64_t destination); + void set_destination(common::id_t destination); /** * Get the id of the target element of this relationship. * * @return Target element id. */ - clanguml::common::id_t destination() const; + common::id_t destination() const; /** * Set the relationship multiplicity at the source. diff --git a/src/common/model/source_file.h b/src/common/model/source_file.h index 24cf26d5..46007d72 100644 --- a/src/common/model/source_file.h +++ b/src/common/model/source_file.h @@ -212,7 +212,7 @@ struct hash> { { using clanguml::common::id_t; - return std::hash{}(key.get().id()); + return std::hash{}(key.get().id().value()); } }; } // namespace std \ No newline at end of file diff --git a/src/common/model/template_parameter.cc b/src/common/model/template_parameter.cc index b31270d9..c66b40b3 100644 --- a/src/common/model/template_parameter.cc +++ b/src/common/model/template_parameter.cc @@ -505,7 +505,7 @@ std::string template_parameter::to_string( } bool template_parameter::find_nested_relationships( - std::vector> + std::vector> &nested_relationships, common::model::relationship_t hint, const std::function &should_include) diff --git a/src/common/model/template_parameter.h b/src/common/model/template_parameter.h index c9d0aecc..27f5270f 100644 --- a/src/common/model/template_parameter.h +++ b/src/common/model/template_parameter.h @@ -19,6 +19,7 @@ #include "common/model/enums.h" #include "common/model/namespace.h" +#include "common/types.h" #include #include @@ -165,14 +166,14 @@ public: * * @param id Id of parameter */ - void set_id(const int64_t id) { id_ = id; } + void set_id(const common::id_t &id) { id_ = id; } /** * Get id of the template parameter * * @return Id of the template parameter */ - const std::optional &id() const { return id_; } + const std::optional &id() const { return id_; } /** * Set the name of the template parameter @@ -388,7 +389,7 @@ public: * @return */ bool find_nested_relationships( - std::vector> + std::vector> &nested_relationships, common::model::relationship_t hint, const std::function &should_include) @@ -532,7 +533,7 @@ private: */ std::vector template_params_; - std::optional id_; + std::optional id_; bool is_unexposed_{false}; }; diff --git a/src/common/types.h b/src/common/types.h index 7da7ea74..d1c3fa64 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -29,7 +29,87 @@ namespace clanguml::common { -using id_t = int64_t; +class id_t { +public: + using type = uint64_t; + + id_t() + : value_{0ULL} + , is_global_{true} + { + } + + explicit id_t(int64_t id) + : value_{static_cast(id)} + , is_global_{false} + { + } + + explicit id_t(type id) + : value_{id} + , is_global_{true} + { + } + + id_t(const id_t &) = default; + id_t(id_t &&) noexcept = default; + id_t &operator=(const id_t &) = default; + id_t &operator=(id_t &&) noexcept = default; + + id_t &operator=(int64_t ast_id) + { + assert(!is_global_); + value_ = static_cast(ast_id); + return *this; + } + + ~id_t() = default; + + bool is_global() const { return is_global_; } + + friend bool operator==(const id_t &lhs, const id_t &rhs) + { + return (lhs.is_global_ == rhs.is_global_) && (lhs.value_ == rhs.value_); + } + + friend bool operator==(const id_t &lhs, const uint64_t &v) + { + return lhs.value_ == v; + } + + friend bool operator!=(const id_t &lhs, const uint64_t &v) + { + return lhs.value_ != v; + } + + friend bool operator!=(const id_t &lhs, const id_t &rhs) + { + return !(lhs == rhs); + } + + friend bool operator<(const id_t &lhs, const id_t &rhs) + { + if (lhs.is_global_ != rhs.is_global_) { + return lhs.value_ < rhs.value_ + 1; + } + + return lhs.value_ < + rhs.value_; // Compare values if is_global_ are the same + } + + type value() const { return value_; } + + int64_t ast_local_value() const + { + assert(!is_global_); + + return static_cast(value_); + } + +private: + type value_; + bool is_global_; +}; /** * Type of output diagram format generator. @@ -292,4 +372,14 @@ using namespace_or_regex = common::or_regex; struct path_or_regex : public or_regex { }; -} // namespace clanguml::common \ No newline at end of file +} // namespace clanguml::common + +template <> class fmt::formatter { +public: + constexpr auto parse(format_parse_context &ctx) { return ctx.begin(); } + template + constexpr auto format(clanguml::common::id_t const &id, Context &ctx) const + { + return format_to(ctx.out(), "{}", id.value()); + } +}; \ No newline at end of file diff --git a/src/common/visitor/ast_id_mapper.cc b/src/common/visitor/ast_id_mapper.cc index b9d22787..6083d429 100644 --- a/src/common/visitor/ast_id_mapper.cc +++ b/src/common/visitor/ast_id_mapper.cc @@ -25,12 +25,17 @@ void ast_id_mapper::add(int64_t ast_id, id_t global_id) id_map_.emplace(ast_id, global_id); } -std::optional ast_id_mapper::get_global_id(int64_t ast_id) +std::optional ast_id_mapper::get_global_id(common::id_t ast_id) { - if (id_map_.count(ast_id) == 0) + assert(!ast_id.is_global()); + + if (ast_id.is_global()) return {}; - return id_map_.at(ast_id); + if (id_map_.count(ast_id.ast_local_value()) == 0) + return {}; + + return id_map_.at(ast_id.ast_local_value()); } } // namespace clanguml::common::visitor \ No newline at end of file diff --git a/src/common/visitor/ast_id_mapper.h b/src/common/visitor/ast_id_mapper.h index 87a7ef42..5951c9c5 100644 --- a/src/common/visitor/ast_id_mapper.h +++ b/src/common/visitor/ast_id_mapper.h @@ -58,7 +58,7 @@ public: * @param ast_id Clang's local AST id. * @return Global id, if exists. */ - std::optional get_global_id(int64_t ast_id); + std::optional get_global_id(common::id_t ast_id); private: std::map::build_from_template_declaration( templated_element.value().add_relationship( {relationship_t::kConstraint, id_mapper() - .get_global_id( - named_concept->getID()) + .get_global_id(common::id_t{ + named_concept->getID()}) .value(), model::access_t::kNone, ct.name().value()}); @@ -865,7 +865,8 @@ void template_builder::build( if constexpr (std::is_same_v) { find_instantiation_relationships(template_instantiation, - template_decl->getID(), full_template_specialization_name); + common::id_t{template_decl->getID()}, + full_template_specialization_name); } template_instantiation.set_id( @@ -910,7 +911,7 @@ void template_builder::build_from_class_template_specialization( if constexpr (std::is_same_v) { find_instantiation_relationships(template_instantiation, - template_specialization.getID(), qualified_name); + common::id_t{template_specialization.getID()}, qualified_name); } visitor_.set_source_location(*template_decl, template_instantiation); diff --git a/src/include_diagram/generators/json/include_diagram_generator.cc b/src/include_diagram/generators/json/include_diagram_generator.cc index a1c6853b..4a2c934c 100644 --- a/src/include_diagram/generators/json/include_diagram_generator.cc +++ b/src/include_diagram/generators/json/include_diagram_generator.cc @@ -44,7 +44,7 @@ void generator::generate_relationships( [this](const auto &r) { return model().should_include(r.type()); }, [&f, &parent](const auto &r) { nlohmann::json rel = r; - rel["source"] = std::to_string(f.id()); + rel["source"] = std::to_string(f.id().value()); parent["relationships"].push_back(std::move(rel)); }); } @@ -53,7 +53,7 @@ void generator::generate_relationships( void generator::generate(const source_file &f, nlohmann::json &parent) const { nlohmann::json j; - j["id"] = std::to_string(f.id()); + j["id"] = std::to_string(f.id().value()); j["name"] = f.name(); auto display_name = f.full_name(false); #if defined(_MSC_VER) diff --git a/src/include_diagram/model/diagram.cc b/src/include_diagram/model/diagram.cc index 0b385581..72275351 100644 --- a/src/include_diagram/model/diagram.cc +++ b/src/include_diagram/model/diagram.cc @@ -51,7 +51,7 @@ void diagram::add_file(std::unique_ptr &&f) auto &ff = *f; assert(!ff.name().empty()); - assert(ff.id() != 0); + assert(ff.id().value() != 0); element_view::add(ff); diff --git a/src/package_diagram/generators/json/package_diagram_generator.cc b/src/package_diagram/generators/json/package_diagram_generator.cc index 7fffd3dd..6cd001e6 100644 --- a/src/package_diagram/generators/json/package_diagram_generator.cc +++ b/src/package_diagram/generators/json/package_diagram_generator.cc @@ -44,7 +44,7 @@ void generator::generate_relationships( dynamic_cast(*destination_package))) continue; - rel["source"] = std::to_string(p.id()); + rel["source"] = std::to_string(p.id().value()); parent["relationships"].push_back(std::move(rel)); } } @@ -63,7 +63,7 @@ void generator::generate(const package &p, nlohmann::json &parent) const const auto &uns = config().using_namespace(); if (!uns.starts_with({p.full_name(false)})) { nlohmann::json j; - j["id"] = std::to_string(p.id()); + j["id"] = std::to_string(p.id().value()); j["name"] = p.name(); j["type"] = to_string(config().package_type()); j["display_name"] = p.name(); diff --git a/src/package_diagram/visitor/translation_unit_visitor.cc b/src/package_diagram/visitor/translation_unit_visitor.cc index 850e1aec..fcfcdb21 100644 --- a/src/package_diagram/visitor/translation_unit_visitor.cc +++ b/src/package_diagram/visitor/translation_unit_visitor.cc @@ -78,7 +78,7 @@ bool translation_unit_visitor::VisitNamespaceDecl(clang::NamespaceDecl *ns) p->set_id(common::to_id(*ns)); set_source_location(*ns, *p); - assert(p->id() > 0); + assert(p->id().value() > 0); if (diagram().should_include(*p) && !diagram().get(p->id())) { process_comment(*ns, *p); @@ -282,7 +282,7 @@ void translation_unit_visitor::add_relationships( auto current_package_id = get_package_id(cls); - if (current_package_id == 0) + if (current_package_id.value() == 0) // These are relationships to a global namespace, and we don't care // about those return; diff --git a/src/sequence_diagram/generators/json/sequence_diagram_generator.cc b/src/sequence_diagram/generators/json/sequence_diagram_generator.cc index ad2b206d..e62b873c 100644 --- a/src/sequence_diagram/generators/json/sequence_diagram_generator.cc +++ b/src/sequence_diagram/generators/json/sequence_diagram_generator.cc @@ -53,7 +53,7 @@ void to_json(nlohmann::json &j, const participant &c) void to_json(nlohmann::json &j, const activity &c) { - j["participant_id"] = std::to_string(c.from()); + j["participant_id"] = std::to_string(c.from().value()); } } // namespace clanguml::sequence_diagram::model @@ -115,8 +115,8 @@ void generator::generate_call(const message &m, nlohmann::json &parent) const msg["name"] = message; msg["type"] = "message"; - msg["from"]["activity_id"] = std::to_string(from.value().id()); - msg["to"]["activity_id"] = std::to_string(to.value().id()); + msg["from"]["activity_id"] = std::to_string(from.value().id().value()); + msg["to"]["activity_id"] = std::to_string(to.value().id().value()); if (const auto &cmt = m.comment(); cmt.has_value()) msg["comment"] = cmt.value(); @@ -125,7 +125,7 @@ void generator::generate_call(const message &m, nlohmann::json &parent) const model().get_participant(from.value().id()).value(); msg["from"]["participant_id"] = - std::to_string(class_participant.class_id()); + std::to_string(class_participant.class_id().value()); } else if (from.value().type_name() == "function" || from.value().type_name() == "function_template") { @@ -134,15 +134,17 @@ void generator::generate_call(const message &m, nlohmann::json &parent) const model() .get_participant(from.value().id()) .value(); - msg["from"]["participant_id"] = - std::to_string(common::to_id(file_participant.file_relative())); + msg["from"]["participant_id"] = std::to_string( + common::to_id(file_participant.file_relative()).value()); } else { - msg["from"]["participant_id"] = std::to_string(from.value().id()); + msg["from"]["participant_id"] = + std::to_string(from.value().id().value()); } } else if (from.value().type_name() == "lambda") { - msg["from"]["participant_id"] = std::to_string(from.value().id()); + msg["from"]["participant_id"] = + std::to_string(from.value().id().value()); } if (to.value().type_name() == "method") { @@ -150,7 +152,7 @@ void generator::generate_call(const message &m, nlohmann::json &parent) const model().get_participant(to.value().id()).value(); msg["to"]["participant_id"] = - std::to_string(class_participant.class_id()); + std::to_string(class_participant.class_id().value()); } else if (to.value().type_name() == "function" || to.value().type_name() == "function_template") { @@ -159,15 +161,16 @@ void generator::generate_call(const message &m, nlohmann::json &parent) const model() .get_participant(to.value().id()) .value(); - msg["to"]["participant_id"] = - std::to_string(common::to_id(file_participant.file_relative())); + msg["to"]["participant_id"] = std::to_string( + common::to_id(file_participant.file_relative()).value()); } else { - msg["to"]["participant_id"] = std::to_string(to.value().id()); + msg["to"]["participant_id"] = + std::to_string(to.value().id().value()); } } else if (to.value().type_name() == "lambda") { - msg["to"]["participant_id"] = std::to_string(to.value().id()); + msg["to"]["participant_id"] = std::to_string(to.value().id().value()); } msg["source_location"] = @@ -299,7 +302,7 @@ void generator::process_while_message(const message &m) const nlohmann::json while_block; while_block["type"] = "loop"; while_block["name"] = "while"; - while_block["activity_id"] = std::to_string(m.from()); + while_block["activity_id"] = std::to_string(m.from().value()); if (auto text = m.condition_text(); text.has_value()) while_block["condition_text"] = *text; @@ -320,7 +323,7 @@ void generator::process_for_message(const message &m) const nlohmann::json for_block; for_block["type"] = "loop"; for_block["name"] = "for"; - for_block["activity_id"] = std::to_string(m.from()); + for_block["activity_id"] = std::to_string(m.from().value()); if (auto text = m.condition_text(); text.has_value()) for_block["condition_text"] = *text; @@ -341,7 +344,7 @@ void generator::process_do_message(const message &m) const nlohmann::json do_block; do_block["type"] = "loop"; do_block["name"] = "do"; - do_block["activity_id"] = std::to_string(m.from()); + do_block["activity_id"] = std::to_string(m.from().value()); if (auto text = m.condition_text(); text.has_value()) do_block["condition_text"] = *text; @@ -362,7 +365,7 @@ void generator::process_try_message(const message &m) const nlohmann::json try_block; try_block["type"] = "break"; try_block["name"] = "try"; - try_block["activity_id"] = std::to_string(m.from()); + try_block["activity_id"] = std::to_string(m.from().value()); current_block_statement()["messages"].push_back(std::move(try_block)); @@ -404,7 +407,7 @@ void generator::process_switch_message(const message &m) const nlohmann::json if_block; if_block["type"] = "alt"; if_block["name"] = "switch"; - if_block["activity_id"] = std::to_string(m.from()); + if_block["activity_id"] = std::to_string(m.from().value()); current_block_statement()["messages"].push_back(std::move(if_block)); @@ -439,7 +442,7 @@ void generator::process_conditional_message(const message &m) const nlohmann::json if_block; if_block["type"] = "alt"; if_block["name"] = "conditional"; - if_block["activity_id"] = std::to_string(m.from()); + if_block["activity_id"] = std::to_string(m.from().value()); if (auto text = m.condition_text(); text.has_value()) if_block["condition_text"] = *text; @@ -507,7 +510,7 @@ void generator::process_if_message(const message &m) const nlohmann::json if_block; if_block["type"] = "alt"; if_block["name"] = "if"; - if_block["activity_id"] = std::to_string(m.from()); + if_block["activity_id"] = std::to_string(m.from().value()); if (auto text = m.condition_text(); text.has_value()) if_block["condition_text"] = *text; @@ -538,10 +541,10 @@ void generator::generate_participant( generate_participant(parent, p.value().id(), true); } -common::id_t generator::generate_participant( +std::optional generator::generate_participant( nlohmann::json & /*parent*/, common::id_t id, bool force) const { - common::id_t participant_id{0}; + std::optional participant_id{}; if (!force) { for (const auto pid : model().active_participants()) { @@ -554,27 +557,27 @@ common::id_t generator::generate_participant( else participant_id = id; - if (participant_id == 0) + if (!participant_id.has_value()) return participant_id; - if (is_participant_generated(participant_id)) + if (is_participant_generated(*participant_id)) return participant_id; const auto &participant = - model().get_participant(participant_id).value(); + model().get_participant(*participant_id).value(); const auto participant_type = participant.type_name(); if (participant_type == "method") { auto class_participant_id = model() - .get_participant(participant_id) + .get_participant(*participant_id) .value() .class_id(); LOG_DBG("Generating JSON method participant: {}", model() - .get_participant(participant_id) + .get_participant(*participant_id) .value() .full_name(false)); @@ -584,7 +587,7 @@ common::id_t generator::generate_participant( .get_participant(class_participant_id) .value(); - generated_participants_.emplace(participant_id); + generated_participants_.emplace(*participant_id); generated_participants_.emplace(class_participant_id); json_["participants"].push_back(class_participant); @@ -600,10 +603,11 @@ common::id_t generator::generate_participant( return class_participant_id; } - if (!is_participant_generated(participant_id)) { + if (!is_participant_generated(*participant_id)) { for (auto &p : json_["participants"]) { - if (p.at("id") == std::to_string(class_participant_id)) { - generated_participants_.emplace(participant_id); + if (p.at("id") == + std::to_string(class_participant_id.value())) { + generated_participants_.emplace(*participant_id); p["activities"].push_back(participant); return class_participant_id; } @@ -617,7 +621,7 @@ common::id_t generator::generate_participant( // single file // participant_id will become activity_id within a file participant const auto &function_participant = - model().get_participant(participant_id).value(); + model().get_participant(*participant_id).value(); const auto file_participant_id = common::to_id(function_participant.file_relative()); @@ -634,11 +638,11 @@ common::id_t generator::generate_participant( if (is_participant_generated(file_participant_id)) return participant_id; - p["id"] = std::to_string(file_participant_id); + p["id"] = std::to_string(file_participant_id.value()); p["type"] = "file"; p.erase("source_location"); - generated_participants_.emplace(participant_id); + generated_participants_.emplace(participant_id.value()); p["activities"].push_back(participant); json_["participants"].push_back(p); @@ -648,10 +652,10 @@ common::id_t generator::generate_participant( return file_participant_id; } - if (!is_participant_generated(participant_id)) { + if (!is_participant_generated(*participant_id)) { for (auto &p : json_["participants"]) { - if (p.at("id") == std::to_string(file_participant_id)) { - generated_participants_.emplace(participant_id); + if (p.at("id") == std::to_string(file_participant_id.value())) { + generated_participants_.emplace(*participant_id); p["activities"].push_back(participant); } } @@ -663,7 +667,7 @@ common::id_t generator::generate_participant( json_["participants"].push_back(participant); } - generated_participants_.emplace(participant_id); + generated_participants_.emplace(*participant_id); return participant_id; } @@ -700,17 +704,19 @@ void generator::generate_diagram(nlohmann::json &parent) const auto from_activity_id = model().get_from_activity_id(from_location); auto to_activity_id = model().get_to_activity_id(to_location); - if (from_activity_id == 0 || to_activity_id == 0) + if (!from_activity_id || !to_activity_id) continue; auto message_chains_unique = model().get_all_from_to_message_chains( - from_activity_id, to_activity_id); + *from_activity_id, *to_activity_id); nlohmann::json sequence; sequence["from_to"]["from"]["location"] = from_location.location; - sequence["from_to"]["from"]["id"] = from_activity_id; + sequence["from_to"]["from"]["id"] = + std::to_string(from_activity_id.value().value()); sequence["from_to"]["to"]["location"] = to_location.location; - sequence["from_to"]["to"]["id"] = to_activity_id; + sequence["from_to"]["to"]["id"] = + std::to_string(to_activity_id.value().value()); block_statements_stack_.push_back(std::ref(sequence)); @@ -742,11 +748,11 @@ void generator::generate_diagram(nlohmann::json &parent) const continue; auto message_chains_unique = - model().get_all_from_to_message_chains(0, to_activity_id); + model().get_all_from_to_message_chains(common::id_t{}, *to_activity_id); nlohmann::json sequence; sequence["to"]["location"] = to_location.location; - sequence["to"]["id"] = to_activity_id; + sequence["to"]["id"] = std::to_string(to_activity_id.value().value()); block_statements_stack_.push_back(std::ref(sequence)); @@ -773,7 +779,7 @@ void generator::generate_diagram(nlohmann::json &parent) const for (const auto &sf : config().from()) { if (sf.location_type == location_t::function) { - common::id_t start_from{0}; + common::id_t start_from{}; std::string start_from_str; for (const auto &[k, v] : model().sequences()) { const auto &caller = *model().participants().at(v.from()); @@ -812,7 +818,7 @@ void generator::generate_diagram(nlohmann::json &parent) const nlohmann::json sequence; sequence["start_from"]["location"] = sf.location; - sequence["start_from"]["id"] = start_from; + sequence["start_from"]["id"] = std::to_string(start_from.value()); block_statements_stack_.push_back(std::ref(sequence)); diff --git a/src/sequence_diagram/generators/json/sequence_diagram_generator.h b/src/sequence_diagram/generators/json/sequence_diagram_generator.h index e519f1bb..0eac7e7b 100644 --- a/src/sequence_diagram/generators/json/sequence_diagram_generator.h +++ b/src/sequence_diagram/generators/json/sequence_diagram_generator.h @@ -77,7 +77,7 @@ public: * the set of active participants * @return Id of the generated participant */ - common::id_t generate_participant( + std::optional generate_participant( nlohmann::json &parent, common::id_t id, bool force = false) const; /** diff --git a/src/sequence_diagram/generators/mermaid/sequence_diagram_generator.cc b/src/sequence_diagram/generators/mermaid/sequence_diagram_generator.cc index 41bf9390..59e4546f 100644 --- a/src/sequence_diagram/generators/mermaid/sequence_diagram_generator.cc +++ b/src/sequence_diagram/generators/mermaid/sequence_diagram_generator.cc @@ -354,7 +354,7 @@ void generator::generate_participant( void generator::generate_participant( std::ostream &ostr, common::id_t id, bool force) const { - common::id_t participant_id{0}; + common::id_t participant_id{}; if (!force) { for (const auto pid : model().active_participants()) { @@ -504,21 +504,21 @@ void generator::generate_diagram(std::ostream &ostr) const auto from_activity_id = model().get_from_activity_id(from_location); auto to_activity_id = model().get_to_activity_id(to_location); - if (from_activity_id == 0 || to_activity_id == 0) + if (!from_activity_id || !to_activity_id) continue; - if (model().participants().count(from_activity_id) == 0) + if (model().participants().count(*from_activity_id) == 0) continue; - if (model().participants().count(to_activity_id) == 0) + if (model().participants().count(*to_activity_id) == 0) continue; auto message_chains_unique = model().get_all_from_to_message_chains( - from_activity_id, to_activity_id); + *from_activity_id, *to_activity_id); for (const auto &mc : message_chains_unique) { const auto &from = - model().get_participant(from_activity_id); + model().get_participant(*from_activity_id); if (from.value().type_name() == "method" || config().combine_free_functions_into_file_participants()) { @@ -526,7 +526,7 @@ void generator::generate_diagram(std::ostream &ostr) const ostr << indent(1) << "participant *\n"; star_participant_generated = true; } - generate_participant(ostr, from_activity_id); + generate_participant(ostr, *from_activity_id); ostr << indent(1) << "* " << common::generators::mermaid::to_mermaid( message_t::kCall) @@ -545,11 +545,11 @@ void generator::generate_diagram(std::ostream &ostr) const for (const auto &to_location : config().to()) { auto to_activity_id = model().get_to_activity_id(to_location); - if (to_activity_id == 0) + if (!to_activity_id) continue; - auto message_chains_unique = - model().get_all_from_to_message_chains(0, to_activity_id); + auto message_chains_unique = model().get_all_from_to_message_chains( + common::id_t{}, *to_activity_id); for (const auto &mc : message_chains_unique) { const auto from_activity_id = mc.front().from(); @@ -580,7 +580,7 @@ void generator::generate_diagram(std::ostream &ostr) const for (const auto &sf : config().from()) { if (sf.location_type == location_t::function) { - common::id_t start_from{0}; + common::id_t start_from{}; for (const auto &[k, v] : model().sequences()) { if (model().participants().count(v.from()) == 0) continue; @@ -649,8 +649,7 @@ void generator::generate_diagram(std::ostream &ostr) const ostr << indent(1) << from_alias << " " << common::generators::mermaid::to_mermaid( message_t::kReturn) - << " *" - << " : "; + << " *" << " : "; if (config().generate_return_types()) ostr << from.value().return_type(); diff --git a/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc b/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc index 571eca2e..0494beca 100644 --- a/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc +++ b/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc @@ -350,7 +350,7 @@ void generator::generate_participant( void generator::generate_participant( std::ostream &ostr, common::id_t id, bool force) const { - common::id_t participant_id{0}; + common::id_t participant_id{}; if (!force) { for (const auto pid : model().active_participants()) { @@ -508,17 +508,17 @@ void generator::generate_diagram(std::ostream &ostr) const auto from_activity_id = model().get_from_activity_id(from_location); auto to_activity_id = model().get_to_activity_id(to_location); - if (from_activity_id == 0 || to_activity_id == 0) + if (!from_activity_id || !to_activity_id) continue; - if (model().participants().count(from_activity_id) == 0) + if (model().participants().count(*from_activity_id) == 0) continue; - if (model().participants().count(to_activity_id) == 0) + if (model().participants().count(*to_activity_id) == 0) continue; auto message_chains_unique = model().get_all_from_to_message_chains( - from_activity_id, to_activity_id); + *from_activity_id, *to_activity_id); bool first_separator_skipped{false}; for (const auto &mc : message_chains_unique) { @@ -528,11 +528,11 @@ void generator::generate_diagram(std::ostream &ostr) const ostr << "====\n"; const auto &from = - model().get_participant(from_activity_id); + model().get_participant(*from_activity_id); if (from.value().type_name() == "method" || config().combine_free_functions_into_file_participants()) { - generate_participant(ostr, from_activity_id); + generate_participant(ostr, *from_activity_id); ostr << "[->" << " " << generate_alias(from.value()) << " : " << from.value().message_name( @@ -549,11 +549,11 @@ void generator::generate_diagram(std::ostream &ostr) const for (const auto &to_location : config().to()) { auto to_activity_id = model().get_to_activity_id(to_location); - if (to_activity_id == 0) + if (!to_activity_id) continue; auto message_chains_unique = - model().get_all_from_to_message_chains(0, to_activity_id); + model().get_all_from_to_message_chains(common::id_t{}, *to_activity_id); bool first_separator_skipped{false}; for (const auto &mc : message_chains_unique) { @@ -588,7 +588,7 @@ void generator::generate_diagram(std::ostream &ostr) const for (const auto &sf : config().from()) { if (sf.location_type == location_t::function) { - common::id_t start_from{0}; + common::id_t start_from{}; for (const auto &[k, v] : model().sequences()) { if (model().participants().count(v.from()) == 0) continue; diff --git a/src/sequence_diagram/model/diagram.cc b/src/sequence_diagram/model/diagram.cc index 5e691f47..98880604 100644 --- a/src/sequence_diagram/model/diagram.cc +++ b/src/sequence_diagram/model/diagram.cc @@ -226,10 +226,10 @@ std::vector diagram::list_to_values() const return result; } -common::id_t diagram::get_to_activity_id( +std::optional diagram::get_to_activity_id( const config::source_location &to_location) const { - common::id_t to_activity{0}; + std::optional to_activity{}; for (const auto &[k, v] : sequences()) { for (const auto &m : v.messages()) { @@ -246,7 +246,7 @@ common::id_t diagram::get_to_activity_id( } } - if (to_activity == 0) { + if (!to_activity.has_value()) { LOG_WARN("Failed to find 'to' participant {} for to " "condition", to_location.location); @@ -255,10 +255,10 @@ common::id_t diagram::get_to_activity_id( return to_activity; } -common::id_t diagram::get_from_activity_id( +std::optional diagram::get_from_activity_id( const config::source_location &from_location) const { - common::id_t from_activity{0}; + std::optional from_activity{}; for (const auto &[k, v] : sequences()) { const auto &caller = *participants().at(v.from()); @@ -270,7 +270,7 @@ common::id_t diagram::get_from_activity_id( } } - if (from_activity == 0) { + if (!from_activity.has_value()) { LOG_WARN("Failed to find 'from' participant {} for from " "condition", from_location.location); @@ -385,7 +385,7 @@ std::vector diagram::get_all_from_to_message_chains( message_chains_unique.end(), mc) != message_chains_unique.end()) continue; - if (from_activity == 0 || (mc.front().from() == from_activity)) { + if (from_activity.value() == 0 || (mc.front().from() == from_activity)) { message_chains_unique.push_back(mc); } } diff --git a/src/sequence_diagram/model/diagram.h b/src/sequence_diagram/model/diagram.h index e269197b..fcbd0009 100644 --- a/src/sequence_diagram/model/diagram.h +++ b/src/sequence_diagram/model/diagram.h @@ -267,7 +267,7 @@ public: * @param to_location Target activity * @return Activity id */ - common::id_t get_to_activity_id( + std::optional get_to_activity_id( const config::source_location &to_location) const; /** @@ -276,7 +276,7 @@ public: * @param from_location Source activity * @return Activity id */ - common::id_t get_from_activity_id( + std::optional get_from_activity_id( const config::source_location &from_location) const; /** diff --git a/src/sequence_diagram/model/participant.cc b/src/sequence_diagram/model/participant.cc index cf183edb..8c5dbc22 100644 --- a/src/sequence_diagram/model/participant.cc +++ b/src/sequence_diagram/model/participant.cc @@ -178,9 +178,9 @@ std::string method::method_name() const { return method_name_; } std::string method::alias() const { - assert(class_id_ >= 0); + assert(class_id_.value() >= 0); - return fmt::format("C_{:022}", class_id_); + return fmt::format("C_{:022}", class_id_.value()); } bool method::is_constructor() const { return is_constructor_; } diff --git a/src/sequence_diagram/model/participant.h b/src/sequence_diagram/model/participant.h index 92de35c8..584826eb 100644 --- a/src/sequence_diagram/model/participant.h +++ b/src/sequence_diagram/model/participant.h @@ -200,7 +200,7 @@ private: bool is_template_instantiation_{false}; bool is_alias_{false}; bool is_lambda_{false}; - common::id_t lambda_operator_id_{0}; + common::id_t lambda_operator_id_{}; std::string full_name_; }; diff --git a/src/sequence_diagram/visitor/call_expression_context.cc b/src/sequence_diagram/visitor/call_expression_context.cc index 8d49c065..241c9bd7 100644 --- a/src/sequence_diagram/visitor/call_expression_context.cc +++ b/src/sequence_diagram/visitor/call_expression_context.cc @@ -24,7 +24,7 @@ call_expression_context::call_expression_context() = default; void call_expression_context::reset() { - current_caller_id_ = 0; + current_caller_id_ = common::id_t{}; current_class_decl_ = nullptr; current_class_template_decl_ = nullptr; current_class_template_specialization_decl_ = nullptr; @@ -130,33 +130,33 @@ void call_expression_context::update( current_function_template_decl_ = function_template; } -std::int64_t call_expression_context::caller_id() const +common::id_t call_expression_context::caller_id() const { - if (lambda_caller_id() != 0) - return lambda_caller_id(); + if (lambda_caller_id().has_value()) + return *lambda_caller_id(); return current_caller_id_; } -std::int64_t call_expression_context::lambda_caller_id() const +std::optional call_expression_context::lambda_caller_id() const { if (current_lambda_caller_id_.empty()) - return 0; + return {}; return current_lambda_caller_id_.top(); } -void call_expression_context::set_caller_id(std::int64_t id) +void call_expression_context::set_caller_id(common::id_t id) { LOG_DBG("Setting current caller id to {}", id); current_caller_id_ = id; } -void call_expression_context::enter_lambda_expression(std::int64_t id) +void call_expression_context::enter_lambda_expression(common::id_t id) { LOG_DBG("Setting current lambda caller id to {}", id); - assert(id != 0); + assert(id.value() != 0); current_lambda_caller_id_.push(id); } diff --git a/src/sequence_diagram/visitor/call_expression_context.h b/src/sequence_diagram/visitor/call_expression_context.h index ba4958f3..38c20dfd 100644 --- a/src/sequence_diagram/visitor/call_expression_context.h +++ b/src/sequence_diagram/visitor/call_expression_context.h @@ -116,14 +116,14 @@ struct call_expression_context { * * @param id Set current caller id. */ - void set_caller_id(std::int64_t id); + void set_caller_id(common::id_t id); /** * @brief Get current caller id * * @return Id of the current caller participant */ - std::int64_t caller_id() const; + common::id_t caller_id() const; /** * @brief Get the id of the current lambda caller. @@ -133,14 +133,14 @@ struct call_expression_context { * * @return Current lambda caller id, or 0 if current caller is not lambda. */ - std::int64_t lambda_caller_id() const; + std::optional lambda_caller_id() const; /** * @brief Enter a lambda expression * * @param id Lambda id */ - void enter_lambda_expression(std::int64_t id); + void enter_lambda_expression(common::id_t id); /** * @brief Leave current lambda expression @@ -315,8 +315,8 @@ struct call_expression_context { clang::FunctionTemplateDecl *current_function_template_decl_{nullptr}; private: - std::int64_t current_caller_id_{0}; - std::stack current_lambda_caller_id_; + common::id_t current_caller_id_{}; + std::stack current_lambda_caller_id_; std::stack call_expr_stack_; diff --git a/src/sequence_diagram/visitor/translation_unit_visitor.cc b/src/sequence_diagram/visitor/translation_unit_visitor.cc index 1093cc5f..90b44b52 100644 --- a/src/sequence_diagram/visitor/translation_unit_visitor.cc +++ b/src/sequence_diagram/visitor/translation_unit_visitor.cc @@ -64,7 +64,8 @@ bool translation_unit_visitor::VisitCXXRecordDecl( // Skip this class if it's parent template is already in the model if (declaration->isTemplated() && declaration->getDescribedTemplate() != nullptr) { - if (get_unique_id(declaration->getDescribedTemplate()->getID())) + if (get_unique_id( + common::id_t{declaration->getDescribedTemplate()->getID()})) return true; } @@ -335,7 +336,8 @@ bool translation_unit_visitor::VisitFunctionDecl( if (declaration->getDescribedTemplate() != nullptr) { // If the described templated of this function is already in the // model skip it: - if (get_unique_id(declaration->getDescribedTemplate()->getID())) + if (get_unique_id( + common::id_t{declaration->getDescribedTemplate()->getID()})) return true; } } @@ -474,7 +476,7 @@ bool translation_unit_visitor::VisitLambdaExpr(clang::LambdaExpr *expr) // method function would be excluded by filters if (std::holds_alternative( context().current_callexpr()) && - (context().lambda_caller_id() == 0)) { + (!context().lambda_caller_id().has_value())) { using clanguml::common::model::message_t; using clanguml::sequence_diagram::model::message; @@ -661,7 +663,7 @@ bool translation_unit_visitor::TraverseCompoundStmt(clang::CompoundStmt *stmt) if (current_elseifstmt->getElse() == stmt) { const auto current_caller_id = context().caller_id(); - if (current_caller_id != 0) { + if (current_caller_id.value() != 0) { model::message m{message_t::kElse, current_caller_id}; set_source_location(*stmt, m); diagram().add_message(std::move(m)); @@ -672,7 +674,7 @@ bool translation_unit_visitor::TraverseCompoundStmt(clang::CompoundStmt *stmt) if (current_ifstmt->getElse() == stmt) { const auto current_caller_id = context().caller_id(); - if (current_caller_id != 0) { + if (current_caller_id.value() != 0) { model::message m{message_t::kElse, current_caller_id}; set_source_location(*stmt, m); diagram().add_message(std::move(m)); @@ -1185,7 +1187,7 @@ bool translation_unit_visitor::VisitCallExpr(clang::CallExpr *expr) } // Add message to diagram - if (m.from() > 0 && m.to() > 0) { + if (m.from().value() > 0 && m.to().value() > 0) { m.set_comment(stripped_comment); if (diagram().sequences().find(m.from()) == @@ -1269,7 +1271,7 @@ bool translation_unit_visitor::VisitCXXConstructExpr( if (!process_construct_expression(m, expr)) return true; - if (m.from() > 0 && m.to() > 0) { + if (m.from().value() > 0 && m.to().value() > 0) { if (diagram().sequences().find(m.from()) == diagram().sequences().end()) { activity a{m.from()}; @@ -1311,10 +1313,10 @@ bool translation_unit_visitor::process_cuda_kernel_call_expression( auto callee_name = callee_function->getQualifiedNameAsString() + "()"; - const auto maybe_id = get_unique_id(callee_function->getID()); + const auto maybe_id = get_unique_id(common::id_t{callee_function->getID()}); if (!maybe_id.has_value()) { // This is hopefully not an interesting call... - m.set_to(callee_function->getID()); + m.set_to(common::id_t{callee_function->getID()}); } else { m.set_to(maybe_id.value()); @@ -1349,16 +1351,17 @@ bool translation_unit_visitor::process_operator_call_expression( auto lambda_name = make_lambda_name(lambda_method->getParent()); - m.set_to(lambda_method->getParent()->getID()); + m.set_to(common::id_t{lambda_method->getParent()->getID()}); } else { - auto maybe_id = - get_unique_id(operator_call_expr->getCalleeDecl()->getID()); + auto maybe_id = get_unique_id( + common::id_t{operator_call_expr->getCalleeDecl()->getID()}); if (maybe_id.has_value()) { m.set_to(maybe_id.value()); } else { - m.set_to(operator_call_expr->getCalleeDecl()->getID()); + m.set_to( + common::id_t{operator_call_expr->getCalleeDecl()->getID()}); } } @@ -1384,19 +1387,19 @@ bool translation_unit_visitor::process_construct_expression( constructor->getID(), construct_expr->getBeginLoc().printToString(source_manager())); - auto maybe_id = get_unique_id(constructor->getID()); + auto maybe_id = get_unique_id(common::id_t{constructor->getID()}); if (maybe_id.has_value()) { m.set_to(maybe_id.value()); } else { - m.set_to(constructor->getID()); + m.set_to(common::id_t{constructor->getID()}); } m.set_message_name( fmt::format("{}::{}", constructor_parent->getQualifiedNameAsString(), constructor_parent->getNameAsString())); - diagram().add_active_participant(constructor->getID()); + diagram().add_active_participant(common::id_t{constructor->getID()}); return true; } @@ -1421,7 +1424,7 @@ bool translation_unit_visitor::process_class_method_call_expression( if (!should_include(callee_decl) || !should_include(method_decl)) return false; - m.set_to(method_decl->getID()); + m.set_to(common::id_t{method_decl->getID()}); m.set_message_name(method_decl->getNameAsString()); m.set_return_type( method_call_expr->getCallReturnType(*context().get_ast_context()) @@ -1430,7 +1433,7 @@ bool translation_unit_visitor::process_class_method_call_expression( LOG_TRACE("Set callee method id {} for method name {}", m.to(), method_decl->getQualifiedNameAsString()); - diagram().add_active_participant(method_decl->getID()); + diagram().add_active_participant(common::id_t{method_decl->getID()}); return true; } @@ -1507,7 +1510,7 @@ bool translation_unit_visitor::process_class_template_method_call_expression( dependent_member_callee->getMember().getAsString()); if (const auto maybe_id = - get_unique_id(template_declaration->getID()); + get_unique_id(common::id_t{template_declaration->getID()}); maybe_id.has_value()) diagram().add_active_participant(maybe_id.value()); } @@ -1544,10 +1547,10 @@ bool translation_unit_visitor::process_function_call_expression( auto callee_name = callee_function->getQualifiedNameAsString() + "()"; - const auto maybe_id = get_unique_id(callee_function->getID()); + const auto maybe_id = get_unique_id(common::id_t{callee_function->getID()}); if (!maybe_id.has_value()) { // This is hopefully not an interesting call... - m.set_to(callee_function->getID()); + m.set_to(common::id_t{callee_function->getID()}); } else { m.set_to(maybe_id.value()); @@ -1567,7 +1570,8 @@ bool translation_unit_visitor::process_lambda_call_expression( if (lambda_expr == nullptr) return true; - const auto lambda_class_id = lambda_expr->getLambdaClass()->getID(); + const auto lambda_class_id = + common::id_t{lambda_expr->getLambdaClass()->getID()}; const auto maybe_id = get_unique_id(lambda_class_id); if (!maybe_id.has_value()) m.set_to(lambda_class_id); @@ -1592,9 +1596,9 @@ bool translation_unit_visitor::process_unresolved_lookup_call_expression( const auto *ftd = clang::dyn_cast_or_null(decl); - const auto maybe_id = get_unique_id(ftd->getID()); + const auto maybe_id = get_unique_id(common::id_t{ftd->getID()}); if (!maybe_id.has_value()) - m.set_to(ftd->getID()); + m.set_to(common::id_t{ftd->getID()}); else { m.set_to(maybe_id.value()); } @@ -1606,9 +1610,9 @@ bool translation_unit_visitor::process_unresolved_lookup_call_expression( const auto *fd = clang::dyn_cast_or_null(decl); - const auto maybe_id = get_unique_id(fd->getID()); + const auto maybe_id = get_unique_id(common::id_t{fd->getID()}); if (!maybe_id.has_value()) - m.set_to(fd->getID()); + m.set_to(common::id_t{fd->getID()}); else { m.set_to(maybe_id.value()); } @@ -1684,18 +1688,18 @@ translation_unit_visitor::create_class_model(clang::CXXRecordDecl *cls) assert(parent_record_decl != nullptr); - int64_t local_id = parent_record_decl->getID(); + const common::id_t ast_id{parent_record_decl->getID()}; // First check if the parent has been added to the diagram as // regular class - id_opt = get_unique_id(local_id); + id_opt = get_unique_id(ast_id); // If not, check if the parent template declaration is in the model if (!id_opt && (parent_record_decl->getDescribedTemplate() != nullptr)) { parent_record_decl->getDescribedTemplate()->getID(); if (parent_record_decl->getDescribedTemplate() != nullptr) - id_opt = get_unique_id(local_id); + id_opt = get_unique_id(ast_id); } if (!id_opt) @@ -1778,12 +1782,13 @@ void translation_unit_visitor::set_unique_id( } std::optional translation_unit_visitor::get_unique_id( - int64_t local_id) const + common::id_t local_id) const { - if (local_ast_id_map_.find(local_id) == local_ast_id_map_.end()) + if (local_ast_id_map_.find(local_id.ast_local_value()) == + local_ast_id_map_.end()) return {}; - return local_ast_id_map_.at(local_id); + return local_ast_id_map_.at(local_id.ast_local_value()); } std::unique_ptr @@ -1927,13 +1932,15 @@ std::string translation_unit_visitor::make_lambda_name( if (context().lambda_caller_id() != 0) { // Parent is also a lambda (this id points to a lambda operator()) std::string parent_lambda_class_name{"()"}; - if (diagram().get_participant( - context().lambda_caller_id())) { - auto parent_lambda_class_id = diagram() - .get_participant( - context().lambda_caller_id()) - .value() - .class_id(); + if (context().lambda_caller_id() && + diagram().get_participant( + context().lambda_caller_id().value())) { + auto parent_lambda_class_id = + diagram() + .get_participant( + context().lambda_caller_id().value()) + .value() + .class_id(); if (diagram().get_participant( parent_lambda_class_id)) { @@ -2054,8 +2061,11 @@ void translation_unit_visitor::resolve_ids_to_global() // Change all active participants AST local ids to diagram global ids for (auto id : diagram().active_participants()) { - if (local_ast_id_map_.find(id) != local_ast_id_map_.end()) { - active_participants_unique.emplace(local_ast_id_map_.at(id)); + if (!id.is_global() && + local_ast_id_map_.find(id.ast_local_value()) != + local_ast_id_map_.end()) { + active_participants_unique.emplace( + local_ast_id_map_.at(id.ast_local_value())); } else { active_participants_unique.emplace(id); @@ -2067,8 +2077,10 @@ void translation_unit_visitor::resolve_ids_to_global() // Change all message callees AST local ids to diagram global ids for (auto &[id, activity] : diagram().sequences()) { for (auto &m : activity.messages()) { - if (local_ast_id_map_.find(m.to()) != local_ast_id_map_.end()) { - m.set_to(local_ast_id_map_.at(m.to())); + if (!id.is_global() && + local_ast_id_map_.find(m.to().ast_local_value()) != + local_ast_id_map_.end()) { + m.set_to(local_ast_id_map_.at(m.to().ast_local_value())); } } } @@ -2280,7 +2292,7 @@ bool translation_unit_visitor::should_include( std::optional translation_unit_visitor::get_expression_comment( const clang::SourceManager &sm, const clang::ASTContext &context, - const int64_t caller_id, const clang::Stmt *stmt) + const common::id_t caller_id, const clang::Stmt *stmt) { const auto *raw_comment = clanguml::common::get_expression_raw_comment(sm, context, stmt); @@ -2288,7 +2300,8 @@ std::optional translation_unit_visitor::get_expression_comment( if (raw_comment == nullptr) return {}; - if (!processed_comments_by_caller_id_.emplace(caller_id, raw_comment) + if (!processed_comments_by_caller_id_ + .emplace(caller_id.ast_local_value(), raw_comment) .second) { return {}; } diff --git a/src/sequence_diagram/visitor/translation_unit_visitor.h b/src/sequence_diagram/visitor/translation_unit_visitor.h index 071509b9..d5f3b717 100644 --- a/src/sequence_diagram/visitor/translation_unit_visitor.h +++ b/src/sequence_diagram/visitor/translation_unit_visitor.h @@ -166,7 +166,7 @@ public: { assert(decl != nullptr); - auto unique_participant_id = get_unique_id(decl->getID()); + auto unique_participant_id = get_unique_id(common::id_t{decl->getID()}); if (!unique_participant_id.has_value()) return {}; @@ -185,7 +185,7 @@ public: { assert(decl != nullptr); - auto unique_participant_id = get_unique_id(decl->getID()); + auto unique_participant_id = get_unique_id(common::id_t{decl->getID()}); if (!unique_participant_id.has_value()) return {}; @@ -243,7 +243,7 @@ public: * @param local_id AST local element id * @return Global diagram element id */ - std::optional get_unique_id(int64_t local_id) const; + std::optional get_unique_id(common::id_t local_id) const; /** * @brief Finalize diagram model for this translation unit @@ -469,7 +469,7 @@ private: std::optional get_expression_comment( const clang::SourceManager &sm, const clang::ASTContext &context, - int64_t caller_id, const clang::Stmt *stmt); + common::id_t caller_id, const clang::Stmt *stmt); /** * @brief Initializes model message from comment call directive From a69938f17f7ad4b035e42a7d16c8840223b8cf7b Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Tue, 4 Jun 2024 20:49:50 +0200 Subject: [PATCH 2/8] Fixed tests after initial refactor --- src/common/types.h | 10 +++- .../mermaid/sequence_diagram_generator.cc | 7 ++- .../plantuml/sequence_diagram_generator.cc | 4 +- src/sequence_diagram/model/diagram.cc | 2 + .../visitor/translation_unit_visitor.cc | 57 ++++++++++--------- 5 files changed, 46 insertions(+), 34 deletions(-) diff --git a/src/common/types.h b/src/common/types.h index d1c3fa64..847283cc 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -79,6 +79,14 @@ public: friend bool operator!=(const id_t &lhs, const uint64_t &v) { + // This is sadly necessary to catch accidental comparisons to empty + // std::optional: + // + // std::optional id{}; + // if(id != 0) { /* id is nullopt, not 0 - so this executes... */ } + // + assert(v != 0); + return lhs.value_ != v; } @@ -115,7 +123,7 @@ private: * Type of output diagram format generator. */ enum class generator_type_t { - plantuml, /*!< Diagrams will be gnerated in PlantUML format */ + plantuml, /*!< Diagrams will be generated in PlantUML format */ json, /*!< Diagrams will be generated in JSON format */ mermaid /*!< Diagrams will be generated in MermaidJS format */ }; diff --git a/src/sequence_diagram/generators/mermaid/sequence_diagram_generator.cc b/src/sequence_diagram/generators/mermaid/sequence_diagram_generator.cc index 59e4546f..fdf78036 100644 --- a/src/sequence_diagram/generators/mermaid/sequence_diagram_generator.cc +++ b/src/sequence_diagram/generators/mermaid/sequence_diagram_generator.cc @@ -424,8 +424,9 @@ void generator::generate_participant( std::filesystem::path{file_path}, config().root_directory()) .string()); - ostr << indent(1) << "participant " << fmt::format("C_{:022}", file_id) - << " as " << render_participant_name(participant_name); + ostr << indent(1) << "participant " + << fmt::format("C_{:022}", file_id.value()) << " as " + << render_participant_name(participant_name); ostr << '\n'; generated_participants_.emplace(file_id); @@ -474,7 +475,7 @@ std::string generator::generate_alias( config().combine_free_functions_into_file_participants()) { const auto file_id = common::to_id(participant.file()); - return fmt::format("C_{:022}", file_id); + return fmt::format("C_{:022}", file_id.value()); } return participant.alias(); diff --git a/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc b/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc index 0494beca..ad1a6ac5 100644 --- a/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc +++ b/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc @@ -429,7 +429,7 @@ void generator::generate_participant( .string()); ostr << "participant \"" << render_name(participant_name) << "\" as " - << fmt::format("C_{:022}", file_id); + << fmt::format("C_{:022}", file_id.value()); ostr << '\n'; @@ -480,7 +480,7 @@ std::string generator::generate_alias( config().combine_free_functions_into_file_participants()) { const auto file_id = common::to_id(participant.file()); - return fmt::format("C_{:022}", file_id); + return fmt::format("C_{:022}", file_id.value()); } return participant.alias(); diff --git a/src/sequence_diagram/model/diagram.cc b/src/sequence_diagram/model/diagram.cc index 98880604..98d033b9 100644 --- a/src/sequence_diagram/model/diagram.cc +++ b/src/sequence_diagram/model/diagram.cc @@ -77,6 +77,8 @@ void diagram::add_participant(std::unique_ptr p) { const auto participant_id = p->id(); + assert(participant_id.is_global()); + if (participants_.find(participant_id) == participants_.end()) { LOG_DBG("Adding '{}' participant: {}, {} [{}]", p->type_name(), p->full_name(false), p->id(), diff --git a/src/sequence_diagram/visitor/translation_unit_visitor.cc b/src/sequence_diagram/visitor/translation_unit_visitor.cc index 90b44b52..b8fe4c8a 100644 --- a/src/sequence_diagram/visitor/translation_unit_visitor.cc +++ b/src/sequence_diagram/visitor/translation_unit_visitor.cc @@ -720,7 +720,7 @@ bool translation_unit_visitor::TraverseIfStmt(clang::IfStmt *stmt) std::any_of(current_elseifstmt->children().begin(), current_elseifstmt->children().end(), child_stmt_compare); - if ((current_caller_id != 0) && !stmt->isConstexpr()) { + if ((current_caller_id.value() != 0) && !stmt->isConstexpr()) { if (elseif_block) { context().enter_elseifstmt(stmt); @@ -745,7 +745,7 @@ bool translation_unit_visitor::TraverseIfStmt(clang::IfStmt *stmt) RecursiveASTVisitor::TraverseIfStmt(stmt); - if ((current_caller_id != 0) && !stmt->isConstexpr()) { + if ((current_caller_id.value() != 0) && !stmt->isConstexpr()) { if (!elseif_block) { diagram().end_block_message( {message_t::kIfEnd, current_caller_id}, message_t::kIf); @@ -768,7 +768,7 @@ bool translation_unit_visitor::TraverseWhileStmt(clang::WhileStmt *stmt) if (config().generate_condition_statements()) condition_text = common::get_condition_text(source_manager(), stmt); - if (current_caller_id != 0) { + if (current_caller_id.value() != 0) { context().enter_loopstmt(stmt); message m{message_t::kWhile, current_caller_id}; set_source_location(*stmt, m); @@ -779,7 +779,7 @@ bool translation_unit_visitor::TraverseWhileStmt(clang::WhileStmt *stmt) } RecursiveASTVisitor::TraverseWhileStmt(stmt); - if (current_caller_id != 0) { + if (current_caller_id.value() != 0) { diagram().end_block_message( {message_t::kWhileEnd, current_caller_id}, message_t::kWhile); context().leave_loopstmt(); @@ -800,7 +800,7 @@ bool translation_unit_visitor::TraverseDoStmt(clang::DoStmt *stmt) if (config().generate_condition_statements()) condition_text = common::get_condition_text(source_manager(), stmt); - if (current_caller_id != 0) { + if (current_caller_id.value() != 0) { context().enter_loopstmt(stmt); message m{message_t::kDo, current_caller_id}; set_source_location(*stmt, m); @@ -812,7 +812,7 @@ bool translation_unit_visitor::TraverseDoStmt(clang::DoStmt *stmt) RecursiveASTVisitor::TraverseDoStmt(stmt); - if (current_caller_id != 0) { + if (current_caller_id.value() != 0) { diagram().end_block_message( {message_t::kDoEnd, current_caller_id}, message_t::kDo); context().leave_loopstmt(); @@ -833,7 +833,7 @@ bool translation_unit_visitor::TraverseForStmt(clang::ForStmt *stmt) if (config().generate_condition_statements()) condition_text = common::get_condition_text(source_manager(), stmt); - if (current_caller_id != 0) { + if (current_caller_id.value() != 0) { context().enter_loopstmt(stmt); message m{message_t::kFor, current_caller_id}; set_source_location(*stmt, m); @@ -847,7 +847,7 @@ bool translation_unit_visitor::TraverseForStmt(clang::ForStmt *stmt) RecursiveASTVisitor::TraverseForStmt(stmt); - if (current_caller_id != 0) { + if (current_caller_id.value() != 0) { diagram().end_block_message( {message_t::kForEnd, current_caller_id}, message_t::kFor); context().leave_loopstmt(); @@ -864,7 +864,7 @@ bool translation_unit_visitor::TraverseCXXTryStmt(clang::CXXTryStmt *stmt) const auto current_caller_id = context().caller_id(); - if (current_caller_id != 0) { + if (current_caller_id.value() != 0) { context().enter_trystmt(stmt); message m{message_t::kTry, current_caller_id}; set_source_location(*stmt, m); @@ -875,7 +875,7 @@ bool translation_unit_visitor::TraverseCXXTryStmt(clang::CXXTryStmt *stmt) RecursiveASTVisitor::TraverseCXXTryStmt(stmt); - if (current_caller_id != 0) { + if (current_caller_id.value() != 0) { diagram().end_block_message( {message_t::kTryEnd, current_caller_id}, message_t::kTry); context().leave_trystmt(); @@ -892,7 +892,8 @@ bool translation_unit_visitor::TraverseCXXCatchStmt(clang::CXXCatchStmt *stmt) const auto current_caller_id = context().caller_id(); - if ((current_caller_id != 0) && (context().current_trystmt() != nullptr)) { + if ((current_caller_id.value() != 0) && + (context().current_trystmt() != nullptr)) { std::string caught_type; if (stmt->getCaughtType().isNull()) caught_type = "..."; @@ -923,7 +924,7 @@ bool translation_unit_visitor::TraverseCXXForRangeStmt( if (config().generate_condition_statements()) condition_text = common::get_condition_text(source_manager(), stmt); - if (current_caller_id != 0) { + if (current_caller_id.value() != 0) { context().enter_loopstmt(stmt); message m{message_t::kFor, current_caller_id}; set_source_location(*stmt, m); @@ -936,7 +937,7 @@ bool translation_unit_visitor::TraverseCXXForRangeStmt( RecursiveASTVisitor::TraverseCXXForRangeStmt( stmt); - if (current_caller_id != 0) { + if (current_caller_id.value() != 0) { diagram().end_block_message( {message_t::kForEnd, current_caller_id}, message_t::kFor); context().leave_loopstmt(); @@ -951,7 +952,7 @@ bool translation_unit_visitor::TraverseSwitchStmt(clang::SwitchStmt *stmt) const auto current_caller_id = context().caller_id(); - if (current_caller_id != 0) { + if (current_caller_id.value() != 0) { context().enter_switchstmt(stmt); model::message m{message_t::kSwitch, current_caller_id}; set_source_location(*stmt, m); @@ -962,7 +963,7 @@ bool translation_unit_visitor::TraverseSwitchStmt(clang::SwitchStmt *stmt) RecursiveASTVisitor::TraverseSwitchStmt(stmt); - if (current_caller_id != 0) { + if (current_caller_id.value() != 0) { context().leave_switchstmt(); diagram().end_block_message( {message_t::kSwitchEnd, current_caller_id}, message_t::kSwitch); @@ -977,7 +978,7 @@ bool translation_unit_visitor::TraverseCaseStmt(clang::CaseStmt *stmt) const auto current_caller_id = context().caller_id(); - if ((current_caller_id != 0) && + if ((current_caller_id.value() != 0) && (context().current_switchstmt() != nullptr)) { model::message m{message_t::kCase, current_caller_id}; m.set_message_name(common::to_string(stmt->getLHS())); @@ -995,7 +996,7 @@ bool translation_unit_visitor::TraverseDefaultStmt(clang::DefaultStmt *stmt) const auto current_caller_id = context().caller_id(); - if ((current_caller_id != 0) && + if ((current_caller_id.value() != 0) && (context().current_switchstmt() != nullptr)) { model::message m{message_t::kCase, current_caller_id}; m.set_message_name("default"); @@ -1018,7 +1019,7 @@ bool translation_unit_visitor::TraverseConditionalOperator( if (config().generate_condition_statements()) condition_text = common::get_condition_text(source_manager(), stmt); - if (current_caller_id != 0) { + if (current_caller_id.value() != 0) { context().enter_conditionaloperator(stmt); model::message m{message_t::kConditional, current_caller_id}; set_source_location(*stmt, m); @@ -1034,7 +1035,7 @@ bool translation_unit_visitor::TraverseConditionalOperator( RecursiveASTVisitor::TraverseStmt( stmt->getTrueExpr()); - if (current_caller_id != 0) { + if (current_caller_id.value() != 0) { model::message m{message_t::kConditionalElse, current_caller_id}; set_source_location(*stmt, m); diagram().add_message(std::move(m)); @@ -1043,7 +1044,7 @@ bool translation_unit_visitor::TraverseConditionalOperator( RecursiveASTVisitor::TraverseStmt( stmt->getFalseExpr()); - if (current_caller_id != 0) { + if (current_caller_id.value() != 0) { context().leave_conditionaloperator(); diagram().end_block_message( {message_t::kConditionalEnd, current_caller_id}, @@ -1929,11 +1930,10 @@ std::string translation_unit_visitor::make_lambda_name( const auto location = cls->getLocation(); const std::string source_location{lambda_source_location(location)}; - if (context().lambda_caller_id() != 0) { + if (context().lambda_caller_id().has_value()) { // Parent is also a lambda (this id points to a lambda operator()) std::string parent_lambda_class_name{"()"}; - if (context().lambda_caller_id() && - diagram().get_participant( + if (diagram().get_participant( context().lambda_caller_id().value())) { auto parent_lambda_class_id = diagram() @@ -1955,7 +1955,7 @@ std::string translation_unit_visitor::make_lambda_name( result = fmt::format( "{}##(lambda {})", parent_lambda_class_name, source_location); } - else if (context().caller_id() != 0 && + else if (context().caller_id().value() != 0 && get_participant(context().caller_id()).has_value()) { auto parent_full_name = get_participant(context().caller_id()).value().full_name_no_ns(); @@ -2044,7 +2044,7 @@ void translation_unit_visitor::ensure_lambda_messages_have_operator_as_target() auto participant = diagram().get_participant(m.to()); if (participant && participant.value().is_lambda() && - participant.value().lambda_operator_id() != 0) { + participant.value().lambda_operator_id().value() != 0) { LOG_DBG("Changing lambda expression target id from {} to {}", m.to(), participant.value().lambda_operator_id()); @@ -2067,7 +2067,7 @@ void translation_unit_visitor::resolve_ids_to_global() active_participants_unique.emplace( local_ast_id_map_.at(id.ast_local_value())); } - else { + else if (id.is_global()) { active_participants_unique.emplace(id); } } @@ -2077,7 +2077,7 @@ void translation_unit_visitor::resolve_ids_to_global() // Change all message callees AST local ids to diagram global ids for (auto &[id, activity] : diagram().sequences()) { for (auto &m : activity.messages()) { - if (!id.is_global() && + if (!m.to().is_global() && local_ast_id_map_.find(m.to().ast_local_value()) != local_ast_id_map_.end()) { m.set_to(local_ast_id_map_.at(m.to().ast_local_value())); @@ -2300,7 +2300,8 @@ std::optional translation_unit_visitor::get_expression_comment( if (raw_comment == nullptr) return {}; - if (!processed_comments_by_caller_id_ + if (!caller_id.is_global() && + !processed_comments_by_caller_id_ .emplace(caller_id.ast_local_value(), raw_comment) .second) { return {}; From 1c9f347c91fc07bbf41f055595ed880b5deecf07 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Tue, 4 Jun 2024 21:01:45 +0200 Subject: [PATCH 3/8] Refactored id_t to types.cpp --- src/common/clang_utils.cc | 5 +- src/common/model/diagram_element.cc | 2 +- src/common/model/diagram_element.h | 2 +- src/common/types.cc | 69 ++++++++++++++++ src/common/types.h | 78 +++---------------- .../json/sequence_diagram_generator.cc | 4 +- .../mermaid/sequence_diagram_generator.cc | 3 +- .../plantuml/sequence_diagram_generator.cc | 4 +- src/sequence_diagram/model/diagram.cc | 3 +- 9 files changed, 95 insertions(+), 75 deletions(-) diff --git a/src/common/clang_utils.cc b/src/common/clang_utils.cc index 66631685..231f08f4 100644 --- a/src/common/clang_utils.cc +++ b/src/common/clang_utils.cc @@ -450,7 +450,10 @@ template <> common::id_t to_id(const clang::CXXRecordDecl &declaration) return to_id(get_qualified_name(declaration)); } -template <> common::id_t to_id(const clang::EnumType &t) { return to_id(*t.getDecl()); } +template <> common::id_t to_id(const clang::EnumType &t) +{ + return to_id(*t.getDecl()); +} template <> common::id_t to_id(const std::filesystem::path &file) { diff --git a/src/common/model/diagram_element.cc b/src/common/model/diagram_element.cc index 97ab0ff4..4051b7c7 100644 --- a/src/common/model/diagram_element.cc +++ b/src/common/model/diagram_element.cc @@ -26,7 +26,7 @@ namespace clanguml::common::model { diagram_element::diagram_element() = default; -const common::id_t & diagram_element::id() const { return id_; } +const common::id_t &diagram_element::id() const { return id_; } void diagram_element::set_id(common::id_t id) { id_ = id; } diff --git a/src/common/model/diagram_element.h b/src/common/model/diagram_element.h index 3074dffe..eeec8a3d 100644 --- a/src/common/model/diagram_element.h +++ b/src/common/model/diagram_element.h @@ -53,7 +53,7 @@ public: * * @return Elements id. */ - const common::id_t& id() const; + const common::id_t &id() const; /** * Set elements id. diff --git a/src/common/types.cc b/src/common/types.cc index 2fe79d12..c2e9286a 100644 --- a/src/common/types.cc +++ b/src/common/types.cc @@ -20,6 +20,75 @@ namespace clanguml::common { +id_t::id_t() + : value_{0ULL} + , is_global_{true} +{ +} + +id_t::id_t(int64_t id) + : value_{static_cast(id)} + , is_global_{false} +{ +} + +id_t::id_t(type id) + : value_{id} + , is_global_{true} +{ +} + +id_t &id_t::operator=(int64_t ast_id) +{ + // Can't assign ast_id if the id is already a global one + assert(!is_global_); + + value_ = static_cast(ast_id); + return *this; +} + +bool id_t::is_global() const { return is_global_; } + +bool operator==(const id_t &lhs, const id_t &rhs) +{ + return (lhs.is_global_ == rhs.is_global_) && (lhs.value_ == rhs.value_); +} + +bool operator==(const id_t &lhs, const uint64_t &v) { return lhs.value_ == v; } + +bool operator!=(const id_t &lhs, const uint64_t &v) +{ + // This is sadly necessary to catch accidental comparisons to empty + // std::optional: + // + // std::optional id{}; + // if(id != 0) { /* id is nullopt, not 0 - so this executes... */ } + // + assert(v != 0); + + return lhs.value_ != v; +} + +bool operator!=(const id_t &lhs, const id_t &rhs) { return !(lhs == rhs); } + +bool operator<(const id_t &lhs, const id_t &rhs) +{ + if (lhs.is_global_ != rhs.is_global_) { + return lhs.value_ < rhs.value_ + 1; + } + + return lhs.value_ < rhs.value_; // Compare values if is_global_ are the same +} + +id_t::type id_t::value() const { return value_; } + +int64_t id_t::ast_local_value() const +{ + assert(!is_global_); + + return static_cast(value_); +} + std::string to_string(const std::string &s) { return s; } std::string to_string(const string_or_regex &sr) { return sr.to_string(); } diff --git a/src/common/types.h b/src/common/types.h index 847283cc..15d78265 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -33,86 +33,32 @@ class id_t { public: using type = uint64_t; - id_t() - : value_{0ULL} - , is_global_{true} - { - } + id_t(); - explicit id_t(int64_t id) - : value_{static_cast(id)} - , is_global_{false} - { - } + explicit id_t(int64_t id); - explicit id_t(type id) - : value_{id} - , is_global_{true} - { - } + explicit id_t(type id); id_t(const id_t &) = default; id_t(id_t &&) noexcept = default; id_t &operator=(const id_t &) = default; id_t &operator=(id_t &&) noexcept = default; - id_t &operator=(int64_t ast_id) - { - assert(!is_global_); - value_ = static_cast(ast_id); - return *this; - } + id_t &operator=(int64_t ast_id); ~id_t() = default; - bool is_global() const { return is_global_; } + bool is_global() const; - friend bool operator==(const id_t &lhs, const id_t &rhs) - { - return (lhs.is_global_ == rhs.is_global_) && (lhs.value_ == rhs.value_); - } + friend bool operator==(const id_t &lhs, const id_t &rhs); + friend bool operator==(const id_t &lhs, const uint64_t &v); + friend bool operator!=(const id_t &lhs, const uint64_t &v); + friend bool operator!=(const id_t &lhs, const id_t &rhs); + friend bool operator<(const id_t &lhs, const id_t &rhs); - friend bool operator==(const id_t &lhs, const uint64_t &v) - { - return lhs.value_ == v; - } + type value() const; - friend bool operator!=(const id_t &lhs, const uint64_t &v) - { - // This is sadly necessary to catch accidental comparisons to empty - // std::optional: - // - // std::optional id{}; - // if(id != 0) { /* id is nullopt, not 0 - so this executes... */ } - // - assert(v != 0); - - return lhs.value_ != v; - } - - friend bool operator!=(const id_t &lhs, const id_t &rhs) - { - return !(lhs == rhs); - } - - friend bool operator<(const id_t &lhs, const id_t &rhs) - { - if (lhs.is_global_ != rhs.is_global_) { - return lhs.value_ < rhs.value_ + 1; - } - - return lhs.value_ < - rhs.value_; // Compare values if is_global_ are the same - } - - type value() const { return value_; } - - int64_t ast_local_value() const - { - assert(!is_global_); - - return static_cast(value_); - } + int64_t ast_local_value() const; private: type value_; diff --git a/src/sequence_diagram/generators/json/sequence_diagram_generator.cc b/src/sequence_diagram/generators/json/sequence_diagram_generator.cc index e62b873c..d401cf35 100644 --- a/src/sequence_diagram/generators/json/sequence_diagram_generator.cc +++ b/src/sequence_diagram/generators/json/sequence_diagram_generator.cc @@ -747,8 +747,8 @@ void generator::generate_diagram(nlohmann::json &parent) const if (to_activity_id == 0) continue; - auto message_chains_unique = - model().get_all_from_to_message_chains(common::id_t{}, *to_activity_id); + auto message_chains_unique = model().get_all_from_to_message_chains( + common::id_t{}, *to_activity_id); nlohmann::json sequence; sequence["to"]["location"] = to_location.location; diff --git a/src/sequence_diagram/generators/mermaid/sequence_diagram_generator.cc b/src/sequence_diagram/generators/mermaid/sequence_diagram_generator.cc index fdf78036..4a8d8e5a 100644 --- a/src/sequence_diagram/generators/mermaid/sequence_diagram_generator.cc +++ b/src/sequence_diagram/generators/mermaid/sequence_diagram_generator.cc @@ -650,7 +650,8 @@ void generator::generate_diagram(std::ostream &ostr) const ostr << indent(1) << from_alias << " " << common::generators::mermaid::to_mermaid( message_t::kReturn) - << " *" << " : "; + << " *" + << " : "; if (config().generate_return_types()) ostr << from.value().return_type(); diff --git a/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc b/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc index ad1a6ac5..7a3b288c 100644 --- a/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc +++ b/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc @@ -552,8 +552,8 @@ void generator::generate_diagram(std::ostream &ostr) const if (!to_activity_id) continue; - auto message_chains_unique = - model().get_all_from_to_message_chains(common::id_t{}, *to_activity_id); + auto message_chains_unique = model().get_all_from_to_message_chains( + common::id_t{}, *to_activity_id); bool first_separator_skipped{false}; for (const auto &mc : message_chains_unique) { diff --git a/src/sequence_diagram/model/diagram.cc b/src/sequence_diagram/model/diagram.cc index 98d033b9..c0eb4ffe 100644 --- a/src/sequence_diagram/model/diagram.cc +++ b/src/sequence_diagram/model/diagram.cc @@ -387,7 +387,8 @@ std::vector diagram::get_all_from_to_message_chains( message_chains_unique.end(), mc) != message_chains_unique.end()) continue; - if (from_activity.value() == 0 || (mc.front().from() == from_activity)) { + if (from_activity.value() == 0 || + (mc.front().from() == from_activity)) { message_chains_unique.push_back(mc); } } From 50851531f971ead87accc21d91e5c84e249f23e3 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Tue, 4 Jun 2024 22:50:53 +0200 Subject: [PATCH 4/8] Fixed clang-tidy warnings --- src/common/model/diagram_element.cc | 3 ++- .../generators/json/sequence_diagram_generator.cc | 4 ++-- src/sequence_diagram/model/participant.cc | 2 +- src/sequence_diagram/visitor/call_expression_context.cc | 2 +- src/sequence_diagram/visitor/translation_unit_visitor.cc | 4 ++-- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/common/model/diagram_element.cc b/src/common/model/diagram_element.cc index 4051b7c7..987505bd 100644 --- a/src/common/model/diagram_element.cc +++ b/src/common/model/diagram_element.cc @@ -42,7 +42,8 @@ void diagram_element::set_parent_element_id(common::id_t id) std::string diagram_element::alias() const { - assert(id_.value() >= 0); + // Only generate alias for global id's + assert(id_.is_global()); return fmt::format("C_{:022}", id_.value()); } diff --git a/src/sequence_diagram/generators/json/sequence_diagram_generator.cc b/src/sequence_diagram/generators/json/sequence_diagram_generator.cc index d401cf35..a4e01c88 100644 --- a/src/sequence_diagram/generators/json/sequence_diagram_generator.cc +++ b/src/sequence_diagram/generators/json/sequence_diagram_generator.cc @@ -744,11 +744,11 @@ void generator::generate_diagram(nlohmann::json &parent) const for (const auto &to_location : config().to()) { auto to_activity_id = model().get_to_activity_id(to_location); - if (to_activity_id == 0) + if (!to_activity_id.has_value()) continue; auto message_chains_unique = model().get_all_from_to_message_chains( - common::id_t{}, *to_activity_id); + common::id_t{}, to_activity_id.value()); nlohmann::json sequence; sequence["to"]["location"] = to_location.location; diff --git a/src/sequence_diagram/model/participant.cc b/src/sequence_diagram/model/participant.cc index 8c5dbc22..28969acf 100644 --- a/src/sequence_diagram/model/participant.cc +++ b/src/sequence_diagram/model/participant.cc @@ -178,7 +178,7 @@ std::string method::method_name() const { return method_name_; } std::string method::alias() const { - assert(class_id_.value() >= 0); + assert(class_id_.is_global()); return fmt::format("C_{:022}", class_id_.value()); } diff --git a/src/sequence_diagram/visitor/call_expression_context.cc b/src/sequence_diagram/visitor/call_expression_context.cc index 241c9bd7..50dedcdb 100644 --- a/src/sequence_diagram/visitor/call_expression_context.cc +++ b/src/sequence_diagram/visitor/call_expression_context.cc @@ -133,7 +133,7 @@ void call_expression_context::update( common::id_t call_expression_context::caller_id() const { if (lambda_caller_id().has_value()) - return *lambda_caller_id(); + return *lambda_caller_id(); // NOLINT return current_caller_id_; } diff --git a/src/sequence_diagram/visitor/translation_unit_visitor.cc b/src/sequence_diagram/visitor/translation_unit_visitor.cc index b8fe4c8a..bffe738e 100644 --- a/src/sequence_diagram/visitor/translation_unit_visitor.cc +++ b/src/sequence_diagram/visitor/translation_unit_visitor.cc @@ -1934,11 +1934,11 @@ std::string translation_unit_visitor::make_lambda_name( // Parent is also a lambda (this id points to a lambda operator()) std::string parent_lambda_class_name{"()"}; if (diagram().get_participant( - context().lambda_caller_id().value())) { + context().lambda_caller_id().value())) { // NOLINT auto parent_lambda_class_id = diagram() .get_participant( - context().lambda_caller_id().value()) + context().lambda_caller_id().value()) // NOLINT .value() .class_id(); From a6a92c3543adc545044fc69c8d4a16b2e9011a10 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Tue, 4 Jun 2024 23:49:42 +0200 Subject: [PATCH 5/8] Updated to clang-tidy-17 --- Makefile | 2 +- .../visitor/translation_unit_visitor.cc | 6 +++--- src/common/generators/generators.h | 1 - .../visitor/translation_unit_visitor.cc | 5 +++-- .../visitor/call_expression_context.cc | 18 +++++++++--------- .../visitor/translation_unit_visitor.cc | 7 ++++--- src/util/util.h | 2 +- 7 files changed, 21 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index 577b6153..bfe2b285 100644 --- a/Makefile +++ b/Makefile @@ -163,7 +163,7 @@ format: .PHONY: debug_tidy tidy: debug_tidy - run-clang-tidy-15 -extra-arg=-Wno-unknown-warning-option -j $(NUMPROC) -p debug_tidy ./src + run-clang-tidy-17 -extra-arg=-Wno-unknown-warning-option -j $(NUMPROC) -p debug_tidy ./src .PHONY: check-formatting check-formatting: diff --git a/src/class_diagram/visitor/translation_unit_visitor.cc b/src/class_diagram/visitor/translation_unit_visitor.cc index 9dbd3d3e..3c9fa101 100644 --- a/src/class_diagram/visitor/translation_unit_visitor.cc +++ b/src/class_diagram/visitor/translation_unit_visitor.cc @@ -917,7 +917,7 @@ void translation_unit_visitor::process_record_parent( std::string destination_multiplicity_str{}; if (destination_multiplicity.has_value()) { destination_multiplicity_str = - std::to_string(*destination_multiplicity); // NOLINT + std::to_string(*destination_multiplicity); } parent_class.value().add_relationship( @@ -1673,8 +1673,8 @@ void translation_unit_visitor::add_relationships(class_ &c, } if (!mulitplicity_provided_in_comment && field.destination_multiplicity().has_value()) { - r.set_multiplicity_destination(std::to_string( - *field.destination_multiplicity())); // NOLINT + r.set_multiplicity_destination( + std::to_string(*field.destination_multiplicity())); } r.set_style(field.style_spec()); diff --git a/src/common/generators/generators.h b/src/common/generators/generators.h index d39dd83d..7f3d38b6 100644 --- a/src/common/generators/generators.h +++ b/src/common/generators/generators.h @@ -22,7 +22,6 @@ #include "class_diagram/generators/plantuml/class_diagram_generator.h" #include "cli/cli_handler.h" #include "common/compilation_database.h" -#include "common/generators/generators.h" #include "common/model/diagram_filter.h" #include "config/config.h" #include "include_diagram/generators/json/include_diagram_generator.h" diff --git a/src/package_diagram/visitor/translation_unit_visitor.cc b/src/package_diagram/visitor/translation_unit_visitor.cc index fcfcdb21..c020147e 100644 --- a/src/package_diagram/visitor/translation_unit_visitor.cc +++ b/src/package_diagram/visitor/translation_unit_visitor.cc @@ -684,8 +684,9 @@ std::vector translation_unit_visitor::get_parent_package_ids( std::optional parent_id = id; while (parent_id.has_value()) { - parent_ids.push_back(parent_id.value()); - auto parent = this->diagram().get(parent_id.value()); + const auto pid = parent_id.value(); // NOLINT + parent_ids.push_back(pid); + auto parent = this->diagram().get(pid); if (parent) parent_id = parent.value().parent_element_id(); else diff --git a/src/sequence_diagram/visitor/call_expression_context.cc b/src/sequence_diagram/visitor/call_expression_context.cc index 50dedcdb..1194daa3 100644 --- a/src/sequence_diagram/visitor/call_expression_context.cc +++ b/src/sequence_diagram/visitor/call_expression_context.cc @@ -158,7 +158,7 @@ void call_expression_context::enter_lambda_expression(common::id_t id) assert(id.value() != 0); - current_lambda_caller_id_.push(id); + current_lambda_caller_id_.emplace(id); } void call_expression_context::leave_lambda_expression() @@ -182,7 +182,7 @@ clang::IfStmt *call_expression_context::current_ifstmt() const void call_expression_context::enter_ifstmt(clang::IfStmt *stmt) { - if_stmt_stack_.push(stmt); + if_stmt_stack_.emplace(stmt); } void call_expression_context::leave_ifstmt() @@ -197,7 +197,7 @@ void call_expression_context::enter_elseifstmt(clang::IfStmt *stmt) { assert(current_ifstmt() != nullptr); - elseif_stmt_stacks_[current_ifstmt()].push(stmt); + elseif_stmt_stacks_[current_ifstmt()].emplace(stmt); } clang::IfStmt *call_expression_context::current_elseifstmt() const @@ -221,7 +221,7 @@ clang::Stmt *call_expression_context::current_loopstmt() const void call_expression_context::enter_loopstmt(clang::Stmt *stmt) { - loop_stmt_stack_.push(stmt); + loop_stmt_stack_.emplace(stmt); } void call_expression_context::leave_loopstmt() @@ -241,12 +241,12 @@ call_expression_context::current_callexpr() const void call_expression_context::enter_callexpr(clang::CallExpr *expr) { - call_expr_stack_.push(expr); + call_expr_stack_.emplace(expr); } void call_expression_context::enter_callexpr(clang::CXXConstructExpr *expr) { - call_expr_stack_.push(expr); + call_expr_stack_.emplace(expr); } void call_expression_context::leave_callexpr() @@ -266,7 +266,7 @@ clang::Stmt *call_expression_context::current_trystmt() const void call_expression_context::enter_trystmt(clang::Stmt *stmt) { - try_stmt_stack_.push(stmt); + try_stmt_stack_.emplace(stmt); } void call_expression_context::leave_trystmt() @@ -285,7 +285,7 @@ clang::SwitchStmt *call_expression_context::current_switchstmt() const void call_expression_context::enter_switchstmt(clang::SwitchStmt *stmt) { - switch_stmt_stack_.push(stmt); + switch_stmt_stack_.emplace(stmt); } void call_expression_context::leave_switchstmt() @@ -306,7 +306,7 @@ call_expression_context::current_conditionaloperator() const void call_expression_context::enter_conditionaloperator( clang::ConditionalOperator *stmt) { - conditional_operator_stack_.push(stmt); + conditional_operator_stack_.emplace(stmt); } void call_expression_context::leave_conditionaloperator() diff --git a/src/sequence_diagram/visitor/translation_unit_visitor.cc b/src/sequence_diagram/visitor/translation_unit_visitor.cc index bffe738e..643ba7fa 100644 --- a/src/sequence_diagram/visitor/translation_unit_visitor.cc +++ b/src/sequence_diagram/visitor/translation_unit_visitor.cc @@ -1930,15 +1930,16 @@ std::string translation_unit_visitor::make_lambda_name( const auto location = cls->getLocation(); const std::string source_location{lambda_source_location(location)}; - if (context().lambda_caller_id().has_value()) { + const auto maybe_lambda_caller_id = context().lambda_caller_id(); + if (maybe_lambda_caller_id.has_value()) { // Parent is also a lambda (this id points to a lambda operator()) std::string parent_lambda_class_name{"()"}; if (diagram().get_participant( - context().lambda_caller_id().value())) { // NOLINT + maybe_lambda_caller_id.value())) { auto parent_lambda_class_id = diagram() .get_participant( - context().lambda_caller_id().value()) // NOLINT + maybe_lambda_caller_id.value()) .value() .class_id(); diff --git a/src/util/util.h b/src/util/util.h index d547fa18..1db0af1d 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -164,7 +164,7 @@ template std::unique_ptr unique_pointer_cast(std::unique_ptr &&p) noexcept { if (T *const converted = dynamic_cast(p.get())) { - p.release(); // NOLINT + std::move(p).release(); // NOLINT return std::unique_ptr{converted}; } From 2cf9d2f22a73a1a21c4dcbe9d66193f0e6ce09e1 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Wed, 5 Jun 2024 00:15:21 +0200 Subject: [PATCH 6/8] Added test case for common::id_t --- tests/CMakeLists.txt | 1 + tests/test_types.cc | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 tests/test_types.cc diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 862b36cd..8a106be2 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -84,6 +84,7 @@ if(APPLE) endif(APPLE) set(TEST_NAMES + test_types test_util test_model test_cases diff --git a/tests/test_types.cc b/tests/test_types.cc new file mode 100644 index 00000000..439973ab --- /dev/null +++ b/tests/test_types.cc @@ -0,0 +1,43 @@ +/** + * @file tests/test_types.cc + * + * Copyright (c) 2021-2024 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. + */ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN + +#include "common/types.h" + +#include "doctest/doctest.h" + +TEST_CASE("Test common::id_t") +{ + using namespace clanguml; + + common::id_t empty{}; + + REQUIRE(empty.is_global()); + REQUIRE_EQ(empty.value(), 0); + + common::id_t local_id{(int64_t)100}; + REQUIRE_EQ(local_id.ast_local_value(), 100); + REQUIRE_EQ(local_id.value(), 100); + REQUIRE(!local_id.is_global()); + + common::id_t global_id{(uint64_t)100}; + REQUIRE_EQ(global_id.value(), 100); + REQUIRE(global_id.is_global()); + + REQUIRE(local_id != global_id); +} \ No newline at end of file From 420475ab642e86c97a7fa903f4cd28f15492bba1 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Wed, 5 Jun 2024 21:19:46 +0200 Subject: [PATCH 7/8] Renamed common::id_t to eid_t to avoid conflicts with system id_t --- .../mermaid/class_diagram_generator.cc | 7 ++- .../plantuml/class_diagram_generator.cc | 6 +- .../plantuml/class_diagram_generator.h | 1 + src/class_diagram/model/class.h | 2 - src/class_diagram/model/class_parent.cc | 4 +- src/class_diagram/model/class_parent.h | 8 ++- src/class_diagram/model/diagram.cc | 10 ++-- src/class_diagram/model/diagram.h | 11 ++-- .../visitor/translation_unit_visitor.cc | 20 +++---- .../visitor/translation_unit_visitor.h | 6 +- src/common/clang_utils.cc | 22 +++---- src/common/clang_utils.h | 22 +++---- src/common/model/diagram.h | 4 +- src/common/model/diagram_element.cc | 8 +-- src/common/model/diagram_element.h | 12 ++-- src/common/model/diagram_filter.cc | 8 +-- src/common/model/diagram_filter.h | 19 +++--- src/common/model/element_view.h | 4 +- src/common/model/package.h | 4 +- src/common/model/relationship.cc | 9 +-- src/common/model/relationship.h | 10 ++-- src/common/model/source_file.h | 4 +- src/common/model/template_parameter.cc | 2 +- src/common/model/template_parameter.h | 10 ++-- src/common/types.cc | 24 ++++---- src/common/types.h | 49 +++++++++------ src/common/visitor/ast_id_mapper.cc | 4 +- src/common/visitor/ast_id_mapper.h | 10 ++-- src/common/visitor/template_builder.h | 19 +++--- src/common/visitor/translation_unit_visitor.h | 4 +- src/include_diagram/model/diagram.cc | 2 +- src/include_diagram/model/diagram.h | 8 +-- .../visitor/translation_unit_visitor.cc | 7 +-- .../visitor/translation_unit_visitor.h | 9 +-- src/package_diagram/model/diagram.cc | 4 +- src/package_diagram/model/diagram.h | 10 ++-- .../visitor/translation_unit_visitor.cc | 11 ++-- .../visitor/translation_unit_visitor.h | 10 ++-- .../json/sequence_diagram_generator.cc | 18 +++--- .../json/sequence_diagram_generator.h | 14 +++-- .../mermaid/sequence_diagram_generator.cc | 18 +++--- .../mermaid/sequence_diagram_generator.h | 10 ++-- .../plantuml/sequence_diagram_generator.cc | 19 +++--- .../plantuml/sequence_diagram_generator.h | 10 ++-- src/sequence_diagram/model/activity.cc | 4 +- src/sequence_diagram/model/activity.h | 6 +- src/sequence_diagram/model/diagram.cc | 48 +++++++-------- src/sequence_diagram/model/diagram.h | 41 +++++++------ src/sequence_diagram/model/message.cc | 10 ++-- src/sequence_diagram/model/message.h | 14 ++--- src/sequence_diagram/model/participant.cc | 4 +- src/sequence_diagram/model/participant.h | 13 ++-- .../visitor/call_expression_context.cc | 10 ++-- .../visitor/call_expression_context.h | 14 +++-- .../visitor/translation_unit_visitor.cc | 60 +++++++++---------- .../visitor/translation_unit_visitor.h | 19 +++--- tests/test_types.cc | 10 ++-- 57 files changed, 370 insertions(+), 356 deletions(-) diff --git a/src/class_diagram/generators/mermaid/class_diagram_generator.cc b/src/class_diagram/generators/mermaid/class_diagram_generator.cc index b37c0c0a..5af414d0 100644 --- a/src/class_diagram/generators/mermaid/class_diagram_generator.cc +++ b/src/class_diagram/generators/mermaid/class_diagram_generator.cc @@ -24,6 +24,7 @@ namespace clanguml::class_diagram::generators::mermaid { +using clanguml::common::eid_t; using clanguml::common::generators::mermaid::indent; using clanguml::common::generators::mermaid::render_name; @@ -405,7 +406,7 @@ void generator::generate_relationships( LOG_DBG("== Processing relationship {}", to_string(r.type())); std::stringstream relstr; - clanguml::common::id_t destination{}; + eid_t destination{}; try { destination = r.destination(); @@ -513,7 +514,7 @@ void generator::generate_relationships( LOG_DBG("== Processing relationship {}", to_string(r.type())); std::stringstream relstr; - clanguml::common::id_t destination{}; + eid_t destination{}; try { destination = r.destination(); @@ -584,7 +585,7 @@ void generator::generate_relationships(const enum_ &e, std::ostream &ostr) const if (!model().should_include(r.type())) continue; - clanguml::common::id_t destination{}; + eid_t destination{}; std::stringstream relstr; try { destination = r.destination(); diff --git a/src/class_diagram/generators/plantuml/class_diagram_generator.cc b/src/class_diagram/generators/plantuml/class_diagram_generator.cc index 11bdbc78..8a11ca2e 100644 --- a/src/class_diagram/generators/plantuml/class_diagram_generator.cc +++ b/src/class_diagram/generators/plantuml/class_diagram_generator.cc @@ -488,7 +488,7 @@ void generator::generate_relationships( plantuml_common::to_plantuml(r, config())); std::stringstream relstr; - clanguml::common::id_t destination{}; + eid_t destination{}; try { destination = r.destination(); @@ -583,7 +583,7 @@ void generator::generate_relationships( LOG_DBG("== Processing relationship {}", to_string(r.type())); std::stringstream relstr; - clanguml::common::id_t destination{}; + eid_t destination{}; try { destination = r.destination(); @@ -664,7 +664,7 @@ void generator::generate_relationships(const enum_ &e, std::ostream &ostr) const if (!model().should_include(r.type())) continue; - clanguml::common::id_t destination{}; + eid_t destination{}; std::stringstream relstr; try { destination = r.destination(); diff --git a/src/class_diagram/generators/plantuml/class_diagram_generator.h b/src/class_diagram/generators/plantuml/class_diagram_generator.h index 0d19eb2e..451a8df9 100644 --- a/src/class_diagram/generators/plantuml/class_diagram_generator.h +++ b/src/class_diagram/generators/plantuml/class_diagram_generator.h @@ -52,6 +52,7 @@ using clanguml::class_diagram::model::class_member; using clanguml::class_diagram::model::class_method; using clanguml::class_diagram::model::concept_; using clanguml::class_diagram::model::enum_; +using clanguml::common::eid_t; using clanguml::common::model::access_t; using clanguml::common::model::package; using clanguml::common::model::relationship; diff --git a/src/class_diagram/model/class.h b/src/class_diagram/model/class.h index 5e20990c..414ec45e 100644 --- a/src/class_diagram/model/class.h +++ b/src/class_diagram/model/class.h @@ -185,8 +185,6 @@ struct hash> { const std::reference_wrapper &key) const { - using clanguml::common::id_t; - return std::hash{}(key.get().id().value()); } }; diff --git a/src/class_diagram/model/class_parent.cc b/src/class_diagram/model/class_parent.cc index 35588082..b20cc1c5 100644 --- a/src/class_diagram/model/class_parent.cc +++ b/src/class_diagram/model/class_parent.cc @@ -24,9 +24,9 @@ void class_parent::set_name(const std::string &name) { name_ = name; } std::string class_parent::name() const { return name_; } -void class_parent::set_id(clanguml::common::id_t id) { id_ = id; } +void class_parent::set_id(eid_t id) { id_ = id; } -clanguml::common::id_t class_parent::id() const noexcept { return id_; } +eid_t class_parent::id() const noexcept { return id_; } void class_parent::is_virtual(bool is_virtual) { is_virtual_ = is_virtual; } diff --git a/src/class_diagram/model/class_parent.h b/src/class_diagram/model/class_parent.h index 1e0521fe..1dc5aa3f 100644 --- a/src/class_diagram/model/class_parent.h +++ b/src/class_diagram/model/class_parent.h @@ -25,6 +25,8 @@ namespace clanguml::class_diagram::model { +using clanguml::common::eid_t; + /** * @brief Class parent relationship model. * @@ -59,14 +61,14 @@ public: * * @param id Id of the parent class. */ - void set_id(clanguml::common::id_t id); + void set_id(eid_t id); /** * @brief Get the id of class parent. * * @return Id of the parent class. */ - clanguml::common::id_t id() const noexcept; + eid_t id() const noexcept; /** * @brief Set whether the parent is virtual. @@ -97,7 +99,7 @@ public: common::model::access_t access() const; private: - clanguml::common::id_t id_{}; + eid_t id_{}; std::string name_; bool is_virtual_{false}; common::model::access_t access_{common::model::access_t::kPublic}; diff --git a/src/class_diagram/model/diagram.cc b/src/class_diagram/model/diagram.cc index 270bef0b..a1aa7eca 100644 --- a/src/class_diagram/model/diagram.cc +++ b/src/class_diagram/model/diagram.cc @@ -74,7 +74,7 @@ common::optional_ref diagram::get( } common::optional_ref diagram::get( - const clanguml::common::id_t id) const + const eid_t id) const { common::optional_ref res; @@ -153,7 +153,7 @@ void diagram::get_parents( } } -bool diagram::has_element(clanguml::common::id_t id) const +bool diagram::has_element(eid_t id) const { const auto has_class = std::any_of(classes().begin(), classes().end(), [id](const auto &c) { return c.get().id() == id; }); @@ -171,7 +171,7 @@ bool diagram::has_element(clanguml::common::id_t id) const [id](const auto &c) { return c.get().id() == id; }); } -std::string diagram::to_alias(clanguml::common::id_t id) const +std::string diagram::to_alias(eid_t id) const { LOG_DBG("Looking for alias for {}", id); @@ -224,12 +224,12 @@ inja::json diagram::context() const void diagram::remove_redundant_dependencies() { - using common::id_t; + using common::eid_t; using common::model::relationship; using common::model::relationship_t; for (auto &c : element_view::view()) { - std::set dependency_relationships_to_remove; + std::set dependency_relationships_to_remove; for (auto &r : c.get().relationships()) { if (r.type() != relationship_t::kDependency) diff --git a/src/class_diagram/model/diagram.h b/src/class_diagram/model/diagram.h index dc023048..d5402fdb 100644 --- a/src/class_diagram/model/diagram.h +++ b/src/class_diagram/model/diagram.h @@ -103,7 +103,7 @@ public: * @param id Element id. * @return Optional reference to a diagram element. */ - opt_ref get(common::id_t id) const override; + opt_ref get(eid_t id) const override; /** * @brief Get list of references to classes in the diagram model. @@ -172,7 +172,7 @@ public: * @param id Id of the element * @return Optional reference to a diagram element */ - template opt_ref find(common::id_t id) const; + template opt_ref find(eid_t id) const; /** * @brief Get reference to vector of elements of specific type @@ -218,7 +218,7 @@ public: * @param id Id of the diagram element. * @return PlantUML alias. */ - std::string to_alias(common::id_t id) const; + std::string to_alias(eid_t id) const; /** * @brief Given an initial set of classes, add all their parents to the @@ -235,7 +235,7 @@ public: * @param id Id of the element. * @return True, if diagram contains an element with a specific id. */ - bool has_element(common::id_t id) const override; + bool has_element(eid_t id) const override; /** * @brief Remove redundant dependency relationships @@ -431,8 +431,7 @@ std::vector> diagram::find( return result; } -template -opt_ref diagram::find(common::id_t id) const +template opt_ref diagram::find(eid_t id) const { for (const auto &element : element_view::view()) { if (element.get().id() == id) { diff --git a/src/class_diagram/visitor/translation_unit_visitor.cc b/src/class_diagram/visitor/translation_unit_visitor.cc index 3c9fa101..1280874c 100644 --- a/src/class_diagram/visitor/translation_unit_visitor.cc +++ b/src/class_diagram/visitor/translation_unit_visitor.cc @@ -123,14 +123,14 @@ bool translation_unit_visitor::VisitEnumDecl(clang::EnumDecl *enm) const auto *parent = enm->getParent(); // Id of parent class or struct in which this enum is potentially nested - std::optional parent_id_opt; + std::optional parent_id_opt; if (parent != nullptr) { const auto *parent_record_decl = clang::dyn_cast(parent); if (parent_record_decl != nullptr) { - common::id_t local_id{parent_record_decl->getID()}; + eid_t local_id{parent_record_decl->getID()}; // First check if the parent has been added to the diagram as // regular class @@ -222,7 +222,7 @@ bool translation_unit_visitor::VisitClassTemplateSpecializationDecl( if (!template_specialization.template_specialization_found()) { // Only do this if we haven't found a better specialization during // construction of the template specialization - const common::id_t ast_id{cls->getSpecializedTemplate()->getID()}; + const eid_t ast_id{cls->getSpecializedTemplate()->getID()}; const auto maybe_id = id_mapper().get_global_id(ast_id); if (maybe_id.has_value()) template_specialization.add_relationship( @@ -621,7 +621,7 @@ void translation_unit_visitor::process_concept_specialization_relationships( should_include(cpt)) { const auto cpt_name = cpt->getNameAsString(); - const common::id_t ast_id{cpt->getID()}; + const eid_t ast_id{cpt->getID()}; const auto maybe_id = id_mapper().get_global_id(ast_id); if (!maybe_id) return; @@ -707,7 +707,7 @@ bool translation_unit_visitor::VisitCXXRecordDecl(clang::CXXRecordDecl *cls) if (cls->isTemplated() && (cls->getDescribedTemplate() != nullptr)) { // If the described templated of this class is already in the model // skip it: - const common::id_t ast_id{cls->getDescribedTemplate()->getID()}; + const eid_t ast_id{cls->getDescribedTemplate()->getID()}; if (id_mapper().get_global_id(ast_id)) return true; } @@ -869,7 +869,7 @@ void translation_unit_visitor::process_record_parent( { const auto *parent = cls->getParent(); - std::optional id_opt; + std::optional id_opt; auto parent_ns = ns; if (parent != nullptr) { @@ -879,7 +879,7 @@ void translation_unit_visitor::process_record_parent( if (parent_record_decl != nullptr) { parent_ns = common::get_tag_namespace(*parent_record_decl); - common::id_t ast_id{parent_record_decl->getID()}; + eid_t ast_id{parent_record_decl->getID()}; // First check if the parent has been added to the diagram as // regular class @@ -2176,7 +2176,7 @@ void translation_unit_visitor::add_concept(std::unique_ptr &&c) void translation_unit_visitor::find_instantiation_relationships( common::model::template_element &template_instantiation_base, - const std::string &full_name, common::id_t templated_decl_id) + const std::string &full_name, eid_t templated_decl_id) { auto &template_instantiation = dynamic_cast( template_instantiation_base); @@ -2187,7 +2187,7 @@ void translation_unit_visitor::find_instantiation_relationships( std::string best_match_full_name{}; auto full_template_name = template_instantiation.full_name(false); int best_match{}; - common::id_t best_match_id{}; + eid_t best_match_id{}; for (const auto templ : diagram().classes()) { if (templ.get() == template_instantiation) @@ -2206,7 +2206,7 @@ void translation_unit_visitor::find_instantiation_relationships( } auto templated_decl_global_id = - id_mapper().get_global_id(templated_decl_id).value_or(common::id_t{}); + id_mapper().get_global_id(templated_decl_id).value_or(eid_t{}); if (best_match_id.value() > 0) { destination = best_match_full_name; diff --git a/src/class_diagram/visitor/translation_unit_visitor.h b/src/class_diagram/visitor/translation_unit_visitor.h index d5d6e35b..e4196e8a 100644 --- a/src/class_diagram/visitor/translation_unit_visitor.h +++ b/src/class_diagram/visitor/translation_unit_visitor.h @@ -45,6 +45,7 @@ using clanguml::class_diagram::model::concept_; using clanguml::class_diagram::model::diagram; using clanguml::class_diagram::model::enum_; using clanguml::class_diagram::model::method_parameter; +using clanguml::common::eid_t; using clanguml::common::model::access_t; using clanguml::common::model::namespace_; using clanguml::common::model::relationship; @@ -149,7 +150,7 @@ public: void find_instantiation_relationships( common::model::template_element &template_instantiation_base, - const std::string &full_name, common::id_t templated_decl_id); + const std::string &full_name, eid_t templated_decl_id); private: /** @@ -432,8 +433,7 @@ private: template_builder_t template_builder_; - std::map> + std::map> forward_declarations_; std::map common::id_t to_id(const std::string &full_name) +template <> eid_t to_id(const std::string &full_name) { - return static_cast(std::hash{}(full_name)); + return static_cast(std::hash{}(full_name)); } -common::id_t to_id(const clang::QualType &type, const clang::ASTContext &ctx) +eid_t to_id(const clang::QualType &type, const clang::ASTContext &ctx) { return to_id(common::to_string(type, ctx)); } -template <> common::id_t to_id(const clang::NamespaceDecl &declaration) +template <> eid_t to_id(const clang::NamespaceDecl &declaration) { return to_id(get_qualified_name(declaration)); } -template <> common::id_t to_id(const clang::RecordDecl &declaration) +template <> eid_t to_id(const clang::RecordDecl &declaration) { return to_id(get_qualified_name(declaration)); } -template <> common::id_t to_id(const clang::EnumDecl &declaration) +template <> eid_t to_id(const clang::EnumDecl &declaration) { return to_id(get_qualified_name(declaration)); } -template <> common::id_t to_id(const clang::TagDecl &declaration) +template <> eid_t to_id(const clang::TagDecl &declaration) { return to_id(get_qualified_name(declaration)); } -template <> common::id_t to_id(const clang::CXXRecordDecl &declaration) +template <> eid_t to_id(const clang::CXXRecordDecl &declaration) { return to_id(get_qualified_name(declaration)); } -template <> common::id_t to_id(const clang::EnumType &t) +template <> eid_t to_id(const clang::EnumType &t) { return to_id(*t.getDecl()); } -template <> common::id_t to_id(const std::filesystem::path &file) +template <> eid_t to_id(const std::filesystem::path &file) { return to_id(file.lexically_normal().string()); } -template <> common::id_t to_id(const clang::TemplateArgument &template_argument) +template <> eid_t to_id(const clang::TemplateArgument &template_argument) { if (template_argument.getKind() == clang::TemplateArgument::Type) { if (const auto *enum_type = diff --git a/src/common/clang_utils.h b/src/common/clang_utils.h index 80f4c7db..b6df132c 100644 --- a/src/common/clang_utils.h +++ b/src/common/clang_utils.h @@ -178,27 +178,27 @@ bool is_subexpr_of(const clang::Stmt *parent_stmt, const clang::Stmt *sub_stmt); * * @{ */ -template common::id_t to_id(const T &declaration); +template eid_t to_id(const T &declaration); -template <> common::id_t to_id(const std::string &full_name); +template <> eid_t to_id(const std::string &full_name); -common::id_t to_id(const clang::QualType &type, const clang::ASTContext &ctx); +eid_t to_id(const clang::QualType &type, const clang::ASTContext &ctx); -template <> common::id_t to_id(const clang::NamespaceDecl &declaration); +template <> eid_t to_id(const clang::NamespaceDecl &declaration); -template <> common::id_t to_id(const clang::CXXRecordDecl &declaration); +template <> eid_t to_id(const clang::CXXRecordDecl &declaration); -template <> common::id_t to_id(const clang::RecordDecl &declaration); +template <> eid_t to_id(const clang::RecordDecl &declaration); -template <> common::id_t to_id(const clang::EnumDecl &declaration); +template <> eid_t to_id(const clang::EnumDecl &declaration); -template <> common::id_t to_id(const clang::TagDecl &declaration); +template <> eid_t to_id(const clang::TagDecl &declaration); -template <> common::id_t to_id(const clang::EnumType &type); +template <> eid_t to_id(const clang::EnumType &type); -template <> common::id_t to_id(const clang::TemplateSpecializationType &type); +template <> eid_t to_id(const clang::TemplateSpecializationType &type); -template <> common::id_t to_id(const std::filesystem::path &type); +template <> eid_t to_id(const std::filesystem::path &type); /** @} */ // end of to_id /** diff --git a/src/common/model/diagram.h b/src/common/model/diagram.h index 0c1b497d..0cd8568f 100644 --- a/src/common/model/diagram.h +++ b/src/common/model/diagram.h @@ -70,7 +70,7 @@ public: * @return Optional reference to a diagram element. */ virtual common::optional_ref get( - common::id_t id) const = 0; + eid_t id) const = 0; /** * Return optional reference to a diagram_element by name and namespace. @@ -152,7 +152,7 @@ public: // Disallow std::string overload bool should_include(const std::string &s) const = delete; - virtual bool has_element(const common::id_t /*id*/) const { return false; } + virtual bool has_element(const eid_t /*id*/) const { return false; } virtual bool should_include( const namespace_ &ns, const std::string &name) const; diff --git a/src/common/model/diagram_element.cc b/src/common/model/diagram_element.cc index 987505bd..98824181 100644 --- a/src/common/model/diagram_element.cc +++ b/src/common/model/diagram_element.cc @@ -26,16 +26,16 @@ namespace clanguml::common::model { diagram_element::diagram_element() = default; -const common::id_t &diagram_element::id() const { return id_; } +const eid_t &diagram_element::id() const { return id_; } -void diagram_element::set_id(common::id_t id) { id_ = id; } +void diagram_element::set_id(eid_t id) { id_ = id; } -std::optional diagram_element::parent_element_id() const +std::optional diagram_element::parent_element_id() const { return parent_element_id_; } -void diagram_element::set_parent_element_id(common::id_t id) +void diagram_element::set_parent_element_id(eid_t id) { parent_element_id_ = id; } diff --git a/src/common/model/diagram_element.h b/src/common/model/diagram_element.h index eeec8a3d..50b18297 100644 --- a/src/common/model/diagram_element.h +++ b/src/common/model/diagram_element.h @@ -53,28 +53,28 @@ public: * * @return Elements id. */ - const common::id_t &id() const; + const eid_t &id() const; /** * Set elements id. * * @param id Elements id. */ - void set_id(common::id_t id); + void set_id(eid_t id); /** * Get elements parent package id. * * @return Parent package id if element is nested. */ - std::optional parent_element_id() const; + std::optional parent_element_id() const; /** * Set elements parent package id. * * @param id Id of parent package. */ - void set_parent_element_id(id_t id); + void set_parent_element_id(eid_t id); /** * @brief Return elements' diagram alias. @@ -185,8 +185,8 @@ public: void complete(bool completed); private: - id_t id_{}; - std::optional parent_element_id_{}; + eid_t id_{}; + std::optional parent_element_id_{}; std::string name_; std::vector relationships_; bool nested_{false}; diff --git a/src/common/model/diagram_filter.cc b/src/common/model/diagram_filter.cc index d2406f60..e290215f 100644 --- a/src/common/model/diagram_filter.cc +++ b/src/common/model/diagram_filter.cc @@ -81,7 +81,7 @@ const clanguml::common::optional_ref get( } template <> -clanguml::common::id_t destination_comparator( +eid_t destination_comparator( const common::model::source_file &f) { return f.id(); @@ -690,7 +690,7 @@ void context_filter::initialize_effective_context( // Now repeat radius times - extend the effective context with elements // matching in direct relationship to what is in context auto radius_counter = context.radius; - std::set current_iteration_context; + std::set current_iteration_context; while (radius_counter > 0 && effective_context_extended) { // If at any iteration the effective context was not extended - we @@ -725,8 +725,8 @@ void context_filter::initialize_effective_context( } void context_filter::find_elements_inheritance_relationship(const diagram &d, - std::set &effective_context, - std::set ¤t_iteration_context) const + std::set &effective_context, + std::set ¤t_iteration_context) const { const auto &cd = dynamic_cast(d); diff --git a/src/common/model/diagram_filter.h b/src/common/model/diagram_filter.h index 2176e13a..df8f82d4 100644 --- a/src/common/model/diagram_filter.h +++ b/src/common/model/diagram_filter.h @@ -37,6 +37,8 @@ namespace clanguml::common::model { +using clanguml::common::eid_t; + /** * Diagram filters can be add in 2 modes: * - inclusive - the elements that match are included in the diagram @@ -55,15 +57,12 @@ template const clanguml::common::optional_ref get( const DiagramT &d, const std::string &full_name); -template -common::id_t destination_comparator(const ElementT &e) +template eid_t destination_comparator(const ElementT &e) { return e.id(); } -template <> -clanguml::common::id_t destination_comparator( - const common::model::source_file &f); +template <> eid_t destination_comparator(const common::model::source_file &f); } // namespace detail /** @@ -493,8 +492,8 @@ private: template void find_elements_in_direct_relationship(const diagram &d, - std::set &effective_context, - std::set ¤t_iteration_context) const + std::set &effective_context, + std::set ¤t_iteration_context) const { static_assert(std::is_same_v || std::is_same_v || @@ -535,8 +534,8 @@ private: } void find_elements_inheritance_relationship(const diagram &d, - std::set &effective_context, - std::set ¤t_iteration_context) const; + std::set &effective_context, + std::set ¤t_iteration_context) const; std::vector context_; @@ -544,7 +543,7 @@ private: * Represents all elements which should belong to the diagram based * on this filter. It is populated by the initialize() method. */ - mutable std::vector> effective_contexts_; + mutable std::vector> effective_contexts_; /*! Flag to mark whether the filter context has been computed */ mutable bool initialized_{false}; diff --git a/src/common/model/element_view.h b/src/common/model/element_view.h index bd3ad090..bf7da9ea 100644 --- a/src/common/model/element_view.h +++ b/src/common/model/element_view.h @@ -21,6 +21,8 @@ namespace clanguml::common::model { +using clanguml::common::eid_t; + /** * Provides type based views over elements in a diagram. * @@ -58,7 +60,7 @@ public: * * @return */ - common::optional_ref get(clanguml::common::id_t id) const + common::optional_ref get(eid_t id) const { for (const auto &e : elements_) { if (e.get().id() == id) { diff --git a/src/common/model/package.h b/src/common/model/package.h index 981ad5ae..98fffd41 100644 --- a/src/common/model/package.h +++ b/src/common/model/package.h @@ -89,9 +89,9 @@ struct hash> { const std::reference_wrapper &key) const { - using clanguml::common::id_t; + using clanguml::common::eid_t; - return std::hash{}(key.get().id().value()); + return key.get().id().value(); } }; } // namespace std \ No newline at end of file diff --git a/src/common/model/relationship.cc b/src/common/model/relationship.cc index fa02676e..8762ee2b 100644 --- a/src/common/model/relationship.cc +++ b/src/common/model/relationship.cc @@ -22,7 +22,7 @@ namespace clanguml::common::model { -relationship::relationship(relationship_t type, common::id_t destination, +relationship::relationship(relationship_t type, eid_t destination, access_t access, std::string label, std::string multiplicity_source, std::string multiplicity_destination) : type_{type} @@ -38,15 +38,12 @@ void relationship::set_type(relationship_t type) noexcept { type_ = type; } relationship_t relationship::type() const noexcept { return type_; } -void relationship::set_destination(common::id_t destination) +void relationship::set_destination(eid_t destination) { destination_ = destination; } -clanguml::common::id_t relationship::destination() const -{ - return destination_; -} +eid_t relationship::destination() const { return destination_; } void relationship::set_multiplicity_source( const std::string &multiplicity_source) diff --git a/src/common/model/relationship.h b/src/common/model/relationship.h index 400ff663..1b98a7cf 100644 --- a/src/common/model/relationship.h +++ b/src/common/model/relationship.h @@ -25,6 +25,8 @@ namespace clanguml::common::model { +using clanguml::common::eid_t; + /** * @brief Class representing any relationship other than inheritance * @@ -47,7 +49,7 @@ public: * @param multiplicity_source Multiplicity at the source * @param multiplicity_destination Multiplicity at the destination */ - relationship(relationship_t type, clanguml::common::id_t destination, + relationship(relationship_t type, eid_t destination, access_t access = access_t::kPublic, std::string label = "", std::string multiplicity_source = "", std::string multiplicity_destination = ""); @@ -74,14 +76,14 @@ public: * * @param destination Target element id. */ - void set_destination(common::id_t destination); + void set_destination(eid_t destination); /** * Get the id of the target element of this relationship. * * @return Target element id. */ - common::id_t destination() const; + eid_t destination() const; /** * Set the relationship multiplicity at the source. @@ -144,7 +146,7 @@ public: private: relationship_t type_; - clanguml::common::id_t destination_; + eid_t destination_; std::string multiplicity_source_; std::string multiplicity_destination_; std::string label_; diff --git a/src/common/model/source_file.h b/src/common/model/source_file.h index 46007d72..fc1b5176 100644 --- a/src/common/model/source_file.h +++ b/src/common/model/source_file.h @@ -210,9 +210,7 @@ struct hash> { const std::reference_wrapper &key) const { - using clanguml::common::id_t; - - return std::hash{}(key.get().id().value()); + return key.get().id().value(); } }; } // namespace std \ No newline at end of file diff --git a/src/common/model/template_parameter.cc b/src/common/model/template_parameter.cc index c66b40b3..447ad29e 100644 --- a/src/common/model/template_parameter.cc +++ b/src/common/model/template_parameter.cc @@ -505,7 +505,7 @@ std::string template_parameter::to_string( } bool template_parameter::find_nested_relationships( - std::vector> + std::vector> &nested_relationships, common::model::relationship_t hint, const std::function &should_include) diff --git a/src/common/model/template_parameter.h b/src/common/model/template_parameter.h index 27f5270f..854b9536 100644 --- a/src/common/model/template_parameter.h +++ b/src/common/model/template_parameter.h @@ -29,6 +29,8 @@ namespace clanguml::common::model { +using clanguml::common::eid_t; + /** * Type of template parameter or argument. */ @@ -166,14 +168,14 @@ public: * * @param id Id of parameter */ - void set_id(const common::id_t &id) { id_ = id; } + void set_id(const eid_t &id) { id_ = id; } /** * Get id of the template parameter * * @return Id of the template parameter */ - const std::optional &id() const { return id_; } + const std::optional &id() const { return id_; } /** * Set the name of the template parameter @@ -389,7 +391,7 @@ public: * @return */ bool find_nested_relationships( - std::vector> + std::vector> &nested_relationships, common::model::relationship_t hint, const std::function &should_include) @@ -533,7 +535,7 @@ private: */ std::vector template_params_; - std::optional id_; + std::optional id_; bool is_unexposed_{false}; }; diff --git a/src/common/types.cc b/src/common/types.cc index c2e9286a..80aa377b 100644 --- a/src/common/types.cc +++ b/src/common/types.cc @@ -20,25 +20,25 @@ namespace clanguml::common { -id_t::id_t() +eid_t::eid_t() : value_{0ULL} , is_global_{true} { } -id_t::id_t(int64_t id) +eid_t::eid_t(int64_t id) : value_{static_cast(id)} , is_global_{false} { } -id_t::id_t(type id) +eid_t::eid_t(type id) : value_{id} , is_global_{true} { } -id_t &id_t::operator=(int64_t ast_id) +eid_t &eid_t::operator=(int64_t ast_id) { // Can't assign ast_id if the id is already a global one assert(!is_global_); @@ -47,16 +47,16 @@ id_t &id_t::operator=(int64_t ast_id) return *this; } -bool id_t::is_global() const { return is_global_; } +bool eid_t::is_global() const { return is_global_; } -bool operator==(const id_t &lhs, const id_t &rhs) +bool operator==(const eid_t &lhs, const eid_t &rhs) { return (lhs.is_global_ == rhs.is_global_) && (lhs.value_ == rhs.value_); } -bool operator==(const id_t &lhs, const uint64_t &v) { return lhs.value_ == v; } +bool operator==(const eid_t &lhs, const uint64_t &v) { return lhs.value_ == v; } -bool operator!=(const id_t &lhs, const uint64_t &v) +bool operator!=(const eid_t &lhs, const uint64_t &v) { // This is sadly necessary to catch accidental comparisons to empty // std::optional: @@ -69,9 +69,9 @@ bool operator!=(const id_t &lhs, const uint64_t &v) return lhs.value_ != v; } -bool operator!=(const id_t &lhs, const id_t &rhs) { return !(lhs == rhs); } +bool operator!=(const eid_t &lhs, const eid_t &rhs) { return !(lhs == rhs); } -bool operator<(const id_t &lhs, const id_t &rhs) +bool operator<(const eid_t &lhs, const eid_t &rhs) { if (lhs.is_global_ != rhs.is_global_) { return lhs.value_ < rhs.value_ + 1; @@ -80,9 +80,9 @@ bool operator<(const id_t &lhs, const id_t &rhs) return lhs.value_ < rhs.value_; // Compare values if is_global_ are the same } -id_t::type id_t::value() const { return value_; } +eid_t::type eid_t::value() const { return value_; } -int64_t id_t::ast_local_value() const +int64_t eid_t::ast_local_value() const { assert(!is_global_); diff --git a/src/common/types.h b/src/common/types.h index 15d78265..d1a250e9 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -29,32 +29,47 @@ namespace clanguml::common { -class id_t { +/** + * @brief Universal class for representing all kinds of Id's in the diagram + * model. + * + * This class provides a convenient way of representing id's in the diagram + * model. The main problem it solves is that it allows to store both + * Clang AST ID's (obtained using getID() method), which are local to a single + * translation unit and have a type int64_t as well as global (across + * multiple translation units) id's used by clang-uml in the intermediate + * model (which are uint64_t). + * + * The class is aware which kind of value it holds and tries to ensure that + * mistakes such as using AST local ID in place where global id is needed + * do not happen. + */ +class eid_t { public: using type = uint64_t; - id_t(); + eid_t(); - explicit id_t(int64_t id); + explicit eid_t(int64_t id); - explicit id_t(type id); + explicit eid_t(type id); - id_t(const id_t &) = default; - id_t(id_t &&) noexcept = default; - id_t &operator=(const id_t &) = default; - id_t &operator=(id_t &&) noexcept = default; + eid_t(const eid_t &) = default; + eid_t(eid_t &&) noexcept = default; + eid_t &operator=(const eid_t &) = default; + eid_t &operator=(eid_t &&) noexcept = default; - id_t &operator=(int64_t ast_id); + eid_t &operator=(int64_t ast_id); - ~id_t() = default; + ~eid_t() = default; bool is_global() const; - friend bool operator==(const id_t &lhs, const id_t &rhs); - friend bool operator==(const id_t &lhs, const uint64_t &v); - friend bool operator!=(const id_t &lhs, const uint64_t &v); - friend bool operator!=(const id_t &lhs, const id_t &rhs); - friend bool operator<(const id_t &lhs, const id_t &rhs); + friend bool operator==(const eid_t &lhs, const eid_t &rhs); + friend bool operator==(const eid_t &lhs, const uint64_t &v); + friend bool operator!=(const eid_t &lhs, const uint64_t &v); + friend bool operator!=(const eid_t &lhs, const eid_t &rhs); + friend bool operator<(const eid_t &lhs, const eid_t &rhs); type value() const; @@ -328,11 +343,11 @@ struct path_or_regex : public or_regex { }; } // namespace clanguml::common -template <> class fmt::formatter { +template <> class fmt::formatter { public: constexpr auto parse(format_parse_context &ctx) { return ctx.begin(); } template - constexpr auto format(clanguml::common::id_t const &id, Context &ctx) const + constexpr auto format(clanguml::common::eid_t const &id, Context &ctx) const { return format_to(ctx.out(), "{}", id.value()); } diff --git a/src/common/visitor/ast_id_mapper.cc b/src/common/visitor/ast_id_mapper.cc index 6083d429..628480aa 100644 --- a/src/common/visitor/ast_id_mapper.cc +++ b/src/common/visitor/ast_id_mapper.cc @@ -20,12 +20,12 @@ namespace clanguml::common::visitor { -void ast_id_mapper::add(int64_t ast_id, id_t global_id) +void ast_id_mapper::add(int64_t ast_id, eid_t global_id) { id_map_.emplace(ast_id, global_id); } -std::optional ast_id_mapper::get_global_id(common::id_t ast_id) +std::optional ast_id_mapper::get_global_id(eid_t ast_id) { assert(!ast_id.is_global()); diff --git a/src/common/visitor/ast_id_mapper.h b/src/common/visitor/ast_id_mapper.h index 5951c9c5..ad0a6d20 100644 --- a/src/common/visitor/ast_id_mapper.h +++ b/src/common/visitor/ast_id_mapper.h @@ -24,6 +24,8 @@ namespace clanguml::common::visitor { +using clanguml::common::eid_t; + /** * @brief Mapping between Clang AST identifier and `clang-uml` unique ids * @@ -40,8 +42,6 @@ namespace clanguml::common::visitor { */ class ast_id_mapper { public: - using id_t = common::id_t; - ast_id_mapper() = default; /** @@ -50,7 +50,7 @@ public: * @param ast_id Clang's local AST id. * @param global_id Global element id. */ - void add(int64_t ast_id, id_t global_id); + void add(int64_t ast_id, eid_t global_id); /** * Get global element id based on it's local Clang AST id, if exists. @@ -58,11 +58,11 @@ public: * @param ast_id Clang's local AST id. * @return Global id, if exists. */ - std::optional get_global_id(common::id_t ast_id); + std::optional get_global_id(eid_t ast_id); private: std::map + /* clang-uml global id */ eid_t> id_map_; }; diff --git a/src/common/visitor/template_builder.h b/src/common/visitor/template_builder.h index d68afbd2..b6d2b397 100644 --- a/src/common/visitor/template_builder.h +++ b/src/common/visitor/template_builder.h @@ -30,8 +30,8 @@ using common::model::namespace_; using common::model::relationship_t; using common::model::template_parameter; -using found_relationships_t = std::vector< - std::pair>; +using found_relationships_t = + std::vector>; namespace detail { @@ -524,8 +524,8 @@ public: const template_parameter &ct, found_relationships_t &relationships); void find_instantiation_relationships( - common::model::template_element &template_instantiation, - common::id_t id, const std::string &qualified_name) const; + common::model::template_element &template_instantiation, eid_t id, + const std::string &qualified_name) const; /** * @brief Get reference to Clang AST to clang-uml id mapper @@ -661,8 +661,8 @@ void template_builder::build_from_template_declaration( templated_element.value().add_relationship( {relationship_t::kConstraint, id_mapper() - .get_global_id(common::id_t{ - named_concept->getID()}) + .get_global_id( + eid_t{named_concept->getID()}) .value(), model::access_t::kNone, ct.name().value()}); @@ -865,8 +865,7 @@ void template_builder::build( if constexpr (std::is_same_v) { find_instantiation_relationships(template_instantiation, - common::id_t{template_decl->getID()}, - full_template_specialization_name); + eid_t{template_decl->getID()}, full_template_specialization_name); } template_instantiation.set_id( @@ -911,7 +910,7 @@ void template_builder::build_from_class_template_specialization( if constexpr (std::is_same_v) { find_instantiation_relationships(template_instantiation, - common::id_t{template_specialization.getID()}, qualified_name); + eid_t{template_specialization.getID()}, qualified_name); } visitor_.set_source_location(*template_decl, template_instantiation); @@ -919,7 +918,7 @@ void template_builder::build_from_class_template_specialization( template void template_builder::find_instantiation_relationships( - common::model::template_element &template_instantiation, common::id_t id, + common::model::template_element &template_instantiation, eid_t id, const std::string &qualified_name) const { visitor_.find_instantiation_relationships( diff --git a/src/common/visitor/translation_unit_visitor.h b/src/common/visitor/translation_unit_visitor.h index 7f7d8242..9593ba8f 100644 --- a/src/common/visitor/translation_unit_visitor.h +++ b/src/common/visitor/translation_unit_visitor.h @@ -42,8 +42,8 @@ namespace clanguml::common::visitor { -using found_relationships_t = std::vector< - std::pair>; +using found_relationships_t = + std::vector>; /** * @brief Diagram translation unit visitor base class diff --git a/src/include_diagram/model/diagram.cc b/src/include_diagram/model/diagram.cc index 72275351..6a200b61 100644 --- a/src/include_diagram/model/diagram.cc +++ b/src/include_diagram/model/diagram.cc @@ -35,7 +35,7 @@ common::optional_ref diagram::get( } common::optional_ref diagram::get( - const common::id_t id) const + const eid_t id) const { return find(id); } diff --git a/src/include_diagram/model/diagram.h b/src/include_diagram/model/diagram.h index e8a1deba..3abbfb02 100644 --- a/src/include_diagram/model/diagram.h +++ b/src/include_diagram/model/diagram.h @@ -28,6 +28,7 @@ namespace clanguml::include_diagram::model { +using clanguml::common::eid_t; using clanguml::common::opt_ref; using clanguml::common::model::diagram_element; using clanguml::common::model::source_file; @@ -68,7 +69,7 @@ public: * @param id Element id. * @return Optional reference to a diagram element. */ - opt_ref get(common::id_t id) const override; + opt_ref get(eid_t id) const override; /** * @brief Add include diagram element, an include file. @@ -100,7 +101,7 @@ public: * @param id Id of the element * @return Optional reference to a diagram element */ - template opt_ref find(common::id_t id) const; + template opt_ref find(eid_t id) const; /** * @brief Convert element id to PlantUML alias. @@ -158,8 +159,7 @@ opt_ref diagram::find(const std::string &name) const return {}; } -template -opt_ref diagram::find(common::id_t id) const +template opt_ref diagram::find(eid_t id) const { for (const auto &element : element_view::view()) { if (element.get().id() == id) { diff --git a/src/include_diagram/visitor/translation_unit_visitor.cc b/src/include_diagram/visitor/translation_unit_visitor.cc index c6158291..3e83df8e 100644 --- a/src/include_diagram/visitor/translation_unit_visitor.cc +++ b/src/include_diagram/visitor/translation_unit_visitor.cc @@ -112,7 +112,7 @@ void translation_unit_visitor::include_visitor::InclusionDirective( void translation_unit_visitor::include_visitor::process_internal_header( const std::filesystem::path &include_path, bool is_system, - const common::id_t current_file_id) + const eid_t current_file_id) { // Make the path relative with respect to relative_to config option auto relative_include_path = @@ -151,8 +151,7 @@ void translation_unit_visitor::include_visitor::process_internal_header( } void translation_unit_visitor::include_visitor::process_external_system_header( - const std::filesystem::path &include_path, - const common::id_t current_file_id) + const std::filesystem::path &include_path, const eid_t current_file_id) { const auto file_name = include_path.filename(); const auto file_name_str = file_name.string(); @@ -177,7 +176,7 @@ void translation_unit_visitor::include_visitor::process_external_system_header( } } -std::optional +std::optional translation_unit_visitor::include_visitor::process_source_file( const std::filesystem::path &file) { diff --git a/src/include_diagram/visitor/translation_unit_visitor.h b/src/include_diagram/visitor/translation_unit_visitor.h index 872c9709..e537a0db 100644 --- a/src/include_diagram/visitor/translation_unit_visitor.h +++ b/src/include_diagram/visitor/translation_unit_visitor.h @@ -35,6 +35,8 @@ namespace clanguml::include_diagram::visitor { +using clanguml::common::eid_t; + using visitor_specialization_t = common::visitor::translation_unit_visitor; @@ -104,7 +106,7 @@ public: * @param current_file_id File id */ void process_internal_header(const std::filesystem::path &include_path, - bool is_system, common::id_t current_file_id); + bool is_system, eid_t current_file_id); /** * @brief Handle system header include directive @@ -113,8 +115,7 @@ public: * @param current_file_id File id */ void process_external_system_header( - const std::filesystem::path &include_path, - common::id_t current_file_id); + const std::filesystem::path &include_path, eid_t current_file_id); /** * @brief Handle a source file @@ -125,7 +126,7 @@ public: * @param file Absolute path to a source file * @return Diagram element id, in case the file was added to the diagram */ - std::optional process_source_file( + std::optional process_source_file( const std::filesystem::path &file); }; diff --git a/src/package_diagram/model/diagram.cc b/src/package_diagram/model/diagram.cc index 21a903ed..b1ad3d18 100644 --- a/src/package_diagram/model/diagram.cc +++ b/src/package_diagram/model/diagram.cc @@ -41,12 +41,12 @@ common::optional_ref diagram::get( } common::optional_ref diagram::get( - const clanguml::common::id_t id) const + const eid_t id) const { return find(id); } -std::string diagram::to_alias(const clanguml::common::id_t id) const +std::string diagram::to_alias(const eid_t id) const { LOG_DBG("Looking for alias for {}", id); diff --git a/src/package_diagram/model/diagram.h b/src/package_diagram/model/diagram.h index f29c9c66..a06bdb28 100644 --- a/src/package_diagram/model/diagram.h +++ b/src/package_diagram/model/diagram.h @@ -26,6 +26,7 @@ namespace clanguml::package_diagram::model { +using clanguml::common::eid_t; using clanguml::common::opt_ref; using clanguml::common::model::diagram_element; using clanguml::common::model::package; @@ -75,7 +76,7 @@ public: * @param id Element id. * @return Optional reference to a diagram element. */ - opt_ref get(common::id_t id) const override; + opt_ref get(eid_t id) const override; /** * @brief Find an element in the diagram by name. @@ -100,7 +101,7 @@ public: * @param id Id of the element * @return Optional reference to a diagram element */ - template opt_ref find(common::id_t id) const; + template opt_ref find(eid_t id) const; /** * @brief Find elements in the diagram by regex pattern. @@ -148,7 +149,7 @@ public: * @param id Id of a package in the diagram * @return PlantUML alias of the element */ - std::string to_alias(common::id_t id) const; + std::string to_alias(eid_t id) const; /** * @brief Return the elements JSON context for inja templates. @@ -213,8 +214,7 @@ opt_ref diagram::find(const std::string &name) const return {}; } -template -opt_ref diagram::find(common::id_t id) const +template opt_ref diagram::find(eid_t id) const { for (const auto &element : element_view::view()) { if (element.get().id() == id) { diff --git a/src/package_diagram/visitor/translation_unit_visitor.cc b/src/package_diagram/visitor/translation_unit_visitor.cc index c020147e..bdcf452b 100644 --- a/src/package_diagram/visitor/translation_unit_visitor.cc +++ b/src/package_diagram/visitor/translation_unit_visitor.cc @@ -290,7 +290,7 @@ void translation_unit_visitor::add_relationships( auto current_package = diagram().get(current_package_id); if (current_package) { - std::vector parent_ids = + std::vector parent_ids = get_parent_package_ids(current_package_id); for (const auto &dependency : relationships) { @@ -313,7 +313,7 @@ void translation_unit_visitor::add_relationships( } } -common::id_t translation_unit_visitor::get_package_id(const clang::Decl *cls) +eid_t translation_unit_visitor::get_package_id(const clang::Decl *cls) { if (config().package_type() == config::package_type_t::kNamespace) { const auto *namespace_context = @@ -677,11 +677,10 @@ bool translation_unit_visitor::find_relationships(const clang::QualType &type, void translation_unit_visitor::finalize() { } -std::vector translation_unit_visitor::get_parent_package_ids( - common::id_t id) +std::vector translation_unit_visitor::get_parent_package_ids(eid_t id) { - std::vector parent_ids; - std::optional parent_id = id; + std::vector parent_ids; + std::optional parent_id = id; while (parent_id.has_value()) { const auto pid = parent_id.value(); // NOLINT diff --git a/src/package_diagram/visitor/translation_unit_visitor.h b/src/package_diagram/visitor/translation_unit_visitor.h index 5aeb2657..acf17bc6 100644 --- a/src/package_diagram/visitor/translation_unit_visitor.h +++ b/src/package_diagram/visitor/translation_unit_visitor.h @@ -33,8 +33,10 @@ namespace clanguml::package_diagram::visitor { -using found_relationships_t = std::vector< - std::pair>; +using clanguml::common::eid_t; + +using found_relationships_t = + std::vector>; using visitor_specialization_t = common::visitor::translation_unit_visitor get_parent_package_ids(common::id_t id); + std::vector get_parent_package_ids(eid_t id); }; } // namespace clanguml::package_diagram::visitor diff --git a/src/sequence_diagram/generators/json/sequence_diagram_generator.cc b/src/sequence_diagram/generators/json/sequence_diagram_generator.cc index a4e01c88..8964350b 100644 --- a/src/sequence_diagram/generators/json/sequence_diagram_generator.cc +++ b/src/sequence_diagram/generators/json/sequence_diagram_generator.cc @@ -186,7 +186,7 @@ void generator::generate_call(const message &m, nlohmann::json &parent) const } void generator::generate_activity( - const activity &a, std::vector &visited) const + const activity &a, std::vector &visited) const { // Generate calls from this activity to other activities for (const auto &m : a.messages()) { @@ -263,7 +263,7 @@ nlohmann::json &generator::current_block_statement() const } void generator::process_call_message( - const model::message &m, std::vector &visited) const + const model::message &m, std::vector &visited) const { visited.push_back(m.from()); @@ -541,10 +541,10 @@ void generator::generate_participant( generate_participant(parent, p.value().id(), true); } -std::optional generator::generate_participant( - nlohmann::json & /*parent*/, common::id_t id, bool force) const +std::optional generator::generate_participant( + nlohmann::json & /*parent*/, eid_t id, bool force) const { - std::optional participant_id{}; + std::optional participant_id{}; if (!force) { for (const auto pid : model().active_participants()) { @@ -672,7 +672,7 @@ std::optional generator::generate_participant( return participant_id; } -bool generator::is_participant_generated(common::id_t id) const +bool generator::is_participant_generated(eid_t id) const { return std::find(generated_participants_.begin(), generated_participants_.end(), @@ -748,7 +748,7 @@ void generator::generate_diagram(nlohmann::json &parent) const continue; auto message_chains_unique = model().get_all_from_to_message_chains( - common::id_t{}, to_activity_id.value()); + eid_t{}, to_activity_id.value()); nlohmann::json sequence; sequence["to"]["location"] = to_location.location; @@ -779,7 +779,7 @@ void generator::generate_diagram(nlohmann::json &parent) const for (const auto &sf : config().from()) { if (sf.location_type == location_t::function) { - common::id_t start_from{}; + eid_t start_from{}; std::string start_from_str; for (const auto &[k, v] : model().sequences()) { const auto &caller = *model().participants().at(v.from()); @@ -799,7 +799,7 @@ void generator::generate_diagram(nlohmann::json &parent) const } // Use this to break out of recurrent loops - std::vector visited_participants; + std::vector visited_participants; const auto &from = model().get_participant(start_from); diff --git a/src/sequence_diagram/generators/json/sequence_diagram_generator.h b/src/sequence_diagram/generators/json/sequence_diagram_generator.h index 0eac7e7b..233f2738 100644 --- a/src/sequence_diagram/generators/json/sequence_diagram_generator.h +++ b/src/sequence_diagram/generators/json/sequence_diagram_generator.h @@ -32,6 +32,8 @@ namespace clanguml::sequence_diagram::generators::json { +using clanguml::common::eid_t; + std::string render_name(std::string name); using diagram_config = clanguml::config::sequence_diagram; @@ -77,8 +79,8 @@ public: * the set of active participants * @return Id of the generated participant */ - std::optional generate_participant( - nlohmann::json &parent, common::id_t id, bool force = false) const; + std::optional generate_participant( + nlohmann::json &parent, eid_t id, bool force = false) const; /** * @brief Generate sequence diagram participant by name @@ -99,7 +101,7 @@ public: * for breaking infinite recursion on recursive calls */ void generate_activity(const sequence_diagram::model::activity &a, - std::vector &visited) const; + std::vector &visited) const; /** * @brief Get reference to the current block statement. @@ -120,7 +122,7 @@ private: * @param id Participant id. * @return True, if participant has already been generated. */ - bool is_participant_generated(common::id_t id) const; + bool is_participant_generated(eid_t id) const; /** * @brief Process call message @@ -129,7 +131,7 @@ private: * @param visited List of already visited participants */ void process_call_message( - const model::message &m, std::vector &visited) const; + const model::message &m, std::vector &visited) const; /** * @brief Process `if` statement message @@ -239,7 +241,7 @@ private: */ void process_end_while_message() const; - mutable std::set generated_participants_; + mutable std::set generated_participants_; // Needed to add "participants" array in a temporary object accessible from // all methods of the generator diff --git a/src/sequence_diagram/generators/mermaid/sequence_diagram_generator.cc b/src/sequence_diagram/generators/mermaid/sequence_diagram_generator.cc index 4a8d8e5a..003e18ed 100644 --- a/src/sequence_diagram/generators/mermaid/sequence_diagram_generator.cc +++ b/src/sequence_diagram/generators/mermaid/sequence_diagram_generator.cc @@ -192,8 +192,8 @@ void generator::generate_return(const message &m, std::ostream &ostr) const } } -void generator::generate_activity(const activity &a, std::ostream &ostr, - std::vector &visited) const +void generator::generate_activity( + const activity &a, std::ostream &ostr, std::vector &visited) const { for (const auto &m : a.messages()) { if (m.in_static_declaration_context()) { @@ -352,9 +352,9 @@ void generator::generate_participant( } void generator::generate_participant( - std::ostream &ostr, common::id_t id, bool force) const + std::ostream &ostr, eid_t id, bool force) const { - common::id_t participant_id{}; + eid_t participant_id{}; if (!force) { for (const auto pid : model().active_participants()) { @@ -460,7 +460,7 @@ void generator::generate_participant( } } -bool generator::is_participant_generated(common::id_t id) const +bool generator::is_participant_generated(eid_t id) const { return std::find(generated_participants_.begin(), generated_participants_.end(), @@ -549,8 +549,8 @@ void generator::generate_diagram(std::ostream &ostr) const if (!to_activity_id) continue; - auto message_chains_unique = model().get_all_from_to_message_chains( - common::id_t{}, *to_activity_id); + auto message_chains_unique = + model().get_all_from_to_message_chains(eid_t{}, *to_activity_id); for (const auto &mc : message_chains_unique) { const auto from_activity_id = mc.front().from(); @@ -581,7 +581,7 @@ void generator::generate_diagram(std::ostream &ostr) const for (const auto &sf : config().from()) { if (sf.location_type == location_t::function) { - common::id_t start_from{}; + eid_t start_from{}; for (const auto &[k, v] : model().sequences()) { if (model().participants().count(v.from()) == 0) continue; @@ -603,7 +603,7 @@ void generator::generate_diagram(std::ostream &ostr) const } // Use this to break out of recurrent loops - std::vector visited_participants; + std::vector visited_participants; if (model().participants().count(start_from) == 0) continue; diff --git a/src/sequence_diagram/generators/mermaid/sequence_diagram_generator.h b/src/sequence_diagram/generators/mermaid/sequence_diagram_generator.h index e8446479..aee6f91f 100644 --- a/src/sequence_diagram/generators/mermaid/sequence_diagram_generator.h +++ b/src/sequence_diagram/generators/mermaid/sequence_diagram_generator.h @@ -35,6 +35,8 @@ namespace sequence_diagram { namespace generators { namespace mermaid { +using clanguml::common::eid_t; + using diagram_config = clanguml::config::sequence_diagram; using diagram_model = clanguml::sequence_diagram::model::diagram; @@ -95,7 +97,7 @@ public: * @return Id of the generated participant */ void generate_participant( - std::ostream &ostr, common::id_t id, bool force = false) const; + std::ostream &ostr, eid_t id, bool force = false) const; /** * @brief Generate sequence diagram participant by name @@ -117,7 +119,7 @@ public: * for breaking infinite recursion on recursive calls */ void generate_activity(const clanguml::sequence_diagram::model::activity &a, - std::ostream &ostr, std::vector &visited) const; + std::ostream &ostr, std::vector &visited) const; private: /** @@ -126,7 +128,7 @@ private: * @param id Participant id. * @return True, if participant has already been generated. */ - bool is_participant_generated(common::id_t id) const; + bool is_participant_generated(eid_t id) const; /** * @brief Generate MermaidJS alias for participant @@ -153,7 +155,7 @@ private: model::function::message_render_mode select_method_arguments_render_mode() const; - mutable std::set generated_participants_; + mutable std::set generated_participants_; mutable std::vector already_generated_in_static_context_; }; diff --git a/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc b/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc index 7a3b288c..2efd7565 100644 --- a/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc +++ b/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc @@ -20,6 +20,7 @@ namespace clanguml::sequence_diagram::generators::plantuml { +using clanguml::common::eid_t; using clanguml::common::model::message_t; using clanguml::config::location_t; using clanguml::sequence_diagram::model::activity; @@ -149,8 +150,8 @@ void generator::generate_return(const message &m, std::ostream &ostr) const } } -void generator::generate_activity(const activity &a, std::ostream &ostr, - std::vector &visited) const +void generator::generate_activity( + const activity &a, std::ostream &ostr, std::vector &visited) const { for (const auto &m : a.messages()) { if (m.in_static_declaration_context()) { @@ -348,9 +349,9 @@ void generator::generate_participant( } void generator::generate_participant( - std::ostream &ostr, common::id_t id, bool force) const + std::ostream &ostr, eid_t id, bool force) const { - common::id_t participant_id{}; + eid_t participant_id{}; if (!force) { for (const auto pid : model().active_participants()) { @@ -465,7 +466,7 @@ void generator::generate_participant( } } -bool generator::is_participant_generated(common::id_t id) const +bool generator::is_participant_generated(eid_t id) const { return std::find(generated_participants_.begin(), generated_participants_.end(), @@ -552,8 +553,8 @@ void generator::generate_diagram(std::ostream &ostr) const if (!to_activity_id) continue; - auto message_chains_unique = model().get_all_from_to_message_chains( - common::id_t{}, *to_activity_id); + auto message_chains_unique = + model().get_all_from_to_message_chains(eid_t{}, *to_activity_id); bool first_separator_skipped{false}; for (const auto &mc : message_chains_unique) { @@ -588,7 +589,7 @@ void generator::generate_diagram(std::ostream &ostr) const for (const auto &sf : config().from()) { if (sf.location_type == location_t::function) { - common::id_t start_from{}; + eid_t start_from{}; for (const auto &[k, v] : model().sequences()) { if (model().participants().count(v.from()) == 0) continue; @@ -613,7 +614,7 @@ void generator::generate_diagram(std::ostream &ostr) const continue; // Use this to break out of recurrent loops - std::vector visited_participants; + std::vector visited_participants; const auto &from = model().get_participant(start_from); diff --git a/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.h b/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.h index 8d02deec..fe9eb970 100644 --- a/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.h +++ b/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.h @@ -35,6 +35,8 @@ namespace sequence_diagram { namespace generators { namespace plantuml { +using clanguml::common::eid_t; + using diagram_config = clanguml::config::sequence_diagram; using diagram_model = clanguml::sequence_diagram::model::diagram; @@ -89,7 +91,7 @@ public: * @return Id of the generated participant */ void generate_participant( - std::ostream &ostr, common::id_t id, bool force = false) const; + std::ostream &ostr, eid_t id, bool force = false) const; /** * @brief Generate sequence diagram participant by name @@ -111,7 +113,7 @@ public: * for breaking infinite recursion on recursive calls */ void generate_activity(const clanguml::sequence_diagram::model::activity &a, - std::ostream &ostr, std::vector &visited) const; + std::ostream &ostr, std::vector &visited) const; private: /** @@ -120,7 +122,7 @@ private: * @param id Participant id. * @return True, if participant has already been generated. */ - bool is_participant_generated(common::id_t id) const; + bool is_participant_generated(eid_t id) const; /** * @brief Generate PlantUML alias for participant @@ -155,7 +157,7 @@ private: model::function::message_render_mode select_method_arguments_render_mode() const; - mutable std::set generated_participants_; + mutable std::set generated_participants_; mutable std::vector already_generated_in_static_context_; }; diff --git a/src/sequence_diagram/model/activity.cc b/src/sequence_diagram/model/activity.cc index c66ba730..13b49c38 100644 --- a/src/sequence_diagram/model/activity.cc +++ b/src/sequence_diagram/model/activity.cc @@ -20,7 +20,7 @@ namespace clanguml::sequence_diagram::model { -activity::activity(common::id_t id) +activity::activity(eid_t id) : from_{id} { } @@ -31,6 +31,6 @@ std::vector &activity::messages() { return messages_; } const std::vector &activity::messages() const { return messages_; } -common::id_t activity::from() const { return from_; } +eid_t activity::from() const { return from_; } } // namespace clanguml::sequence_diagram::model diff --git a/src/sequence_diagram/model/activity.h b/src/sequence_diagram/model/activity.h index ac0d1592..d3c52d85 100644 --- a/src/sequence_diagram/model/activity.h +++ b/src/sequence_diagram/model/activity.h @@ -35,7 +35,7 @@ public: * * @param id Id of the participant parent for the activity */ - activity(common::id_t id); + activity(eid_t id); /** * @brief Add a message call to the activity @@ -63,10 +63,10 @@ public: * * @return Id of activity participant */ - common::id_t from() const; + eid_t from() const; private: - common::id_t from_; + eid_t from_; std::vector messages_; }; diff --git a/src/sequence_diagram/model/diagram.cc b/src/sequence_diagram/model/diagram.cc index c0eb4ffe..cd32f3a2 100644 --- a/src/sequence_diagram/model/diagram.cc +++ b/src/sequence_diagram/model/diagram.cc @@ -42,7 +42,7 @@ common::optional_ref diagram::get( } common::optional_ref diagram::get( - const common::id_t id) const + const eid_t id) const { if (participants_.find(id) != participants_.end()) return {*participants_.at(id)}; @@ -90,22 +90,19 @@ void diagram::add_participant(std::unique_ptr p) } } -void diagram::add_active_participant(common::id_t id) +void diagram::add_active_participant(eid_t id) { active_participants_.emplace(id); } -const activity &diagram::get_activity(common::id_t id) const +const activity &diagram::get_activity(eid_t id) const { return activities_.at(id); } -bool diagram::has_activity(common::id_t id) const -{ - return activities_.count(id) > 0; -} +bool diagram::has_activity(eid_t id) const { return activities_.count(id) > 0; } -activity &diagram::get_activity(common::id_t id) { return activities_.at(id); } +activity &diagram::get_activity(eid_t id) { return activities_.at(id); } void diagram::add_message(model::message &&message) { @@ -153,30 +150,27 @@ void diagram::add_case_stmt_message(model::message &&m) } } -std::map &diagram::sequences() { return activities_; } +std::map &diagram::sequences() { return activities_; } -const std::map &diagram::sequences() const +const std::map &diagram::sequences() const { return activities_; } -std::map> &diagram::participants() +std::map> &diagram::participants() { return participants_; } -const std::map> & +const std::map> & diagram::participants() const { return participants_; } -std::set &diagram::active_participants() -{ - return active_participants_; -} +std::set &diagram::active_participants() { return active_participants_; } -const std::set &diagram::active_participants() const +const std::set &diagram::active_participants() const { return active_participants_; } @@ -228,10 +222,10 @@ std::vector diagram::list_to_values() const return result; } -std::optional diagram::get_to_activity_id( +std::optional diagram::get_to_activity_id( const config::source_location &to_location) const { - std::optional to_activity{}; + std::optional to_activity{}; for (const auto &[k, v] : sequences()) { for (const auto &m : v.messages()) { @@ -257,10 +251,10 @@ std::optional diagram::get_to_activity_id( return to_activity; } -std::optional diagram::get_from_activity_id( +std::optional diagram::get_from_activity_id( const config::source_location &from_location) const { - std::optional from_activity{}; + std::optional from_activity{}; for (const auto &[k, v] : sequences()) { const auto &caller = *participants().at(v.from()); @@ -282,7 +276,7 @@ std::optional diagram::get_from_activity_id( } std::vector diagram::get_all_from_to_message_chains( - const common::id_t from_activity, const common::id_t to_activity) const + const eid_t from_activity, const eid_t to_activity) const { std::vector message_chains_unique{}; @@ -414,9 +408,9 @@ bool diagram::is_empty() const void diagram::inline_lambda_operator_calls() { - std::map activities; - std::map> participants; - std::set active_participants; + std::map activities; + std::map> participants; + std::set active_participants; for (auto &[id, act] : sequences()) { model::activity new_activity{id}; @@ -488,8 +482,8 @@ void diagram::inline_lambda_operator_calls() active_participants_ = std::move(active_participants); } -bool diagram::inline_lambda_operator_call(const common::id_t id, - model::activity &new_activity, const model::message &m) +bool diagram::inline_lambda_operator_call( + const eid_t id, model::activity &new_activity, const model::message &m) { bool message_call_to_lambda{false}; auto maybe_lambda_operator = get_participant(m.to()); diff --git a/src/sequence_diagram/model/diagram.h b/src/sequence_diagram/model/diagram.h index fcbd0009..1f1c0460 100644 --- a/src/sequence_diagram/model/diagram.h +++ b/src/sequence_diagram/model/diagram.h @@ -67,7 +67,7 @@ public: * @return Optional reference to a diagram element. */ common::optional_ref get( - common::id_t id) const override; + eid_t id) const override; /** * @brief Get participant by id @@ -76,7 +76,7 @@ public: * @return Optional reference to a diagram element. */ template - common::optional_ref get_participant(common::id_t id) const + common::optional_ref get_participant(eid_t id) const { if (participants_.find(id) == participants_.end()) { return {}; @@ -98,7 +98,7 @@ public: * * @param id Id of participant to activate */ - void add_active_participant(common::id_t id); + void add_active_participant(eid_t id); /** * @brief Check if diagram has activity identified by caller id @@ -106,7 +106,7 @@ public: * @param id Caller id representing the activity * @return True, if an activity already exists */ - bool has_activity(common::id_t id) const; + bool has_activity(eid_t id) const; /** * @brief Get reference to current activity of a participant @@ -114,7 +114,7 @@ public: * @param id Participant id * @return */ - const activity &get_activity(common::id_t id) const; + const activity &get_activity(eid_t id) const; /** * @brief Get reference to current activity of a participant @@ -122,7 +122,7 @@ public: * @param id Participant id * @return */ - activity &get_activity(common::id_t id); + activity &get_activity(eid_t id); /** * @brief Add message to current activity @@ -163,43 +163,42 @@ public: * * @return Map of sequences in the diagram */ - std::map &sequences(); + std::map &sequences(); /** * @brief Get all sequences in the diagram * * @return Map of sequences in the diagram */ - const std::map &sequences() const; + const std::map &sequences() const; /** * @brief Get map of all participants in the diagram * * @return Map of participants in the diagram */ - std::map> &participants(); + std::map> &participants(); /** * @brief Get map of all participants in the diagram * * @return Map of participants in the diagram */ - const std::map> & - participants() const; + const std::map> &participants() const; /** * @brief Get all active participants in the diagram * * @return Set of all active participant ids */ - std::set &active_participants(); + std::set &active_participants(); /** * @brief Get all active participants in the diagram * * @return Set of all active participant ids */ - const std::set &active_participants() const; + const std::set &active_participants() const; /** * @brief Convert element full name to PlantUML alias. @@ -259,7 +258,7 @@ public: * @return List of message chains */ std::vector get_all_from_to_message_chains( - common::id_t from_activity, common::id_t to_activity) const; + eid_t from_activity, eid_t to_activity) const; /** * @brief Get id of a 'to' activity @@ -267,7 +266,7 @@ public: * @param to_location Target activity * @return Activity id */ - std::optional get_to_activity_id( + std::optional get_to_activity_id( const config::source_location &to_location) const; /** @@ -276,7 +275,7 @@ public: * @param from_location Source activity * @return Activity id */ - std::optional get_from_activity_id( + std::optional get_from_activity_id( const config::source_location &from_location) const; /** @@ -344,14 +343,14 @@ private: return block_end_types.count(mt) > 0; }; - bool inline_lambda_operator_call(common::id_t id, - model::activity &new_activity, const model::message &m); + bool inline_lambda_operator_call( + eid_t id, model::activity &new_activity, const model::message &m); - std::map activities_; + std::map activities_; - std::map> participants_; + std::map> participants_; - std::set active_participants_; + std::set active_participants_; }; } // namespace clanguml::sequence_diagram::model diff --git a/src/sequence_diagram/model/message.cc b/src/sequence_diagram/model/message.cc index 012aecc0..211513f8 100644 --- a/src/sequence_diagram/model/message.cc +++ b/src/sequence_diagram/model/message.cc @@ -20,7 +20,7 @@ namespace clanguml::sequence_diagram::model { -message::message(common::model::message_t type, common::id_t from) +message::message(common::model::message_t type, eid_t from) : type_{type} , from_{from} { @@ -38,13 +38,13 @@ void message::set_type(common::model::message_t t) { type_ = t; } common::model::message_t message::type() const { return type_; } -void message::set_from(common::id_t f) { from_ = f; } +void message::set_from(eid_t f) { from_ = f; } -common::id_t message::from() const { return from_; } +eid_t message::from() const { return from_; } -void message::set_to(common::id_t t) { to_ = t; } +void message::set_to(eid_t t) { to_ = t; } -common::id_t message::to() const { return to_; } +eid_t message::to() const { return to_; } void message::set_message_name(std::string name) { diff --git a/src/sequence_diagram/model/message.h b/src/sequence_diagram/model/message.h index 476b55fa..573f80e4 100644 --- a/src/sequence_diagram/model/message.h +++ b/src/sequence_diagram/model/message.h @@ -38,7 +38,7 @@ public: * @param type Message type * @param from Id of originating sequence */ - message(common::model::message_t type, common::id_t from); + message(common::model::message_t type, eid_t from); /** * @brief Equality operator @@ -67,28 +67,28 @@ public: * * @param f Id of the participant from which message originates */ - void set_from(common::id_t f); + void set_from(eid_t f); /** * @brief Get the id of source of message * * @return */ - common::id_t from() const; + eid_t from() const; /** * @brief Set the id of the message target * * @param t Id of the message target */ - void set_to(common::id_t t); + void set_to(eid_t t); /** * @brief Get the id of the message target * * @return Id of the message target */ - common::id_t to() const; + eid_t to() const; /** * @brief Set the message label @@ -162,9 +162,9 @@ public: private: common::model::message_t type_{common::model::message_t::kNone}; - common::id_t from_{}; + eid_t from_{}; - common::id_t to_{}; + eid_t to_{}; common::model::message_scope_t scope_{ common::model::message_scope_t::kNormal}; diff --git a/src/sequence_diagram/model/participant.cc b/src/sequence_diagram/model/participant.cc index 28969acf..c340e513 100644 --- a/src/sequence_diagram/model/participant.cc +++ b/src/sequence_diagram/model/participant.cc @@ -197,7 +197,7 @@ void method::is_assignment(bool a) { is_assignment_ = a; } void method::set_method_name(const std::string &name) { method_name_ = name; } -void method::set_class_id(common::id_t id) { class_id_ = id; } +void method::set_class_id(eid_t id) { class_id_ = id; } void method::set_class_full_name(const std::string &name) { @@ -238,7 +238,7 @@ std::string method::message_name(message_render_mode mode) const fmt::join(parameters(), ","), is_const() ? " const" : "", style); } -common::id_t method::class_id() const { return class_id_; } +eid_t method::class_id() const { return class_id_; } std::string method::to_string() const { diff --git a/src/sequence_diagram/model/participant.h b/src/sequence_diagram/model/participant.h index 584826eb..ea5550c0 100644 --- a/src/sequence_diagram/model/participant.h +++ b/src/sequence_diagram/model/participant.h @@ -27,6 +27,7 @@ namespace clanguml::sequence_diagram::model { +using clanguml::common::eid_t; using clanguml::common::model::template_trait; /** @@ -190,9 +191,9 @@ public: */ void is_lambda(bool is_lambda); - void set_lambda_operator_id(common::id_t id) { lambda_operator_id_ = id; } + void set_lambda_operator_id(eid_t id) { lambda_operator_id_ = id; } - common::id_t lambda_operator_id() const { return lambda_operator_id_; } + eid_t lambda_operator_id() const { return lambda_operator_id_; } private: bool is_struct_{false}; @@ -200,7 +201,7 @@ private: bool is_template_instantiation_{false}; bool is_alias_{false}; bool is_lambda_{false}; - common::id_t lambda_operator_id_{}; + eid_t lambda_operator_id_{}; std::string full_name_; }; @@ -420,7 +421,7 @@ struct method : public function { * * @param id Id of the class to which this method belongs to */ - void set_class_id(common::id_t id); + void set_class_id(eid_t id); /** * @brief Set full qualified name of the class @@ -450,7 +451,7 @@ struct method : public function { * * @return Class id */ - common::id_t class_id() const; + eid_t class_id() const; /** * @brief Create a string representation of the participant @@ -502,7 +503,7 @@ struct method : public function { void is_assignment(bool a); private: - common::id_t class_id_{}; + eid_t class_id_{}; std::string method_name_; std::string class_full_name_; bool is_constructor_{false}; diff --git a/src/sequence_diagram/visitor/call_expression_context.cc b/src/sequence_diagram/visitor/call_expression_context.cc index 1194daa3..b33eab5b 100644 --- a/src/sequence_diagram/visitor/call_expression_context.cc +++ b/src/sequence_diagram/visitor/call_expression_context.cc @@ -24,7 +24,7 @@ call_expression_context::call_expression_context() = default; void call_expression_context::reset() { - current_caller_id_ = common::id_t{}; + current_caller_id_ = eid_t{}; current_class_decl_ = nullptr; current_class_template_decl_ = nullptr; current_class_template_specialization_decl_ = nullptr; @@ -130,7 +130,7 @@ void call_expression_context::update( current_function_template_decl_ = function_template; } -common::id_t call_expression_context::caller_id() const +eid_t call_expression_context::caller_id() const { if (lambda_caller_id().has_value()) return *lambda_caller_id(); // NOLINT @@ -138,7 +138,7 @@ common::id_t call_expression_context::caller_id() const return current_caller_id_; } -std::optional call_expression_context::lambda_caller_id() const +std::optional call_expression_context::lambda_caller_id() const { if (current_lambda_caller_id_.empty()) return {}; @@ -146,13 +146,13 @@ std::optional call_expression_context::lambda_caller_id() const return current_lambda_caller_id_.top(); } -void call_expression_context::set_caller_id(common::id_t id) +void call_expression_context::set_caller_id(eid_t id) { LOG_DBG("Setting current caller id to {}", id); current_caller_id_ = id; } -void call_expression_context::enter_lambda_expression(common::id_t id) +void call_expression_context::enter_lambda_expression(eid_t id) { LOG_DBG("Setting current lambda caller id to {}", id); diff --git a/src/sequence_diagram/visitor/call_expression_context.h b/src/sequence_diagram/visitor/call_expression_context.h index 38c20dfd..6a831a9b 100644 --- a/src/sequence_diagram/visitor/call_expression_context.h +++ b/src/sequence_diagram/visitor/call_expression_context.h @@ -28,6 +28,8 @@ namespace clanguml::sequence_diagram::visitor { +using clanguml::common::eid_t; + /** * @brief This class is used to track current context of the call expressions. * @@ -116,14 +118,14 @@ struct call_expression_context { * * @param id Set current caller id. */ - void set_caller_id(common::id_t id); + void set_caller_id(eid_t id); /** * @brief Get current caller id * * @return Id of the current caller participant */ - common::id_t caller_id() const; + eid_t caller_id() const; /** * @brief Get the id of the current lambda caller. @@ -133,14 +135,14 @@ struct call_expression_context { * * @return Current lambda caller id, or 0 if current caller is not lambda. */ - std::optional lambda_caller_id() const; + std::optional lambda_caller_id() const; /** * @brief Enter a lambda expression * * @param id Lambda id */ - void enter_lambda_expression(common::id_t id); + void enter_lambda_expression(eid_t id); /** * @brief Leave current lambda expression @@ -315,8 +317,8 @@ struct call_expression_context { clang::FunctionTemplateDecl *current_function_template_decl_{nullptr}; private: - common::id_t current_caller_id_{}; - std::stack current_lambda_caller_id_; + eid_t current_caller_id_{}; + std::stack current_lambda_caller_id_; std::stack call_expr_stack_; diff --git a/src/sequence_diagram/visitor/translation_unit_visitor.cc b/src/sequence_diagram/visitor/translation_unit_visitor.cc index 643ba7fa..2a41abc7 100644 --- a/src/sequence_diagram/visitor/translation_unit_visitor.cc +++ b/src/sequence_diagram/visitor/translation_unit_visitor.cc @@ -64,8 +64,7 @@ bool translation_unit_visitor::VisitCXXRecordDecl( // Skip this class if it's parent template is already in the model if (declaration->isTemplated() && declaration->getDescribedTemplate() != nullptr) { - if (get_unique_id( - common::id_t{declaration->getDescribedTemplate()->getID()})) + if (get_unique_id(eid_t{declaration->getDescribedTemplate()->getID()})) return true; } @@ -337,7 +336,7 @@ bool translation_unit_visitor::VisitFunctionDecl( // If the described templated of this function is already in the // model skip it: if (get_unique_id( - common::id_t{declaration->getDescribedTemplate()->getID()})) + eid_t{declaration->getDescribedTemplate()->getID()})) return true; } } @@ -1314,10 +1313,10 @@ bool translation_unit_visitor::process_cuda_kernel_call_expression( auto callee_name = callee_function->getQualifiedNameAsString() + "()"; - const auto maybe_id = get_unique_id(common::id_t{callee_function->getID()}); + const auto maybe_id = get_unique_id(eid_t{callee_function->getID()}); if (!maybe_id.has_value()) { // This is hopefully not an interesting call... - m.set_to(common::id_t{callee_function->getID()}); + m.set_to(eid_t{callee_function->getID()}); } else { m.set_to(maybe_id.value()); @@ -1352,17 +1351,16 @@ bool translation_unit_visitor::process_operator_call_expression( auto lambda_name = make_lambda_name(lambda_method->getParent()); - m.set_to(common::id_t{lambda_method->getParent()->getID()}); + m.set_to(eid_t{lambda_method->getParent()->getID()}); } else { - auto maybe_id = get_unique_id( - common::id_t{operator_call_expr->getCalleeDecl()->getID()}); + auto maybe_id = + get_unique_id(eid_t{operator_call_expr->getCalleeDecl()->getID()}); if (maybe_id.has_value()) { m.set_to(maybe_id.value()); } else { - m.set_to( - common::id_t{operator_call_expr->getCalleeDecl()->getID()}); + m.set_to(eid_t{operator_call_expr->getCalleeDecl()->getID()}); } } @@ -1388,19 +1386,19 @@ bool translation_unit_visitor::process_construct_expression( constructor->getID(), construct_expr->getBeginLoc().printToString(source_manager())); - auto maybe_id = get_unique_id(common::id_t{constructor->getID()}); + auto maybe_id = get_unique_id(eid_t{constructor->getID()}); if (maybe_id.has_value()) { m.set_to(maybe_id.value()); } else { - m.set_to(common::id_t{constructor->getID()}); + m.set_to(eid_t{constructor->getID()}); } m.set_message_name( fmt::format("{}::{}", constructor_parent->getQualifiedNameAsString(), constructor_parent->getNameAsString())); - diagram().add_active_participant(common::id_t{constructor->getID()}); + diagram().add_active_participant(eid_t{constructor->getID()}); return true; } @@ -1425,7 +1423,7 @@ bool translation_unit_visitor::process_class_method_call_expression( if (!should_include(callee_decl) || !should_include(method_decl)) return false; - m.set_to(common::id_t{method_decl->getID()}); + m.set_to(eid_t{method_decl->getID()}); m.set_message_name(method_decl->getNameAsString()); m.set_return_type( method_call_expr->getCallReturnType(*context().get_ast_context()) @@ -1434,7 +1432,7 @@ bool translation_unit_visitor::process_class_method_call_expression( LOG_TRACE("Set callee method id {} for method name {}", m.to(), method_decl->getQualifiedNameAsString()); - diagram().add_active_participant(common::id_t{method_decl->getID()}); + diagram().add_active_participant(eid_t{method_decl->getID()}); return true; } @@ -1511,7 +1509,7 @@ bool translation_unit_visitor::process_class_template_method_call_expression( dependent_member_callee->getMember().getAsString()); if (const auto maybe_id = - get_unique_id(common::id_t{template_declaration->getID()}); + get_unique_id(eid_t{template_declaration->getID()}); maybe_id.has_value()) diagram().add_active_participant(maybe_id.value()); } @@ -1548,10 +1546,10 @@ bool translation_unit_visitor::process_function_call_expression( auto callee_name = callee_function->getQualifiedNameAsString() + "()"; - const auto maybe_id = get_unique_id(common::id_t{callee_function->getID()}); + const auto maybe_id = get_unique_id(eid_t{callee_function->getID()}); if (!maybe_id.has_value()) { // This is hopefully not an interesting call... - m.set_to(common::id_t{callee_function->getID()}); + m.set_to(eid_t{callee_function->getID()}); } else { m.set_to(maybe_id.value()); @@ -1571,8 +1569,7 @@ bool translation_unit_visitor::process_lambda_call_expression( if (lambda_expr == nullptr) return true; - const auto lambda_class_id = - common::id_t{lambda_expr->getLambdaClass()->getID()}; + const auto lambda_class_id = eid_t{lambda_expr->getLambdaClass()->getID()}; const auto maybe_id = get_unique_id(lambda_class_id); if (!maybe_id.has_value()) m.set_to(lambda_class_id); @@ -1597,9 +1594,9 @@ bool translation_unit_visitor::process_unresolved_lookup_call_expression( const auto *ftd = clang::dyn_cast_or_null(decl); - const auto maybe_id = get_unique_id(common::id_t{ftd->getID()}); + const auto maybe_id = get_unique_id(eid_t{ftd->getID()}); if (!maybe_id.has_value()) - m.set_to(common::id_t{ftd->getID()}); + m.set_to(eid_t{ftd->getID()}); else { m.set_to(maybe_id.value()); } @@ -1611,9 +1608,9 @@ bool translation_unit_visitor::process_unresolved_lookup_call_expression( const auto *fd = clang::dyn_cast_or_null(decl); - const auto maybe_id = get_unique_id(common::id_t{fd->getID()}); + const auto maybe_id = get_unique_id(eid_t{fd->getID()}); if (!maybe_id.has_value()) - m.set_to(common::id_t{fd->getID()}); + m.set_to(eid_t{fd->getID()}); else { m.set_to(maybe_id.value()); } @@ -1683,13 +1680,13 @@ translation_unit_visitor::create_class_model(clang::CXXRecordDecl *cls) // - the parent is a regular C++ class/struct // - the parent is a class template declaration/specialization // - the parent is a lambda (i.e. this is a nested lambda expression) - std::optional id_opt; + std::optional id_opt; const auto *parent_record_decl = clang::dyn_cast(parent); assert(parent_record_decl != nullptr); - const common::id_t ast_id{parent_record_decl->getID()}; + const eid_t ast_id{parent_record_decl->getID()}; // First check if the parent has been added to the diagram as // regular class @@ -1774,16 +1771,15 @@ translation_unit_visitor::create_class_model(clang::CXXRecordDecl *cls) return c_ptr; } -void translation_unit_visitor::set_unique_id( - int64_t local_id, common::id_t global_id) +void translation_unit_visitor::set_unique_id(int64_t local_id, eid_t global_id) { LOG_TRACE("Setting local element mapping {} --> {}", local_id, global_id); local_ast_id_map_[local_id] = global_id; } -std::optional translation_unit_visitor::get_unique_id( - common::id_t local_id) const +std::optional translation_unit_visitor::get_unique_id( + eid_t local_id) const { if (local_ast_id_map_.find(local_id.ast_local_value()) == local_ast_id_map_.end()) @@ -2058,7 +2054,7 @@ void translation_unit_visitor::ensure_lambda_messages_have_operator_as_target() void translation_unit_visitor::resolve_ids_to_global() { - std::set active_participants_unique; + std::set active_participants_unique; // Change all active participants AST local ids to diagram global ids for (auto id : diagram().active_participants()) { @@ -2293,7 +2289,7 @@ bool translation_unit_visitor::should_include( std::optional translation_unit_visitor::get_expression_comment( const clang::SourceManager &sm, const clang::ASTContext &context, - const common::id_t caller_id, const clang::Stmt *stmt) + const eid_t caller_id, const clang::Stmt *stmt) { const auto *raw_comment = clanguml::common::get_expression_raw_comment(sm, context, stmt); diff --git a/src/sequence_diagram/visitor/translation_unit_visitor.h b/src/sequence_diagram/visitor/translation_unit_visitor.h index d5f3b717..851584e6 100644 --- a/src/sequence_diagram/visitor/translation_unit_visitor.h +++ b/src/sequence_diagram/visitor/translation_unit_visitor.h @@ -166,7 +166,7 @@ public: { assert(decl != nullptr); - auto unique_participant_id = get_unique_id(common::id_t{decl->getID()}); + auto unique_participant_id = get_unique_id(eid_t{decl->getID()}); if (!unique_participant_id.has_value()) return {}; @@ -185,7 +185,7 @@ public: { assert(decl != nullptr); - auto unique_participant_id = get_unique_id(common::id_t{decl->getID()}); + auto unique_participant_id = get_unique_id(eid_t{decl->getID()}); if (!unique_participant_id.has_value()) return {}; @@ -200,7 +200,7 @@ public: * @return Optional reference to participant diagram element */ template - common::optional_ref get_participant(const common::id_t id) + common::optional_ref get_participant(const eid_t id) { if (diagram().participants().find(id) == diagram().participants().end()) return {}; @@ -217,7 +217,7 @@ public: * @return Optional reference to participant diagram element */ template - common::optional_ref get_participant(common::id_t id) const + common::optional_ref get_participant(eid_t id) const { if (diagram().participants().find(id) == diagram().participants().end()) return {}; @@ -235,7 +235,7 @@ public: * @param local_id Local AST element id * @param global_id Globa diagram element id */ - void set_unique_id(int64_t local_id, common::id_t global_id); + void set_unique_id(int64_t local_id, eid_t global_id); /** * @brief Retrieve the global `clang-uml` entity id based on the Clang @@ -243,7 +243,7 @@ public: * @param local_id AST local element id * @return Global diagram element id */ - std::optional get_unique_id(common::id_t local_id) const; + std::optional get_unique_id(eid_t local_id) const; /** * @brief Finalize diagram model for this translation unit @@ -469,7 +469,7 @@ private: std::optional get_expression_comment( const clang::SourceManager &sm, const clang::ASTContext &context, - common::id_t caller_id, const clang::Stmt *stmt); + eid_t caller_id, const clang::Stmt *stmt); /** * @brief Initializes model message from comment call directive @@ -502,15 +502,14 @@ private: std::map construct_expr_message_map_; - std::map> + std::map> forward_declarations_; /** * @todo Refactor to @ref ast_id_mapper */ std::mapgetID() */ int64_t, - /* global ID based on full name */ common::id_t> + /* global ID based on full name */ eid_t> local_ast_id_map_; std::map Date: Wed, 5 Jun 2024 23:06:51 +0200 Subject: [PATCH 8/8] Fixed building on macos --- src/common/clang_utils.cc | 3 ++- src/common/types.h | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/common/clang_utils.cc b/src/common/clang_utils.cc index 7f5d06b3..85fee0aa 100644 --- a/src/common/clang_utils.cc +++ b/src/common/clang_utils.cc @@ -417,7 +417,8 @@ bool is_subexpr_of(const clang::Stmt *parent_stmt, const clang::Stmt *sub_stmt) template <> eid_t to_id(const std::string &full_name) { - return static_cast(std::hash{}(full_name)); + return static_cast( + static_cast(std::hash{}(full_name))); } eid_t to_id(const clang::QualType &type, const clang::ASTContext &ctx) diff --git a/src/common/types.h b/src/common/types.h index d1a250e9..53c203e8 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -349,6 +349,6 @@ public: template constexpr auto format(clanguml::common::eid_t const &id, Context &ctx) const { - return format_to(ctx.out(), "{}", id.value()); + return fmt::format_to(ctx.out(), "{}", id.value()); } -}; \ No newline at end of file +};