23#include <inja/inja.hpp>
32 *
this, config.generate_packages()}
43 if (maybe_link_pattern) {
44 const auto &[link_prefix, link_pattern] = *maybe_link_pattern;
57 if (maybe_tooltip_pattern) {
58 const auto &[tooltip_prefix, tooltip_pattern] = *maybe_tooltip_pattern;
73 std::string class_type{
"class"};
75 class_type =
"abstract";
77 std::string full_name;
78 if (!
config().generate_fully_qualified_name())
83 assert(!full_name.empty());
87 auto fn =
config().simplify_template_type(full_name);
92 fn = fn.substr(0, fn.size() - 2) +
"< >";
95 ostr << class_type <<
" \"" << fn;
97 ostr <<
"\" as " << c.
alias() <<
'\n';
107 if (!
config().generate_fully_qualified_name())
112 ostr <<
"\" as " << e.
alias() <<
'\n';
122 if (!
config().generate_fully_qualified_name())
127 ostr <<
"\" as " << c.
alias() <<
'\n';
145 ostr <<
"\" as " << e.
alias() <<
'\n';
153 std::string class_type{
"class"};
155 class_type =
"abstract";
157 ostr << class_type <<
" " << c.
alias();
160 ostr <<
" " <<
"<<union>>";
162 if (
config().generate_links) {
168 ostr <<
" {" <<
'\n';
184 std::set<std::string> rendered_relations;
186 std::stringstream all_relations_str;
192 LOG_DBG(
"Skipping {} relation from {} to {} due "
194 to_string(r.type()), c.
full_name(
true), r.destination(),
202 std::vector<clanguml::class_diagram::model::class_member> members{
210 for (
const auto &m : members) {
211 if (!
config().include_relations_also_as_members() &&
212 rendered_relations.find(m.name()) != rendered_relations.end())
224 for (
const auto &member : c.
members())
227 for (
const auto &method : c.
methods())
234 const std::vector<class_method> &methods, std::ostream &ostr)
const
236 auto sorted_methods = methods;
239 for (
const auto &m : sorted_methods) {
246 const std::vector<objc_method> &methods, std::ostream &ostr)
const
248 auto sorted_methods = methods;
251 for (
const auto &m : sorted_methods) {
261 const auto &uns =
config().using_namespace();
263 constexpr auto kAbbreviatedMethodArgumentsLength{15};
268 ostr <<
"{abstract} ";
273 std::string type{uns.relative(
config().simplify_template_type(m.
type()))};
275 ostr << plantuml_common::to_plantuml(m.
access()) << m.
name();
282 if (
config().generate_method_arguments() !=
284 std::vector<std::string> params;
286 std::back_inserter(params), [
this](
const auto &mp) {
287 return config().simplify_template_type(
288 mp.to_string(config().using_namespace()));
290 auto args_string = fmt::format(
"{}", fmt::join(params,
", "));
291 if (
config().generate_method_arguments() ==
294 args_string, kAbbreviatedMethodArgumentsLength);
301 ostr <<
" constexpr";
303 ostr <<
" consteval";
317 ostr <<
" = default";
319 ostr <<
" = deleted";
322 ostr <<
" [coroutine]";
324 ostr <<
" : " << type;
326 if (
config().generate_links) {
335 const auto &uns =
config().using_namespace();
342 ostr << plantuml_common::to_plantuml(m.
access())
344 << uns.relative(
config().simplify_template_type(
347 if (
config().generate_links) {
354 std::string class_type{
"class"};
356 ostr << class_type <<
" " << c.
alias() <<
" <<concept>>";
358 if (
config().generate_links) {
364 ostr <<
" {" <<
'\n';
366 if (
config().generate_concept_requirements() &&
368 std::vector<std::string> parameters;
371 parameters.emplace_back(p.to_string(
config().using_namespace()));
374 ostr << fmt::format(
"({})\n", fmt::join(parameters,
","));
386 std::string class_type{
"class"};
388 class_type =
"protocol";
390 ostr << class_type <<
" " << c.
alias();
394 ostr <<
"<<ObjC Protocol>>";
396 ostr <<
"<<ObjC Category>>";
398 ostr <<
"<<ObjC Interface>>";
400 if (
config().generate_links) {
406 ostr <<
" {" <<
'\n';
417 std::set<std::string> rendered_relations;
419 std::stringstream all_relations_str;
425 LOG_DBG(
"Skipping {} relation from {} to {} due "
427 to_string(r.type()), c.
full_name(
true), r.destination(),
435 std::vector<clanguml::class_diagram::model::objc_member> members{
443 for (
const auto &m : members) {
444 if (!
config().include_relations_also_as_members() &&
445 rendered_relations.find(m.name()) != rendered_relations.end())
457 for (
const auto &member : c.
members())
460 for (
const auto &method : c.
methods())
468 const auto &uns =
config().using_namespace();
470 constexpr auto kAbbreviatedMethodArgumentsLength{15};
477 std::string type{uns.relative(
config().simplify_template_type(m.
type()))};
479 ostr << plantuml_common::to_plantuml(m.
access()) << m.
name();
482 if (
config().generate_method_arguments() !=
484 std::vector<std::string> params;
486 std::back_inserter(params), [
this](
const auto &mp) {
487 return config().simplify_template_type(
488 mp.to_string(config().using_namespace()));
490 auto args_string = fmt::format(
"{}", fmt::join(params,
", "));
491 if (
config().generate_method_arguments() ==
494 args_string, kAbbreviatedMethodArgumentsLength);
500 ostr <<
" : " << type;
502 if (
config().generate_links) {
511 const auto &uns =
config().using_namespace();
518 ostr << plantuml_common::to_plantuml(m.
access())
520 << uns.relative(
config().simplify_template_type(
523 if (
config().generate_links) {
531 for (
const auto &decorator : member.
decorators()) {
532 auto note = std::dynamic_pointer_cast<decorators::note>(decorator);
533 if (note && note->applies_to_diagram(
config().name)) {
534 ostr <<
"note " << note->position <<
" of " << alias
535 <<
"::" << member.
name() <<
'\n'
536 << note->text <<
'\n'
543 const relationship &r, std::set<std::string> &rendered_relations)
const
547 LOG_DBG(
"Processing relationship {}", to_string(r.
type()));
549 std::string destination;
552 if (!target_element.has_value())
554 "Missing element in the model for ID: {}", r.
destination())};
556 destination = target_element.value().full_name(
false);
559 destination = destination.substr(2, destination.size());
561 std::string puml_relation;
565 puml_relation += plantuml_common::to_plantuml(r,
config());
570 if (!r.
label().empty()) {
571 rendered_relations.emplace(r.
label());
576 const class_ &c, std::ostream &ostr)
const
583 std::set<std::string> rendered_relations;
585 std::stringstream all_relations_str;
586 std::set<std::string> unique_relations;
589 LOG_DBG(
"== Processing relationship {}",
590 plantuml_common::to_plantuml(r,
config()));
592 std::stringstream relstr;
595 destination = r.destination();
597 std::string puml_relation;
598 if (!r.multiplicity_source().empty())
599 puml_relation +=
"\"" + r.multiplicity_source() +
"\" ";
601 puml_relation += plantuml_common::to_plantuml(r,
config());
603 if (!r.multiplicity_destination().empty())
604 puml_relation +=
" \"" + r.multiplicity_destination() +
"\"";
606 std::string target_alias;
608 target_alias =
model().to_alias(destination);
611 LOG_DBG(
"Failed to find alias to {}", destination);
619 if (r.type() != relationship_t::kExtension)
620 relstr << c.
alias() <<
" " << puml_relation <<
" "
623 relstr << target_alias <<
" <|-- " << c.
alias();
625 if (
config().generate_links) {
630 if (!r.label().empty()) {
631 relstr <<
" : " << plantuml_common::to_plantuml(r.access())
633 rendered_relations.emplace(r.label());
636 if (unique_relations.count(relstr.str()) == 0) {
637 unique_relations.emplace(relstr.str());
639 LOG_TRACE(
"=== Adding relation {}", relstr.str());
641 all_relations_str << relstr.str() <<
'\n';
645 LOG_DBG(
"=== Skipping {} relation from {} to {} due "
647 to_string(r.type()), c.
full_name(
true), destination, e.what());
651 ostr << all_relations_str.str();
655 const concept_ &c, std::ostream &ostr)
const
662 std::set<std::string> rendered_relations;
664 std::stringstream all_relations_str;
665 std::set<std::string> unique_relations;
668 if (!
model().should_include(r.type()))
671 LOG_DBG(
"== Processing relationship {}", to_string(r.type()));
673 std::stringstream relstr;
676 destination = r.destination();
678 std::string puml_relation;
679 if (!r.multiplicity_source().empty())
680 puml_relation +=
"\"" + r.multiplicity_source() +
"\" ";
682 puml_relation += plantuml_common::to_plantuml(r,
config());
684 if (!r.multiplicity_destination().empty())
685 puml_relation +=
" \"" + r.multiplicity_destination() +
"\"";
687 std::string target_alias;
689 target_alias =
model().to_alias(destination);
692 LOG_DBG(
"Failed to find alias to {}", destination);
700 relstr << c.
alias() <<
" " << puml_relation <<
" " << target_alias;
702 if (
config().generate_links) {
707 if (!r.label().empty()) {
708 relstr <<
" : " << plantuml_common::to_plantuml(r.access())
710 rendered_relations.emplace(r.label());
713 if (unique_relations.count(relstr.str()) == 0) {
714 unique_relations.emplace(relstr.str());
716 LOG_TRACE(
"=== Adding relation {}", relstr.str());
718 all_relations_str << relstr.str() <<
'\n';
722 LOG_DBG(
"=== Skipping {} relation from {} to {} due "
724 to_string(r.type()), c.
full_name(
true), destination, e.what());
728 ostr << all_relations_str.str();
733 ostr <<
"enum " << e.
alias();
735 if (
config().generate_links) {
741 ostr <<
" {" <<
'\n';
743 for (
const auto &enum_constant : e.
constants()) {
744 ostr << enum_constant <<
'\n';
756 std::stringstream relstr;
758 destination = r.destination();
760 auto target_alias =
model().to_alias(destination);
766 relstr << e.
alias() <<
" "
769 <<
" " << target_alias;
771 if (
config().generate_links) {
776 if (!r.label().empty())
777 relstr <<
" : " << r.label();
781 ostr << relstr.str();
784 LOG_DBG(
"Skipping {} relation from {} to {} due "
788 e.
full_name(
true), destination, ex.what());
801 std::set<std::string> rendered_relations;
803 std::stringstream all_relations_str;
804 std::set<std::string> unique_relations;
807 LOG_DBG(
"== Processing relationship {}",
808 plantuml_common::to_plantuml(r,
config()));
810 std::stringstream relstr;
813 destination = r.destination();
815 std::string puml_relation;
816 if (!r.multiplicity_source().empty())
817 puml_relation +=
"\"" + r.multiplicity_source() +
"\" ";
819 puml_relation += plantuml_common::to_plantuml(r,
config());
821 if (!r.multiplicity_destination().empty())
822 puml_relation +=
" \"" + r.multiplicity_destination() +
"\"";
824 std::string target_alias;
826 target_alias =
model().to_alias(destination);
829 LOG_DBG(
"Failed to find alias to {}", destination);
837 if (r.type() != relationship_t::kExtension)
838 relstr << c.
alias() <<
" " << puml_relation <<
" "
841 relstr << target_alias <<
" <|-- " << c.
alias();
843 if (
config().generate_links) {
848 if (!r.label().empty()) {
849 relstr <<
" : " << plantuml_common::to_plantuml(r.access())
851 rendered_relations.emplace(r.label());
854 if (unique_relations.count(relstr.str()) == 0) {
855 unique_relations.emplace(relstr.str());
857 LOG_TRACE(
"=== Adding relation {}", relstr.str());
859 all_relations_str << relstr.str() <<
'\n';
863 LOG_DBG(
"=== Skipping {} relation from {} to {} due "
865 to_string(r.type()), c.
full_name(
true), destination, e.what());
869 ostr << all_relations_str.str();
874 if (
config().generate_packages()) {
875 LOG_DBG(
"Generating package {}",
881 ostr <<
"as " << p.
alias();
884 ostr <<
" <<deprecated>>";
888 ostr <<
" {" <<
'\n';
894 if (
config().generate_packages()) {
901 const std::string & , std::ostream &ostr)
const
903 ostr <<
"together {\n";
907 const std::string & , std::ostream &ostr)
const