31 std::vector<std::vector<eid_t>> all_message_chains;
32 std::vector<eid_t> current_chain;
38 current_chain.push_back(node.activity_id);
40 if (node.callers.empty()) {
41 auto reversed = current_chain;
42 std::reverse(reversed.begin(), reversed.end());
43 all_message_chains.emplace_back(std::move(reversed));
46 for (
const auto &child : node.callers) {
52 current_chain.pop_back();
58 return all_message_chains;
67 const std::string &full_name)
const
93 const auto participant_id = p->id();
97 assert(participant_id.is_global());
100 LOG_DBG(
"Adding '{}' participant: {}, {} [{}]", p->type_name(),
101 p->full_name(
false), p->id(),
102 p->type_name() ==
"method"
157 std::move(
message), start_type, current_messages);
164 const auto caller_id = m.from();
169 if (current_messages.back().type() == message_t::kCase) {
173 current_messages.emplace_back(std::move(m));
190const std::map<eid_t, std::unique_ptr<participant>> &
213 std::vector<std::string> result;
218 const auto &full_name = from_activity.full_name(
false);
219 if (!full_name.empty())
220 result.push_back(full_name);
223 std::sort(result.begin(), result.end());
224 result.erase(std::unique(result.begin(), result.end()), result.end());
231 std::vector<std::string> result;
234 for (
const auto &m : act.messages()) {
237 const auto &full_name = to_activity.full_name(
false);
238 if (!full_name.empty())
239 result.push_back(full_name);
244 std::sort(result.begin(), result.end());
245 result.erase(std::unique(result.begin(), result.end()), result.end());
253 std::vector<eid_t> to_activities{};
256 for (
const auto &m : v.messages()) {
261 std::string vto = callee.full_name(
false);
264 "Found sequence diagram end point '{}': {}", vto, m.to());
265 to_activities.push_back(m.to());
270 if (to_activities.empty()) {
271 LOG_WARN(
"Failed to find 'to' participant {} for to "
278 return to_activities;
284 std::vector<eid_t> from_activities{};
291 std::string vfrom = caller.full_name(
false);
292 if (from_location.
location == vfrom) {
293 LOG_DBG(
"Found sequence diagram start point '{}': {}", vfrom, k);
294 from_activities.push_back(k);
298 if (from_activities.empty()) {
299 LOG_WARN(
"Failed to find 'from' participant {} for from "
306 return from_activities;
310 std::set<eid_t> visited_callers)
const
321 for (
const auto &caller : callers) {
322 if (visited_callers.count(caller) > 0) {
332 node.
callers.emplace_back(std::move(caller_node));
337 const eid_t from_activity,
const eid_t to_activity)
const
340 std::vector<message_chain_t> message_chains;
348 for (
const auto &m : v.messages()) {
352 if (m.to() == to_activity) {
355 target_roots.
callers.emplace_back(std::move(node));
362 for (
auto &caller : target_roots.
callers)
370 sort(begin(activity_id_chains), end(activity_id_chains));
371 activity_id_chains.erase(
372 unique(begin(activity_id_chains), end(activity_id_chains)),
373 end(activity_id_chains));
376 for (
const auto &chain : activity_id_chains) {
378 for (
auto it = begin(chain); it != end(chain); it++) {
379 const auto next_it = it + 1;
380 if (next_it == end(chain))
387 auto to_id = *(next_it);
391 for (
const auto &m : act.messages()) {
392 if (m.to() == to_id) {
393 message_chain.push_back(m);
398 message_chains.emplace_back(std::move(message_chain));
402 std::vector<message_chain_t> message_chains_filtered{};
404 for (
auto &mc : message_chains) {
410 if (from_activity.
value() == 0 ||
411 (mc.front().from() == from_activity)) {
412 message_chains_filtered.push_back(mc);
416 int message_chain_index{};
417 for (
const auto &mc : message_chains_filtered) {
418 LOG_INFO(
"\t{}: {}", message_chain_index++,
419 fmt::join(util::map<std::string>(mc,
426 return message_chains_filtered;
436 std::map<eid_t, activity> activities;
437 std::map<eid_t, std::unique_ptr<participant>>
participants;
444 auto maybe_lambda_activity = get_participant<model::method>(
id);
446 if (maybe_lambda_activity) {
447 const auto parent_class_id =
448 maybe_lambda_activity.value().class_id();
449 auto maybe_parent_class =
450 get_participant<model::class_>(parent_class_id);
452 if (maybe_parent_class && maybe_parent_class.value().is_lambda()) {
460 for (
auto &m : act.messages()) {
462 auto message_call_to_lambda{
false};
464 message_call_to_lambda =
467 if (!message_call_to_lambda)
468 new_activity.add_message(m);
472 activities.insert({id, std::move(new_activity)});
477 if (
const auto *maybe_class =
479 maybe_class !=
nullptr && maybe_class->
is_lambda()) {
484 if (
const auto *maybe_method =
486 maybe_method !=
nullptr) {
488 get_participant<model::class_>(maybe_method->class_id());
489 if (maybe_class && maybe_class.value().is_lambda())
494 auto participant_id = p->id();
500 if (participants.count(
id) > 0) {
513 bool message_call_to_lambda{
false};
514 auto maybe_lambda_operator = get_participant<model::method>(m.
to());
516 if (maybe_lambda_operator) {
517 const auto parent_class_id = maybe_lambda_operator.value().class_id();
518 auto maybe_parent_class =
519 get_participant<model::class_>(parent_class_id);
521 if (maybe_parent_class && maybe_parent_class.value().is_lambda()) {
527 for (
auto &mm : lambda_operator_activity.messages()) {
529 auto new_message{mm};
531 new_message.set_from(
id);
537 message_call_to_lambda =
true;
541 return message_call_to_lambda;
560 LOG_TRACE(
" Activity id={}, from={}:", act.from(),
561 from_activity.full_name(
false));
563 for (
const auto &
message : act.messages()) {
570 LOG_TRACE(
" Message from={}, from_id={}, "
571 "to={}, to_id={}, name={}, type={}",
572 from_participant.full_name(
false), from_participant.id(),
579 std::string message_comment{
"None"};
581 message_comment = cmt.value().at(
"comment");
584 LOG_TRACE(
" Message from={}, from_id={}, "
585 "to={}, to_id={}, name={}, type={}, comment={}",
586 from_participant.full_name(
false), from_participant.id(),
587 to_participant.full_name(
false), to_participant.id(),
597 std::vector<message> ¤t_messages)
const
599 bool is_empty_statement{
true};
601 auto rit = current_messages.rbegin();
602 for (; rit != current_messages.rend(); rit++) {
603 if (rit->type() == statement_begin) {
607 is_empty_statement =
false;
612 if (is_empty_statement) {
613 current_messages.erase((rit + 1).base(), current_messages.end());
616 current_messages.emplace_back(std::move(m));
629 if (m.type() != message_t::kCall)
632 const auto &to = get_participant<model::participant>(m.to());
633 if (!to || to.value().skip())
636 if (!should_include(to.value())) {
637 LOG_DBG(
"Excluding call from [{}] to {} [{}]", m.from(),
638 to.value().full_name(false), m.to());
647 for (
auto &[
id, act] : activities_) {
648 int64_t block_nest_level{0};
649 std::vector<std::vector<message>> block_message_stack;
652 block_message_stack.emplace_back();
656 for (
auto &m : act.messages()) {
657 if (is_begin_block_message(m.type())) {
659 block_message_stack.push_back({m});
661 else if (is_end_block_message(m.type())) {
664 block_message_stack.back().push_back(m);
668 if (std::count_if(block_message_stack.back().begin(),
669 block_message_stack.back().end(), [](
auto &m) {
670 return m.type() == message_t::kCall;
672 std::copy(block_message_stack.back().begin(),
673 block_message_stack.back().end(),
675 block_message_stack.at(block_nest_level)));
678 block_message_stack.pop_back();
680 assert(block_nest_level >= 0);
683 if (m.type() == message_t::kCall) {
686 auto to_participant =
687 get_participant<sequence_diagram::model::function>(
689 if (to_participant.has_value()) {
690 m.set_return_type(to_participant.value().return_type());
693 block_message_stack.back().push_back(m);
697 act.messages().clear();
699 for (
auto &m : block_message_stack[0]) {
708bool check_diagram_type<clanguml::sequence_diagram::model::diagram>(
diagram_t t)
710 return t == diagram_t::kSequence;