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