From dfa39a0433b68d4c6f068494223b0f3debb72c6c Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Thu, 25 Feb 2021 20:43:13 +0100 Subject: [PATCH] Added handling of static class fields --- src/cx/cursor.h | 5 +++++ src/puml/class_diagram_generator.h | 3 +++ src/uml/class_diagram_model.h | 1 + src/uml/class_diagram_visitor.h | 11 +++-------- tests/t00003/t00003.cc | 12 +++++++++++- tests/test_cases.cc | 1 + 6 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/cx/cursor.h b/src/cx/cursor.h index 46b9f772..13cb9890 100644 --- a/src/cx/cursor.h +++ b/src/cx/cursor.h @@ -137,6 +137,11 @@ public: return clang_CXXMethod_isVirtual(m_cursor); } + bool is_static() const + { + return clang_Cursor_getStorageClass(m_cursor) == CX_SC_Static; + } + bool is_method_static() const { return clang_CXXMethod_isStatic(m_cursor); } bool is_method_const() const { return clang_CXXMethod_isConst(m_cursor); } diff --git a/src/puml/class_diagram_generator.h b/src/puml/class_diagram_generator.h index 94eda9a2..9e4b98a1 100644 --- a/src/puml/class_diagram_generator.h +++ b/src/puml/class_diagram_generator.h @@ -135,6 +135,9 @@ public: // Process members // for (const auto &m : c.members) { + if (m.is_static) + ostr << "{static} "; + ostr << to_string(m.scope) << m.type << " " << m.name << std::endl; } diff --git a/src/uml/class_diagram_model.h b/src/uml/class_diagram_model.h index 1431a01c..4f5de56b 100644 --- a/src/uml/class_diagram_model.h +++ b/src/uml/class_diagram_model.h @@ -54,6 +54,7 @@ struct class_element { struct class_member : public class_element { bool is_relationship{false}; + bool is_static{false}; }; struct method_argument { diff --git a/src/uml/class_diagram_visitor.h b/src/uml/class_diagram_visitor.h index 4d9ea354..1ae65a18 100644 --- a/src/uml/class_diagram_visitor.h +++ b/src/uml/class_diagram_visitor.h @@ -182,6 +182,7 @@ static enum CXChildVisitResult class_visitor( ret = CXChildVisit_Continue; break; } + case CXCursor_VarDecl: case CXCursor_FieldDecl: { visit_if_cursor_valid(cursor, [c](cx::cursor cursor) { auto t = cursor.type(); @@ -190,6 +191,7 @@ static enum CXChildVisitResult class_visitor( m.type = cursor.type().spelling(); m.scope = cx_access_specifier_to_scope(cursor.cxxaccess_specifier()); + m.is_static = cursor.is_static(); spdlog::info("Adding member {} {}::{}", m.type, c->name, cursor.spelling()); @@ -215,11 +217,7 @@ static enum CXChildVisitResult class_visitor( t = t.pointee_type(); continue; } - /*else if(t.kind == CXType_Elaborated) { - t = clang_Type_getNamedType(t); - continue; - }*/ - else /*if (t.kind == CXType_Record) */ { + else { spdlog::error("UNKNOWN CXTYPE: {}", t.kind()); class_relationship r; auto template_argument_count = @@ -259,9 +257,6 @@ static enum CXChildVisitResult class_visitor( spdlog::debug( "Adding relationship to: {}", r.destination); } - // else { - // spdlog::error("UNKNOWN CXTYPE: {}", t.kind); - //} break; } } diff --git a/tests/t00003/t00003.cc b/tests/t00003/t00003.cc index a9d61d96..e1c93197 100644 --- a/tests/t00003/t00003.cc +++ b/tests/t00003/t00003.cc @@ -1,3 +1,5 @@ +#include + namespace clanguml { namespace t00003 { @@ -11,20 +13,28 @@ public: void basic_method() {} static int static_method() { return 0; } void const_method() const {} + auto auto_method() { return 1; } int public_member; + static int static_int; + static const int static_const_int = 1; protected: void protected_method() {} int protected_member; + std::function compare = [this](const int v) { + return private_member > v; + }; + private: void private_method() {} int private_member; - int a, b, c; }; + +int A::static_int = 1; } } diff --git a/tests/test_cases.cc b/tests/test_cases.cc index f30d3a0f..4a7721ae 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -204,6 +204,7 @@ TEST_CASE("Test t00003", "[unit-test]") REQUIRE_THAT(puml, Contains("-int a")); REQUIRE_THAT(puml, Contains("-int b")); REQUIRE_THAT(puml, Contains("-int c")); + REQUIRE_THAT(puml, Contains("{static} +int static_int")); save_puml( "./" + config.output_directory + "/" + diagram->name + ".puml", puml);