This commit is contained in:
Bartek Kryza
2023-04-28 22:46:36 +02:00
parent 0f4a2e1f9c
commit 6ebdc8ab77
13 changed files with 254 additions and 87 deletions

View File

@@ -306,6 +306,10 @@ template <> id_t to_id(const std::string &full_name)
return static_cast<id_t>(std::hash<std::string>{}(full_name) >> 3U);
}
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)
{
return to_id(get_qualified_name(declaration));
@@ -533,7 +537,7 @@ std::vector<std::string> tokenize_unexposed_template_parameter(
std::string tok;
for (const char c : word) {
if (c == '(' || c == ')' || c == '[' || c == ']') {
if (c == '(' || c == ')' || c == '[' || c == ']' || c == '<' || c == '>') {
if (!tok.empty())
result.push_back(tok);
result.push_back(std::string{c});
@@ -544,6 +548,10 @@ std::vector<std::string> tokenize_unexposed_template_parameter(
result.push_back(tok);
tok = ":";
}
else if (tok == ":") {
result.push_back("::");
tok = "";
}
else {
tok += ':';
}

View File

@@ -129,6 +129,8 @@ template <typename T> id_t to_id(const T &declaration);
template <> id_t to_id(const std::string &full_name);
id_t to_id(const clang::QualType &type, const clang::ASTContext &ctx);
template <> id_t to_id(const clang::NamespaceDecl &declaration);
template <> id_t to_id(const clang::CXXRecordDecl &declaration);

View File

@@ -46,11 +46,12 @@ void diagram_element::add_relationship(relationship &&cr)
return;
}
LOG_DBG("Adding relationship from: '{}' ({}) - {} - '{}'", id(),
full_name(true), to_string(cr.type()), cr.destination());
if (!util::contains(relationships_, cr)) {
LOG_DBG("Adding relationship from: '{}' ({}) - {} - '{}'", id(),
full_name(true), to_string(cr.type()), cr.destination());
if (!util::contains(relationships_, cr))
relationships_.emplace_back(std::move(cr));
}
}
std::vector<relationship> &diagram_element::relationships()

View File

@@ -113,7 +113,10 @@ int template_parameter::calculate_specialization_match(
{
int res{0};
if (qualifier() != base_template_parameter.qualifier())
// If the potential base template has a qualifier, the current template
// must match it
if (!base_template_parameter.qualifiers().empty() &&
(qualifiers() != base_template_parameter.qualifiers()))
return 0;
if (is_template_parameter() &&
@@ -211,10 +214,33 @@ bool operator!=(const template_parameter &l, const template_parameter &r)
return !(l == r);
}
std::string template_parameter::to_string(
const clanguml::common::model::namespace_ &using_namespace,
bool relative) const
std::string template_parameter::qualifiers_str() const
{
std::string res;
if (qualifiers_.count(cvqualifier::kConst) == 1)
res += "const";
if (is_rvalue_reference())
res += "&&";
else if (is_lvalue_reference())
res += "&";
if (is_pointer())
res += "*";
if(res.empty())
return res;
return " " + res;
}
std::string template_parameter::to_string(
const clanguml::common::model::namespace_ &using_namespace, bool relative,
bool skip_qualifiers) const
{
if(is_elipssis())
return "...";
using clanguml::common::model::namespace_;
assert(!(type().has_value() && concept_constraint().has_value()));
@@ -235,11 +261,11 @@ std::string template_parameter::to_string(
if (is_method_template()) {
assert(template_params().size() > 1);
std::string unqualified;
if (template_params().size() == 2) {
return fmt::format("{} {}::*{}",
unqualified = fmt::format("{} {}::*",
template_params().at(0).to_string(using_namespace, relative),
template_params().at(1).to_string(using_namespace, relative),
qualifier());
template_params().at(1).to_string(using_namespace, relative));
}
else {
auto it = template_params().begin();
@@ -253,9 +279,14 @@ std::string template_parameter::to_string(
args.push_back(it->to_string(using_namespace, relative));
}
return fmt::format("{} ({}::*)({}){}", return_type, class_type,
fmt::join(args, ","), qualifier());
unqualified = fmt::format("{} ({}::*)({})", return_type, class_type,
fmt::join(args, ","));
}
if (skip_qualifiers)
return unqualified;
else
return unqualified + qualifiers_str();
}
std::string res;
@@ -307,8 +338,8 @@ std::string template_parameter::to_string(
res += fmt::format("<{}>", fmt::join(params, ","));
}
if (!qualifier().empty())
res += " " + qualifier();
if (!skip_qualifiers)
res += qualifiers_str();
const auto &maybe_default_value = default_value();
if (maybe_default_value) {
@@ -332,6 +363,9 @@ bool template_parameter::find_nested_relationships(
// just add it and skip recursion (e.g. this is a user defined type)
const auto maybe_type = type();
if (maybe_type && should_include(maybe_type.value())) {
if (is_pointer() || is_lvalue_reference() || is_rvalue_reference())
hint = common::model::relationship_t::kAssociation;
const auto maybe_id = id();
if (maybe_id) {
nested_relationships.emplace_back(maybe_id.value(), hint);
@@ -349,6 +383,11 @@ bool template_parameter::find_nested_relationships(
if (maybe_id && maybe_arg_type && should_include(*maybe_arg_type)) {
if (template_argument.is_pointer() ||
template_argument.is_lvalue_reference() ||
template_argument.is_rvalue_reference())
hint = common::model::relationship_t::kAssociation;
nested_relationships.emplace_back(maybe_id.value(), hint);
added_aggregation_relationship =

View File

@@ -21,6 +21,7 @@
#include "common/model/namespace.h"
#include <optional>
#include <set>
#include <string>
#include <vector>
@@ -44,6 +45,13 @@ std::string to_string(template_parameter_kind_t k);
/// nested templates
class template_parameter {
public:
enum class cvqualifier {
kConst,
kVolatile,
kLValueReference,
kRValueReference
};
static template_parameter make_template_type(const std::string &name,
const std::optional<std::string> &default_value = {},
bool is_variadic = false)
@@ -149,7 +157,7 @@ public:
std::string to_string(
const clanguml::common::model::namespace_ &using_namespace,
bool relative) const;
bool relative, bool skip_qualifiers = false) const;
void add_template_param(template_parameter &&ct);
@@ -186,13 +194,26 @@ public:
bool is_method_template() const { return is_method_template_; }
void set_qualifier(const std::string &q) { qualifier_ = q; }
void set_qualifier(const cvqualifier q) { qualifiers_.emplace(q); }
const std::string &qualifier() const { return qualifier_; }
const std::set<cvqualifier> &qualifiers() const { return qualifiers_; }
void is_pointer(bool p) { is_pointer_ = p; }
bool is_pointer() const { return is_pointer_; }
void is_lvalue_reference(bool p) { is_lvalue_reference_ = p; }
bool is_lvalue_reference() const { return is_lvalue_reference_; }
void is_rvalue_reference(bool p) { is_rvalue_reference_ = p; }
bool is_rvalue_reference() const { return is_rvalue_reference_; }
void is_elipssis(bool e) { is_elipssis_ = e; }
bool is_elipssis() const { return is_elipssis_; }
private:
template_parameter() = default;
std::string qualifiers_str() const;
template_parameter_kind_t kind_{template_parameter_kind_t::template_type};
/// Represents the type of non-type template parameters
@@ -213,14 +234,20 @@ private:
/// Can only be true when is_template_parameter_ is true
bool is_template_template_parameter_{false};
bool is_elipssis_{false};
/// Whether the template parameter is variadic
bool is_variadic_{false};
bool is_pointer_{false};
bool is_lvalue_reference_{false};
bool is_rvalue_reference_{false};
bool is_function_template_{false};
bool is_method_template_{false};
std::string qualifier_;
std::set<cvqualifier> qualifiers_;
/// Stores optional fully qualified name of constraint for this template
/// parameter