Added start_from function and method entrypoints in sequence diagrams
This commit is contained in:
@@ -248,7 +248,7 @@ void generator::generate(std::ostream &ostr) const
|
||||
visited_participants;
|
||||
|
||||
const auto &from =
|
||||
m_model.get_participant<model::participant>(start_from);
|
||||
m_model.get_participant<model::function>(start_from);
|
||||
|
||||
if (!from.has_value()) {
|
||||
LOG_WARN("Failed to find participant {} for start_from "
|
||||
@@ -261,11 +261,29 @@ void generator::generate(std::ostream &ostr) const
|
||||
|
||||
std::string from_alias = generate_alias(from.value());
|
||||
|
||||
if (from.value().type_name() == "method" ||
|
||||
m_config.combine_free_functions_into_file_participants()) {
|
||||
ostr << "[->"
|
||||
<< " " << from_alias << " : "
|
||||
<< from.value().message_name(
|
||||
model::function::message_render_mode::full)
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
ostr << "activate " << from_alias << std::endl;
|
||||
|
||||
generate_activity(
|
||||
m_model.sequences[start_from], ostr, visited_participants);
|
||||
|
||||
if (from.value().type_name() == "method" ||
|
||||
m_config.combine_free_functions_into_file_participants()) {
|
||||
|
||||
if (!from.value().is_void()) {
|
||||
ostr << "[<--"
|
||||
<< " " << from_alias << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
ostr << "deactivate " << from_alias << std::endl;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -57,6 +57,10 @@ void template_trait::add_template(
|
||||
templates_.push_back(std::move(tmplt));
|
||||
}
|
||||
|
||||
bool template_trait::is_implicit() const { return is_implicit_; }
|
||||
|
||||
void template_trait::set_implicit(bool implicit) { is_implicit_ = implicit; }
|
||||
|
||||
const std::vector<class_diagram::model::template_parameter> &
|
||||
template_trait::templates() const
|
||||
{
|
||||
@@ -95,6 +99,12 @@ int template_trait::calculate_template_specialization_match(
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string participant::to_string() const
|
||||
{
|
||||
return fmt::format(
|
||||
"Participant '{}': id={} name={}", type_name(), id(), full_name(false));
|
||||
}
|
||||
|
||||
class_::class_(const common::model::namespace_ &using_namespace)
|
||||
: participant{using_namespace}
|
||||
{
|
||||
@@ -154,6 +164,14 @@ std::string class_::full_name(bool relative) const
|
||||
return res;
|
||||
}
|
||||
|
||||
bool class_::is_alias() const { return is_alias_; }
|
||||
|
||||
void class_::is_alias(bool alias) { is_alias_ = alias; }
|
||||
|
||||
bool class_::is_lambda() const { return is_lambda_; }
|
||||
|
||||
void class_::is_lambda(bool is_lambda) { is_lambda_ = is_lambda; }
|
||||
|
||||
bool operator==(const class_ &l, const class_ &r) { return l.id() == r.id(); }
|
||||
|
||||
function::function(const common::model::namespace_ &using_namespace)
|
||||
@@ -173,11 +191,38 @@ std::string function::full_name_no_ns() const
|
||||
fmt::join(parameters_, ","), is_const() ? " const" : "");
|
||||
}
|
||||
|
||||
std::string function::message_name(message_render_mode mode) const
|
||||
{
|
||||
if (mode == message_render_mode::no_arguments) {
|
||||
return fmt::format("{}(){}", name(), is_const() ? " const" : "");
|
||||
}
|
||||
|
||||
return fmt::format("{}({}){}", name(), fmt::join(parameters_, ","),
|
||||
is_const() ? " const" : "");
|
||||
}
|
||||
|
||||
bool function::is_const() const { return is_const_; }
|
||||
|
||||
void function::is_const(bool c) { is_const_ = c; }
|
||||
|
||||
bool function::is_void() const { return is_void_; }
|
||||
|
||||
void function::is_void(bool v) { is_void_ = v; }
|
||||
|
||||
void function::add_parameter(const std::string &a) { parameters_.push_back(a); }
|
||||
|
||||
const std::vector<std::string> &function::parameters() const
|
||||
{
|
||||
return parameters_;
|
||||
}
|
||||
|
||||
method::method(const common::model::namespace_ &using_namespace)
|
||||
: function{using_namespace}
|
||||
{
|
||||
}
|
||||
|
||||
const std::string method::method_name() const { return method_name_; }
|
||||
|
||||
std::string method::alias() const
|
||||
{
|
||||
assert(class_id_ >= 0);
|
||||
@@ -185,6 +230,41 @@ std::string method::alias() const
|
||||
return fmt::format("C_{:022}", class_id_);
|
||||
}
|
||||
|
||||
void method::set_method_name(const std::string &name) { method_name_ = name; }
|
||||
|
||||
void method::set_class_id(diagram_element::id_t id) { class_id_ = id; }
|
||||
|
||||
void method::set_class_full_name(const std::string &name)
|
||||
{
|
||||
class_full_name_ = name;
|
||||
}
|
||||
|
||||
const auto &method::class_full_name() const { return class_full_name_; }
|
||||
|
||||
std::string method::full_name(bool /*relative*/) const
|
||||
{
|
||||
return fmt::format("{}::{}({}){}", class_full_name(), method_name(),
|
||||
fmt::join(parameters(), ","), is_const() ? " const" : "");
|
||||
}
|
||||
|
||||
std::string method::message_name(message_render_mode mode) const
|
||||
{
|
||||
if (mode == message_render_mode::no_arguments) {
|
||||
return fmt::format("{}(){}", method_name(), is_const() ? " const" : "");
|
||||
}
|
||||
|
||||
return fmt::format("{}({}){}", method_name(), fmt::join(parameters(), ","),
|
||||
is_const() ? " const" : "");
|
||||
}
|
||||
|
||||
class_::diagram_element::id_t method::class_id() const { return class_id_; }
|
||||
|
||||
std::string method::to_string() const
|
||||
{
|
||||
return fmt::format("Participant '{}': id={}, name={}, class_id={}",
|
||||
type_name(), id(), full_name(false), class_id());
|
||||
}
|
||||
|
||||
function_template::function_template(
|
||||
const common::model::namespace_ &using_namespace)
|
||||
: function{using_namespace}
|
||||
@@ -233,4 +313,19 @@ std::string function_template::full_name_no_ns() const
|
||||
return ostr.str();
|
||||
}
|
||||
|
||||
std::string function_template::message_name(message_render_mode mode) const
|
||||
{
|
||||
std::ostringstream s;
|
||||
render_template_params(s, using_namespace(), true);
|
||||
std::string template_params = s.str();
|
||||
|
||||
if (mode == message_render_mode::no_arguments) {
|
||||
return fmt::format(
|
||||
"{}{}(){}", name(), template_params, is_const() ? " const" : "");
|
||||
}
|
||||
|
||||
return fmt::format("{}{}({}){}", name(), template_params,
|
||||
fmt::join(parameters(), ","), is_const() ? " const" : "");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -42,9 +42,9 @@ struct template_trait {
|
||||
int calculate_template_specialization_match(
|
||||
const template_trait &other, const std::string &full_name) const;
|
||||
|
||||
bool is_implicit() const { return is_implicit_; }
|
||||
bool is_implicit() const;
|
||||
|
||||
void set_implicit(bool implicit) { is_implicit_ = implicit; }
|
||||
void set_implicit(bool implicit);
|
||||
|
||||
private:
|
||||
std::vector<class_diagram::model::template_parameter> templates_;
|
||||
@@ -74,11 +74,7 @@ struct participant : public common::model::element,
|
||||
|
||||
std::string type_name() const override { return "participant"; }
|
||||
|
||||
virtual std::string to_string() const
|
||||
{
|
||||
return fmt::format("Participant '{}': id={} name={}", type_name(), id(),
|
||||
full_name(false));
|
||||
}
|
||||
virtual std::string to_string() const;
|
||||
|
||||
stereotype_t stereotype_{stereotype_t::participant};
|
||||
};
|
||||
@@ -111,13 +107,13 @@ public:
|
||||
|
||||
bool is_abstract() const;
|
||||
|
||||
bool is_alias() const { return is_alias_; }
|
||||
bool is_alias() const;
|
||||
|
||||
void is_alias(bool alias) { is_alias_ = alias; }
|
||||
void is_alias(bool alias);
|
||||
|
||||
bool is_lambda() const { return is_lambda_; }
|
||||
bool is_lambda() const;
|
||||
|
||||
void is_lambda(bool is_lambda) { is_lambda_ = is_lambda; }
|
||||
void is_lambda(bool is_lambda);
|
||||
|
||||
private:
|
||||
bool is_struct_{false};
|
||||
@@ -154,26 +150,23 @@ struct function : public participant {
|
||||
|
||||
std::string full_name_no_ns() const override;
|
||||
|
||||
virtual std::string message_name(message_render_mode mode) const
|
||||
{
|
||||
if (mode == message_render_mode::no_arguments) {
|
||||
return fmt::format("{}(){}", name(), is_const() ? " const" : "");
|
||||
}
|
||||
virtual std::string message_name(message_render_mode mode) const;
|
||||
|
||||
return fmt::format("{}({}){}", name(), fmt::join(parameters_, ","),
|
||||
is_const() ? " const" : "");
|
||||
}
|
||||
bool is_const() const;
|
||||
|
||||
bool is_const() const { return is_const_; }
|
||||
void is_const(bool c);
|
||||
|
||||
void is_const(bool c) { is_const_ = c; }
|
||||
bool is_void() const;
|
||||
|
||||
void add_parameter(const std::string &a) { parameters_.push_back(a); }
|
||||
void is_void(bool v);
|
||||
|
||||
const std::vector<std::string> ¶meters() const { return parameters_; }
|
||||
void add_parameter(const std::string &a);
|
||||
|
||||
const std::vector<std::string> ¶meters() const;
|
||||
|
||||
private:
|
||||
bool is_const_{false};
|
||||
bool is_void_{false};
|
||||
std::vector<std::string> parameters_;
|
||||
};
|
||||
|
||||
@@ -187,45 +180,25 @@ struct method : public function {
|
||||
|
||||
std::string type_name() const override { return "method"; }
|
||||
|
||||
const std::string method_name() const { return method_name_; }
|
||||
const std::string method_name() const;
|
||||
|
||||
std::string alias() const override;
|
||||
|
||||
void set_method_name(const std::string &name) { method_name_ = name; }
|
||||
void set_method_name(const std::string &name);
|
||||
|
||||
void set_class_id(diagram_element::id_t id) { class_id_ = id; }
|
||||
void set_class_id(diagram_element::id_t id);
|
||||
|
||||
void set_class_full_name(const std::string &name)
|
||||
{
|
||||
class_full_name_ = name;
|
||||
}
|
||||
void set_class_full_name(const std::string &name);
|
||||
|
||||
const auto &class_full_name() const { return class_full_name_; }
|
||||
const auto &class_full_name() const;
|
||||
|
||||
std::string full_name(bool /*relative*/) const override
|
||||
{
|
||||
return fmt::format("{}::{}({}){}", class_full_name(), method_name(),
|
||||
fmt::join(parameters(), ","), is_const() ? " const" : "");
|
||||
}
|
||||
std::string full_name(bool /*relative*/) const override;
|
||||
|
||||
std::string message_name(message_render_mode mode) const override
|
||||
{
|
||||
if (mode == message_render_mode::no_arguments) {
|
||||
return fmt::format(
|
||||
"{}(){}", method_name(), is_const() ? " const" : "");
|
||||
}
|
||||
std::string message_name(message_render_mode mode) const override;
|
||||
|
||||
return fmt::format("{}({}){}", method_name(),
|
||||
fmt::join(parameters(), ","), is_const() ? " const" : "");
|
||||
}
|
||||
diagram_element::id_t class_id() const;
|
||||
|
||||
diagram_element::id_t class_id() const { return class_id_; }
|
||||
|
||||
std::string to_string() const override
|
||||
{
|
||||
return fmt::format("Participant '{}': id={}, name={}, class_id={}",
|
||||
type_name(), id(), full_name(false), class_id());
|
||||
}
|
||||
std::string to_string() const override;
|
||||
|
||||
private:
|
||||
diagram_element::id_t class_id_;
|
||||
@@ -247,20 +220,6 @@ struct function_template : public function, public template_trait {
|
||||
|
||||
std::string full_name_no_ns() const override;
|
||||
|
||||
std::string message_name(message_render_mode mode) const override
|
||||
{
|
||||
std::ostringstream s;
|
||||
render_template_params(s, using_namespace(), true);
|
||||
std::string template_params = s.str();
|
||||
|
||||
if (mode == message_render_mode::no_arguments) {
|
||||
return fmt::format("{}{}(){}", name(), template_params,
|
||||
is_const() ? " const" : "");
|
||||
}
|
||||
|
||||
return fmt::format("{}{}({}){}", name(), template_params,
|
||||
fmt::join(parameters(), ","), is_const() ? " const" : "");
|
||||
}
|
||||
std::string message_name(message_render_mode mode) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -307,6 +307,8 @@ bool translation_unit_visitor::VisitCXXMethodDecl(clang::CXXMethodDecl *m)
|
||||
const auto &method_class =
|
||||
get_participant<model::class_>(parent_decl).value();
|
||||
|
||||
m_ptr->is_void(m->getReturnType()->isVoidType());
|
||||
|
||||
m_ptr->set_class_id(method_class.id());
|
||||
m_ptr->set_class_full_name(method_class.full_name(false));
|
||||
m_ptr->set_name(
|
||||
@@ -370,6 +372,8 @@ bool translation_unit_visitor::VisitFunctionDecl(clang::FunctionDecl *f)
|
||||
|
||||
f_ptr->set_id(common::to_id(f_ptr->full_name(false)));
|
||||
|
||||
f_ptr->is_void(f->getReturnType()->isVoidType());
|
||||
|
||||
context().update(f);
|
||||
|
||||
context().set_caller_id(f_ptr->id());
|
||||
@@ -397,6 +401,8 @@ bool translation_unit_visitor::VisitFunctionDecl(clang::FunctionDecl *f)
|
||||
|
||||
f_ptr->set_id(common::to_id(f_ptr->full_name(false)));
|
||||
|
||||
f_ptr->is_void(f->getReturnType()->isVoidType());
|
||||
|
||||
context().update(f);
|
||||
|
||||
context().set_caller_id(f_ptr->id());
|
||||
@@ -441,6 +447,9 @@ bool translation_unit_visitor::VisitFunctionTemplateDecl(
|
||||
|
||||
f_ptr->set_id(common::to_id(f_ptr->full_name(false)));
|
||||
|
||||
f_ptr->is_void(
|
||||
function_template->getAsFunction()->getReturnType()->isVoidType());
|
||||
|
||||
set_source_location(*function_template, *f_ptr);
|
||||
|
||||
context().update(function_template);
|
||||
|
||||
@@ -35,9 +35,10 @@ TEST_CASE("t20005", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, EndsWith("@enduml\n"));
|
||||
|
||||
// Check if all calls exist
|
||||
REQUIRE_THAT(puml, HasEntrypoint(_A("C<T>"), "c(T)"));
|
||||
REQUIRE_THAT(puml, HasCall(_A("C<T>"), _A("B<T>"), "b(T)"));
|
||||
REQUIRE_THAT(puml, HasCall(_A("B<T>"), _A("A<T>"), "a(T)"));
|
||||
|
||||
REQUIRE_THAT(puml, HasExitpoint(_A("C<T>")));
|
||||
save_puml(
|
||||
"./" + config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
}
|
||||
@@ -35,16 +35,19 @@ TEST_CASE("t20017", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, EndsWith("@enduml\n"));
|
||||
|
||||
// Check if all calls exist
|
||||
REQUIRE_THAT(puml, HasEntrypoint(_A("t20017.cc"), "tmain()"));
|
||||
REQUIRE_THAT(puml,
|
||||
HasCall(_A("t20017.cc"), _A("include/t20017_a.h"), "a1(int,int)"));
|
||||
REQUIRE_THAT(
|
||||
puml, HasCall(_A("t20017.cc"), _A("include/t20017_a.h"), "a2(int,int)"));
|
||||
REQUIRE_THAT(puml,
|
||||
HasCall(_A("t20017.cc"), _A("include/t20017_a.h"), "a2(int,int)"));
|
||||
REQUIRE_THAT(puml,
|
||||
HasCall(_A("t20017.cc"), _A("include/t20017_a.h"), "a3(int,int)"));
|
||||
REQUIRE_THAT(puml,
|
||||
HasCall(_A("t20017.cc"), _A("include/t20017_b.h"), "b1(int,int)"));
|
||||
REQUIRE_THAT(puml,
|
||||
HasCall(_A("t20017.cc"), _A("include/t20017_b.h"), "b2<int>(int,int)"));
|
||||
HasCall(
|
||||
_A("t20017.cc"), _A("include/t20017_b.h"), "b2<int>(int,int)"));
|
||||
REQUIRE_THAT(puml, HasExitpoint(_A("t20017.cc")));
|
||||
|
||||
save_puml(
|
||||
"./" + config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
@@ -310,4 +310,4 @@ int main(int argc, char *argv[])
|
||||
clanguml::util::setup_logging(debug_log);
|
||||
|
||||
return session.run();
|
||||
}
|
||||
}
|
||||
@@ -79,26 +79,19 @@ template <typename T, typename... Ts> constexpr bool has_type() noexcept
|
||||
return (std::is_same_v<T, Ts> || ... || false);
|
||||
}
|
||||
|
||||
struct Public {
|
||||
};
|
||||
struct Public { };
|
||||
|
||||
struct Protected {
|
||||
};
|
||||
struct Protected { };
|
||||
|
||||
struct Private {
|
||||
};
|
||||
struct Private { };
|
||||
|
||||
struct Abstract {
|
||||
};
|
||||
struct Abstract { };
|
||||
|
||||
struct Static {
|
||||
};
|
||||
struct Static { };
|
||||
|
||||
struct Const {
|
||||
};
|
||||
struct Const { };
|
||||
|
||||
struct Default {
|
||||
};
|
||||
struct Default { };
|
||||
|
||||
struct HasCallWithResultMatcher : ContainsMatcher {
|
||||
HasCallWithResultMatcher(
|
||||
@@ -144,6 +137,20 @@ auto HasCallWithResponse(std::string const &from, std::string const &to,
|
||||
CasedString(fmt::format("{} --> {}", to, from), caseSensitivity));
|
||||
}
|
||||
|
||||
ContainsMatcher HasEntrypoint(std::string const &to, std::string const &message,
|
||||
CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes)
|
||||
{
|
||||
return ContainsMatcher(
|
||||
CasedString(fmt::format("[-> {} : {}", to, message), caseSensitivity));
|
||||
}
|
||||
|
||||
ContainsMatcher HasExitpoint(std::string const &to,
|
||||
CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes)
|
||||
{
|
||||
return ContainsMatcher(
|
||||
CasedString(fmt::format("[<-- {}", to), caseSensitivity));
|
||||
}
|
||||
|
||||
struct AliasMatcher {
|
||||
AliasMatcher(const std::string &puml_)
|
||||
: puml{split(puml_, "\n")}
|
||||
|
||||
Reference in New Issue
Block a user