Improved rendering of template methods in class diagrams
This commit is contained in:
@@ -144,6 +144,10 @@ void generator::generate(const class_ &c, std::ostream &ostr) const
|
|||||||
|
|
||||||
ostr << plantuml_common::to_plantuml(m.access()) << m.name();
|
ostr << plantuml_common::to_plantuml(m.access()) << m.name();
|
||||||
|
|
||||||
|
if (!m.templates().empty()) {
|
||||||
|
m.render_template_params(ostr, m_config.using_namespace(), false);
|
||||||
|
}
|
||||||
|
|
||||||
ostr << "(";
|
ostr << "(";
|
||||||
if (m_config.generate_method_arguments() !=
|
if (m_config.generate_method_arguments() !=
|
||||||
config::method_arguments::none) {
|
config::method_arguments::none) {
|
||||||
|
|||||||
@@ -68,29 +68,12 @@ void class_::add_parent(class_parent &&parent)
|
|||||||
bases_.emplace_back(std::move(parent));
|
bases_.emplace_back(std::move(parent));
|
||||||
}
|
}
|
||||||
|
|
||||||
void class_::add_template(template_parameter &&tmplt)
|
|
||||||
{
|
|
||||||
templates_.emplace_back(std::move(tmplt));
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<class_member> &class_::members() const { return members_; }
|
const std::vector<class_member> &class_::members() const { return members_; }
|
||||||
|
|
||||||
const std::vector<class_method> &class_::methods() const { return methods_; }
|
const std::vector<class_method> &class_::methods() const { return methods_; }
|
||||||
|
|
||||||
const std::vector<class_parent> &class_::parents() const { return bases_; }
|
const std::vector<class_parent> &class_::parents() const { return bases_; }
|
||||||
|
|
||||||
const std::vector<template_parameter> &class_::templates() const
|
|
||||||
{
|
|
||||||
return templates_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void class_::set_base_template(const std::string &full_name)
|
|
||||||
{
|
|
||||||
base_template_full_name_ = full_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string class_::base_template() const { return base_template_full_name_; }
|
|
||||||
|
|
||||||
bool operator==(const class_ &l, const class_ &r) { return l.id() == r.id(); }
|
bool operator==(const class_ &l, const class_ &r) { return l.id() == r.id(); }
|
||||||
|
|
||||||
std::string class_::full_name_no_ns() const
|
std::string class_::full_name_no_ns() const
|
||||||
@@ -101,7 +84,7 @@ std::string class_::full_name_no_ns() const
|
|||||||
|
|
||||||
ostr << name();
|
ostr << name();
|
||||||
|
|
||||||
render_template_params(ostr, false);
|
render_template_params(ostr, using_namespace(), false);
|
||||||
|
|
||||||
return ostr.str();
|
return ostr.str();
|
||||||
}
|
}
|
||||||
@@ -114,7 +97,8 @@ std::string class_::full_name(bool relative) const
|
|||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
|
|
||||||
ostr << name_and_ns();
|
ostr << name_and_ns();
|
||||||
render_template_params(ostr, relative);
|
|
||||||
|
render_template_params(ostr, using_namespace(), relative);
|
||||||
|
|
||||||
std::string res;
|
std::string res;
|
||||||
|
|
||||||
@@ -129,26 +113,6 @@ std::string class_::full_name(bool relative) const
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostringstream &class_::render_template_params(
|
|
||||||
std::ostringstream &ostr, bool relative) const
|
|
||||||
{
|
|
||||||
using clanguml::common::model::namespace_;
|
|
||||||
|
|
||||||
if (!templates_.empty()) {
|
|
||||||
std::vector<std::string> tnames;
|
|
||||||
std::vector<std::string> tnames_simplified;
|
|
||||||
|
|
||||||
std::transform(templates_.cbegin(), templates_.cend(),
|
|
||||||
std::back_inserter(tnames),
|
|
||||||
[ns = using_namespace(), relative](
|
|
||||||
const auto &tmplt) { return tmplt.to_string(ns, relative); });
|
|
||||||
|
|
||||||
ostr << fmt::format("<{}>", fmt::join(tnames, ","));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ostr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool class_::is_abstract() const
|
bool class_::is_abstract() const
|
||||||
{
|
{
|
||||||
// TODO check if all base abstract methods are overriden
|
// TODO check if all base abstract methods are overriden
|
||||||
|
|||||||
@@ -23,8 +23,9 @@
|
|||||||
#include "common/model/element.h"
|
#include "common/model/element.h"
|
||||||
#include "common/model/enums.h"
|
#include "common/model/enums.h"
|
||||||
#include "common/model/stylable_element.h"
|
#include "common/model/stylable_element.h"
|
||||||
|
#include "common/model/template_parameter.h"
|
||||||
|
#include "common/model/template_trait.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "template_parameter.h"
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -32,7 +33,8 @@
|
|||||||
namespace clanguml::class_diagram::model {
|
namespace clanguml::class_diagram::model {
|
||||||
|
|
||||||
class class_ : public common::model::element,
|
class class_ : public common::model::element,
|
||||||
public common::model::stylable_element {
|
public common::model::stylable_element,
|
||||||
|
public template_trait {
|
||||||
public:
|
public:
|
||||||
class_(const common::model::namespace_ &using_namespace);
|
class_(const common::model::namespace_ &using_namespace);
|
||||||
|
|
||||||
@@ -55,12 +57,10 @@ public:
|
|||||||
void add_member(class_member &&member);
|
void add_member(class_member &&member);
|
||||||
void add_method(class_method &&method);
|
void add_method(class_method &&method);
|
||||||
void add_parent(class_parent &&parent);
|
void add_parent(class_parent &&parent);
|
||||||
void add_template(template_parameter &&tmplt);
|
|
||||||
|
|
||||||
const std::vector<class_member> &members() const;
|
const std::vector<class_member> &members() const;
|
||||||
const std::vector<class_method> &methods() const;
|
const std::vector<class_method> &methods() const;
|
||||||
const std::vector<class_parent> &parents() const;
|
const std::vector<class_parent> &parents() const;
|
||||||
const std::vector<template_parameter> &templates() const;
|
|
||||||
|
|
||||||
void set_base_template(const std::string &full_name);
|
void set_base_template(const std::string &full_name);
|
||||||
std::string base_template() const;
|
std::string base_template() const;
|
||||||
@@ -85,9 +85,6 @@ public:
|
|||||||
const class_ &other, const std::string &full_name) const;
|
const class_ &other, const std::string &full_name) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::ostringstream &render_template_params(
|
|
||||||
std::ostringstream &ostr, bool relative) const;
|
|
||||||
|
|
||||||
bool is_struct_{false};
|
bool is_struct_{false};
|
||||||
bool is_template_{false};
|
bool is_template_{false};
|
||||||
bool is_template_instantiation_{false};
|
bool is_template_instantiation_{false};
|
||||||
@@ -95,7 +92,6 @@ private:
|
|||||||
std::vector<class_member> members_;
|
std::vector<class_member> members_;
|
||||||
std::vector<class_method> methods_;
|
std::vector<class_method> methods_;
|
||||||
std::vector<class_parent> bases_;
|
std::vector<class_parent> bases_;
|
||||||
std::vector<template_parameter> templates_;
|
|
||||||
std::string base_template_full_name_;
|
std::string base_template_full_name_;
|
||||||
|
|
||||||
std::string full_name_;
|
std::string full_name_;
|
||||||
|
|||||||
@@ -61,4 +61,5 @@ void class_method::add_parameter(method_parameter &¶meter)
|
|||||||
{
|
{
|
||||||
parameters_.emplace_back(std::move(parameter));
|
parameters_.emplace_back(std::move(parameter));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace clanguml::class_diagram::model
|
} // namespace clanguml::class_diagram::model
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "class_element.h"
|
#include "class_element.h"
|
||||||
|
#include "common/model/template_parameter.h"
|
||||||
|
#include "common/model/template_trait.h"
|
||||||
#include "method_parameter.h"
|
#include "method_parameter.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -25,7 +27,9 @@
|
|||||||
|
|
||||||
namespace clanguml::class_diagram::model {
|
namespace clanguml::class_diagram::model {
|
||||||
|
|
||||||
class class_method : public class_element {
|
using clanguml::common::model::template_trait;
|
||||||
|
|
||||||
|
class class_method : public class_element, public template_trait {
|
||||||
public:
|
public:
|
||||||
class_method(common::model::access_t access, const std::string &name,
|
class_method(common::model::access_t access, const std::string &name,
|
||||||
const std::string &type);
|
const std::string &type);
|
||||||
@@ -52,6 +56,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<method_parameter> parameters_;
|
std::vector<method_parameter> parameters_;
|
||||||
|
|
||||||
bool is_pure_virtual_{false};
|
bool is_pure_virtual_{false};
|
||||||
bool is_virtual_{false};
|
bool is_virtual_{false};
|
||||||
bool is_const_{false};
|
bool is_const_{false};
|
||||||
|
|||||||
@@ -26,19 +26,6 @@
|
|||||||
|
|
||||||
namespace clanguml::class_diagram::visitor {
|
namespace clanguml::class_diagram::visitor {
|
||||||
|
|
||||||
using clanguml::class_diagram::model::class_;
|
|
||||||
using clanguml::class_diagram::model::class_member;
|
|
||||||
using clanguml::class_diagram::model::class_method;
|
|
||||||
using clanguml::class_diagram::model::class_parent;
|
|
||||||
using clanguml::class_diagram::model::diagram;
|
|
||||||
using clanguml::class_diagram::model::enum_;
|
|
||||||
using clanguml::class_diagram::model::method_parameter;
|
|
||||||
using clanguml::class_diagram::model::template_parameter;
|
|
||||||
using clanguml::common::model::access_t;
|
|
||||||
using clanguml::common::model::namespace_;
|
|
||||||
using clanguml::common::model::relationship;
|
|
||||||
using clanguml::common::model::relationship_t;
|
|
||||||
|
|
||||||
translation_unit_visitor::translation_unit_visitor(clang::SourceManager &sm,
|
translation_unit_visitor::translation_unit_visitor(clang::SourceManager &sm,
|
||||||
clanguml::class_diagram::model::diagram &diagram,
|
clanguml::class_diagram::model::diagram &diagram,
|
||||||
const clanguml::config::class_diagram &config)
|
const clanguml::config::class_diagram &config)
|
||||||
@@ -513,7 +500,8 @@ void translation_unit_visitor::process_class_declaration(
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool translation_unit_visitor::process_template_parameters(
|
bool translation_unit_visitor::process_template_parameters(
|
||||||
const clang::ClassTemplateDecl &template_declaration, class_ &c)
|
const clang::TemplateDecl &template_declaration,
|
||||||
|
common::model::template_trait &c)
|
||||||
{
|
{
|
||||||
LOG_DBG("Processing class {} template parameters...",
|
LOG_DBG("Processing class {} template parameters...",
|
||||||
common::get_qualified_name(template_declaration));
|
common::get_qualified_name(template_declaration));
|
||||||
@@ -966,6 +954,8 @@ void translation_unit_visitor::process_template_method(
|
|||||||
method.is_defaulted(mf.getTemplatedDecl()->isDefaulted());
|
method.is_defaulted(mf.getTemplatedDecl()->isDefaulted());
|
||||||
method.is_static(mf.getTemplatedDecl()->isStatic());
|
method.is_static(mf.getTemplatedDecl()->isStatic());
|
||||||
|
|
||||||
|
process_template_parameters(mf, method);
|
||||||
|
|
||||||
process_comment(mf, method);
|
process_comment(mf, method);
|
||||||
|
|
||||||
if (method.skip())
|
if (method.skip())
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "class_diagram/model/class.h"
|
#include "class_diagram/model/class.h"
|
||||||
#include "class_diagram/model/diagram.h"
|
#include "class_diagram/model/diagram.h"
|
||||||
#include "common/model/enums.h"
|
#include "common/model/enums.h"
|
||||||
|
#include "common/model/template_trait.h"
|
||||||
#include "common/visitor/translation_unit_visitor.h"
|
#include "common/visitor/translation_unit_visitor.h"
|
||||||
#include "config/config.h"
|
#include "config/config.h"
|
||||||
|
|
||||||
@@ -34,6 +35,20 @@
|
|||||||
|
|
||||||
namespace clanguml::class_diagram::visitor {
|
namespace clanguml::class_diagram::visitor {
|
||||||
|
|
||||||
|
using clanguml::class_diagram::model::class_;
|
||||||
|
using clanguml::class_diagram::model::class_member;
|
||||||
|
using clanguml::class_diagram::model::class_method;
|
||||||
|
using clanguml::class_diagram::model::class_parent;
|
||||||
|
using clanguml::class_diagram::model::diagram;
|
||||||
|
using clanguml::class_diagram::model::enum_;
|
||||||
|
using clanguml::class_diagram::model::method_parameter;
|
||||||
|
using clanguml::common::model::access_t;
|
||||||
|
using clanguml::common::model::namespace_;
|
||||||
|
using clanguml::common::model::relationship;
|
||||||
|
using clanguml::common::model::relationship_t;
|
||||||
|
using clanguml::common::model::template_parameter;
|
||||||
|
using clanguml::common::model::template_trait;
|
||||||
|
|
||||||
using found_relationships_t =
|
using found_relationships_t =
|
||||||
std::vector<std::pair<clanguml::common::model::diagram_element::id_t,
|
std::vector<std::pair<clanguml::common::model::diagram_element::id_t,
|
||||||
common::model::relationship_t>>;
|
common::model::relationship_t>>;
|
||||||
@@ -108,12 +123,11 @@ private:
|
|||||||
clang::ClassTemplateSpecializationDecl *cls);
|
clang::ClassTemplateSpecializationDecl *cls);
|
||||||
|
|
||||||
void process_template_specialization_children(
|
void process_template_specialization_children(
|
||||||
const clang::ClassTemplateSpecializationDecl *cls,
|
const clang::ClassTemplateSpecializationDecl *cls, class_ &c);
|
||||||
clanguml::class_diagram::model::class_ &c);
|
|
||||||
|
|
||||||
bool process_template_parameters(
|
bool process_template_parameters(
|
||||||
const clang::ClassTemplateDecl &template_declaration,
|
const clang::TemplateDecl &template_declaration,
|
||||||
clanguml::class_diagram::model::class_ &c);
|
clanguml::common::model::template_trait &t);
|
||||||
|
|
||||||
void process_template_specialization_argument(
|
void process_template_specialization_argument(
|
||||||
const clang::ClassTemplateSpecializationDecl *cls,
|
const clang::ClassTemplateSpecializationDecl *cls,
|
||||||
@@ -171,7 +185,7 @@ private:
|
|||||||
clanguml::class_diagram::model::class_ &tinst,
|
clanguml::class_diagram::model::class_ &tinst,
|
||||||
std::deque<std::tuple<std::string, int, bool>> &template_base_params,
|
std::deque<std::tuple<std::string, int, bool>> &template_base_params,
|
||||||
int arg_index, bool variadic_params,
|
int arg_index, bool variadic_params,
|
||||||
const clanguml::class_diagram::model::template_parameter &ct) const;
|
const clanguml::common::model::template_parameter &ct) const;
|
||||||
|
|
||||||
void build_template_instantiation_process_template_arguments(
|
void build_template_instantiation_process_template_arguments(
|
||||||
std::optional<clanguml::class_diagram::model::class_ *> &parent,
|
std::optional<clanguml::class_diagram::model::class_ *> &parent,
|
||||||
@@ -186,15 +200,15 @@ private:
|
|||||||
const std::string &full_template_specialization_name,
|
const std::string &full_template_specialization_name,
|
||||||
const clang::TemplateDecl *template_decl,
|
const clang::TemplateDecl *template_decl,
|
||||||
const clang::TemplateArgument &arg,
|
const clang::TemplateArgument &arg,
|
||||||
model::template_parameter &argument);
|
common::model::template_parameter &argument);
|
||||||
|
|
||||||
void build_template_instantiation_process_expression_argument(
|
void build_template_instantiation_process_expression_argument(
|
||||||
const clang::TemplateArgument &arg,
|
const clang::TemplateArgument &arg,
|
||||||
model::template_parameter &argument) const;
|
common::model::template_parameter &argument) const;
|
||||||
|
|
||||||
void build_template_instantiation_process_integral_argument(
|
void build_template_instantiation_process_integral_argument(
|
||||||
const clang::TemplateArgument &arg,
|
const clang::TemplateArgument &arg,
|
||||||
model::template_parameter &argument) const;
|
common::model::template_parameter &argument) const;
|
||||||
|
|
||||||
void build_template_instantiation_process_type_argument(
|
void build_template_instantiation_process_type_argument(
|
||||||
std::optional<clanguml::class_diagram::model::class_ *> &parent,
|
std::optional<clanguml::class_diagram::model::class_ *> &parent,
|
||||||
@@ -202,11 +216,11 @@ private:
|
|||||||
const clang::TemplateDecl *template_decl,
|
const clang::TemplateDecl *template_decl,
|
||||||
const clang::TemplateArgument &arg,
|
const clang::TemplateArgument &arg,
|
||||||
model::class_ &template_instantiation,
|
model::class_ &template_instantiation,
|
||||||
model::template_parameter &argument);
|
common::model::template_parameter &argument);
|
||||||
|
|
||||||
void build_template_instantiation_process_template_argument(
|
void build_template_instantiation_process_template_argument(
|
||||||
const clang::TemplateArgument &arg,
|
const clang::TemplateArgument &arg,
|
||||||
model::template_parameter &argument) const;
|
common::model::template_parameter &argument) const;
|
||||||
|
|
||||||
void ensure_lambda_type_is_relative(std::string ¶meter_type) const;
|
void ensure_lambda_type_is_relative(std::string ¶meter_type) const;
|
||||||
|
|
||||||
@@ -220,19 +234,19 @@ private:
|
|||||||
|
|
||||||
void process_unexposed_template_specialization_parameters(
|
void process_unexposed_template_specialization_parameters(
|
||||||
const std::string &tspec,
|
const std::string &tspec,
|
||||||
clanguml::class_diagram::model::template_parameter &tp,
|
clanguml::common::model::template_parameter &tp,
|
||||||
clanguml::class_diagram::model::class_ &c);
|
clanguml::class_diagram::model::class_ &c);
|
||||||
|
|
||||||
bool find_relationships_in_unexposed_template_params(
|
bool find_relationships_in_unexposed_template_params(
|
||||||
const clanguml::class_diagram::model::template_parameter &ct,
|
const clanguml::common::model::template_parameter &ct,
|
||||||
found_relationships_t &relationships);
|
found_relationships_t &relationships);
|
||||||
|
|
||||||
void add_incomplete_forward_declarations();
|
void add_incomplete_forward_declarations();
|
||||||
|
|
||||||
void resolve_local_to_global_ids();
|
void resolve_local_to_global_ids();
|
||||||
|
|
||||||
bool simplify_system_template(
|
bool simplify_system_template(common::model::template_parameter &ct,
|
||||||
model::template_parameter &ct, const std::string &full_name) const;
|
const std::string &full_name) const;
|
||||||
|
|
||||||
/// Store the mapping from local clang entity id (obtained using
|
/// Store the mapping from local clang entity id (obtained using
|
||||||
/// getID()) method to clang-uml global id
|
/// getID()) method to clang-uml global id
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* src/class_diagram/model/template_parameter.cc
|
* src/common/model/template_parameter.cc
|
||||||
*
|
*
|
||||||
* Copyright (c) 2021-2023 Bartek Kryza <bkryza@gmail.com>
|
* Copyright (c) 2021-2023 Bartek Kryza <bkryza@gmail.com>
|
||||||
*
|
*
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace clanguml::class_diagram::model {
|
namespace clanguml::common::model {
|
||||||
|
|
||||||
template_parameter::template_parameter(const std::string &type,
|
template_parameter::template_parameter(const std::string &type,
|
||||||
const std::string &name, std::string default_value, bool is_variadic)
|
const std::string &name, std::string default_value, bool is_variadic)
|
||||||
@@ -216,4 +216,4 @@ bool template_parameter::find_nested_relationships(
|
|||||||
return added_aggregation_relationship;
|
return added_aggregation_relationship;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace clanguml::class_diagram::model
|
} // namespace clanguml::common::model
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* src/class_diagram/model/template_parameter.h
|
* src/common/model/template_parameter.h
|
||||||
*
|
*
|
||||||
* Copyright (c) 2021-2023 Bartek Kryza <bkryza@gmail.com>
|
* Copyright (c) 2021-2023 Bartek Kryza <bkryza@gmail.com>
|
||||||
*
|
*
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace clanguml::class_diagram::model {
|
namespace clanguml::common::model {
|
||||||
|
|
||||||
/// @brief Represents template parameter or template argument
|
/// @brief Represents template parameter or template argument
|
||||||
///
|
///
|
||||||
@@ -130,4 +130,4 @@ private:
|
|||||||
|
|
||||||
std::optional<int64_t> id_;
|
std::optional<int64_t> id_;
|
||||||
};
|
};
|
||||||
} // namespace clanguml::class_diagram::model
|
} // namespace clanguml::common::model
|
||||||
97
src/common/model/template_trait.cc
Normal file
97
src/common/model/template_trait.cc
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
/**
|
||||||
|
* src/common/model/template_trait.cc
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021-2023 Bartek Kryza <bkryza@gmail.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/model/template_trait.h"
|
||||||
|
|
||||||
|
namespace clanguml::common::model {
|
||||||
|
|
||||||
|
std::ostream &template_trait::render_template_params(std::ostream &ostr,
|
||||||
|
const common::model::namespace_ &using_namespace, bool relative) const
|
||||||
|
{
|
||||||
|
using clanguml::common::model::namespace_;
|
||||||
|
|
||||||
|
if (!templates_.empty()) {
|
||||||
|
std::vector<std::string> tnames;
|
||||||
|
std::vector<std::string> tnames_simplified;
|
||||||
|
|
||||||
|
std::transform(templates_.cbegin(), templates_.cend(),
|
||||||
|
std::back_inserter(tnames),
|
||||||
|
[ns = using_namespace, relative](
|
||||||
|
const auto &tmplt) { return tmplt.to_string(ns, relative); });
|
||||||
|
|
||||||
|
ostr << fmt::format("<{}>", fmt::join(tnames, ","));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ostr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void template_trait::set_base_template(const std::string &full_name)
|
||||||
|
{
|
||||||
|
base_template_full_name_ = full_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string template_trait::base_template() const
|
||||||
|
{
|
||||||
|
return base_template_full_name_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void template_trait::add_template(template_parameter &&tmplt)
|
||||||
|
{
|
||||||
|
templates_.push_back(std::move(tmplt));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool template_trait::is_implicit() const { return is_implicit_; }
|
||||||
|
|
||||||
|
void template_trait::set_implicit(bool implicit) { is_implicit_ = implicit; }
|
||||||
|
|
||||||
|
const std::vector<template_parameter> &template_trait::templates() const
|
||||||
|
{
|
||||||
|
return templates_;
|
||||||
|
}
|
||||||
|
|
||||||
|
int template_trait::calculate_template_specialization_match(
|
||||||
|
const template_trait &other, const std::string & /*full_name*/) const
|
||||||
|
{
|
||||||
|
int res{};
|
||||||
|
|
||||||
|
// TODO: handle variadic templates
|
||||||
|
if (templates().size() != other.templates().size()) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate over all template arguments
|
||||||
|
for (auto i = 0U; i < other.templates().size(); i++) {
|
||||||
|
const auto &template_arg = templates().at(i);
|
||||||
|
const auto &other_template_arg = other.templates().at(i);
|
||||||
|
|
||||||
|
if (template_arg == other_template_arg) {
|
||||||
|
res++;
|
||||||
|
}
|
||||||
|
else if (other_template_arg.is_specialization_of(template_arg)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
res = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace clanguml::common::model
|
||||||
54
src/common/model/template_trait.h
Normal file
54
src/common/model/template_trait.h
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* src/common/model/template_trait.h
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021-2023 Bartek Kryza <bkryza@gmail.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/model/element.h"
|
||||||
|
#include "common/model/template_parameter.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace clanguml::common::model {
|
||||||
|
|
||||||
|
class template_trait {
|
||||||
|
public:
|
||||||
|
std::ostream &render_template_params(std::ostream &ostr,
|
||||||
|
const common::model::namespace_ &using_namespace, bool relative) const;
|
||||||
|
|
||||||
|
void set_base_template(const std::string &full_name);
|
||||||
|
|
||||||
|
std::string base_template() const;
|
||||||
|
|
||||||
|
void add_template(template_parameter &&tmplt);
|
||||||
|
|
||||||
|
const std::vector<template_parameter> &templates() const;
|
||||||
|
|
||||||
|
int calculate_template_specialization_match(
|
||||||
|
const template_trait &other, const std::string &full_name) const;
|
||||||
|
|
||||||
|
bool is_implicit() const;
|
||||||
|
|
||||||
|
void set_implicit(bool implicit);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<template_parameter> templates_;
|
||||||
|
std::string base_template_full_name_;
|
||||||
|
bool is_implicit_{false};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace clanguml::common::model
|
||||||
@@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
#include <class_diagram/model/template_parameter.h>
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
namespace clanguml::cx::util {
|
namespace clanguml::cx::util {
|
||||||
@@ -39,12 +38,12 @@ std::pair<common::model::namespace_, std::string> split_ns(
|
|||||||
return {ns, name};
|
return {ns, name};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<class_diagram::model::template_parameter>
|
std::vector<common::model::template_parameter> parse_unexposed_template_params(
|
||||||
parse_unexposed_template_params(const std::string ¶ms,
|
const std::string ¶ms,
|
||||||
const std::function<std::string(const std::string &)> &ns_resolve,
|
const std::function<std::string(const std::string &)> &ns_resolve,
|
||||||
int depth)
|
int depth)
|
||||||
{
|
{
|
||||||
using class_diagram::model::template_parameter;
|
using common::model::template_parameter;
|
||||||
|
|
||||||
std::vector<template_parameter> res;
|
std::vector<template_parameter> res;
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,8 @@
|
|||||||
|
|
||||||
#include "common/model/namespace.h"
|
#include "common/model/namespace.h"
|
||||||
|
|
||||||
#include <class_diagram/model/template_parameter.h>
|
#include "common/model/template_parameter.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace clanguml::cx::util {
|
namespace clanguml::cx::util {
|
||||||
@@ -27,8 +28,8 @@ namespace clanguml::cx::util {
|
|||||||
std::pair<common::model::namespace_, std::string> split_ns(
|
std::pair<common::model::namespace_, std::string> split_ns(
|
||||||
const std::string &full_name);
|
const std::string &full_name);
|
||||||
|
|
||||||
std::vector<class_diagram::model::template_parameter>
|
std::vector<common::model::template_parameter> parse_unexposed_template_params(
|
||||||
parse_unexposed_template_params(const std::string ¶ms,
|
const std::string ¶ms,
|
||||||
const std::function<std::string(const std::string &)> &ns_resolve,
|
const std::function<std::string(const std::string &)> &ns_resolve,
|
||||||
int depth = 0);
|
int depth = 0);
|
||||||
|
|
||||||
|
|||||||
@@ -20,83 +20,6 @@
|
|||||||
|
|
||||||
namespace clanguml::sequence_diagram::model {
|
namespace clanguml::sequence_diagram::model {
|
||||||
|
|
||||||
std::ostringstream &template_trait::render_template_params(
|
|
||||||
std::ostringstream &ostr, const common::model::namespace_ &using_namespace,
|
|
||||||
bool relative) const
|
|
||||||
{
|
|
||||||
using clanguml::common::model::namespace_;
|
|
||||||
|
|
||||||
if (!templates_.empty()) {
|
|
||||||
std::vector<std::string> tnames;
|
|
||||||
std::vector<std::string> tnames_simplified;
|
|
||||||
|
|
||||||
std::transform(templates_.cbegin(), templates_.cend(),
|
|
||||||
std::back_inserter(tnames),
|
|
||||||
[ns = using_namespace, relative](
|
|
||||||
const auto &tmplt) { return tmplt.to_string(ns, relative); });
|
|
||||||
|
|
||||||
ostr << fmt::format("<{}>", fmt::join(tnames, ","));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ostr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void template_trait::set_base_template(const std::string &full_name)
|
|
||||||
{
|
|
||||||
base_template_full_name_ = full_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string template_trait::base_template() const
|
|
||||||
{
|
|
||||||
return base_template_full_name_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void template_trait::add_template(
|
|
||||||
class_diagram::model::template_parameter tmplt)
|
|
||||||
{
|
|
||||||
templates_.push_back(std::move(tmplt));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool template_trait::is_implicit() const { return is_implicit_; }
|
|
||||||
|
|
||||||
void template_trait::set_implicit(bool implicit) { is_implicit_ = implicit; }
|
|
||||||
|
|
||||||
const std::vector<class_diagram::model::template_parameter> &
|
|
||||||
template_trait::templates() const
|
|
||||||
{
|
|
||||||
return templates_;
|
|
||||||
}
|
|
||||||
|
|
||||||
int template_trait::calculate_template_specialization_match(
|
|
||||||
const template_trait &other, const std::string & /*full_name*/) const
|
|
||||||
{
|
|
||||||
int res{};
|
|
||||||
|
|
||||||
// TODO: handle variadic templates
|
|
||||||
if (templates().size() != other.templates().size()) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iterate over all template arguments
|
|
||||||
for (auto i = 0U; i < other.templates().size(); i++) {
|
|
||||||
const auto &template_arg = templates().at(i);
|
|
||||||
const auto &other_template_arg = other.templates().at(i);
|
|
||||||
|
|
||||||
if (template_arg == other_template_arg) {
|
|
||||||
res++;
|
|
||||||
}
|
|
||||||
else if (other_template_arg.is_specialization_of(template_arg)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
res = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string participant::to_string() const
|
std::string participant::to_string() const
|
||||||
{
|
{
|
||||||
return fmt::format(
|
return fmt::format(
|
||||||
|
|||||||
@@ -17,39 +17,16 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "class_diagram/model/template_parameter.h"
|
|
||||||
#include "common/model/element.h"
|
#include "common/model/element.h"
|
||||||
|
#include "common/model/template_parameter.h"
|
||||||
|
#include "common/model/template_trait.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace clanguml::sequence_diagram::model {
|
namespace clanguml::sequence_diagram::model {
|
||||||
|
|
||||||
struct template_trait {
|
using clanguml::common::model::template_trait;
|
||||||
std::ostringstream &render_template_params(std::ostringstream &ostr,
|
|
||||||
const common::model::namespace_ &using_namespace, bool relative) const;
|
|
||||||
|
|
||||||
void set_base_template(const std::string &full_name);
|
|
||||||
|
|
||||||
std::string base_template() const;
|
|
||||||
|
|
||||||
void add_template(class_diagram::model::template_parameter tmplt);
|
|
||||||
|
|
||||||
const std::vector<class_diagram::model::template_parameter> &
|
|
||||||
templates() const;
|
|
||||||
|
|
||||||
int calculate_template_specialization_match(
|
|
||||||
const template_trait &other, const std::string &full_name) const;
|
|
||||||
|
|
||||||
bool is_implicit() const;
|
|
||||||
|
|
||||||
void set_implicit(bool implicit);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<class_diagram::model::template_parameter> templates_;
|
|
||||||
std::string base_template_full_name_;
|
|
||||||
bool is_implicit_{false};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct participant : public common::model::element,
|
struct participant : public common::model::element,
|
||||||
public common::model::stylable_element {
|
public common::model::stylable_element {
|
||||||
|
|||||||
@@ -1336,7 +1336,7 @@ bool translation_unit_visitor::process_template_parameters(
|
|||||||
const clang::TemplateDecl &template_declaration,
|
const clang::TemplateDecl &template_declaration,
|
||||||
sequence_diagram::model::template_trait &c)
|
sequence_diagram::model::template_trait &c)
|
||||||
{
|
{
|
||||||
using class_diagram::model::template_parameter;
|
using common::model::template_parameter;
|
||||||
|
|
||||||
LOG_TRACE("Processing class {} template parameters...",
|
LOG_TRACE("Processing class {} template parameters...",
|
||||||
common::get_qualified_name(template_declaration));
|
common::get_qualified_name(template_declaration));
|
||||||
@@ -1357,7 +1357,7 @@ bool translation_unit_visitor::process_template_parameters(
|
|||||||
ct.set_default_value("");
|
ct.set_default_value("");
|
||||||
ct.is_variadic(template_type_parameter->isParameterPack());
|
ct.is_variadic(template_type_parameter->isParameterPack());
|
||||||
|
|
||||||
c.add_template(ct);
|
c.add_template(std::move(ct));
|
||||||
}
|
}
|
||||||
else if (clang::dyn_cast_or_null<clang::NonTypeTemplateParmDecl>(
|
else if (clang::dyn_cast_or_null<clang::NonTypeTemplateParmDecl>(
|
||||||
parameter) != nullptr) {
|
parameter) != nullptr) {
|
||||||
@@ -1371,7 +1371,7 @@ bool translation_unit_visitor::process_template_parameters(
|
|||||||
ct.set_default_value("");
|
ct.set_default_value("");
|
||||||
ct.is_variadic(template_nontype_parameter->isParameterPack());
|
ct.is_variadic(template_nontype_parameter->isParameterPack());
|
||||||
|
|
||||||
c.add_template(ct);
|
c.add_template(std::move(ct));
|
||||||
}
|
}
|
||||||
else if (clang::dyn_cast_or_null<clang::TemplateTemplateParmDecl>(
|
else if (clang::dyn_cast_or_null<clang::TemplateTemplateParmDecl>(
|
||||||
parameter) != nullptr) {
|
parameter) != nullptr) {
|
||||||
@@ -1385,7 +1385,7 @@ bool translation_unit_visitor::process_template_parameters(
|
|||||||
ct.set_default_value("");
|
ct.set_default_value("");
|
||||||
ct.is_variadic(template_template_parameter->isParameterPack());
|
ct.is_variadic(template_template_parameter->isParameterPack());
|
||||||
|
|
||||||
c.add_template(ct);
|
c.add_template(std::move(ct));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// pass
|
// pass
|
||||||
@@ -1510,7 +1510,7 @@ void translation_unit_visitor::
|
|||||||
{
|
{
|
||||||
for (const auto &arg : template_args) {
|
for (const auto &arg : template_args) {
|
||||||
const auto argument_kind = arg.getKind();
|
const auto argument_kind = arg.getKind();
|
||||||
class_diagram::model::template_parameter argument;
|
common::model::template_parameter argument;
|
||||||
if (argument_kind == clang::TemplateArgument::Template) {
|
if (argument_kind == clang::TemplateArgument::Template) {
|
||||||
build_template_instantiation_process_template_argument(
|
build_template_instantiation_process_template_argument(
|
||||||
arg, argument);
|
arg, argument);
|
||||||
@@ -1535,14 +1535,14 @@ void translation_unit_visitor::
|
|||||||
simplify_system_template(
|
simplify_system_template(
|
||||||
argument, argument.to_string(config().using_namespace(), false));
|
argument, argument.to_string(config().using_namespace(), false));
|
||||||
|
|
||||||
template_instantiation.add_template(argument);
|
template_instantiation.add_template(std::move(argument));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void translation_unit_visitor::
|
void translation_unit_visitor::
|
||||||
build_template_instantiation_process_template_argument(
|
build_template_instantiation_process_template_argument(
|
||||||
const clang::TemplateArgument &arg,
|
const clang::TemplateArgument &arg,
|
||||||
class_diagram::model::template_parameter &argument) const
|
common::model::template_parameter &argument) const
|
||||||
{
|
{
|
||||||
argument.is_template_parameter(true);
|
argument.is_template_parameter(true);
|
||||||
auto arg_name =
|
auto arg_name =
|
||||||
@@ -1553,7 +1553,7 @@ void translation_unit_visitor::
|
|||||||
void translation_unit_visitor::
|
void translation_unit_visitor::
|
||||||
build_template_instantiation_process_integral_argument(
|
build_template_instantiation_process_integral_argument(
|
||||||
const clang::TemplateArgument &arg,
|
const clang::TemplateArgument &arg,
|
||||||
class_diagram::model::template_parameter &argument) const
|
common::model::template_parameter &argument) const
|
||||||
{
|
{
|
||||||
assert(arg.getKind() == clang::TemplateArgument::Integral);
|
assert(arg.getKind() == clang::TemplateArgument::Integral);
|
||||||
|
|
||||||
@@ -1564,7 +1564,7 @@ void translation_unit_visitor::
|
|||||||
void translation_unit_visitor::
|
void translation_unit_visitor::
|
||||||
build_template_instantiation_process_expression_argument(
|
build_template_instantiation_process_expression_argument(
|
||||||
const clang::TemplateArgument &arg,
|
const clang::TemplateArgument &arg,
|
||||||
class_diagram::model::template_parameter &argument) const
|
common::model::template_parameter &argument) const
|
||||||
{
|
{
|
||||||
assert(arg.getKind() == clang::TemplateArgument::Expression);
|
assert(arg.getKind() == clang::TemplateArgument::Expression);
|
||||||
|
|
||||||
@@ -1579,7 +1579,7 @@ void translation_unit_visitor::
|
|||||||
const std::string & /*full_template_specialization_name*/,
|
const std::string & /*full_template_specialization_name*/,
|
||||||
const clang::TemplateDecl *template_decl,
|
const clang::TemplateDecl *template_decl,
|
||||||
const clang::TemplateArgument &arg,
|
const clang::TemplateArgument &arg,
|
||||||
class_diagram::model::template_parameter &argument) const
|
common::model::template_parameter &argument) const
|
||||||
{
|
{
|
||||||
assert(arg.getKind() == clang::TemplateArgument::Type);
|
assert(arg.getKind() == clang::TemplateArgument::Type);
|
||||||
|
|
||||||
@@ -1596,7 +1596,7 @@ void translation_unit_visitor::
|
|||||||
const clang::TemplateDecl *template_decl,
|
const clang::TemplateDecl *template_decl,
|
||||||
const clang::TemplateArgument &arg,
|
const clang::TemplateArgument &arg,
|
||||||
model::template_trait &template_instantiation,
|
model::template_trait &template_instantiation,
|
||||||
class_diagram::model::template_parameter &argument)
|
common::model::template_parameter &argument)
|
||||||
{
|
{
|
||||||
assert(arg.getKind() == clang::TemplateArgument::Type);
|
assert(arg.getKind() == clang::TemplateArgument::Type);
|
||||||
|
|
||||||
@@ -1685,7 +1685,7 @@ void translation_unit_visitor::process_template_specialization_argument(
|
|||||||
const auto argument_kind = arg.getKind();
|
const auto argument_kind = arg.getKind();
|
||||||
|
|
||||||
if (argument_kind == clang::TemplateArgument::Type) {
|
if (argument_kind == clang::TemplateArgument::Type) {
|
||||||
class_diagram::model::template_parameter argument;
|
common::model::template_parameter argument;
|
||||||
argument.is_template_parameter(false);
|
argument.is_template_parameter(false);
|
||||||
|
|
||||||
// If this is a nested template type - add nested templates as
|
// If this is a nested template type - add nested templates as
|
||||||
@@ -1816,23 +1816,23 @@ void translation_unit_visitor::process_template_specialization_argument(
|
|||||||
simplify_system_template(
|
simplify_system_template(
|
||||||
argument, argument.to_string(config().using_namespace(), false));
|
argument, argument.to_string(config().using_namespace(), false));
|
||||||
|
|
||||||
template_instantiation.add_template(argument);
|
template_instantiation.add_template(std::move(argument));
|
||||||
}
|
}
|
||||||
else if (argument_kind == clang::TemplateArgument::Integral) {
|
else if (argument_kind == clang::TemplateArgument::Integral) {
|
||||||
class_diagram::model::template_parameter argument;
|
common::model::template_parameter argument;
|
||||||
argument.is_template_parameter(false);
|
argument.is_template_parameter(false);
|
||||||
argument.set_type(std::to_string(arg.getAsIntegral().getExtValue()));
|
argument.set_type(std::to_string(arg.getAsIntegral().getExtValue()));
|
||||||
template_instantiation.add_template(argument);
|
template_instantiation.add_template(std::move(argument));
|
||||||
}
|
}
|
||||||
else if (argument_kind == clang::TemplateArgument::Expression) {
|
else if (argument_kind == clang::TemplateArgument::Expression) {
|
||||||
class_diagram::model::template_parameter argument;
|
common::model::template_parameter argument;
|
||||||
argument.is_template_parameter(false);
|
argument.is_template_parameter(false);
|
||||||
argument.set_type(common::get_source_text(
|
argument.set_type(common::get_source_text(
|
||||||
arg.getAsExpr()->getSourceRange(), source_manager()));
|
arg.getAsExpr()->getSourceRange(), source_manager()));
|
||||||
template_instantiation.add_template(argument);
|
template_instantiation.add_template(std::move(argument));
|
||||||
}
|
}
|
||||||
else if (argument_kind == clang::TemplateArgument::TemplateExpansion) {
|
else if (argument_kind == clang::TemplateArgument::TemplateExpansion) {
|
||||||
class_diagram::model::template_parameter argument;
|
common::model::template_parameter argument;
|
||||||
argument.is_template_parameter(true);
|
argument.is_template_parameter(true);
|
||||||
|
|
||||||
cls->getLocation().dump(source_manager());
|
cls->getLocation().dump(source_manager());
|
||||||
@@ -2040,8 +2040,7 @@ translation_unit_visitor::build_template_instantiation(
|
|||||||
|
|
||||||
void translation_unit_visitor::
|
void translation_unit_visitor::
|
||||||
process_unexposed_template_specialization_parameters(
|
process_unexposed_template_specialization_parameters(
|
||||||
const std::string &type_name,
|
const std::string &type_name, common::model::template_parameter &tp,
|
||||||
class_diagram::model::template_parameter &tp,
|
|
||||||
model::class_ & /*c*/) const
|
model::class_ & /*c*/) const
|
||||||
{
|
{
|
||||||
auto template_params = cx::util::parse_unexposed_template_params(
|
auto template_params = cx::util::parse_unexposed_template_params(
|
||||||
@@ -2053,8 +2052,7 @@ void translation_unit_visitor::
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool translation_unit_visitor::simplify_system_template(
|
bool translation_unit_visitor::simplify_system_template(
|
||||||
class_diagram::model::template_parameter &ct,
|
common::model::template_parameter &ct, const std::string &full_name) const
|
||||||
const std::string &full_name) const
|
|
||||||
{
|
{
|
||||||
if (config().type_aliases().count(full_name) > 0) {
|
if (config().type_aliases().count(full_name) > 0) {
|
||||||
ct.set_name(config().type_aliases().at(full_name));
|
ct.set_name(config().type_aliases().at(full_name));
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
namespace clanguml::sequence_diagram::visitor {
|
namespace clanguml::sequence_diagram::visitor {
|
||||||
|
|
||||||
|
using common::model::template_parameter;
|
||||||
|
|
||||||
std::string to_string(const clang::FunctionTemplateDecl *decl);
|
std::string to_string(const clang::FunctionTemplateDecl *decl);
|
||||||
|
|
||||||
class translation_unit_visitor
|
class translation_unit_visitor
|
||||||
@@ -179,7 +181,7 @@ private:
|
|||||||
|
|
||||||
bool process_template_parameters(
|
bool process_template_parameters(
|
||||||
const clang::TemplateDecl &template_declaration,
|
const clang::TemplateDecl &template_declaration,
|
||||||
sequence_diagram::model::template_trait &c);
|
common::model::template_trait &c);
|
||||||
|
|
||||||
std::unique_ptr<model::function_template>
|
std::unique_ptr<model::function_template>
|
||||||
build_function_template_instantiation(const clang::FunctionDecl &pDecl);
|
build_function_template_instantiation(const clang::FunctionDecl &pDecl);
|
||||||
@@ -200,22 +202,22 @@ private:
|
|||||||
|
|
||||||
void build_template_instantiation_process_template_argument(
|
void build_template_instantiation_process_template_argument(
|
||||||
const clang::TemplateArgument &arg,
|
const clang::TemplateArgument &arg,
|
||||||
class_diagram::model::template_parameter &argument) const;
|
common::model::template_parameter &argument) const;
|
||||||
|
|
||||||
void build_template_instantiation_process_integral_argument(
|
void build_template_instantiation_process_integral_argument(
|
||||||
const clang::TemplateArgument &arg,
|
const clang::TemplateArgument &arg,
|
||||||
class_diagram::model::template_parameter &argument) const;
|
common::model::template_parameter &argument) const;
|
||||||
|
|
||||||
void build_template_instantiation_process_expression_argument(
|
void build_template_instantiation_process_expression_argument(
|
||||||
const clang::TemplateArgument &arg,
|
const clang::TemplateArgument &arg,
|
||||||
class_diagram::model::template_parameter &argument) const;
|
common::model::template_parameter &argument) const;
|
||||||
|
|
||||||
void build_template_instantiation_process_tag_argument(
|
void build_template_instantiation_process_tag_argument(
|
||||||
model::template_trait &template_instantiation,
|
model::template_trait &template_instantiation,
|
||||||
const std::string &full_template_specialization_name,
|
const std::string &full_template_specialization_name,
|
||||||
const clang::TemplateDecl *template_decl,
|
const clang::TemplateDecl *template_decl,
|
||||||
const clang::TemplateArgument &arg,
|
const clang::TemplateArgument &arg,
|
||||||
class_diagram::model::template_parameter &argument) const;
|
common::model::template_parameter &argument) const;
|
||||||
|
|
||||||
void build_template_instantiation_process_type_argument(
|
void build_template_instantiation_process_type_argument(
|
||||||
model::template_trait *parent,
|
model::template_trait *parent,
|
||||||
@@ -223,7 +225,7 @@ private:
|
|||||||
const clang::TemplateDecl *template_decl,
|
const clang::TemplateDecl *template_decl,
|
||||||
const clang::TemplateArgument &arg,
|
const clang::TemplateArgument &arg,
|
||||||
model::template_trait &template_instantiation,
|
model::template_trait &template_instantiation,
|
||||||
class_diagram::model::template_parameter &argument);
|
common::model::template_parameter &argument);
|
||||||
|
|
||||||
std::unique_ptr<model::class_> process_template_specialization(
|
std::unique_ptr<model::class_> process_template_specialization(
|
||||||
clang::ClassTemplateSpecializationDecl *cls);
|
clang::ClassTemplateSpecializationDecl *cls);
|
||||||
@@ -235,14 +237,14 @@ private:
|
|||||||
bool in_parameter_pack = false);
|
bool in_parameter_pack = false);
|
||||||
|
|
||||||
void process_unexposed_template_specialization_parameters(
|
void process_unexposed_template_specialization_parameters(
|
||||||
const std::string &type_name,
|
const std::string &type_name, common::model::template_parameter &tp,
|
||||||
class_diagram::model::template_parameter &tp, model::class_ &c) const;
|
model::class_ &c) const;
|
||||||
|
|
||||||
std::unique_ptr<model::class_> build_template_instantiation(
|
std::unique_ptr<model::class_> build_template_instantiation(
|
||||||
const clang::TemplateSpecializationType &template_type_decl,
|
const clang::TemplateSpecializationType &template_type_decl,
|
||||||
model::class_ *parent);
|
model::class_ *parent);
|
||||||
|
|
||||||
bool simplify_system_template(class_diagram::model::template_parameter &ct,
|
bool simplify_system_template(common::model::template_parameter &ct,
|
||||||
const std::string &full_name) const;
|
const std::string &full_name) const;
|
||||||
|
|
||||||
std::string simplify_system_template(const std::string &full_name) const;
|
std::string simplify_system_template(const std::string &full_name) const;
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} ${LIBCLANG_CXXFLAGS} ${TEST_DISAB
|
|||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
# Without this, clang-uml test cases fail with error saying that clang cannot find stdarg.h
|
# Without this, clang-uml test cases fail with error saying that clang cannot find stdarg.h
|
||||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${LLVM_LIBRARY_DIR}/clang/${LLVM_PACKAGE_VERSION}/include")
|
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -I${LLVM_LIBRARY_DIR}/clang/${LLVM_PACKAGE_VERSION}/include")
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -I${LLVM_LIBRARY_DIR}/clang/${LLVM_PACKAGE_VERSION}/include")
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -I${LLVM_LIBRARY_DIR}/clang/${LLVM_PACKAGE_VERSION}/include")
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -I${LLVM_LIBRARY_DIR}/clang/${LLVM_PACKAGE_VERSION}/include")
|
||||||
endif(APPLE)
|
endif(APPLE)
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ TEST_CASE("t00051", "[test-case][class]")
|
|||||||
REQUIRE_THAT(puml, IsInnerClass(_A("A"), _A("A::custom_thread2")));
|
REQUIRE_THAT(puml, IsInnerClass(_A("A"), _A("A::custom_thread2")));
|
||||||
|
|
||||||
REQUIRE_THAT(puml,
|
REQUIRE_THAT(puml,
|
||||||
(IsMethod<Public>(
|
(IsMethod<Public>("custom_thread1<Function,Args...>", "void",
|
||||||
"custom_thread1", "void", "Function && f, Args &&... args")));
|
"Function && f, Args &&... args")));
|
||||||
REQUIRE_THAT(puml,
|
REQUIRE_THAT(puml,
|
||||||
(IsMethod<Public>("thread", "void",
|
(IsMethod<Public>("thread", "void",
|
||||||
"(lambda at ../../tests/t00051/t00051.cc:59:27) && ")));
|
"(lambda at ../../tests/t00051/t00051.cc:59:27) && ")));
|
||||||
|
|||||||
12
tests/t00052/.clang-uml
Normal file
12
tests/t00052/.clang-uml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
compilation_database_dir: ..
|
||||||
|
output_directory: puml
|
||||||
|
diagrams:
|
||||||
|
t00052_class:
|
||||||
|
type: class
|
||||||
|
glob:
|
||||||
|
- ../../tests/t00052/t00052.cc
|
||||||
|
include:
|
||||||
|
namespaces:
|
||||||
|
- clanguml::t00052
|
||||||
|
using_namespace:
|
||||||
|
- clanguml::t00052
|
||||||
19
tests/t00052/t00052.cc
Normal file
19
tests/t00052/t00052.cc
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
namespace clanguml {
|
||||||
|
namespace t00052 {
|
||||||
|
|
||||||
|
class A {
|
||||||
|
public:
|
||||||
|
template <typename T> T a(T p) { return p; }
|
||||||
|
|
||||||
|
template <typename F, typename Q> void aa(F &&f, Q q) { f(q); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T> class B {
|
||||||
|
public:
|
||||||
|
T b(T t) { return t; }
|
||||||
|
|
||||||
|
template <typename F> T bb(F &&f, T t) { return f(t); }
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
50
tests/t00052/test_case.h
Normal file
50
tests/t00052/test_case.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
* tests/t00052/test_case.h
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021-2023 Bartek Kryza <bkryza@gmail.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST_CASE("t00052", "[test-case][class]")
|
||||||
|
{
|
||||||
|
auto [config, db] = load_config("t00052");
|
||||||
|
|
||||||
|
auto diagram = config.diagrams["t00052_class"];
|
||||||
|
|
||||||
|
REQUIRE(diagram->name == "t00052_class");
|
||||||
|
|
||||||
|
auto model = generate_class_diagram(*db, diagram);
|
||||||
|
|
||||||
|
REQUIRE(model->name() == "t00052_class");
|
||||||
|
|
||||||
|
auto puml = generate_class_puml(diagram, *model);
|
||||||
|
AliasMatcher _A(puml);
|
||||||
|
|
||||||
|
REQUIRE_THAT(puml, StartsWith("@startuml"));
|
||||||
|
REQUIRE_THAT(puml, EndsWith("@enduml\n"));
|
||||||
|
|
||||||
|
// Check if all classes exist
|
||||||
|
REQUIRE_THAT(puml, IsClass(_A("A")));
|
||||||
|
|
||||||
|
// Check if class templates exist
|
||||||
|
REQUIRE_THAT(puml, IsClassTemplate("B", "T"));
|
||||||
|
|
||||||
|
// Check if all methods exist
|
||||||
|
REQUIRE_THAT(puml, (IsMethod<Public>("a<T>", "T", "T p")));
|
||||||
|
REQUIRE_THAT(puml, (IsMethod<Public>("aa<F,Q>", "void", "F && f, Q q")));
|
||||||
|
REQUIRE_THAT(puml, (IsMethod<Public>("b", "T", "T t")));
|
||||||
|
REQUIRE_THAT(puml, (IsMethod<Public>("bb<F>", "T", "F && f, T t")));
|
||||||
|
|
||||||
|
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||||
|
}
|
||||||
@@ -245,6 +245,7 @@ using namespace clanguml::test::matchers;
|
|||||||
#include "t00049/test_case.h"
|
#include "t00049/test_case.h"
|
||||||
#include "t00050/test_case.h"
|
#include "t00050/test_case.h"
|
||||||
#include "t00051/test_case.h"
|
#include "t00051/test_case.h"
|
||||||
|
#include "t00052/test_case.h"
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Sequence diagram tests
|
/// Sequence diagram tests
|
||||||
|
|||||||
@@ -150,6 +150,9 @@ test_cases:
|
|||||||
- name: t00051
|
- name: t00051
|
||||||
title: Test case for relative paths in lambda names
|
title: Test case for relative paths in lambda names
|
||||||
description:
|
description:
|
||||||
|
- name: t00052
|
||||||
|
title: Test case for template methods rendering
|
||||||
|
description:
|
||||||
Sequence diagrams:
|
Sequence diagrams:
|
||||||
- name: t20001
|
- name: t20001
|
||||||
title: Basic sequence diagram test case
|
title: Basic sequence diagram test case
|
||||||
|
|||||||
Reference in New Issue
Block a user