Cleaned up code

This commit is contained in:
Bartek Kryza
2022-08-28 19:46:01 +02:00
parent 0701a082e9
commit feb19c23c7
10 changed files with 150 additions and 166 deletions

View File

@@ -244,8 +244,6 @@ void generator::generate_relationships(
{
namespace plantuml_common = clanguml::common::generators::plantuml;
// const auto &uns = m_config.using_namespace();
//
// Process relationships
//

View File

@@ -59,6 +59,12 @@ void class_::add_method(class_method &&method)
void class_::add_parent(class_parent &&parent)
{
for (const auto &p : bases_) {
if (p.id() == parent.id()) {
return;
}
}
bases_.emplace_back(std::move(parent));
}
@@ -85,12 +91,7 @@ void class_::set_base_template(const std::string &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();
//(l.name_and_ns() == r.name_and_ns()) &&
// (l.templates_ == r.templates_);
}
bool operator==(const class_ &l, const class_ &r) { return l.id() == r.id(); }
void class_::add_type_alias(type_alias &&ta)
{

View File

@@ -168,8 +168,6 @@ bool diagram::add_class(std::unique_ptr<class_> &&c)
auto id = cc.id();
if (!has_class(cc)) {
if (base_name == "cpp_function_parameter")
LOG_DBG("AAAAAAAAAAAAAAAAAAAAAAA");
if (add_element(ns, std::move(c)))
classes_.push_back(std::ref(cc));
@@ -219,8 +217,6 @@ void diagram::get_parents(
bool found_new{false};
for (const auto &parent : parents) {
for (const auto &pp : parent.get().parents()) {
LOG_DBG("=-=-=-=-=-=-= {} HAS PARENT {} [{}]",
parent.get().full_name(false), pp.name(), pp.id());
auto p = get_class(pp.id());
if (p.has_value()) {
@@ -228,9 +224,6 @@ void diagram::get_parents(
if (found)
found_new = true;
}
else {
LOG_DBG("=-=-=-=-=-=-= {} NOT FOUND IN DIAGRAM", pp.id());
}
}
}

View File

@@ -61,80 +61,6 @@ access_t access_specifier_to_access_t(clang::AccessSpecifier access_specifier)
return access;
}
std::optional<clanguml::common::model::namespace_> get_enclosing_namespace(
const clang::DeclContext *decl)
{
if (!decl->getEnclosingNamespaceContext()->isNamespace())
return {};
const auto *namespace_declaration =
clang::cast<clang::NamespaceDecl>(decl->getEnclosingNamespaceContext());
if (namespace_declaration == nullptr) {
return {};
}
return namespace_{common::get_qualified_name(*namespace_declaration)};
}
}
std::string to_string(const clang::QualType &type, const clang::ASTContext &ctx,
bool try_canonical = true)
{
const clang::PrintingPolicy print_policy(ctx.getLangOpts());
auto result{type.getAsString(print_policy)};
if (try_canonical && result.find('<') != std::string::npos) {
auto canonical_type_name =
type.getCanonicalType().getAsString(print_policy);
auto result_qualified_template_name =
result.substr(0, result.find('<'));
auto result_template_arguments = result.substr(result.find('<'));
auto canonical_qualified_template_name =
canonical_type_name.substr(0, canonical_type_name.find('<'));
// Choose the longer name (why do I have to do this?)
if (result_qualified_template_name.size() <
canonical_qualified_template_name.size()) {
result =
canonical_qualified_template_name + result_template_arguments;
}
}
util::replace_all(result, ", ", ",");
return result;
}
std::string to_string(const clang::RecordType &type,
const clang::ASTContext &ctx, bool try_canonical = true)
{
return to_string(type.desugar(), ctx, try_canonical);
}
std::string get_source_text_raw(
clang::SourceRange range, const clang::SourceManager &sm)
{
return clang::Lexer::getSourceText(
clang::CharSourceRange::getCharRange(range), sm, clang::LangOptions())
.str();
}
std::string get_source_text(
clang::SourceRange range, const clang::SourceManager &sm)
{
clang::LangOptions lo;
auto start_loc = sm.getSpellingLoc(range.getBegin());
auto last_token_loc = sm.getSpellingLoc(range.getEnd());
auto end_loc = clang::Lexer::getLocForEndOfToken(last_token_loc, 0, sm, lo);
auto printable_range = clang::SourceRange{start_loc, end_loc};
return get_source_text_raw(printable_range, sm);
}
translation_unit_visitor::translation_unit_visitor(clang::SourceManager &sm,
@@ -238,7 +164,7 @@ bool translation_unit_visitor::VisitEnumDecl(clang::EnumDecl *enm)
process_record_containment(*enm, e);
}
auto namespace_declaration = detail::get_enclosing_namespace(enm);
auto namespace_declaration = common::get_enclosing_namespace(enm);
if (namespace_declaration.has_value()) {
e.set_namespace(namespace_declaration.value());
}
@@ -259,18 +185,6 @@ bool translation_unit_visitor::VisitClassTemplateSpecializationDecl(
cls->getQualifiedNameAsString(),
cls->getLocation().printToString(source_manager_));
// Skip forward declarations
if (!cls->isCompleteDefinition()) {
// Register this forward declaration in case there is no complete
// definition (see t00036)
return true;
}
// else
// // Check if the class was already processed within
// // VisitClassTemplateDecl()
// if (diagram_.has_element(cls->getID()))
// return true;
// TODO: Add support for classes defined in function/method bodies
if (cls->isLocalClass())
return true;
@@ -394,10 +308,6 @@ bool translation_unit_visitor::VisitCXXRecordDecl(clang::CXXRecordDecl *cls)
cls->getQualifiedNameAsString(),
cls->getLocation().printToString(source_manager_));
// Skip forward declarations
// if (!cls->isCompleteDefinition())
// return true;
const auto cls_id = common::to_id(*cls);
set_ast_local_id(cls->getID(), cls_id);
@@ -408,11 +318,6 @@ bool translation_unit_visitor::VisitCXXRecordDecl(clang::CXXRecordDecl *cls)
nullptr))
return true;
// Check if the class was already processed within VisitClassTemplateDecl()
// auto cls_id = cls->getID();
// if (diagram_.has_element(cls_id))
// return true;
// TODO: Add support for classes defined in function/method bodies
if (cls->isLocalClass())
return true;
@@ -481,9 +386,6 @@ std::unique_ptr<class_> translation_unit_visitor::create_class_declaration(
c.set_style(c.style_spec());
if (!cls->isCompleteDefinition())
return c_ptr;
return c_ptr;
}
@@ -571,7 +473,7 @@ void translation_unit_visitor::process_record_containment(
static_cast<const clang::RecordDecl *>(record.getParent())
->getQualifiedNameAsString();
auto namespace_declaration = detail::get_enclosing_namespace(parent);
auto namespace_declaration = common::get_enclosing_namespace(parent);
if (namespace_declaration.has_value()) {
element.set_namespace(namespace_declaration.value());
}
@@ -588,7 +490,7 @@ void translation_unit_visitor::process_class_bases(
for (auto &base : cls->bases()) {
class_parent cp;
auto name_and_ns = common::model::namespace_{
to_string(base.getType(), cls->getASTContext())};
common::to_string(base.getType(), cls->getASTContext())};
cp.set_name(name_and_ns.to_string());
@@ -948,8 +850,8 @@ void translation_unit_visitor::process_function_parameter(
if (p.hasDefaultArg()) {
const auto *default_arg = p.getDefaultArg();
if (default_arg != nullptr) {
auto default_arg_str =
get_source_text(default_arg->getSourceRange(), source_manager_);
auto default_arg_str = common::get_source_text(
default_arg->getSourceRange(), source_manager_);
parameter.set_default_value(default_arg_str);
}
}
@@ -1068,7 +970,8 @@ void translation_unit_visitor::process_static_field(
const clang::VarDecl &field_declaration, class_ &c)
{
const auto field_type = field_declaration.getType();
auto type_name = to_string(field_type, field_declaration.getASTContext());
auto type_name =
common::to_string(field_type, field_declaration.getASTContext());
if (type_name.empty())
type_name = "<<anonymous>>";
@@ -1176,14 +1079,15 @@ void translation_unit_visitor::process_template_specialization_argument(
argument.to_string(config().using_namespace(), false));
}
else if (arg.getAsType()->getAs<clang::TemplateTypeParmType>()) {
auto type_name = to_string(arg.getAsType(), cls->getASTContext());
auto type_name =
common::to_string(arg.getAsType(), cls->getASTContext());
// clang does not provide declared template parameter/argument names
// in template specializations - so we have to extract them from
// raw source code...
if (type_name.find("type-parameter-") == 0) {
auto declaration_text =
get_source_text_raw(cls->getSourceRange(), source_manager_);
auto declaration_text = common::get_source_text_raw(
cls->getSourceRange(), source_manager_);
declaration_text = declaration_text.substr(
declaration_text.find(cls->getNameAsString()) +
@@ -1206,7 +1110,8 @@ void translation_unit_visitor::process_template_specialization_argument(
argument.set_name(type_name);
}
else {
auto type_name = to_string(arg.getAsType(), cls->getASTContext());
auto type_name =
common::to_string(arg.getAsType(), cls->getASTContext());
if (type_name.find('<') != std::string::npos) {
// Sometimes template instantiation is reported as
// RecordType in the AST and getAs to
@@ -1222,8 +1127,8 @@ void translation_unit_visitor::process_template_specialization_argument(
argument.set_name(type_name.substr(0, type_name.find('<')));
}
else if (type_name.find("type-parameter-") == 0) {
auto declaration_text =
get_source_text_raw(cls->getSourceRange(), source_manager_);
auto declaration_text = common::get_source_text_raw(
cls->getSourceRange(), source_manager_);
declaration_text = declaration_text.substr(
declaration_text.find(cls->getNameAsString()) +
@@ -1267,7 +1172,7 @@ void translation_unit_visitor::process_template_specialization_argument(
else if (argument_kind == clang::TemplateArgument::Expression) {
template_parameter argument;
argument.is_template_parameter(false);
argument.set_type(get_source_text(
argument.set_type(common::get_source_text(
arg.getAsExpr()->getSourceRange(), source_manager_));
template_instantiation.add_template(std::move(argument));
}
@@ -1359,7 +1264,7 @@ std::unique_ptr<class_> translation_unit_visitor::
auto &template_instantiation = *template_instantiation_ptr;
std::string full_template_specialization_name =
to_string(record_type, template_specialization.getASTContext());
common::to_string(record_type, template_specialization.getASTContext());
const auto *template_decl =
template_specialization.getSpecializedTemplate();
@@ -1454,7 +1359,7 @@ std::unique_ptr<class_> translation_unit_visitor::build_template_instantiation(
auto template_instantiation_ptr =
std::make_unique<class_>(config_.using_namespace());
auto &template_instantiation = *template_instantiation_ptr;
std::string full_template_specialization_name = to_string(
std::string full_template_specialization_name = common::to_string(
template_type.desugar(),
template_type.getTemplateName().getAsTemplateDecl()->getASTContext());
@@ -1497,7 +1402,7 @@ std::unique_ptr<class_> translation_unit_visitor::build_template_instantiation(
if (templated_class_decl && templated_class_decl->hasDefinition())
for (const auto &base : templated_class_decl->bases()) {
const auto base_class_name = to_string(
const auto base_class_name = common::to_string(
base.getType(), templated_class_decl->getASTContext(), false);
LOG_DBG("Found template instantiation base: {}, {}",
@@ -1589,7 +1494,6 @@ void translation_unit_visitor::
build_template_instantiation_process_template_arguments(
std::optional<clanguml::class_diagram::model::class_ *> &parent,
std::deque<std::tuple<std::string, int, bool>> &template_base_params,
// const clang::TemplateSpecializationType &template_type,
const clang::ArrayRef<clang::TemplateArgument> &template_args,
class_ &template_instantiation,
const std::string &full_template_specialization_name,
@@ -1772,7 +1676,7 @@ void translation_unit_visitor::
else if (arg.getAsType()->getAs<clang::TemplateTypeParmType>()) {
argument.is_template_parameter(true);
argument.set_name(
to_string(arg.getAsType(), template_decl->getASTContext()));
common::to_string(arg.getAsType(), template_decl->getASTContext()));
}
else {
// This is just a regular record type
@@ -1799,8 +1703,8 @@ void translation_unit_visitor::
assert(arg.getKind() == clang::TemplateArgument::Expression);
argument.is_template_parameter(false);
argument.set_type(
get_source_text(arg.getAsExpr()->getSourceRange(), source_manager_));
argument.set_type(common::get_source_text(
arg.getAsExpr()->getSourceRange(), source_manager_));
}
void translation_unit_visitor::
@@ -1815,7 +1719,7 @@ void translation_unit_visitor::
argument.is_template_parameter(false);
argument.set_name(
to_string(arg.getAsType(), template_decl->getASTContext()));
common::to_string(arg.getAsType(), template_decl->getASTContext()));
if (arg.getAsType()->getAs<clang::RecordType>() &&
arg.getAsType()->getAs<clang::RecordType>()->getAsRecordDecl()) {
@@ -1884,7 +1788,8 @@ void translation_unit_visitor::process_field(
// The actual field type
auto field_type = field_declaration.getType();
// String representation of the field type
auto type_name = to_string(field_type, field_declaration.getASTContext());
auto type_name =
common::to_string(field_type, field_declaration.getASTContext());
// The field name
const auto field_name = field_declaration.getNameAsString();
// If for any reason clang reports the type as empty string, make sure
@@ -1895,7 +1800,8 @@ void translation_unit_visitor::process_field(
class_member field{
detail::access_specifier_to_access_t(field_declaration.getAccess()),
field_name,
to_string(field_type, field_declaration.getASTContext(), false)};
common::to_string(
field_type, field_declaration.getASTContext(), false)};
// Parse the field comment
process_comment(field_declaration, field);
@@ -2070,4 +1976,20 @@ bool translation_unit_visitor::simplify_system_template(
else
return false;
}
void translation_unit_visitor::set_ast_local_id(
int64_t local_id, common::model::diagram_element::id_t global_id)
{
local_ast_id_map_[local_id] = global_id;
}
std::optional<common::model::diagram_element::id_t>
translation_unit_visitor::get_ast_local_id(int64_t local_id)
{
if (local_ast_id_map_.find(local_id) == local_ast_id_map_.end())
return {};
return local_ast_id_map_.at(local_id);
}
}

View File

@@ -150,7 +150,6 @@ private:
void build_template_instantiation_process_template_arguments(
std::optional<clanguml::class_diagram::model::class_ *> &parent,
std::deque<std::tuple<std::string, int, bool>> &template_base_params,
// const clang::TemplateSpecializationType &template_type,
const clang::ArrayRef<clang::TemplateArgument> &template_args,
model::class_ &template_instantiation,
const std::string &full_template_specialization_name,
@@ -216,22 +215,14 @@ private:
bool simplify_system_template(
model::template_parameter &ct, const std::string &full_name);
/// Store the mapping from local clang entity id (obtained using
/// getID()) method to clang-uml global id
void set_ast_local_id(
int64_t local_id, common::model::diagram_element::id_t global_id)
{
LOG_DBG("{} >>>>>>>>>>>>>>>>>>>>>>>>> {}", local_id, global_id);
local_ast_id_map_[local_id] = global_id;
}
int64_t local_id, common::model::diagram_element::id_t global_id);
/// Retrieve the global clang-uml entity id based on the clang local id
std::optional<common::model::diagram_element::id_t> get_ast_local_id(
int64_t local_id)
{
if (local_ast_id_map_.find(local_id) == local_ast_id_map_.end())
return {};
return local_ast_id_map_.at(local_id);
}
int64_t local_id);
clang::SourceManager &source_manager_;

View File

@@ -18,8 +18,86 @@
#include "clang_utils.h"
#include <clang/Lex/Preprocessor.h>
namespace clanguml::common {
std::optional<clanguml::common::model::namespace_> get_enclosing_namespace(
const clang::DeclContext *decl)
{
if (!decl->getEnclosingNamespaceContext()->isNamespace())
return {};
const auto *namespace_declaration =
clang::cast<clang::NamespaceDecl>(decl->getEnclosingNamespaceContext());
if (namespace_declaration == nullptr) {
return {};
}
return clanguml::common::model::namespace_{
common::get_qualified_name(*namespace_declaration)};
}
std::string to_string(const clang::QualType &type, const clang::ASTContext &ctx,
bool try_canonical)
{
const clang::PrintingPolicy print_policy(ctx.getLangOpts());
auto result{type.getAsString(print_policy)};
if (try_canonical && result.find('<') != std::string::npos) {
auto canonical_type_name =
type.getCanonicalType().getAsString(print_policy);
auto result_qualified_template_name =
result.substr(0, result.find('<'));
auto result_template_arguments = result.substr(result.find('<'));
auto canonical_qualified_template_name =
canonical_type_name.substr(0, canonical_type_name.find('<'));
// Choose the longer name (why do I have to do this?)
if (result_qualified_template_name.size() <
canonical_qualified_template_name.size()) {
result =
canonical_qualified_template_name + result_template_arguments;
}
}
// Remove trailing spaces after commas in template arguments
clanguml::util::replace_all(result, ", ", ",");
return result;
}
std::string to_string(const clang::RecordType &type,
const clang::ASTContext &ctx, bool try_canonical)
{
return to_string(type.desugar(), ctx, try_canonical);
}
std::string get_source_text_raw(
clang::SourceRange range, const clang::SourceManager &sm)
{
return clang::Lexer::getSourceText(
clang::CharSourceRange::getCharRange(range), sm, clang::LangOptions())
.str();
}
std::string get_source_text(
clang::SourceRange range, const clang::SourceManager &sm)
{
clang::LangOptions lo;
auto start_loc = sm.getSpellingLoc(range.getBegin());
auto last_token_loc = sm.getSpellingLoc(range.getEnd());
auto end_loc = clang::Lexer::getLocForEndOfToken(last_token_loc, 0, sm, lo);
auto printable_range = clang::SourceRange{start_loc, end_loc};
return get_source_text_raw(printable_range, sm);
}
template <> id_t to_id(const std::string &full_name)
{
return std::hash<std::string>{}(full_name) >> 3;
@@ -52,8 +130,6 @@ template <> id_t to_id(const clang::CXXRecordDecl &declaration)
template <> id_t to_id(const clang::EnumType &t) { return to_id(*t.getDecl()); }
// template <> id_t to_id(const clang::TemplateSpecializationType &t);
template <> id_t to_id(const std::filesystem::path &file)
{
return to_id(file.lexically_normal().string());
@@ -74,5 +150,4 @@ template <> id_t to_id(const clang::TemplateArgument &template_argument)
throw std::runtime_error("Cannot generate id for template argument");
}
}

View File

@@ -39,6 +39,21 @@ template <typename T> std::string get_qualified_name(const T &declaration)
return qualified_name;
}
std::optional<clanguml::common::model::namespace_> get_enclosing_namespace(
const clang::DeclContext *decl);
std::string to_string(const clang::QualType &type, const clang::ASTContext &ctx,
bool try_canonical = true);
std::string to_string(const clang::RecordType &type,
const clang::ASTContext &ctx, bool try_canonical = true);
std::string get_source_text_raw(
clang::SourceRange range, const clang::SourceManager &sm);
std::string get_source_text(
clang::SourceRange range, const clang::SourceManager &sm);
template <typename T> id_t to_id(const T &declaration);
template <> id_t to_id(const std::string &full_name);

View File

@@ -198,8 +198,8 @@ void generator<C, D>::generate_plantuml_directives(
directive.replace(std::get<1>(alias_match),
std::get<2>(alias_match), element_opt.value().alias());
else {
LOG_ERROR(
"CANNOT FIND ALIAS TO ELEMENT {}", full_name.to_string());
LOG_ERROR("Cannot find clang-uml alias for element {}",
full_name.to_string());
directive.replace(std::get<1>(alias_match),
std::get<2>(alias_match), "UNKNOWN_ALIAS");
}
@@ -262,9 +262,6 @@ public:
{
visitor_.TraverseDecl(ast_context.getTranslationUnitDecl());
visitor_.finalize();
// LOG_DBG("= Finalized translation unit: {}",
// ast_context.getTranslationUnitDecl());
}
};

View File

@@ -229,8 +229,6 @@ tvl::value_t subclass_filter::match(const diagram &d, const element &e) const
if (!class_ref.has_value())
return false;
LOG_DBG("====================== LOOKING FOR PARENTS OF {} ===========", fn);
parents.emplace(class_ref.value());
cd.get_parents(parents);
@@ -239,15 +237,11 @@ tvl::value_t subclass_filter::match(const diagram &d, const element &e) const
for (const auto p : parents)
parents_names.push_back(p.get().full_name(false));
LOG_DBG("====================== FOUND PARENTS {} ==========",
fmt::join(parents_names, ", "));
// Now check if any of the parents matches the roots specified in the
// filter config
for (const auto &root : roots_) {
for (const auto &parent : parents) {
auto full_name = parent.get().full_name(false);
LOG_DBG("+++ COMPARING {} WITH {}", root, full_name);
if (root == full_name)
return true;
}

View File

@@ -32,8 +32,6 @@ void generator::generate_relationships(
{
LOG_DBG("Generating relationships for package {}", p.full_name(true));
// const auto &uns = m_config.using_namespace();
// Generate this packages relationship
if (m_model.should_include(relationship_t::kDependency)) {
for (const auto &r : p.relationships()) {