Extended generation of method attributes (#142)

This commit is contained in:
Bartek Kryza
2023-05-29 23:19:28 +02:00
parent 75b900bf46
commit 097f7a11ed
13 changed files with 158 additions and 11 deletions

View File

@@ -128,7 +128,7 @@ $ clang-uml --add-compile-flag -Wno-implicit-const-int-float-conversion \
Please note that if your `compile_commands.json` already contains - for instance
`-Wshadow` - then you also have to remove it, i.e.:
```
```yaml
add_compile_flags:
- -Wno-implicit-const-int-float-conversion
- -Wno-shadow

View File

@@ -54,12 +54,19 @@ void to_json(nlohmann::json &j, const class_method &c)
{
j = dynamic_cast<const class_element &>(c);
j["is_static"] = c.is_static();
j["is_const"] = c.is_const();
j["is_defaulted"] = c.is_defaulted();
j["is_pure_virtual"] = c.is_pure_virtual();
j["is_virtual"] = c.is_virtual();
j["is_implicit"] = c.is_implicit();
j["is_const"] = c.is_const();
j["is_defaulted"] = c.is_defaulted();
j["is_deleted"] = c.is_deleted();
j["is_static"] = c.is_static();
j["is_noexcept"] = c.is_noexcept();
j["is_constexpr"] = c.is_constexpr();
j["is_consteval"] = c.is_consteval();
j["is_constructor"] = c.is_constructor();
j["is_move_assignment"] = c.is_move_assignment();
j["is_copy_assignment"] = c.is_copy_assignment();
j["is_operator"] = c.is_operator();
j["parameters"] = c.parameters();
}

View File

@@ -189,9 +189,17 @@ void generator::generate(const class_ &c, std::ostream &ostr) const
}
ostr << ")";
if (m.is_constexpr())
ostr << " constexpr";
else if (m.is_consteval())
ostr << " consteval";
if (m.is_const())
ostr << " const";
if (m.is_noexcept())
ostr << " noexcept";
assert(!(m.is_pure_virtual() && m.is_defaulted()));
if (m.is_pure_virtual())
@@ -199,6 +207,8 @@ void generator::generate(const class_ &c, std::ostream &ostr) const
if (m.is_defaulted())
ostr << " = default";
else if (m.is_deleted())
ostr << " = deleted";
ostr << " : " << type;

View File

@@ -48,10 +48,57 @@ void class_method::is_defaulted(bool is_defaulted)
is_defaulted_ = is_defaulted;
}
bool class_method::is_deleted() const { return is_deleted_; }
void class_method::is_deleted(bool is_deleted) { is_deleted_ = is_deleted; }
bool class_method::is_static() const { return is_static_; }
void class_method::is_static(bool is_static) { is_static_ = is_static; }
bool class_method::is_constexpr() const { return is_constexpr_; }
void class_method::is_constexpr(bool is_constexpr)
{
is_constexpr_ = is_constexpr;
}
bool class_method::is_consteval() const { return is_consteval_; }
void class_method::is_consteval(bool is_consteval)
{
is_consteval_ = is_consteval;
}
bool class_method::is_noexcept() const { return is_noexcept_; }
void class_method::is_noexcept(bool is_noexcept) { is_noexcept_ = is_noexcept; }
bool class_method::is_constructor() const { return is_constructor_; }
void class_method::is_constructor(bool is_constructor)
{
is_constructor_ = is_constructor;
}
bool class_method::is_move_assignment() const { return is_move_assignment_; }
void class_method::is_move_assignment(bool is_move_assignment)
{
is_move_assignment_ = is_move_assignment;
}
bool class_method::is_copy_assignment() const { return is_copy_assignment_; }
void class_method::is_copy_assignment(bool is_copy_assignment)
{
is_copy_assignment_ = is_copy_assignment;
}
bool class_method::is_operator() const { return is_operator_; }
void class_method::is_operator(bool is_operator) { is_operator_ = is_operator; }
const std::vector<method_parameter> &class_method::parameters() const
{
return parameters_;

View File

@@ -48,9 +48,33 @@ public:
bool is_defaulted() const;
void is_defaulted(bool is_defaulted);
bool is_deleted() const;
void is_deleted(bool is_deleted);
bool is_static() const;
void is_static(bool is_static);
bool is_constexpr() const;
void is_constexpr(bool is_constexpr);
bool is_consteval() const;
void is_consteval(bool is_consteval);
bool is_noexcept() const;
void is_noexcept(bool is_noexcept);
bool is_constructor() const;
void is_constructor(bool is_constructor);
bool is_move_assignment() const;
void is_move_assignment(bool is_move_assignment);
bool is_copy_assignment() const;
void is_copy_assignment(bool is_copy_assignment);
bool is_operator() const;
void is_operator(bool is_operator);
const std::vector<method_parameter> &parameters() const;
void add_parameter(method_parameter &&parameter);
@@ -61,6 +85,14 @@ private:
bool is_virtual_{false};
bool is_const_{false};
bool is_defaulted_{false};
bool is_deleted_{false};
bool is_static_{false};
bool is_noexcept_{false};
bool is_constexpr_{false};
bool is_consteval_{false};
bool is_constructor_{false};
bool is_move_assignment_{false};
bool is_copy_assignment_{false};
bool is_operator_{false};
};
} // namespace clanguml::class_diagram::model

View File

@@ -55,8 +55,12 @@ std::string method_parameter::to_string(
auto name_ns =
using_namespace.relative(common::model::namespace_{name()}.to_string());
if (default_value().empty())
if (default_value().empty()) {
if (name_ns.empty())
return type_ns;
return fmt::format("{} {}", type_ns, name_ns);
}
return fmt::format("{} {} = {}", type_ns, name_ns, default_value());
}

View File

@@ -1283,11 +1283,21 @@ void translation_unit_visitor::process_method(
class_method method{common::access_specifier_to_access_t(mf.getAccess()),
util::trim(method_name), method_return_type};
const bool is_constructor = c.name() == method_name;
method.is_pure_virtual(mf.isPure());
method.is_virtual(mf.isVirtual());
method.is_const(mf.isConst());
method.is_defaulted(mf.isDefaulted());
method.is_deleted(mf.isDeleted());
method.is_static(mf.isStatic());
method.is_operator(mf.isOverloadedOperator());
method.is_constexpr(mf.isConstexprSpecified() && !is_constructor);
method.is_consteval(mf.isConsteval());
method.is_constructor(is_constructor);
method.is_move_assignment(mf.isMoveAssignmentOperator());
method.is_copy_assignment(mf.isCopyAssignmentOperator());
method.is_noexcept(isNoexceptExceptionSpec(mf.getExceptionSpecType()));
process_comment(mf, method);

View File

@@ -12,7 +12,7 @@ public:
{
}
A(A &&) = default;
A(const A &) = default;
A(const A &) = delete;
virtual ~A() = default;
void basic_method() { }
@@ -20,6 +20,17 @@ public:
void const_method() const { }
auto auto_method() { return 1; }
A &operator++()
{
private_member++;
return *this;
}
A &operator=(A &&other) noexcept { return *this; }
A &operator=(A &other) noexcept { return *this; }
constexpr std::size_t size() const { return private_member; }
auto double_int(const int i) { return 2 * i; }
auto sum(const double a, const double b) { return a_ + b_ + c_; }

View File

@@ -44,6 +44,10 @@ TEST_CASE("t00003", "[test-case][class]")
REQUIRE_THAT(puml, !IsDependency(_A("A"), _A("A")));
REQUIRE_THAT(puml, (IsMethod<Public, Default>("A")));
REQUIRE_THAT(puml, (IsMethod<Public, Default>("A", "void", "A &&")));
REQUIRE_THAT(
puml, (IsMethod<Public, Deleted>("A", "void", "const A &")));
REQUIRE_THAT(puml, (IsMethod<Public, Default>("~A")));
REQUIRE_THAT(puml, (IsMethod<Public>("basic_method")));
@@ -55,6 +59,9 @@ TEST_CASE("t00003", "[test-case][class]")
(IsMethod<Public>("default_string", "std::string",
"int i, std::string s = \"abc\"")));
REQUIRE_THAT(
puml, (IsMethod<Public, Const, Constexpr>("size", "std::size_t")));
REQUIRE_THAT(puml, (IsMethod<Protected>("protected_method")));
REQUIRE_THAT(puml, (IsMethod<Private>("private_method")));
REQUIRE_THAT(puml, (IsField<Public>("public_member", "int")));

View File

@@ -68,12 +68,14 @@ TEST_CASE("t00064", "[test-case][class]")
REQUIRE_THAT(puml,
(IsMethod<Public>("getp", "value_type const*", "unsigned int i")));
REQUIRE_THAT(puml,
(IsMethod<Public>("find", "unsigned int", "value_type const& v")));
(IsMethod<Public, Constexpr>(
"find", "unsigned int", "value_type const& v")));
#else
REQUIRE_THAT(puml,
(IsMethod<Public>("getp", "const value_type *", "unsigned int i")));
REQUIRE_THAT(puml,
(IsMethod<Public>("find", "unsigned int", "const value_type & v")));
(IsMethod<Public, Constexpr>(
"find", "unsigned int", "const value_type & v")));
#endif
save_puml(

View File

@@ -103,8 +103,16 @@ struct Static { };
struct Const { };
struct Constexpr { };
struct Consteval { };
struct Noexcept { };
struct Default { };
struct Deleted { };
struct HasCallWithResultMatcher : ContainsMatcher {
HasCallWithResultMatcher(
CasedString const &comparator, CasedString const &resultComparator)
@@ -530,6 +538,12 @@ ContainsMatcher IsMethod(std::string const &name,
pattern += "(" + params + ")";
if constexpr (has_type<Constexpr, Ts...>())
pattern += " constexpr";
if constexpr (has_type<Consteval, Ts...>())
pattern += " consteval";
if constexpr (has_type<Const, Ts...>())
pattern += " const";
@@ -539,6 +553,9 @@ ContainsMatcher IsMethod(std::string const &name,
if constexpr (has_type<Default, Ts...>())
pattern += " = default";
if constexpr (has_type<Deleted, Ts...>())
pattern += " = deleted";
pattern += " : " + type;
return ContainsMatcher(CasedString(pattern, caseSensitivity));

View File

@@ -4,7 +4,7 @@ test_cases:
title: Basic class inheritance
description:
- name: t00003
title: Class field and methods
title: Class fields and methods
description:
- name: t00004
title: Nested classes and enums