From f1af5460e30083e9908524f6e6fd48d0e40e01b7 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 27 Nov 2022 19:15:31 +0100 Subject: [PATCH] Refactored sequence diagram visitor --- .../visitor/translation_unit_visitor.cc | 143 +++++++++--------- .../visitor/translation_unit_visitor.h | 8 +- 2 files changed, 77 insertions(+), 74 deletions(-) diff --git a/src/sequence_diagram/visitor/translation_unit_visitor.cc b/src/sequence_diagram/visitor/translation_unit_visitor.cc index 9df65cd0..0ff84b37 100644 --- a/src/sequence_diagram/visitor/translation_unit_visitor.cc +++ b/src/sequence_diagram/visitor/translation_unit_visitor.cc @@ -58,6 +58,16 @@ translation_unit_visitor::translation_unit_visitor(clang::SourceManager &sm, { } +bool translation_unit_visitor::shouldVisitTemplateInstantiations() +{ + return true; +} + +call_expression_context &translation_unit_visitor::context() +{ + return call_expression_context_; +} + clanguml::sequence_diagram::model::diagram &translation_unit_visitor::diagram() { return diagram_; @@ -78,14 +88,10 @@ bool translation_unit_visitor::VisitCXXRecordDecl(clang::CXXRecordDecl *cls) if (!diagram().should_include(cls->getQualifiedNameAsString())) return true; - if (!diagram().should_include(cls->getQualifiedNameAsString())) { - return true; - } - if (cls->isTemplated() && cls->getDescribedTemplate()) { // If the described templated of this class is already in the model // skip it: - if (get_ast_local_id(cls->getDescribedTemplate()->getID())) + if (get_unique_id(cls->getDescribedTemplate()->getID())) return true; } @@ -100,11 +106,11 @@ bool translation_unit_visitor::VisitCXXRecordDecl(clang::CXXRecordDecl *cls) if (!c_ptr) return true; - call_expression_context_.reset(); + context().reset(); const auto cls_id = c_ptr->id(); - set_ast_local_id(cls->getID(), cls_id); + set_unique_id(cls->getID(), cls_id); auto &class_model = diagram() @@ -124,16 +130,16 @@ bool translation_unit_visitor::VisitCXXRecordDecl(clang::CXXRecordDecl *cls) forward_declarations_.erase(id); } - if (diagram_.should_include(class_model)) { + if (diagram().should_include(class_model)) { LOG_DBG("Adding class {} with id {}", class_model.full_name(false), class_model.id()); assert(class_model.id() == cls_id); - call_expression_context_.set_caller_id(cls_id); - call_expression_context_.update(cls); + context().set_caller_id(cls_id); + context().update(cls); - diagram_.add_participant(std::move(c_ptr)); + diagram().add_participant(std::move(c_ptr)); } else { LOG_DBG("Skipping class {} with id {}", class_model.full_name(), @@ -170,7 +176,7 @@ bool translation_unit_visitor::VisitClassTemplateDecl( c_ptr->set_id(id); - set_ast_local_id(cls->getID(), id); + set_unique_id(cls->getID(), id); if (!cls->getTemplatedDecl()->isCompleteDefinition()) { forward_declarations_.emplace(id, std::move(c_ptr)); @@ -180,13 +186,13 @@ bool translation_unit_visitor::VisitClassTemplateDecl( forward_declarations_.erase(id); } - if (diagram_.should_include(*c_ptr)) { + if (diagram().should_include(*c_ptr)) { LOG_DBG("Adding class template {} with id {}", cls_full_name, id); - call_expression_context_.set_caller_id(id); - call_expression_context_.update(cls); + context().set_caller_id(id); + context().update(cls); - diagram_.add_participant(std::move(c_ptr)); + diagram().add_participant(std::move(c_ptr)); } return true; @@ -201,7 +207,7 @@ bool translation_unit_visitor::VisitClassTemplateSpecializationDecl( if (!diagram().should_include(cls->getQualifiedNameAsString())) return true; - LOG_DBG("##### Visiting template specialization declaration {} at {}", + LOG_DBG("Visiting template specialization declaration {} at {}", cls->getQualifiedNameAsString(), cls->getLocation().printToString(source_manager())); @@ -219,7 +225,7 @@ bool translation_unit_visitor::VisitClassTemplateSpecializationDecl( template_specialization_ptr->set_id(id); - set_ast_local_id(cls->getID(), id); + set_unique_id(cls->getID(), id); if (!cls->isCompleteDefinition()) { forward_declarations_.emplace( @@ -230,14 +236,14 @@ bool translation_unit_visitor::VisitClassTemplateSpecializationDecl( forward_declarations_.erase(id); } - if (diagram_.should_include(*template_specialization_ptr)) { + if (diagram().should_include(*template_specialization_ptr)) { LOG_DBG("Adding class template specialization {} with id {}", cls_full_name, id); - call_expression_context_.set_caller_id(id); - call_expression_context_.update(cls); + context().set_caller_id(id); + context().update(cls); - diagram_.add_participant(std::move(template_specialization_ptr)); + diagram().add_participant(std::move(template_specialization_ptr)); } return true; @@ -245,17 +251,16 @@ bool translation_unit_visitor::VisitClassTemplateSpecializationDecl( bool translation_unit_visitor::VisitCXXMethodDecl(clang::CXXMethodDecl *m) { - if (call_expression_context_.current_class_decl_ == nullptr && - call_expression_context_.current_class_template_decl_ == nullptr && - call_expression_context_.current_class_template_specialization_decl_ == - nullptr) + if (context().current_class_decl_ == nullptr && + context().current_class_template_decl_ == nullptr && + context().current_class_template_specialization_decl_ == nullptr) return true; LOG_DBG("= Processing method {} in class {} [{}]", m->getQualifiedNameAsString(), m->getParent()->getQualifiedNameAsString(), (void *)m->getParent()); - call_expression_context_.update(m); + context().update(m); auto m_ptr = std::make_unique( config().using_namespace()); @@ -269,17 +274,15 @@ bool translation_unit_visitor::VisitCXXMethodDecl(clang::CXXMethodDecl *m) clang::Decl *parent_decl = m->getParent(); - if (call_expression_context_.current_class_template_decl_) - parent_decl = call_expression_context_.current_class_template_decl_; - - call_expression_context_.dump(); + if (context().current_class_template_decl_) + parent_decl = context().current_class_template_decl_; LOG_DBG("Getting method's class with local id {}", parent_decl->getID()); const auto &method_class = diagram() .get_participant( - get_ast_local_id(parent_decl->getID()).value()) + get_unique_id(parent_decl->getID()).value()) .value(); m_ptr->set_class_id(method_class.id()); @@ -296,11 +299,11 @@ bool translation_unit_visitor::VisitCXXMethodDecl(clang::CXXMethodDecl *m) diagram().participants.at(m_ptr->class_id())->full_name(false) + "::" + m->getNameAsString()); - call_expression_context_.update(m); + context().update(m); - call_expression_context_.set_caller_id(m_ptr->id()); + context().set_caller_id(m_ptr->id()); - set_ast_local_id(m->getID(), m_ptr->id()); + set_unique_id(m->getID(), m_ptr->id()); diagram().add_participant(std::move(m_ptr)); @@ -324,7 +327,7 @@ bool translation_unit_visitor::VisitFunctionDecl(clang::FunctionDecl *f) if (f->getDescribedTemplate()) { // If the described templated of this function is already in the // model skip it: - if (get_ast_local_id(f->getDescribedTemplate()->getID())) + if (get_unique_id(f->getDescribedTemplate()->getID())) return true; } } @@ -334,11 +337,11 @@ bool translation_unit_visitor::VisitFunctionDecl(clang::FunctionDecl *f) f_ptr->set_id(common::to_id(f_ptr->full_name(false))); - call_expression_context_.update(f); + context().update(f); - call_expression_context_.set_caller_id(f_ptr->id()); + context().set_caller_id(f_ptr->id()); - set_ast_local_id(f->getID(), f_ptr->id()); + set_unique_id(f->getID(), f_ptr->id()); // TODO: Handle overloaded functions with different arguments diagram().add_participant(std::move(f_ptr)); @@ -353,11 +356,11 @@ bool translation_unit_visitor::VisitFunctionDecl(clang::FunctionDecl *f) f_ptr->set_namespace(ns); f_ptr->set_id(common::to_id(function_name)); - call_expression_context_.update(f); + context().update(f); - call_expression_context_.set_caller_id(f_ptr->id()); + context().set_caller_id(f_ptr->id()); - set_ast_local_id(f->getID(), f_ptr->id()); + set_unique_id(f->getID(), f_ptr->id()); // TODO: Handle overloaded functions with different arguments diagram().add_participant(std::move(f_ptr)); @@ -389,10 +392,10 @@ bool translation_unit_visitor::VisitFunctionTemplateDecl( f_ptr->set_id(common::to_id(f_ptr->full_name(false))); - call_expression_context_.update(function_template); - call_expression_context_.set_caller_id(f_ptr->id()); + context().update(function_template); + context().set_caller_id(f_ptr->id()); - set_ast_local_id(function_template->getID(), f_ptr->id()); + set_unique_id(function_template->getID(), f_ptr->id()); // TODO: Handle overloaded functions with different arguments diagram().add_participant(std::move(f_ptr)); @@ -417,15 +420,14 @@ bool translation_unit_visitor::VisitCallExpr(clang::CallExpr *expr) if (clang::dyn_cast_or_null(expr)) return true; - if (!call_expression_context_.valid()) + if (!context().valid()) return true; message m; m.type = message_t::kCall; - m.from = call_expression_context_.caller_id(); + m.from = context().caller_id(); - const auto ¤t_ast_context = - *call_expression_context_.get_ast_context(); + const auto ¤t_ast_context = *context().get_ast_context(); LOG_DBG("Visiting call expression at {}", expr->getBeginLoc().printToString(source_manager())); @@ -463,9 +465,9 @@ bool translation_unit_visitor::VisitCallExpr(clang::CallExpr *expr) const auto &participant = diagram() - .get_participant(get_ast_local_id( - callee_template_specialization->getID()) - .value()) + .get_participant( + get_unique_id(callee_template_specialization->getID()) + .value()) .value(); if (participant.is_implicit()) { @@ -476,7 +478,7 @@ bool translation_unit_visitor::VisitCallExpr(clang::CallExpr *expr) const auto &parent_template_participant = diagram() .get_participant( - get_ast_local_id(parent_template->getID()).value()) + get_unique_id(parent_template->getID()).value()) .value(); const auto parent_method_name = @@ -508,7 +510,7 @@ bool translation_unit_visitor::VisitCallExpr(clang::CallExpr *expr) m_ptr->set_name(method_decl->getNameAsString()); m_ptr->set_class_id(participant.id()); m_ptr->set_class_full_name(participant.full_name(false)); - set_ast_local_id(method_decl->getID(), m_ptr->id()); + set_unique_id(method_decl->getID(), m_ptr->id()); diagram().add_active_participant(m_ptr->id()); diagram().add_participant(std::move(m_ptr)); } @@ -516,7 +518,7 @@ bool translation_unit_visitor::VisitCallExpr(clang::CallExpr *expr) else { const auto &specialization_participant = diagram() - .get_participant(get_ast_local_id( + .get_participant(get_unique_id( callee_template_specialization->getID()) .value()) .value(); @@ -541,9 +543,9 @@ bool translation_unit_visitor::VisitCallExpr(clang::CallExpr *expr) LOG_DBG("Set callee method id {} for method name {}", m.to, method_decl->getQualifiedNameAsString()); - if (get_ast_local_id(callee_decl->getID())) + if (get_unique_id(callee_decl->getID())) diagram().add_active_participant( - get_ast_local_id(callee_decl->getID()).value()); + get_unique_id(callee_decl->getID()).value()); } // // Call to a function @@ -578,7 +580,7 @@ bool translation_unit_visitor::VisitCallExpr(clang::CallExpr *expr) auto callee_method_full_name = diagram() .participants - .at(get_ast_local_id(primary_template->getID()) + .at(get_unique_id(primary_template->getID()) .value()) ->full_name(false) + "::" + @@ -591,10 +593,9 @@ bool translation_unit_visitor::VisitCallExpr(clang::CallExpr *expr) dependent_member_callee->getMember().getAsString(); m.return_type = ""; - if (get_ast_local_id(primary_template->getID())) + if (get_unique_id(primary_template->getID())) diagram().add_active_participant( - get_ast_local_id(primary_template->getID()) - .value()); + get_unique_id(primary_template->getID()).value()); } } // @@ -615,7 +616,7 @@ bool translation_unit_visitor::VisitCallExpr(clang::CallExpr *expr) auto *ftd = clang::dyn_cast_or_null< clang::FunctionTemplateDecl>(decl); - m.to = get_ast_local_id(ftd->getID()).value(); + m.to = get_unique_id(ftd->getID()).value(); auto message_name = diagram() .get_participant( @@ -646,12 +647,12 @@ bool translation_unit_visitor::VisitCallExpr(clang::CallExpr *expr) std::unique_ptr f_ptr; - if (!get_ast_local_id(callee_function->getID()).has_value()) { + if (!get_unique_id(callee_function->getID()).has_value()) { // This is hopefully not an interesting call... return true; } else { - m.to = get_ast_local_id(callee_function->getID()).value(); + m.to = get_unique_id(callee_function->getID()).value(); } auto message_name = callee_name; @@ -701,7 +702,7 @@ translation_unit_visitor::create_class_declaration(clang::CXXRecordDecl *cls) assert(cls != nullptr); auto c_ptr{std::make_unique( - config_.using_namespace())}; + config().using_namespace())}; auto &c = *c_ptr; // TODO: refactor to method get_qualified_name() @@ -725,7 +726,7 @@ translation_unit_visitor::create_class_declaration(clang::CXXRecordDecl *cls) // First check if the parent has been added to the diagram as regular // class - id_opt = get_ast_local_id(local_id); + id_opt = get_unique_id(local_id); // If not, check if the parent template declaration is in the model if (!id_opt) { @@ -734,7 +735,7 @@ translation_unit_visitor::create_class_declaration(clang::CXXRecordDecl *cls) ->getID(); if (static_cast(parent) ->getDescribedTemplate()) - id_opt = get_ast_local_id(local_id); + id_opt = get_unique_id(local_id); } assert(id_opt); @@ -853,7 +854,7 @@ bool translation_unit_visitor::process_template_parameters( return false; } -void translation_unit_visitor::set_ast_local_id( +void translation_unit_visitor::set_unique_id( int64_t local_id, common::model::diagram_element::id_t global_id) { LOG_DBG("== Setting local element mapping {} --> {}", local_id, global_id); @@ -862,7 +863,7 @@ void translation_unit_visitor::set_ast_local_id( } std::optional -translation_unit_visitor::get_ast_local_id(int64_t local_id) const +translation_unit_visitor::get_unique_id(int64_t local_id) const { if (local_ast_id_map_.find(local_id) == local_ast_id_map_.end()) return {}; @@ -1121,7 +1122,7 @@ translation_unit_visitor::process_template_specialization( template_instantiation.set_id( common::to_id(template_instantiation.full_name(false))); - set_ast_local_id(cls->getID(), template_instantiation.id()); + set_unique_id(cls->getID(), template_instantiation.id()); return c_ptr; } @@ -1450,7 +1451,7 @@ translation_unit_visitor::build_template_instantiation( auto templated_decl_id = template_type.getTemplateName().getAsTemplateDecl()->getID(); // auto templated_decl_local_id = - // get_ast_local_id(templated_decl_id).value_or(0); + // get_unique_id(templated_decl_id).value_or(0); if (best_match_id > 0) { destination = best_match_full_name; diff --git a/src/sequence_diagram/visitor/translation_unit_visitor.h b/src/sequence_diagram/visitor/translation_unit_visitor.h index e892282a..27765512 100644 --- a/src/sequence_diagram/visitor/translation_unit_visitor.h +++ b/src/sequence_diagram/visitor/translation_unit_visitor.h @@ -176,7 +176,7 @@ public: clanguml::sequence_diagram::model::diagram &diagram, const clanguml::config::sequence_diagram &config); - bool shouldVisitTemplateInstantiations() { return true; } + bool shouldVisitTemplateInstantiations(); virtual bool VisitCallExpr(clang::CallExpr *expr); @@ -198,15 +198,17 @@ public: const clanguml::config::sequence_diagram &config() const; + call_expression_context &context(); + void finalize() { } /// Store the mapping from local clang entity id (obtained using /// getID()) method to clang-uml global id - void set_ast_local_id( + void set_unique_id( int64_t local_id, common::model::diagram_element::id_t global_id); /// Retrieve the global clang-uml entity id based on the clang local id - std::optional get_ast_local_id( + std::optional get_unique_id( int64_t local_id) const; private: