Added skip and skip_relationship decorator handling
This commit is contained in:
@@ -54,7 +54,29 @@ enum class relationship_t {
|
|||||||
|
|
||||||
std::string to_string(relationship_t r);
|
std::string to_string(relationship_t r);
|
||||||
|
|
||||||
class element {
|
struct decorated_element {
|
||||||
|
std::vector<std::shared_ptr<decorators::decorator>> decorators;
|
||||||
|
|
||||||
|
bool skip()
|
||||||
|
{
|
||||||
|
for (auto d : decorators)
|
||||||
|
if (std::dynamic_pointer_cast<decorators::skip>(d))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool skip_relationship()
|
||||||
|
{
|
||||||
|
for (auto d : decorators)
|
||||||
|
if (std::dynamic_pointer_cast<decorators::skip_relationship>(d))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class element : public decorated_element {
|
||||||
public:
|
public:
|
||||||
element()
|
element()
|
||||||
: m_id{m_nextId++}
|
: m_id{m_nextId++}
|
||||||
@@ -62,7 +84,6 @@ public:
|
|||||||
}
|
}
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<std::string> namespace_;
|
std::vector<std::string> namespace_;
|
||||||
std::vector<std::shared_ptr<decorators::decorator>> decorators;
|
|
||||||
|
|
||||||
std::string alias() const { return fmt::format("C_{:010}", m_id); }
|
std::string alias() const { return fmt::format("C_{:010}", m_id); }
|
||||||
|
|
||||||
@@ -73,7 +94,7 @@ private:
|
|||||||
static std::atomic_uint64_t m_nextId;
|
static std::atomic_uint64_t m_nextId;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct class_element {
|
struct class_element : public decorated_element {
|
||||||
scope_t scope;
|
scope_t scope;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string type;
|
std::string type;
|
||||||
@@ -84,7 +105,7 @@ struct class_member : public class_element {
|
|||||||
bool is_static{false};
|
bool is_static{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct method_parameter {
|
struct method_parameter : public decorated_element {
|
||||||
std::string type;
|
std::string type;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string default_value;
|
std::string default_value;
|
||||||
@@ -117,7 +138,7 @@ struct class_parent {
|
|||||||
access_t access;
|
access_t access;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct class_relationship {
|
struct class_relationship : public decorated_element {
|
||||||
relationship_t type{relationship_t::kAssociation};
|
relationship_t type{relationship_t::kAssociation};
|
||||||
std::string destination;
|
std::string destination;
|
||||||
std::string cardinality_source;
|
std::string cardinality_source;
|
||||||
|
|||||||
@@ -255,7 +255,6 @@ void tu_visitor::process_class_declaration(const cppast::cpp_class &cls,
|
|||||||
}
|
}
|
||||||
else if (child.kind() == cppast::cpp_entity_kind::member_variable_t) {
|
else if (child.kind() == cppast::cpp_entity_kind::member_variable_t) {
|
||||||
auto &mv = static_cast<const cppast::cpp_member_variable &>(child);
|
auto &mv = static_cast<const cppast::cpp_member_variable &>(child);
|
||||||
LOG_DBG("Found member variable {}", mv.name());
|
|
||||||
process_field(mv, c, last_access_specifier);
|
process_field(mv, c, last_access_specifier);
|
||||||
}
|
}
|
||||||
else if (child.kind() == cppast::cpp_entity_kind::variable_t) {
|
else if (child.kind() == cppast::cpp_entity_kind::variable_t) {
|
||||||
@@ -591,6 +590,12 @@ void tu_visitor::process_field(const cppast::cpp_member_variable &mv, class_ &c,
|
|||||||
m.scope = detail::cpp_access_specifier_to_scope(as);
|
m.scope = detail::cpp_access_specifier_to_scope(as);
|
||||||
m.is_static = false;
|
m.is_static = false;
|
||||||
|
|
||||||
|
if (mv.comment().has_value())
|
||||||
|
m.decorators = decorators::parse(mv.comment().value());
|
||||||
|
|
||||||
|
if (m.skip())
|
||||||
|
return;
|
||||||
|
|
||||||
auto &tr = cx::util::unreferenced(cppast::remove_cv(mv.type()));
|
auto &tr = cx::util::unreferenced(cppast::remove_cv(mv.type()));
|
||||||
|
|
||||||
LOG_DBG("Processing field {} with unreferenced type of kind {}", mv.name(),
|
LOG_DBG("Processing field {} with unreferenced type of kind {}", mv.name(),
|
||||||
@@ -614,7 +619,8 @@ void tu_visitor::process_field(const cppast::cpp_member_variable &mv, class_ &c,
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!template_instantiation_added_as_aggregation &&
|
if (!m.skip_relationship() &&
|
||||||
|
!template_instantiation_added_as_aggregation &&
|
||||||
(tr.kind() != cppast::cpp_type_kind::builtin_t) &&
|
(tr.kind() != cppast::cpp_type_kind::builtin_t) &&
|
||||||
(tr.kind() != cppast::cpp_type_kind::template_parameter_t)) {
|
(tr.kind() != cppast::cpp_type_kind::template_parameter_t)) {
|
||||||
const auto &ttt = resolve_alias(mv.type());
|
const auto &ttt = resolve_alias(mv.type());
|
||||||
@@ -665,6 +671,12 @@ void tu_visitor::process_static_field(const cppast::cpp_variable &mv, class_ &c,
|
|||||||
m.scope = detail::cpp_access_specifier_to_scope(as);
|
m.scope = detail::cpp_access_specifier_to_scope(as);
|
||||||
m.is_static = true;
|
m.is_static = true;
|
||||||
|
|
||||||
|
if (mv.comment().has_value())
|
||||||
|
m.decorators = decorators::parse(mv.comment().value());
|
||||||
|
|
||||||
|
if (m.skip())
|
||||||
|
return;
|
||||||
|
|
||||||
c.members.emplace_back(std::move(m));
|
c.members.emplace_back(std::move(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -681,6 +693,12 @@ void tu_visitor::process_method(const cppast::cpp_member_function &mf,
|
|||||||
m.is_static = false;
|
m.is_static = false;
|
||||||
m.scope = detail::cpp_access_specifier_to_scope(as);
|
m.scope = detail::cpp_access_specifier_to_scope(as);
|
||||||
|
|
||||||
|
if (mf.comment().has_value())
|
||||||
|
m.decorators = decorators::parse(mf.comment().value());
|
||||||
|
|
||||||
|
if (m.skip())
|
||||||
|
return;
|
||||||
|
|
||||||
for (auto ¶m : mf.parameters())
|
for (auto ¶m : mf.parameters())
|
||||||
process_function_parameter(param, m, c);
|
process_function_parameter(param, m, c);
|
||||||
|
|
||||||
@@ -710,6 +728,12 @@ void tu_visitor::process_template_method(
|
|||||||
m.is_static = false;
|
m.is_static = false;
|
||||||
m.scope = detail::cpp_access_specifier_to_scope(as);
|
m.scope = detail::cpp_access_specifier_to_scope(as);
|
||||||
|
|
||||||
|
if (mf.comment().has_value())
|
||||||
|
m.decorators = decorators::parse(mf.comment().value());
|
||||||
|
|
||||||
|
if (m.skip())
|
||||||
|
return;
|
||||||
|
|
||||||
for (auto ¶m : mf.function().parameters())
|
for (auto ¶m : mf.function().parameters())
|
||||||
process_function_parameter(param, m, c);
|
process_function_parameter(param, m, c);
|
||||||
|
|
||||||
@@ -731,6 +755,12 @@ void tu_visitor::process_static_method(const cppast::cpp_function &mf,
|
|||||||
m.is_static = true;
|
m.is_static = true;
|
||||||
m.scope = detail::cpp_access_specifier_to_scope(as);
|
m.scope = detail::cpp_access_specifier_to_scope(as);
|
||||||
|
|
||||||
|
if (mf.comment().has_value())
|
||||||
|
m.decorators = decorators::parse(mf.comment().value());
|
||||||
|
|
||||||
|
if (m.skip())
|
||||||
|
return;
|
||||||
|
|
||||||
for (auto ¶m : mf.parameters())
|
for (auto ¶m : mf.parameters())
|
||||||
process_function_parameter(param, m, c);
|
process_function_parameter(param, m, c);
|
||||||
|
|
||||||
@@ -752,6 +782,12 @@ void tu_visitor::process_constructor(const cppast::cpp_constructor &mf,
|
|||||||
m.is_static = false;
|
m.is_static = false;
|
||||||
m.scope = detail::cpp_access_specifier_to_scope(as);
|
m.scope = detail::cpp_access_specifier_to_scope(as);
|
||||||
|
|
||||||
|
if (mf.comment().has_value())
|
||||||
|
m.decorators = decorators::parse(mf.comment().value());
|
||||||
|
|
||||||
|
if (m.skip())
|
||||||
|
return;
|
||||||
|
|
||||||
for (auto ¶m : mf.parameters())
|
for (auto ¶m : mf.parameters())
|
||||||
process_function_parameter(param, m, c);
|
process_function_parameter(param, m, c);
|
||||||
|
|
||||||
@@ -779,6 +815,13 @@ void tu_visitor::process_function_parameter(
|
|||||||
{
|
{
|
||||||
method_parameter mp;
|
method_parameter mp;
|
||||||
mp.name = param.name();
|
mp.name = param.name();
|
||||||
|
|
||||||
|
if (param.comment().has_value())
|
||||||
|
m.decorators = decorators::parse(param.comment().value());
|
||||||
|
|
||||||
|
if (mp.skip())
|
||||||
|
return;
|
||||||
|
|
||||||
const auto ¶m_type =
|
const auto ¶m_type =
|
||||||
cppast::remove_cv(cx::util::unreferenced(param.type()));
|
cppast::remove_cv(cx::util::unreferenced(param.type()));
|
||||||
if (param_type.kind() == cppast::cpp_type_kind::template_instantiation_t) {
|
if (param_type.kind() == cppast::cpp_type_kind::template_instantiation_t) {
|
||||||
@@ -792,7 +835,7 @@ void tu_visitor::process_function_parameter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto dv = param.default_value();
|
auto dv = param.default_value();
|
||||||
if (dv)
|
if (dv) {
|
||||||
switch (dv.value().kind()) {
|
switch (dv.value().kind()) {
|
||||||
case cppast::cpp_expression_kind::literal_t:
|
case cppast::cpp_expression_kind::literal_t:
|
||||||
mp.default_value =
|
mp.default_value =
|
||||||
@@ -809,66 +852,73 @@ void tu_visitor::process_function_parameter(
|
|||||||
default:
|
default:
|
||||||
mp.default_value = "{}";
|
mp.default_value = "{}";
|
||||||
}
|
}
|
||||||
|
|
||||||
// find relationship for the type
|
|
||||||
std::vector<std::pair<std::string, relationship_t>> relationships;
|
|
||||||
find_relationships(cppast::remove_cv(param.type()), relationships,
|
|
||||||
relationship_t::kDependency);
|
|
||||||
for (const auto &[type, relationship_type] : relationships) {
|
|
||||||
if ((relationship_type != relationship_t::kNone) && (type != c.name)) {
|
|
||||||
class_relationship r;
|
|
||||||
r.destination = type;
|
|
||||||
r.type = relationship_t::kDependency;
|
|
||||||
r.label = "";
|
|
||||||
|
|
||||||
LOG_DBG("Adding field relationship {} {} {} : {}", r.destination,
|
|
||||||
model::class_diagram::to_string(r.type), c.usr, r.label);
|
|
||||||
|
|
||||||
c.add_relationship(std::move(r));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also consider the container itself if it is user defined type
|
if (!mp.skip_relationship()) {
|
||||||
const auto &t = cppast::remove_cv(cx::util::unreferenced(param.type()));
|
// find relationship for the type
|
||||||
if (t.kind() == cppast::cpp_type_kind::template_instantiation_t) {
|
std::vector<std::pair<std::string, relationship_t>> relationships;
|
||||||
auto &template_instantiation_type =
|
find_relationships(cppast::remove_cv(param.type()), relationships,
|
||||||
static_cast<const cppast::cpp_template_instantiation_type &>(t);
|
relationship_t::kDependency);
|
||||||
if (template_instantiation_type.primary_template()
|
for (const auto &[type, relationship_type] : relationships) {
|
||||||
.get(ctx.entity_index)
|
if ((relationship_type != relationship_t::kNone) &&
|
||||||
.size()) {
|
(type != c.name)) {
|
||||||
// Here we need the name of the primary template with full
|
|
||||||
// namespace prefix to apply config inclusion filters
|
|
||||||
auto primary_template_name = cx::util::full_name(ctx.namespace_,
|
|
||||||
template_instantiation_type.primary_template()
|
|
||||||
.get(ctx.entity_index)[0]
|
|
||||||
.get());
|
|
||||||
|
|
||||||
LOG_DBG(
|
|
||||||
"Maybe building instantiation for: {}", primary_template_name);
|
|
||||||
|
|
||||||
if (ctx.config.should_include(primary_template_name)) {
|
|
||||||
class_ tinst =
|
|
||||||
build_template_instantiation(template_instantiation_type);
|
|
||||||
|
|
||||||
LOG_DBG("Created template instantiation: {}, {}", tinst.name,
|
|
||||||
tinst.usr);
|
|
||||||
|
|
||||||
class_relationship r;
|
class_relationship r;
|
||||||
r.destination = tinst.base_template_usr;
|
r.destination = type;
|
||||||
r.type = relationship_t::kInstantiation;
|
r.type = relationship_t::kDependency;
|
||||||
r.label = "";
|
r.label = "";
|
||||||
tinst.add_relationship(std::move(r));
|
|
||||||
|
|
||||||
class_relationship rr;
|
LOG_DBG("Adding field relationship {} {} {} : {}",
|
||||||
rr.destination = tinst.usr;
|
r.destination, model::class_diagram::to_string(r.type),
|
||||||
rr.type = relationship_t::kDependency;
|
c.usr, r.label);
|
||||||
rr.label = "";
|
|
||||||
LOG_DBG("Adding field dependency relationship {} {} {} : {}",
|
|
||||||
rr.destination, model::class_diagram::to_string(rr.type),
|
|
||||||
c.usr, rr.label);
|
|
||||||
c.add_relationship(std::move(rr));
|
|
||||||
|
|
||||||
ctx.d.add_class(std::move(tinst));
|
c.add_relationship(std::move(r));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also consider the container itself if it is user defined type
|
||||||
|
const auto &t = cppast::remove_cv(cx::util::unreferenced(param.type()));
|
||||||
|
if (t.kind() == cppast::cpp_type_kind::template_instantiation_t) {
|
||||||
|
auto &template_instantiation_type =
|
||||||
|
static_cast<const cppast::cpp_template_instantiation_type &>(t);
|
||||||
|
if (template_instantiation_type.primary_template()
|
||||||
|
.get(ctx.entity_index)
|
||||||
|
.size()) {
|
||||||
|
// Here we need the name of the primary template with full
|
||||||
|
// namespace prefix to apply config inclusion filters
|
||||||
|
auto primary_template_name = cx::util::full_name(ctx.namespace_,
|
||||||
|
template_instantiation_type.primary_template()
|
||||||
|
.get(ctx.entity_index)[0]
|
||||||
|
.get());
|
||||||
|
|
||||||
|
LOG_DBG("Maybe building instantiation for: {}",
|
||||||
|
primary_template_name);
|
||||||
|
|
||||||
|
if (ctx.config.should_include(primary_template_name)) {
|
||||||
|
class_ tinst = build_template_instantiation(
|
||||||
|
template_instantiation_type);
|
||||||
|
|
||||||
|
LOG_DBG("Created template instantiation: {}, {}",
|
||||||
|
tinst.name, tinst.usr);
|
||||||
|
|
||||||
|
class_relationship r;
|
||||||
|
r.destination = tinst.base_template_usr;
|
||||||
|
r.type = relationship_t::kInstantiation;
|
||||||
|
r.label = "";
|
||||||
|
tinst.add_relationship(std::move(r));
|
||||||
|
|
||||||
|
class_relationship rr;
|
||||||
|
rr.destination = tinst.usr;
|
||||||
|
rr.type = relationship_t::kDependency;
|
||||||
|
rr.label = "";
|
||||||
|
LOG_DBG(
|
||||||
|
"Adding field dependency relationship {} {} {} : {}",
|
||||||
|
rr.destination,
|
||||||
|
model::class_diagram::to_string(rr.type), c.usr,
|
||||||
|
rr.label);
|
||||||
|
c.add_relationship(std::move(rr));
|
||||||
|
|
||||||
|
ctx.d.add_class(std::move(tinst));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -925,6 +975,12 @@ void tu_visitor::process_friend(const cppast::cpp_friend &f, class_ &parent)
|
|||||||
r.type = relationship_t::kFriendship;
|
r.type = relationship_t::kFriendship;
|
||||||
r.label = "<<friend>>";
|
r.label = "<<friend>>";
|
||||||
|
|
||||||
|
if (f.comment().has_value())
|
||||||
|
r.decorators = decorators::parse(f.comment().value());
|
||||||
|
|
||||||
|
if (r.skip() || r.skip_relationship())
|
||||||
|
return;
|
||||||
|
|
||||||
if (f.type()) {
|
if (f.type()) {
|
||||||
auto name = cppast::to_string(f.type().value());
|
auto name = cppast::to_string(f.type().value());
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user