Implemented tests for concept test case 00056

This commit is contained in:
Bartek Kryza
2023-02-26 13:51:25 +01:00
parent 1fc0bf3f80
commit 3509853dba
7 changed files with 132 additions and 67 deletions

View File

@@ -512,8 +512,14 @@ void translation_unit_visitor::process_concept_specialization_relationships(
common::model::element &c,
const clang::ConceptSpecializationExpr *concept_specialization)
{
const auto *cpt = concept_specialization->getNamedConcept();
if (cpt && diagram().should_include(cpt->getQualifiedNameAsString())) {
if (const auto *cpt = concept_specialization->getNamedConcept();
should_include(cpt)) {
const auto cpt_name = cpt->getNameAsString();
if (!get_ast_local_id(cpt->getID()))
return;
auto target_id = get_ast_local_id(cpt->getID()).value();
std::vector<std::string> constrained_template_params;
@@ -524,43 +530,9 @@ void translation_unit_visitor::process_concept_specialization_relationships(
if (ta.getKind() == clang::TemplateArgument::Type) {
auto type_name =
common::to_string(ta.getAsType(), cpt->getASTContext());
if (const auto *nested_template_type =
ta.getAsType()->getAs<clang::TemplateTypeParmType>();
nested_template_type != nullptr) {
auto declaration_text = common::get_source_text_raw(
concept_specialization->getSourceRange(),
source_manager());
if (!declaration_text.empty()) {
// Handle typename constraint in requires clause
if (type_name.find("type-parameter-") == 0) {
declaration_text = declaration_text.substr(
declaration_text.find(cpt->getNameAsString()) +
cpt->getNameAsString().size() + 1);
auto template_params =
common::parse_unexposed_template_params(
declaration_text,
[](const auto &t) { return t; });
if (template_params.size() > argument_index)
type_name =
template_params[argument_index].to_string(
config().using_namespace(), false);
else {
LOG_DBG("Failed to find type specialization "
"for argument "
"{} at index {} in declaration "
"\n===\n{}\n===\n",
type_name, argument_index,
declaration_text);
}
}
constrained_template_params.push_back(type_name);
}
}
extract_constrained_template_param_name(concept_specialization,
cpt, constrained_template_params, argument_index,
type_name);
}
else {
auto type_name =
@@ -572,7 +544,7 @@ void translation_unit_visitor::process_concept_specialization_relationships(
}
if (!constrained_template_params.empty())
c.add_relationship(
{relationship_t::kDependency, target_id, access_t::kNone,
{relationship_t::kConstraint, target_id, access_t::kNone,
fmt::format(
"{}", fmt::join(constrained_template_params, ","))});
}
@@ -877,7 +849,7 @@ bool translation_unit_visitor::process_template_parameters(
diagram().should_include(
named_concept->getQualifiedNameAsString())) {
templated_element.value().add_relationship(
{relationship_t::kDependency,
{relationship_t::kConstraint,
get_ast_local_id(named_concept->getID())
.value(),
access_t::kNone, ct.name()});
@@ -1301,7 +1273,6 @@ void translation_unit_visitor::
deduced_auto_decl->getQualifiedNameAsString();
if (diagram().should_include(template_field_decl_name)) {
relationship r{relationship_t::kDependency,
template_specialization_model.get().id()};
@@ -2715,4 +2686,38 @@ translation_unit_visitor::get_ast_local_id(int64_t local_id) const
return local_ast_id_map_.at(local_id);
}
void translation_unit_visitor::extract_constrained_template_param_name(
const clang::ConceptSpecializationExpr *concept_specialization,
const clang::ConceptDecl *cpt,
std::vector<std::string> &constrained_template_params,
size_t argument_index, std::string &type_name) const
{
const auto full_declaration_text = common::get_source_text_raw(
concept_specialization->getSourceRange(), source_manager());
if (!full_declaration_text.empty()) {
// Handle typename constraint in requires clause
if (type_name.find("type-parameter-") == 0) {
const auto concept_declaration_text = full_declaration_text.substr(
full_declaration_text.find(cpt->getNameAsString()) +
cpt->getNameAsString().size() + 1);
auto template_params = common::parse_unexposed_template_params(
concept_declaration_text, [](const auto &t) { return t; });
if (template_params.size() > argument_index)
type_name = template_params[argument_index].to_string(
config().using_namespace(), false);
}
constrained_template_params.push_back(type_name);
}
}
bool translation_unit_visitor::should_include(const clang::NamedDecl *decl)
{
return decl != nullptr &&
diagram().should_include(decl->getQualifiedNameAsString());
}
} // namespace clanguml::class_diagram::visitor

View File

@@ -111,6 +111,8 @@ public:
void finalize();
private:
bool should_include(const clang::NamedDecl *decl);
std::unique_ptr<clanguml::class_diagram::model::class_>
create_class_declaration(clang::CXXRecordDecl *cls);
@@ -268,6 +270,15 @@ private:
bool simplify_system_template(common::model::template_parameter &ct,
const std::string &full_name) const;
void process_concept_specialization_relationships(common::model::element &c,
const clang::ConceptSpecializationExpr *concept_specialization);
void extract_constrained_template_param_name(
const clang::ConceptSpecializationExpr *concept_specialization,
const clang::ConceptDecl *cpt,
std::vector<std::string> &constrained_template_params,
size_t argument_index, std::string &type_name) const;
/// Store the mapping from local clang entity id (obtained using
/// getID()) method to clang-uml global id
void set_ast_local_id(
@@ -293,7 +304,5 @@ private:
std::tuple<std::string /* field name */, common::model::relationship_t,
common::model::access_t>>
anonymous_struct_relationships_;
void process_concept_specialization_relationships(common::model::element &c,
const clang::ConceptSpecializationExpr *concept_specialization);
};
} // namespace clanguml::class_diagram::visitor

View File

@@ -37,6 +37,8 @@ std::string to_plantuml(relationship_t r, const std::string &style)
return style.empty() ? "<.." : fmt::format("<.[{}].", style);
case relationship_t::kDependency:
return style.empty() ? "..>" : fmt::format(".[{}].>", style);
case relationship_t::kConstraint:
return style.empty() ? "..>" : fmt::format(".[{}].>", style);
case relationship_t::kAlias:
return style.empty() ? ".." : fmt::format(".[{}].", style);
default:

View File

@@ -46,6 +46,8 @@ std::string to_string(relationship_t r)
return "dependency";
case relationship_t::kAlias:
return "alias";
case relationship_t::kConstraint:
return "constraint";
default:
assert(false);
return "";

View File

@@ -36,7 +36,8 @@ enum class relationship_t {
kInstantiation,
kFriendship,
kAlias,
kDependency
kDependency,
kConstraint
};
/// Types of sequence diagram activity elements