Added smart pointer dereference sequence diagram test case
This commit is contained in:
@@ -279,32 +279,29 @@ bool translation_unit_visitor::VisitCXXMethodDecl(clang::CXXMethodDecl *m)
|
||||
|
||||
LOG_DBG("Getting method's class with local id {}", parent_decl->getID());
|
||||
|
||||
set_unique_id(m->getID(), m_ptr->id());
|
||||
|
||||
const auto &method_class =
|
||||
diagram()
|
||||
.get_participant<model::class_>(
|
||||
get_unique_id(parent_decl->getID()).value())
|
||||
.value();
|
||||
get_participant<model::class_>(parent_decl).value();
|
||||
|
||||
m_ptr->set_class_id(method_class.id());
|
||||
m_ptr->set_class_full_name(method_class.full_name(false));
|
||||
m_ptr->set_name(
|
||||
diagram().participants.at(m_ptr->class_id())->full_name_no_ns() +
|
||||
get_participant(m_ptr->class_id()).value().full_name_no_ns() +
|
||||
"::" + m->getNameAsString());
|
||||
|
||||
m_ptr->set_id(common::to_id(
|
||||
diagram().participants.at(m_ptr->class_id())->full_name(false) +
|
||||
get_participant(m_ptr->class_id()).value().full_name(false) +
|
||||
"::" + m->getNameAsString()));
|
||||
|
||||
LOG_DBG("Set id {} for method name {}", m_ptr->id(),
|
||||
diagram().participants.at(m_ptr->class_id())->full_name(false) +
|
||||
get_participant(m_ptr->class_id()).value().full_name(false) +
|
||||
"::" + m->getNameAsString());
|
||||
|
||||
context().update(m);
|
||||
|
||||
context().set_caller_id(m_ptr->id());
|
||||
|
||||
set_unique_id(m->getID(), m_ptr->id());
|
||||
|
||||
diagram().add_participant(std::move(m_ptr));
|
||||
|
||||
return true;
|
||||
@@ -577,14 +574,36 @@ bool translation_unit_visitor::VisitCallExpr(clang::CallExpr *expr)
|
||||
->getTemplateName()
|
||||
.getAsTemplateDecl();
|
||||
|
||||
auto callee_method_full_name =
|
||||
diagram()
|
||||
.participants
|
||||
.at(get_unique_id(primary_template->getID())
|
||||
.value())
|
||||
->full_name(false) +
|
||||
"::" +
|
||||
dependent_member_callee->getMember().getAsString();
|
||||
std::string callee_method_full_name;
|
||||
|
||||
// First check if the primary template is already in the
|
||||
// participants map
|
||||
if (get_participant(primary_template).has_value()) {
|
||||
callee_method_full_name =
|
||||
get_participant(primary_template)
|
||||
.value()
|
||||
.full_name(false) +
|
||||
"::" +
|
||||
dependent_member_callee->getMember().getAsString();
|
||||
}
|
||||
else if (is_smart_pointer(primary_template)) {
|
||||
// Otherwise check if it a smart pointer
|
||||
primary_template->getTemplateParameters()
|
||||
->asArray()
|
||||
.front();
|
||||
|
||||
if (get_participant(primary_template).has_value()) {
|
||||
callee_method_full_name =
|
||||
get_participant(primary_template)
|
||||
.value()
|
||||
.full_name(false) +
|
||||
"::" +
|
||||
dependent_member_callee->getMember()
|
||||
.getAsString();
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
auto callee_id = common::to_id(callee_method_full_name);
|
||||
m.to = callee_id;
|
||||
@@ -696,6 +715,16 @@ bool translation_unit_visitor::VisitCallExpr(clang::CallExpr *expr)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool translation_unit_visitor::is_smart_pointer(
|
||||
const clang::TemplateDecl *primary_template) const
|
||||
{
|
||||
return primary_template->getQualifiedNameAsString().find(
|
||||
"std::unique_ptr") == 0 ||
|
||||
primary_template->getQualifiedNameAsString().find("std::shared_ptr") ==
|
||||
0 ||
|
||||
primary_template->getQualifiedNameAsString().find("std::weak_ptr") == 0;
|
||||
}
|
||||
|
||||
std::unique_ptr<clanguml::sequence_diagram::model::class_>
|
||||
translation_unit_visitor::create_class_declaration(clang::CXXRecordDecl *cls)
|
||||
{
|
||||
|
||||
@@ -202,6 +202,29 @@ public:
|
||||
|
||||
void finalize() { }
|
||||
|
||||
template <typename T = model::participant>
|
||||
common::optional_ref<T> get_participant(const clang::Decl *decl)
|
||||
{
|
||||
assert(decl != nullptr);
|
||||
|
||||
auto unique_participant_id = get_unique_id(decl->getID());
|
||||
if (!unique_participant_id.has_value())
|
||||
return {};
|
||||
|
||||
return get_participant<T>(unique_participant_id.value());
|
||||
}
|
||||
|
||||
template <typename T = model::participant>
|
||||
common::optional_ref<T> get_participant(
|
||||
const common::model::diagram_element::id_t id)
|
||||
{
|
||||
if (diagram().participants.find(id) == diagram().participants.end())
|
||||
return {};
|
||||
|
||||
return common::optional_ref<T>(
|
||||
*(static_cast<T *>(diagram().participants.at(id).get())));
|
||||
}
|
||||
|
||||
/// Store the mapping from local clang entity id (obtained using
|
||||
/// getID()) method to clang-uml global id
|
||||
void set_unique_id(
|
||||
@@ -277,6 +300,8 @@ private:
|
||||
bool simplify_system_template(class_diagram::model::template_parameter &ct,
|
||||
const std::string &full_name);
|
||||
|
||||
bool is_smart_pointer(const clang::TemplateDecl *primary_template) const;
|
||||
|
||||
// Reference to the output diagram model
|
||||
clanguml::sequence_diagram::model::diagram &diagram_;
|
||||
|
||||
@@ -296,5 +321,4 @@ private:
|
||||
common::model::access_t>>
|
||||
anonymous_struct_relationships_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user