27#include <clang/Basic/Version.h>
28#include <clang/Frontend/CompilerInstance.h>
29#include <clang/Tooling/CompilationDatabase.h>
30#include <clang/Tooling/Tooling.h>
31#include <glob/glob.hpp>
32#include <inja/inja.hpp>
45std::string
indent(
unsigned level);
48std::string
escape_name(std::string name,
bool round_brackets =
true);
56template <
typename ConfigType,
typename DiagramType>
84 void generate(std::ostream &ostr)
const override;
107 std::ostream &ostr,
const std::vector<std::string> &directives)
const;
159 template <
typename E>
175template <
typename C,
typename D>
181 if (!config.allow_empty_diagrams() && model.is_empty() &&
182 config.mermaid().before.empty() && config.mermaid().after.empty()) {
184 "Diagram configuration resulted in empty diagram."};
189 generate_title(ostr);
191 generate_diagram_type(ostr);
193 generate_mermaid_directives(ostr, config.mermaid().before);
197 generate_mermaid_directives(ostr, config.mermaid().after);
199 generate_metadata(ostr);
202template <
typename C,
typename D>
206 if (e.file().empty() && e.file_relative().empty())
211 if (!maybe_link_pattern)
214 const auto &[link_prefix, link_pattern] = *maybe_link_pattern;
216 ostr <<
indent(1) <<
"click " << e.alias() <<
" href \"";
221 if (!link_pattern.empty()) {
223 std::string_view{link_pattern}, ec);
229 catch (
const inja::json::parse_error &e) {
230 LOG_ERROR(
"Failed to parse Jinja template: {}", link_pattern);
233 catch (
const inja::json::exception &e) {
234 LOG_ERROR(
"Failed to render comment directive: \n{}\n due to: {}",
235 link_pattern, e.what());
240 auto maybe_tooltip_pattern =
243 if (maybe_tooltip_pattern) {
244 const auto &[tooltip_prefix, tooltip_pattern] = *maybe_tooltip_pattern;
246 if (!tooltip_pattern.empty()) {
253 std::string_view{tooltip_pattern}, ec);
255 ostr << tooltip_text;
257 catch (
const inja::json::parse_error &e) {
259 "Failed to parse Jinja template: {}", tooltip_pattern);
262 catch (
const inja::json::exception &e) {
264 "Failed to render PlantUML directive: \n{}\n due to: {}",
265 tooltip_pattern, e.what());
275template <
typename C,
typename D>
277 std::ostream &ostr,
const std::vector<std::string> &directives)
const
285 for (
const auto &d : directives) {
293 std::tuple<std::string, size_t, size_t> alias_match;
295 const auto full_name =
296 config.using_namespace() | std::get<0>(alias_match);
297 auto element_opt = model.get(full_name.to_string());
300 directive.replace(std::get<1>(alias_match),
301 std::get<2>(alias_match), element_opt.value().alias());
303 LOG_ERROR(
"Cannot find clang-uml alias for element {}",
304 full_name.to_string());
305 directive.replace(std::get<1>(alias_match),
306 std::get<2>(alias_match),
"UNKNOWN_ALIAS");
310 ostr <<
indent(1) << directive <<
'\n';
314 "Failed to render MermaidJS directive due to unresolvable "
318 catch (
const inja::json::parse_error &e) {
319 LOG_ERROR(
"Failed to parse Jinja template: {}", d);
321 catch (
const inja::json::exception &e) {
322 LOG_ERROR(
"Failed to render MermaidJS directive: \n{}\n due to: {}",
325 catch (
const std::regex_error &e) {
326 LOG_ERROR(
"Failed to render MermaidJS directive: \n{}\n due to "
327 "std::regex_error: {}",
330 catch (
const std::exception &e) {
331 LOG_ERROR(
"Failed to render PlantUML directive: \n{}\n due to: {}",
337template <
typename C,
typename D>
343 for (
const auto &decorator : e.
decorators()) {
344 auto note = std::dynamic_pointer_cast<decorators::note>(decorator);
345 if (note && note->applies_to_diagram(config.name)) {
346 ostr <<
indent(1) <<
"note for " << e.
alias() <<
" \"" << note->text
352template <
typename C,
typename D>
357 if (config.generate_metadata()) {
359 <<
"%% Generated with clang-uml, version "
360 << clanguml::version::CLANG_UML_VERSION <<
'\n'
361 <<
"%% LLVM version " << clang::getClangFullVersion() <<
'\n';
365template <
typename C,
typename D>
372 ostr <<
"title: " << config.title() <<
'\n';
377template <
typename C,
typename D>
383 if (config.debug_mode())
384 ostr <<
"%% " << e.
file() <<
":" << e.
line() <<
'\n';
387template <
typename DiagramModel,
typename DiagramConfig>