Refactored template_builder to common namespace (#227)

This commit is contained in:
Bartek Kryza
2024-01-14 13:38:08 +01:00
parent 100f7c88ad
commit 16195bfa62
18 changed files with 545 additions and 359 deletions

View File

@@ -334,6 +334,40 @@ extract_template_parameter_index(const std::string &type_parameter)
return {std::stoi(toks.at(0)), std::stoi(toks.at(1)), std::move(qualifier)};
}
void ensure_lambda_type_is_relative(
const config::diagram &config, std::string &parameter_type)
{
#ifdef _MSC_VER
auto root_name =
fmt::format("{}", std::filesystem::current_path().root_name().string());
#else
auto root_name = std::string{"/"};
#endif
std::string lambda_prefix{fmt::format("(lambda at {}", root_name)};
while (parameter_type.find(lambda_prefix) != std::string::npos) {
auto lambda_begin = parameter_type.find(lambda_prefix);
auto lambda_prefix_size = lambda_prefix.size();
#ifdef _MSC_VER
// Skip the `\` or `/` after drive letter and semicolon
lambda_prefix_size++;
#endif
auto absolute_lambda_path_end =
parameter_type.find(':', lambda_begin + lambda_prefix_size);
auto absolute_lambda_path = parameter_type.substr(
lambda_begin + lambda_prefix_size - 1,
absolute_lambda_path_end - (lambda_begin + lambda_prefix_size - 1));
auto relative_lambda_path = util::path_to_url(
config.make_path_relative(absolute_lambda_path).string());
parameter_type = fmt::format("{}(lambda at {}{}",
parameter_type.substr(0, lambda_begin), relative_lambda_path,
parameter_type.substr(absolute_lambda_path_end));
}
}
bool is_subexpr_of(const clang::Stmt *parent_stmt, const clang::Stmt *sub_stmt)
{
if (parent_stmt == nullptr || sub_stmt == nullptr)
@@ -893,4 +927,23 @@ bool is_coroutine(const clang::FunctionDecl &decl)
return clang::isa_and_nonnull<clang::CoroutineBodyStmt>(body);
}
bool is_struct(const clang::NamedDecl *decl)
{
if (decl == nullptr)
return false;
if (const clang::CXXRecordDecl *record =
clang::dyn_cast<clang::CXXRecordDecl>(decl);
record) {
return record->isStruct();
}
if (const clang::TagDecl *tag = clang::dyn_cast<clang::TagDecl>(decl);
tag) {
return tag->isStruct();
}
return false;
}
} // namespace clanguml::common

View File

@@ -17,9 +17,11 @@
*/
#pragma once
// #include "class_diagram/model/diagram.h"
#include "common/model/enums.h"
#include "common/model/namespace.h"
#include "common/model/template_parameter.h"
#include "config/config.h"
#include "types.h"
#include "util/util.h"
@@ -153,6 +155,9 @@ std::string get_source_text(
std::tuple<unsigned int, unsigned int, std::string>
extract_template_parameter_index(const std::string &type_parameter);
void ensure_lambda_type_is_relative(
const config::diagram &config, std::string &parameter_type);
/**
* @brief Check if an expression is contained in another expression
*
@@ -303,4 +308,12 @@ clang::RawComment *get_expression_raw_comment(const clang::SourceManager &sm,
*/
bool is_coroutine(const clang::FunctionDecl &decl);
/**
* Check if named declaration is a C++ struct.
*
* @param decl Declaration to check
* @return True, if declaration represents a struct.
*/
bool is_struct(const clang::NamedDecl *decl);
} // namespace clanguml::common

View File

@@ -0,0 +1,52 @@
/**
* @file src/common/model/template_element.cc
*
* Copyright (c) 2021-2024 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 "template_element.h"
namespace clanguml::common::model {
bool template_element::is_template() const { return is_template_; }
void template_element::is_template(bool is_template)
{
is_template_ = is_template;
}
int template_element::calculate_template_specialization_match(
const template_element &other) const
{
int res{0};
if (name_and_ns() != other.name_and_ns()) {
return res;
}
return template_trait::calculate_template_specialization_match(other);
}
void template_element::template_specialization_found(bool found)
{
template_specialization_found_ = found;
}
bool template_element::template_specialization_found() const
{
return template_specialization_found_;
}
} // namespace clanguml::common::model

View File

@@ -0,0 +1,79 @@
/**
* @file src/common/model/template_element.h
*
* Copyright (c) 2021-2024 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 "element.h"
#include "template_trait.h"
namespace clanguml::common::model {
/**
* @brief Base class for any element qualified by namespace.
*/
class template_element : public element, public template_trait {
public:
using element::element;
virtual ~template_element() = default;
/**
* Whether or not the class is a template.
*
* @return True, if the class is a template.
*/
bool is_template() const;
/**
* Set, whether the class is a template.
*
* @param is_struct True, if the class is a template.
*/
void is_template(bool is_template);
/**
* @brief Calculate template specialization match with other class.
*
* This method is a wrapper over
* @ref template_trait::calculate_template_specialization_match()
*
* @param other
* @return
*/
int calculate_template_specialization_match(
const template_element &other) const;
/**
* Whether, a template specialization has already been found for this class.
* @return True, if a template specialization has already been found.
*/
bool template_specialization_found() const;
/**
* Set, whether a template specialization has already been found for this
* class.
*
* @param found True, if a template specialization has already been found.
*/
void template_specialization_found(bool found);
private:
bool template_specialization_found_{false};
bool is_template_{false};
};
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -18,8 +18,9 @@
#pragma once
#include "comment/comment_visitor.h"
#include "common/model/element.h"
#include "common/model/source_location.h"
#include "common/model/template_element.h"
#include "common/visitor/ast_id_mapper.h"
#include "config/config.h"
#include <clang/AST/Comment.h>
@@ -65,6 +66,13 @@ public:
*/
const std::filesystem::path &tu_path() const;
/**
* @brief Get reference to Clang AST to clang-uml id mapper
*
* @return Reference to Clang AST to clang-uml id mapper
*/
common::visitor::ast_id_mapper &id_mapper() const { return id_mapper_; }
/**
* @brief Get clang::SourceManager
* @return Reference to @ref clang::SourceManager used by this translation
@@ -105,6 +113,11 @@ public:
void set_owning_module(
const clang::Decl &decl, clanguml::common::model::element &element);
virtual void add_diagram_element(
std::unique_ptr<common::model::template_element> element)
{
}
protected:
/**
* @brief Process comment directives in comment attached to a declaration
@@ -136,5 +149,7 @@ private:
std::filesystem::path translation_unit_path_;
std::set<const clang::RawComment *> processed_comments_;
mutable common::visitor::ast_id_mapper id_mapper_;
};
} // namespace clanguml::common::visitor