Added initial abstract class rendering
This commit is contained in:
@@ -132,6 +132,23 @@ public:
|
|||||||
|
|
||||||
bool is_preprocessing() const { return clang_isPreprocessing(kind()); }
|
bool is_preprocessing() const { return clang_isPreprocessing(kind()); }
|
||||||
|
|
||||||
|
bool is_method_virtual() const
|
||||||
|
{
|
||||||
|
return clang_CXXMethod_isVirtual(m_cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_method_const() const { return clang_CXXMethod_isConst(m_cursor); }
|
||||||
|
|
||||||
|
bool is_method_pure_virtual() const
|
||||||
|
{
|
||||||
|
return clang_CXXMethod_isPureVirtual(m_cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_method_defaulted() const
|
||||||
|
{
|
||||||
|
return clang_CXXMethod_isDefaulted(m_cursor);
|
||||||
|
}
|
||||||
|
|
||||||
CXVisibilityKind visibitity() const
|
CXVisibilityKind visibitity() const
|
||||||
{
|
{
|
||||||
return clang_getCursorVisibility(m_cursor);
|
return clang_getCursorVisibility(m_cursor);
|
||||||
|
|||||||
@@ -94,11 +94,23 @@ public:
|
|||||||
|
|
||||||
void generate(const class_ &c, std::ostream &ostr) const
|
void generate(const class_ &c, std::ostream &ostr) const
|
||||||
{
|
{
|
||||||
ostr << "Class " << c.name << " {" << std::endl;
|
if (c.is_abstract())
|
||||||
|
ostr << "abstract ";
|
||||||
|
else
|
||||||
|
ostr << "class ";
|
||||||
|
|
||||||
|
ostr << c.name << " {" << std::endl;
|
||||||
|
|
||||||
for (const auto &m : c.methods) {
|
for (const auto &m : c.methods) {
|
||||||
ostr << to_string(m.scope) << m.type << " " << m.name + "()"
|
if (m.is_pure_virtual)
|
||||||
<< std::endl;
|
ostr << "{abstract} ";
|
||||||
|
|
||||||
|
ostr << to_string(m.scope) << m.type << " " << m.name + "()";
|
||||||
|
|
||||||
|
if (m.is_pure_virtual)
|
||||||
|
ostr << " = 0";
|
||||||
|
|
||||||
|
ostr << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &m : c.members) {
|
for (const auto &m : c.members) {
|
||||||
|
|||||||
@@ -63,6 +63,10 @@ struct method_argument {
|
|||||||
|
|
||||||
struct class_method : public class_element {
|
struct class_method : public class_element {
|
||||||
std::vector<method_argument> arguments;
|
std::vector<method_argument> arguments;
|
||||||
|
bool is_pure_virtual{false};
|
||||||
|
bool is_virtual{false};
|
||||||
|
bool is_const{false};
|
||||||
|
bool is_defaulted{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct class_parent {
|
struct class_parent {
|
||||||
@@ -89,6 +93,14 @@ struct class_ : public element {
|
|||||||
std::vector<std::string> inner_classes;
|
std::vector<std::string> inner_classes;
|
||||||
|
|
||||||
std::vector<class_relationship> relationships;
|
std::vector<class_relationship> relationships;
|
||||||
|
|
||||||
|
bool is_abstract() const
|
||||||
|
{
|
||||||
|
// TODO check if all base abstract methods are overriden
|
||||||
|
// with non-abstract methods
|
||||||
|
return std::any_of(methods.begin(), methods.end(),
|
||||||
|
[](const auto &method) { return method.is_pure_virtual; });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct enum_ : public element {
|
struct enum_ : public element {
|
||||||
|
|||||||
@@ -84,6 +84,15 @@ enum CXChildVisitResult visit_if_cursor_valid(
|
|||||||
ret = CXChildVisit_Recurse;
|
ret = CXChildVisit_Recurse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (cursor.is_declaration()) {
|
||||||
|
if (cursor.is_method_pure_virtual()) {
|
||||||
|
f(cursor);
|
||||||
|
ret = CXChildVisit_Continue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = CXChildVisit_Recurse;
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
ret = CXChildVisit_Continue;
|
ret = CXChildVisit_Continue;
|
||||||
}
|
}
|
||||||
@@ -143,7 +152,11 @@ static enum CXChildVisitResult class_visitor(
|
|||||||
visit_if_cursor_valid(cursor, [c](cx::cursor cursor) {
|
visit_if_cursor_valid(cursor, [c](cx::cursor cursor) {
|
||||||
class_method m;
|
class_method m;
|
||||||
m.name = cursor.spelling();
|
m.name = cursor.spelling();
|
||||||
m.type = cursor.type().spelling();
|
m.type = cursor.type().result_type().spelling();
|
||||||
|
m.is_pure_virtual = cursor.is_method_pure_virtual();
|
||||||
|
m.is_virtual = cursor.is_method_virtual();
|
||||||
|
m.is_const = cursor.is_method_const();
|
||||||
|
m.is_defaulted = cursor.is_method_defaulted();
|
||||||
|
|
||||||
spdlog::info("Adding method {} {}::{}()", m.type, c->name,
|
spdlog::info("Adding method {} {}::{}()", m.type, c->name,
|
||||||
cursor.spelling());
|
cursor.spelling());
|
||||||
|
|||||||
@@ -5,16 +5,35 @@ namespace t00002 {
|
|||||||
|
|
||||||
class A {
|
class A {
|
||||||
public:
|
public:
|
||||||
virtual void foo() {}
|
virtual void foo_a() = 0;
|
||||||
|
virtual void foo_c() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class B : public A {
|
class B : public A {
|
||||||
|
public:
|
||||||
|
virtual void foo_a() override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class C : public A {
|
class C : public A {
|
||||||
|
public:
|
||||||
|
virtual void foo_c() override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class D : public B, public C {
|
class D : public B, public C {
|
||||||
|
public:
|
||||||
|
void foo_a() override
|
||||||
|
{
|
||||||
|
for (auto a : as)
|
||||||
|
a->foo_a();
|
||||||
|
}
|
||||||
|
|
||||||
|
void foo_c() override
|
||||||
|
{
|
||||||
|
for (auto a : as)
|
||||||
|
a->foo_c();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
std::vector<A *> as;
|
std::vector<A *> as;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,6 +152,10 @@ TEST_CASE("Test t00002", "[unit-test]")
|
|||||||
|
|
||||||
REQUIRE_THAT(puml, StartsWith("@startuml"));
|
REQUIRE_THAT(puml, StartsWith("@startuml"));
|
||||||
REQUIRE_THAT(puml, EndsWith("@enduml\n"));
|
REQUIRE_THAT(puml, EndsWith("@enduml\n"));
|
||||||
|
REQUIRE_THAT(puml, Contains("abstract A"));
|
||||||
|
REQUIRE_THAT(puml, Contains("class B"));
|
||||||
|
REQUIRE_THAT(puml, Contains("class C"));
|
||||||
|
REQUIRE_THAT(puml, Contains("class D"));
|
||||||
|
|
||||||
save_puml(
|
save_puml(
|
||||||
"./" + config.output_directory + "/" + diagram->name + ".puml", puml);
|
"./" + config.output_directory + "/" + diagram->name + ".puml", puml);
|
||||||
|
|||||||
Reference in New Issue
Block a user