diff --git a/src/cx/cursor.h b/src/cx/cursor.h index 246ff152..b2b48e84 100644 --- a/src/cx/cursor.h +++ b/src/cx/cursor.h @@ -194,6 +194,8 @@ public: return clang_CXXMethod_isDefaulted(m_cursor); } + bool is_method_parameter() const { return kind() == CXCursor_ParmDecl; } + CXVisibilityKind visibitity() const { return clang_getCursorVisibility(m_cursor); @@ -266,6 +268,20 @@ public: return res; } + std::string default_value() const + { + assert(is_method_parameter()); + + auto toks = tokenize(); + std::string res; + auto it = std::find(toks.begin(), toks.end(), "="); + if (it != toks.end()) { + res = fmt::format("{}", fmt::join(it + 1, toks.end(), "")); + } + + return res; + } + std::vector tokenize_template_parameters() const { auto toks = tokenize(); diff --git a/src/puml/class_diagram_generator.h b/src/puml/class_diagram_generator.h index a95ff172..31e5771d 100644 --- a/src/puml/class_diagram_generator.h +++ b/src/puml/class_diagram_generator.h @@ -136,8 +136,9 @@ public: if (true) { // TODO: add option to disable parameter generation std::vector params; std::transform(m.parameters.begin(), m.parameters.end(), - std::back_inserter(params), - [](const auto &mp) { return mp.to_string(); }); + std::back_inserter(params), [this](const auto &mp) { + return mp.to_string(m_config.using_namespace); + }); ostr << fmt::format("{}", fmt::join(params, ", ")); } ostr << ")"; diff --git a/src/uml/class_diagram_model.h b/src/uml/class_diagram_model.h index 9968d55e..3828faad 100644 --- a/src/uml/class_diagram_model.h +++ b/src/uml/class_diagram_model.h @@ -82,12 +82,15 @@ struct method_parameter { std::string name; std::string default_value; - std::string to_string() const + std::string to_string( + const std::vector &using_namespaces) const { + using namespace clanguml::util; + auto t = ns_relative(using_namespaces, type); if (default_value.empty()) - return fmt::format("{} {}", type, name); + return fmt::format("{} {}", t, name); - return fmt::format("{} {} = {}", type, name, default_value); + return fmt::format("{} {} = {}", t, name, default_value); } }; diff --git a/src/uml/class_diagram_visitor.h b/src/uml/class_diagram_visitor.h index f17cd3ad..0d75d8b0 100644 --- a/src/uml/class_diagram_visitor.h +++ b/src/uml/class_diagram_visitor.h @@ -223,6 +223,7 @@ static enum CXChildVisitResult method_parameter_visitor( method_parameter mp; mp.name = cursor.spelling(); mp.type = cursor.type().spelling(); + mp.default_value = cursor.default_value(); ctx->element.parameters.emplace_back(std::move(mp)); diff --git a/src/util/util.cc b/src/util/util.cc index 42169939..a992797c 100644 --- a/src/util/util.cc +++ b/src/util/util.cc @@ -67,6 +67,8 @@ std::string ns_relative( std::sort(namespaces_sorted.rbegin(), namespaces_sorted.rend()); + auto res = n; + for (const auto &ns : namespaces_sorted) { if (ns.empty()) continue; @@ -74,15 +76,14 @@ std::string ns_relative( if (n == ns) return split(n, "::").back(); - if (n.find(ns) == 0) { - if (n.size() <= ns.size() + 2) - return ""; - - return n.substr(ns.size() + 2); + auto ns_prefix = ns + "::"; + auto it = res.find(ns_prefix); + while (it != std::string::npos) { + res.erase(it, ns_prefix.size()); + it = res.find(ns_prefix); } } - - return n; + return res; } } } diff --git a/tests/t00003/t00003.cc b/tests/t00003/t00003.cc index 120976eb..b3176941 100644 --- a/tests/t00003/t00003.cc +++ b/tests/t00003/t00003.cc @@ -18,6 +18,12 @@ public: auto double_int(const int i) { return 2 * i; } auto sum(const double a, const double b) { return a + b; } + auto default_int(int i = 12) { return i + 10; } + auto default_string(int i, std::string s = "abc") + { + return s + std::to_string(i); + } + int public_member; static int static_int; static const int static_const_int = 1; diff --git a/tests/test_util.cc b/tests/test_util.cc index 76e70929..1cd75d0f 100644 --- a/tests/test_util.cc +++ b/tests/test_util.cc @@ -39,4 +39,10 @@ TEST_CASE("Test ns_relative", "[unit-test]") using namespace clanguml::util; CHECK(ns_relative({}, "std::vector") == "std::vector"); + CHECK(ns_relative({"std"}, "std::vector") == "vector"); + CHECK(ns_relative({"std"}, "const std::vector&") == "const vector&"); + CHECK(ns_relative({"std", "clanguml::t0"}, + "static const std::vector&") == + "static const vector&"); + CHECK(ns_relative({"clanguml::t0"}, "clanguml::t0") == "t0"); }