Added generation of type alias map
This commit is contained in:
@@ -17,9 +17,11 @@
|
||||
*/
|
||||
|
||||
#include "cx/util.h"
|
||||
#include "util/util.h"
|
||||
|
||||
#include <cppast/cpp_class.hpp>
|
||||
#include <cppast/cpp_entity_kind.hpp>
|
||||
#include <cppast/cpp_template.hpp>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
namespace clanguml {
|
||||
@@ -62,6 +64,19 @@ std::string full_name(const cppast::cpp_entity &e)
|
||||
return scopes + e.name();
|
||||
}
|
||||
|
||||
std::string full_name(const cppast::cpp_type &t,
|
||||
const cppast::cpp_entity_index &idx, bool inside_class)
|
||||
{
|
||||
std::string t_ns;
|
||||
if (!inside_class)
|
||||
t_ns = ns(t, idx);
|
||||
|
||||
if (t_ns.size() > 0)
|
||||
return t_ns + "::" + cppast::to_string(t);
|
||||
|
||||
return cppast::to_string(t);
|
||||
}
|
||||
|
||||
std::string ns(const cppast::cpp_entity &e)
|
||||
{
|
||||
std::vector<std::string> res{};
|
||||
@@ -73,8 +88,45 @@ std::string ns(const cppast::cpp_entity &e)
|
||||
}
|
||||
it = it.value().parent();
|
||||
}
|
||||
std::reverse(res.begin(), res.end());
|
||||
|
||||
return fmt::format("{}", fmt::join(res.rbegin(), res.rend(), "::"));
|
||||
return fmt::format("{}", fmt::join(res, "::"));
|
||||
}
|
||||
|
||||
bool is_inside_class(const cppast::cpp_entity &e)
|
||||
{
|
||||
auto it = e.parent();
|
||||
while (it) {
|
||||
if (it.value().kind() == cppast::cpp_entity_kind::class_t) {
|
||||
return true;
|
||||
}
|
||||
it = it.value().parent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string ns(const cppast::cpp_type &t, const cppast::cpp_entity_index &idx)
|
||||
{
|
||||
auto canon = cppast::to_string(t.canonical());
|
||||
auto full_name = canon.substr(0, canon.find("<"));
|
||||
if (canon.find("type-parameter-") == std::string::npos) {
|
||||
// This is an easy case, canonical representation contains full
|
||||
// namespace
|
||||
auto ns_toks = clanguml::util::split(full_name, "::");
|
||||
if (ns_toks.size() > 0)
|
||||
ns_toks.pop_back();
|
||||
return fmt::format(
|
||||
"{}", fmt::join(ns_toks.begin(), ns_toks.end(), "::"));
|
||||
}
|
||||
else {
|
||||
// This is a bug/feature in libclang, where canonical representation of
|
||||
// a template type with incomplete specialization doesn't have a full
|
||||
// namespace We have to extract it from te primary template
|
||||
const auto &primary_template =
|
||||
static_cast<const cppast::cpp_template_instantiation_type &>(t)
|
||||
.primary_template();
|
||||
return ns(primary_template.get(idx)[0].get());
|
||||
}
|
||||
}
|
||||
|
||||
std::string fully_prefixed(const cppast::cpp_entity &e)
|
||||
|
||||
@@ -42,10 +42,19 @@ std::string to_string(CXString &&cxs);
|
||||
|
||||
std::string full_name(const cppast::cpp_entity &e);
|
||||
|
||||
std::string full_name(const cppast::cpp_type &t,
|
||||
const cppast::cpp_entity_index &idx, bool inside_class);
|
||||
|
||||
std::string fully_prefixed(const cppast::cpp_entity &e);
|
||||
|
||||
const cppast::cpp_type &unreferenced(const cppast::cpp_type &t);
|
||||
|
||||
std::string ns(const cppast::cpp_entity &e);
|
||||
|
||||
std::string ns(const cppast::cpp_type &t, const cppast::cpp_entity_index &idx);
|
||||
|
||||
bool is_inside_class(const cppast::cpp_entity &e);
|
||||
|
||||
} // namespace util
|
||||
} // namespace cx
|
||||
} // namespace clanguml
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
@@ -140,6 +141,11 @@ struct class_template {
|
||||
}
|
||||
};
|
||||
|
||||
struct type_alias {
|
||||
std::string alias;
|
||||
std::string underlying_type;
|
||||
};
|
||||
|
||||
class class_ : public element {
|
||||
public:
|
||||
std::string usr;
|
||||
@@ -153,12 +159,20 @@ public:
|
||||
std::vector<class_relationship> relationships;
|
||||
std::vector<class_template> templates;
|
||||
std::string base_template_usr;
|
||||
std::map<std::string, type_alias> type_aliases;
|
||||
|
||||
friend bool operator==(const class_ &l, const class_ &r)
|
||||
{
|
||||
return (l.usr == r.usr) && (l.templates == r.templates);
|
||||
}
|
||||
|
||||
void add_type_alias(type_alias &&ta)
|
||||
{
|
||||
spdlog::debug(
|
||||
"Adding class alias: {} -> {}", ta.alias, ta.underlying_type);
|
||||
type_aliases[ta.alias] = std::move(ta);
|
||||
}
|
||||
|
||||
void add_relationship(class_relationship &&cr)
|
||||
{
|
||||
auto it = std::find(relationships.begin(), relationships.end(), cr);
|
||||
@@ -225,6 +239,7 @@ struct diagram {
|
||||
std::string name;
|
||||
std::vector<class_> classes;
|
||||
std::vector<enum_> enums;
|
||||
std::map<std::string, type_alias> type_aliases;
|
||||
|
||||
bool has_class(const std::string &usr) const
|
||||
{
|
||||
@@ -232,6 +247,14 @@ struct diagram {
|
||||
[&usr](const auto &c) { return c.usr == usr; });
|
||||
}
|
||||
|
||||
void add_type_alias(type_alias &&ta)
|
||||
{
|
||||
spdlog::debug(
|
||||
"Adding global alias: {} -> {}", ta.alias, ta.underlying_type);
|
||||
|
||||
type_aliases[ta.alias] = std::move(ta);
|
||||
}
|
||||
|
||||
void add_class(class_ &&c)
|
||||
{
|
||||
spdlog::debug("Adding class: {}, {}", c.name, c.usr);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <cppast/cpp_member_function.hpp>
|
||||
#include <cppast/cpp_member_variable.hpp>
|
||||
#include <cppast/cpp_template.hpp>
|
||||
#include <cppast/cpp_type_alias.hpp>
|
||||
#include <cppast/cpp_variable.hpp>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
@@ -43,6 +44,7 @@ using clanguml::model::class_diagram::enum_;
|
||||
using clanguml::model::class_diagram::method_parameter;
|
||||
using clanguml::model::class_diagram::relationship_t;
|
||||
using clanguml::model::class_diagram::scope_t;
|
||||
using clanguml::model::class_diagram::type_alias;
|
||||
|
||||
namespace detail {
|
||||
scope_t cpp_access_specifier_to_scope(cppast::cpp_access_specifier_kind as)
|
||||
@@ -97,6 +99,18 @@ void tu_visitor::operator()(const cppast::cpp_entity &file)
|
||||
if (ctx.config.should_include(cx::util::fully_prefixed(enm)))
|
||||
process_enum_declaration(enm);
|
||||
}
|
||||
else if (e.kind() == cppast::cpp_entity_kind::type_alias_t) {
|
||||
spdlog::debug("========== Visiting '{}' - {}",
|
||||
cx::util::full_name(e), cppast::to_string(e.kind()));
|
||||
|
||||
auto &ta = static_cast<const cppast::cpp_type_alias &>(e);
|
||||
type_alias t;
|
||||
t.alias = cx::util::full_name(ta);
|
||||
t.underlying_type = cx::util::full_name(ta.underlying_type(),
|
||||
ctx.entity_index, cx::util::is_inside_class(e));
|
||||
|
||||
ctx.d.add_type_alias(std::move(t));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,12 @@
|
||||
#include <type_traits>
|
||||
#include <variant>
|
||||
|
||||
template <typename T> struct clanguml_t00014_A {
|
||||
T value;
|
||||
};
|
||||
|
||||
using clanguml_t00014_AString = clanguml_t00014_A<std::string>;
|
||||
|
||||
namespace clanguml {
|
||||
namespace t00014 {
|
||||
|
||||
@@ -18,9 +24,9 @@ template <typename T> using AString = A<T, std::string>;
|
||||
|
||||
using AIntString = AString<int>;
|
||||
using AStringString = AString<std::string>;
|
||||
using BStringString = AStringString;
|
||||
|
||||
class R {
|
||||
using BStringString = AStringString;
|
||||
A<bool, std::string> boolstring;
|
||||
AString<float> floatstring;
|
||||
AIntString intstring;
|
||||
|
||||
Reference in New Issue
Block a user