31 j[
"name"] =
dynamic_cast<const method &
>(c).method_name();
33 else if (c.
type_name() ==
"objc_method") {
34 j[
"name"] =
dynamic_cast<const objc_method &
>(c).method_name();
40 const auto &f =
dynamic_cast<const function &
>(c);
41 if (f.is_cuda_kernel())
42 j[
"is_cuda_kernel"] =
true;
43 if (f.is_cuda_device())
44 j[
"is_cuda_device"] =
true;
50 j[
"participant_id"] = std::to_string(c.
from().
value());
81 LOG_DBG(
"Skipping empty call from '{}' to '{}'", m.
from(), m.
to());
95 .message_name(render_mode);
97 else if (to.value().
type_name() ==
"objc_method") {
99 .message_name(render_mode);
101 else if (
config().combine_free_functions_into_file_participants()) {
102 if (to.value().
type_name() ==
"function") {
104 .message_name(render_mode);
106 else if (to.value().
type_name() ==
"function_template") {
108 .message_name(render_mode);
117 msg[
"type"] =
"message";
118 msg[
"from"][
"activity_id"] = std::to_string(from.value().id().value());
119 msg[
"to"][
"activity_id"] = std::to_string(to.value().
id().
value());
120 if (
const auto &cmt = m.
comment(); cmt.has_value())
121 msg[
"comment"] = cmt.value().at(
"comment");
123 if (from.value().type_name() ==
"method") {
124 const auto &class_participant =
127 msg[
"from"][
"participant_id"] =
128 std::to_string(class_participant.class_id().value());
130 else if (from.value().type_name() ==
"objc_method") {
131 const auto &class_participant =
136 msg[
"from"][
"participant_id"] =
137 std::to_string(class_participant.class_id().value());
139 else if (from.value().type_name() ==
"function" ||
140 from.value().type_name() ==
"function_template") {
141 if (
config().combine_free_functions_into_file_participants()) {
142 const auto &file_participant =
146 msg[
"from"][
"participant_id"] = std::to_string(
150 msg[
"from"][
"participant_id"] =
151 std::to_string(from.value().id().value());
154 else if (from.value().type_name() ==
"lambda") {
155 msg[
"from"][
"participant_id"] =
156 std::to_string(from.value().id().value());
159 if (to.value().
type_name() ==
"method") {
160 const auto &class_participant =
163 msg[
"to"][
"participant_id"] =
164 std::to_string(class_participant.class_id().value());
166 else if (to.value().
type_name() ==
"objc_method") {
167 const auto &class_participant =
172 msg[
"to"][
"participant_id"] =
173 std::to_string(class_participant.class_id().value());
175 else if (to.value().
type_name() ==
"function" ||
176 to.value().
type_name() ==
"function_template") {
177 if (
config().combine_free_functions_into_file_participants()) {
178 const auto &file_participant =
182 msg[
"to"][
"participant_id"] = std::to_string(
186 msg[
"to"][
"participant_id"] =
187 std::to_string(to.value().
id().
value());
190 else if (to.value().
type_name() ==
"lambda") {
191 msg[
"to"][
"participant_id"] = std::to_string(to.value().
id().
value());
194 msg[
"source_location"] =
200 parent[
"messages"].push_back(std::move(msg));
208 const activity &a, std::vector<eid_t> &visited)
const
211 for (
const auto &m : a.
messages()) {
213 case message_t::kCall:
219 case message_t::kElseIf:
220 case message_t::kElse:
223 case message_t::kIfEnd:
226 case message_t::kWhile:
229 case message_t::kWhileEnd:
232 case message_t::kFor:
235 case message_t::kForEnd:
241 case message_t::kDoEnd:
244 case message_t::kTry:
247 case message_t::kCatch:
250 case message_t::kTryEnd:
253 case message_t::kSwitch:
256 case message_t::kCase:
259 case message_t::kSwitchEnd:
262 case message_t::kConditional:
265 case message_t::kConditionalElse:
268 case message_t::kConditionalEnd:
271 case message_t::kNone:
272 case message_t::kReturn:;
287 visited.push_back(m.
from());
302 if (
model().sequences().find(m.
to()) !=
model().sequences().end()) {
303 if (std::find(visited.begin(), visited.end(), m.
to()) ==
306 LOG_DBG(
"Creating activity {} --> {} - missing sequence {}",
313 LOG_DBG(
"Skipping activity {} --> {} - missing sequence {}", m.
from(),
321 nlohmann::json while_block;
322 while_block[
"type"] =
"loop";
323 while_block[
"name"] =
"while";
324 while_block[
"activity_id"] = std::to_string(m.
from().
value());
326 while_block[
"condition_text"] = *text;
342 nlohmann::json for_block;
343 for_block[
"type"] =
"loop";
344 for_block[
"name"] =
"for";
345 for_block[
"activity_id"] = std::to_string(m.
from().
value());
347 for_block[
"condition_text"] = *text;
363 nlohmann::json do_block;
364 do_block[
"type"] =
"loop";
365 do_block[
"name"] =
"do";
366 do_block[
"activity_id"] = std::to_string(m.
from().
value());
368 do_block[
"condition_text"] = *text;
384 nlohmann::json try_block;
385 try_block[
"type"] =
"break";
386 try_block[
"name"] =
"try";
387 try_block[
"activity_id"] = std::to_string(m.
from().
value());
394 nlohmann::json branch;
395 branch[
"type"] =
"main";
407 nlohmann::json branch;
408 branch[
"type"] =
"catch";
426 nlohmann::json if_block;
427 if_block[
"type"] =
"alt";
428 if_block[
"name"] =
"switch";
429 if_block[
"activity_id"] = std::to_string(m.
from().
value());
442 nlohmann::json case_block;
443 case_block[
"type"] =
"case";
461 nlohmann::json if_block;
462 if_block[
"type"] =
"alt";
463 if_block[
"name"] =
"conditional";
464 if_block[
"activity_id"] = std::to_string(m.
from().
value());
466 if_block[
"condition_text"] = *text;
473 nlohmann::json branch;
474 branch[
"type"] =
"consequent";
486 nlohmann::json branch;
487 branch[
"type"] =
"alternative";
489 branch[
"condition_text"] = *text;
519 nlohmann::json branch;
520 branch[
"type"] =
"alternative";
529 nlohmann::json if_block;
530 if_block[
"type"] =
"alt";
531 if_block[
"name"] =
"if";
532 if_block[
"activity_id"] = std::to_string(m.
from().
value());
534 if_block[
"condition_text"] = *text;
541 nlohmann::json branch;
542 branch[
"type"] =
"consequent";
550 nlohmann::json &parent,
const std::string &name)
const
552 auto p =
model().get(name);
554 if (!p.has_value()) {
555 LOG_WARN(
"Cannot find participant {} from `participants_order` option",
564 nlohmann::json & ,
eid_t id,
bool force)
const
566 std::optional<eid_t> participant_id{};
569 for (
const auto pid :
model().active_participants()) {
571 participant_id = pid;
579 if (!participant_id.has_value())
580 return participant_id;
583 return participant_id;
585 const auto &participant =
588 const auto participant_type = participant.
type_name();
590 if (participant_type ==
"method") {
591 auto class_participant_id =
597 LOG_DBG(
"Generating JSON method participant: {}",
599 .get_participant<model::method>(*participant_id)
604 const auto &class_participant =
612 json_[
"participants"].push_back(class_participant);
613 json_[
"participants"].back()[
"activities"].push_back(participant);
616 const auto class_participant_full_name =
619 json_[
"participants"].back().at(
"display_name") =
622 return class_participant_id;
626 for (
auto &p :
json_[
"participants"]) {
628 std::to_string(class_participant_id.value())) {
630 p[
"activities"].push_back(participant);
631 return class_participant_id;
636 if (participant_type ==
"objc_method") {
637 auto class_participant_id =
643 LOG_DBG(
"Generating JSON ObjC method participant: {}",
645 .get_participant<model::objc_method>(*participant_id)
650 const auto &class_participant =
658 json_[
"participants"].push_back(class_participant);
659 json_[
"participants"].back()[
"activities"].push_back(participant);
662 const auto class_participant_full_name =
665 json_[
"participants"].back().at(
"display_name") =
668 return class_participant_id;
672 for (
auto &p :
json_[
"participants"]) {
674 std::to_string(class_participant_id.value())) {
676 p[
"activities"].push_back(participant);
677 return class_participant_id;
682 else if ((participant_type ==
"function" ||
683 participant_type ==
"function_template") &&
684 config().combine_free_functions_into_file_participants()) {
688 const auto &function_participant =
691 const auto file_participant_id =
695 nlohmann::json p = function_participant;
697 const auto file_path =
698 config().make_path_relative(function_participant.file());
701 p[
"name"] = file_path.filename();
704 return participant_id;
706 p[
"id"] = std::to_string(file_participant_id.value());
708 p.erase(
"source_location");
712 p[
"activities"].push_back(participant);
713 json_[
"participants"].push_back(p);
717 return file_participant_id;
721 for (
auto &p :
json_[
"participants"]) {
722 if (p.at(
"id") == std::to_string(file_participant_id.value())) {
724 p[
"activities"].push_back(participant);
729 return file_participant_id;
732 json_[
"participants"].push_back(participant);
733 const auto function_participant_full_name =
736 json_[
"participants"].back().at(
"display_name") =
742 return participant_id;
756 if (
config().using_namespace)
757 parent[
"using_namespace"] =
config().using_namespace().to_string();
759 if (
config().participants_order.has_value) {
760 for (
const auto &p :
config().participants_order()) {
761 LOG_DBG(
"Pregenerating participant {}", p);
773 for (
auto &p :
json_[
"participants"]) {
774 if (p.contains(
"display_name")) {
779 parent[
"participants"] =
json_[
"participants"];
787 std::vector<eid_t> visited_participants;
788 for (
const auto from_id : start_from) {
792 if (!from.has_value()) {
793 LOG_WARN(
"Failed to find participant {} for 'from' "
803 nlohmann::json sequence;
804 sequence[
"from"][
"location"] = from.value().full_name(
false);
805 sequence[
"from"][
"id"] = std::to_string(from_id.value());
813 if (from.value().type_name() ==
"method" ||
814 config().combine_free_functions_into_file_participants()) {
816 sequence[
"return_type"] =
820 parent[
"sequences"].push_back(std::move(sequence));
826 for (
const auto &to_location :
config().to()) {
827 auto to_activity_ids =
model().get_to_activity_ids(to_location);
829 if (to_activity_ids.empty()) {
830 LOG_WARN(
"Failed to find participant matching '{}' for "
832 to_location.location.to_string());
835 for (
const auto to_activity_id : to_activity_ids) {
839 nlohmann::json sequence;
840 sequence[
"to"][
"location"] = to.value().
full_name(
false);
841 sequence[
"to"][
"id"] = std::to_string(to_activity_id.value());
842 sequence[
"message_chains"] = nlohmann::json::array();
846 std::vector<model::message_chain_t> message_chains =
847 model().get_all_from_to_message_chains(
eid_t{}, to_activity_id);
849 for (
const auto &mc : message_chains) {
850 const auto from_activity_id = mc.front().from();
852 if (
model().participants().count(from_activity_id) == 0)
855 nlohmann::json message_chain;
859 for (
const auto &m : mc) {
865 sequence[
"message_chains"].push_back(std::move(message_chain));
870 parent[
"sequences"].push_back(std::move(sequence));
877 for (
const auto &ft :
config().from_to()) {
880 assert(ft.size() == 2);
882 const auto &from_location = ft.front();
883 const auto &to_location = ft.back();
885 auto from_activity_ids =
model().get_from_activity_ids(from_location);
886 auto to_activity_ids =
model().get_to_activity_ids(to_location);
888 if (from_activity_ids.empty()) {
891 fmt::format(
"Failed to find participant matching '{}' for "
892 "'from' condition: ",
893 from_location.location.to_string()));
896 if (from_activity_ids.empty() || to_activity_ids.empty()) {
899 fmt::format(
"Failed to find participant matching '{}' for "
901 to_location.location.to_string()));
904 for (
const auto from_activity_id : from_activity_ids) {
905 if (
model().participants().count(from_activity_id) == 0)
911 for (
const auto to_activity_id : to_activity_ids) {
912 if (
model().participants().count(to_activity_id) == 0)
918 auto message_chains_unique =
919 model().get_all_from_to_message_chains(
920 from_activity_id, to_activity_id);
922 nlohmann::json sequence;
923 sequence[
"from_to"][
"from"][
"location"] =
924 from.value().full_name(
false);
925 sequence[
"from_to"][
"from"][
"id"] =
926 std::to_string(from_activity_id.value());
927 sequence[
"from_to"][
"to"][
"location"] =
928 to.value().full_name(
false);
929 sequence[
"from_to"][
"to"][
"id"] =
930 std::to_string(to_activity_id.value());
934 sequence[
"message_chains"] = nlohmann::json::array();
936 for (
const auto &mc : message_chains_unique) {
937 nlohmann::json message_chain;
941 for (
const auto &m : mc) {
947 sequence[
"message_chains"].push_back(
948 std::move(message_chain));
953 parent[
"sequences"].push_back(std::move(sequence));
961 std::vector<eid_t> start_from;
962 for (
const auto &sf :
config().from()) {
963 if (sf.location_type == location_t::function) {
965 for (
const auto &[k, v] :
model().sequences()) {
966 if (
model().participants().count(v.from()) == 0)
969 const auto &caller = *
model().participants().at(v.from());
970 std::string vfrom = caller.full_name(
false);
971 if (sf.location == vfrom) {
972 LOG_DBG(
"Found sequence diagram start point: {}", k);
973 start_from.push_back(k);
981 fmt::format(
"Failed to find participant matching '{}' for "
982 "'from' condition: ",
983 sf.location.to_string()));
992 auto result =
config().simplify_template_type(full_name);
993 result =
config().using_namespace().relative(result);