Refactored and unified JSON generators output (#223)
This commit is contained in:
@@ -191,7 +191,7 @@ void generator::generate(const package &p, nlohmann::json &parent) const
|
||||
|
||||
package_object["type"] = to_string(config().package_type());
|
||||
package_object["name"] = p.name();
|
||||
package_object["display_name"] = p.full_name(false);
|
||||
package_object["display_name"] = p.name();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ void to_json(nlohmann::json &j, const element &c)
|
||||
j = json{{"id", std::to_string(c.id())},
|
||||
{"name", detail::render_name(c.name())},
|
||||
{"namespace", c.get_namespace().to_string()}, {"type", c.type_name()},
|
||||
{"display_name", detail::render_name(c.full_name(false))}};
|
||||
{"display_name", detail::render_name(c.full_name(true))}};
|
||||
|
||||
if (const auto &comment = c.comment(); comment)
|
||||
j["comment"] = comment.value();
|
||||
|
||||
@@ -35,13 +35,13 @@
|
||||
namespace clanguml::common::model {
|
||||
using nlohmann::json;
|
||||
|
||||
void to_json(nlohmann::json &j, const source_location &sl);
|
||||
void to_json(json &j, const source_location &sl);
|
||||
|
||||
void to_json(nlohmann::json &j, const element &c);
|
||||
void to_json(json &j, const element &c);
|
||||
|
||||
void to_json(nlohmann::json &j, const template_parameter &c);
|
||||
void to_json(json &j, const template_parameter &c);
|
||||
|
||||
void to_json(nlohmann::json &j, const relationship &c);
|
||||
void to_json(json &j, const relationship &c);
|
||||
} // namespace clanguml::common::model
|
||||
|
||||
namespace clanguml::common::generators::json {
|
||||
|
||||
@@ -123,8 +123,11 @@ public:
|
||||
*
|
||||
* @return Fully qualified elements name.
|
||||
*/
|
||||
std::string full_name(bool /*relative*/) const override
|
||||
std::string full_name(bool relative) const override
|
||||
{
|
||||
if (relative)
|
||||
return name();
|
||||
|
||||
return name_and_ns();
|
||||
}
|
||||
|
||||
|
||||
@@ -60,26 +60,49 @@ void generator::generate(const package &p, nlohmann::json &parent) const
|
||||
{
|
||||
LOG_DBG("Generating package {}", p.full_name(false));
|
||||
|
||||
nlohmann::json j;
|
||||
j["id"] = std::to_string(p.id());
|
||||
j["name"] = p.name();
|
||||
j["type"] = to_string(config().package_type());
|
||||
j["display_name"] = p.full_name(false);
|
||||
j["is_deprecated"] = p.is_deprecated();
|
||||
if (!p.file().empty())
|
||||
j["source_location"] =
|
||||
dynamic_cast<const common::model::source_location &>(p);
|
||||
if (const auto &comment = p.comment(); comment)
|
||||
j["comment"] = comment.value();
|
||||
const auto &uns = config().using_namespace();
|
||||
if (!uns.starts_with({p.full_name(false)})) {
|
||||
nlohmann::json j;
|
||||
j["id"] = std::to_string(p.id());
|
||||
j["name"] = p.name();
|
||||
j["type"] = to_string(config().package_type());
|
||||
j["display_name"] = p.name();
|
||||
switch (config().package_type()) {
|
||||
case config::package_type_t::kNamespace:
|
||||
j["namespace"] = p.get_namespace().to_string();
|
||||
break;
|
||||
case config::package_type_t::kModule:
|
||||
j["namespace"] = p.get_namespace().to_string();
|
||||
break;
|
||||
case config::package_type_t::kDirectory:
|
||||
j["path"] = p.get_namespace().to_string();
|
||||
break;
|
||||
}
|
||||
|
||||
for (const auto &subpackage : p) {
|
||||
auto &pkg = dynamic_cast<package &>(*subpackage);
|
||||
if (model().should_include(pkg)) {
|
||||
generate(pkg, j);
|
||||
j["is_deprecated"] = p.is_deprecated();
|
||||
if (!p.file().empty())
|
||||
j["source_location"] =
|
||||
dynamic_cast<const common::model::source_location &>(p);
|
||||
if (const auto &comment = p.comment(); comment)
|
||||
j["comment"] = comment.value();
|
||||
|
||||
for (const auto &subpackage : p) {
|
||||
auto &pkg = dynamic_cast<package &>(*subpackage);
|
||||
if (model().should_include(pkg)) {
|
||||
generate(pkg, j);
|
||||
}
|
||||
}
|
||||
|
||||
parent["elements"].push_back(std::move(j));
|
||||
}
|
||||
else {
|
||||
for (const auto &subpackage : p) {
|
||||
auto &pkg = dynamic_cast<package &>(*subpackage);
|
||||
if (model().should_include(pkg)) {
|
||||
generate(pkg, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parent["elements"].push_back(std::move(j));
|
||||
}
|
||||
|
||||
void generator::generate_diagram(nlohmann::json &parent) const
|
||||
|
||||
@@ -33,14 +33,12 @@ namespace clanguml::sequence_diagram::model {
|
||||
|
||||
void to_json(nlohmann::json &j, const participant &c)
|
||||
{
|
||||
j["name"] = generators::json::render_name(c.full_name(false));
|
||||
j["id"] = std::to_string(c.id());
|
||||
to_json(j, dynamic_cast<const participant::element &>(c));
|
||||
j["type"] = c.type_name();
|
||||
if (!c.file().empty())
|
||||
j["source_location"] =
|
||||
dynamic_cast<const common::model::source_location &>(c);
|
||||
if (const auto &comment = c.comment(); comment)
|
||||
j["comment"] = comment.value();
|
||||
|
||||
if (c.type_name() == "method") {
|
||||
j["name"] = dynamic_cast<const method &>(c).method_name();
|
||||
}
|
||||
}
|
||||
|
||||
void to_json(nlohmann::json &j, const activity &c)
|
||||
@@ -105,11 +103,8 @@ void generator::generate_call(const message &m, nlohmann::json &parent) const
|
||||
|
||||
msg["name"] = message;
|
||||
msg["type"] = "message";
|
||||
msg["from"]["activity_name"] =
|
||||
generators::json::render_name(from.value().full_name(false));
|
||||
msg["from"]["activity_id"] = std::to_string(from.value().id());
|
||||
msg["to"]["activity_id"] = std::to_string(to.value().id());
|
||||
msg["to"]["activity_name"] = to.value().full_name(false);
|
||||
if (const auto &cmt = m.comment(); cmt.has_value())
|
||||
msg["comment"] = cmt.value();
|
||||
|
||||
@@ -132,7 +127,6 @@ void generator::generate_call(const message &m, nlohmann::json &parent) const
|
||||
}
|
||||
else {
|
||||
msg["from"]["participant_id"] = std::to_string(from.value().id());
|
||||
msg["from"]["participant_name"] = from.value().full_name(false);
|
||||
}
|
||||
}
|
||||
else if (from.value().type_name() == "lambda") {
|
||||
@@ -553,43 +547,92 @@ common::id_t generator::generate_participant(
|
||||
const auto &participant =
|
||||
model().get_participant<model::participant>(participant_id).value();
|
||||
|
||||
if (participant.type_name() == "method") {
|
||||
participant_id = model()
|
||||
.get_participant<model::method>(participant_id)
|
||||
.value()
|
||||
.class_id();
|
||||
const auto participant_type = participant.type_name();
|
||||
|
||||
if (is_participant_generated(participant_id))
|
||||
return participant_id;
|
||||
if (participant_type == "method") {
|
||||
auto class_participant_id =
|
||||
model()
|
||||
.get_participant<model::method>(participant_id)
|
||||
.value()
|
||||
.class_id();
|
||||
|
||||
const auto &class_participant =
|
||||
model().get_participant<model::participant>(participant_id).value();
|
||||
if (!is_participant_generated(class_participant_id)) {
|
||||
const auto &class_participant =
|
||||
model()
|
||||
.get_participant<model::participant>(class_participant_id)
|
||||
.value();
|
||||
|
||||
parent["participants"].push_back(class_participant);
|
||||
generated_participants_.emplace(participant_id);
|
||||
generated_participants_.emplace(class_participant_id);
|
||||
|
||||
json_["participants"].push_back(class_participant);
|
||||
json_["participants"].back()["activities"].push_back(participant);
|
||||
|
||||
return class_participant_id;
|
||||
}
|
||||
else {
|
||||
if (!is_participant_generated(participant_id)) {
|
||||
for (auto &p : json_["participants"]) {
|
||||
if (p.at("id") == std::to_string(class_participant_id)) {
|
||||
generated_participants_.emplace(participant_id);
|
||||
p["activities"].push_back(participant);
|
||||
return class_participant_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((participant.type_name() == "function" ||
|
||||
participant.type_name() == "function_template") &&
|
||||
else if ((participant_type == "function" ||
|
||||
participant_type == "function_template") &&
|
||||
config().combine_free_functions_into_file_participants()) {
|
||||
// Create a single participant for all functions declared in a
|
||||
// single file
|
||||
// participant_id will become activity_id within a file participant
|
||||
const auto &function_participant =
|
||||
model().get_participant<model::function>(participant_id).value();
|
||||
|
||||
nlohmann::json j = function_participant;
|
||||
j["name"] = util::path_to_url(
|
||||
config().make_path_relative(function_participant.file()).string());
|
||||
const auto file_participant_id =
|
||||
common::to_id(function_participant.file_relative());
|
||||
|
||||
participant_id = common::to_id(function_participant.file_relative());
|
||||
if (!is_participant_generated(file_participant_id)) {
|
||||
nlohmann::json p = function_participant;
|
||||
|
||||
if (is_participant_generated(participant_id))
|
||||
return participant_id;
|
||||
const auto file_path =
|
||||
config().make_path_relative(function_participant.file());
|
||||
|
||||
j["id"] = std::to_string(participant_id);
|
||||
p["display_name"] = util::path_to_url(file_path.string());
|
||||
p["name"] = file_path.filename();
|
||||
|
||||
parent["participants"].push_back(j);
|
||||
if (is_participant_generated(file_participant_id))
|
||||
return participant_id;
|
||||
|
||||
p["id"] = std::to_string(file_participant_id);
|
||||
p["type"] = "file";
|
||||
p.erase("source_location");
|
||||
|
||||
generated_participants_.emplace(participant_id);
|
||||
|
||||
p["activities"].push_back(participant);
|
||||
json_["participants"].push_back(p);
|
||||
|
||||
generated_participants_.emplace(file_participant_id);
|
||||
|
||||
return file_participant_id;
|
||||
}
|
||||
else {
|
||||
if (!is_participant_generated(participant_id)) {
|
||||
for (auto &p : json_["participants"]) {
|
||||
if (p.at("id") == std::to_string(file_participant_id)) {
|
||||
generated_participants_.emplace(participant_id);
|
||||
p["activities"].push_back(participant);
|
||||
}
|
||||
}
|
||||
}
|
||||
return file_participant_id;
|
||||
}
|
||||
}
|
||||
else {
|
||||
parent["participants"].push_back(participant);
|
||||
json_["participants"].push_back(participant);
|
||||
}
|
||||
|
||||
generated_participants_.emplace(participant_id);
|
||||
@@ -614,7 +657,7 @@ void generator::generate_diagram(nlohmann::json &parent) const
|
||||
if (config().participants_order.has_value) {
|
||||
for (const auto &p : config().participants_order()) {
|
||||
LOG_DBG("Pregenerating participant {}", p);
|
||||
generate_participant(parent, p);
|
||||
generate_participant(json_, p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -661,7 +704,7 @@ void generator::generate_diagram(nlohmann::json &parent) const
|
||||
|
||||
block_statements_stack_.pop_back();
|
||||
|
||||
json_["sequences"].push_back(std::move(sequence));
|
||||
parent["sequences"].push_back(std::move(sequence));
|
||||
}
|
||||
|
||||
for (const auto &to_location : config().to()) {
|
||||
@@ -697,7 +740,7 @@ void generator::generate_diagram(nlohmann::json &parent) const
|
||||
|
||||
block_statements_stack_.pop_back();
|
||||
|
||||
json_["sequences"].push_back(std::move(sequence));
|
||||
parent["sequences"].push_back(std::move(sequence));
|
||||
}
|
||||
|
||||
for (const auto &sf : config().from()) {
|
||||
@@ -757,7 +800,7 @@ void generator::generate_diagram(nlohmann::json &parent) const
|
||||
sequence["return_type"] = from.value().return_type();
|
||||
}
|
||||
|
||||
json_["sequences"].push_back(std::move(sequence));
|
||||
parent["sequences"].push_back(std::move(sequence));
|
||||
}
|
||||
else {
|
||||
// TODO: Add support for other sequence start location types
|
||||
@@ -765,6 +808,6 @@ void generator::generate_diagram(nlohmann::json &parent) const
|
||||
}
|
||||
}
|
||||
|
||||
parent.update(json_);
|
||||
parent["participants"] = json_["participants"];
|
||||
}
|
||||
} // namespace clanguml::sequence_diagram::generators::json
|
||||
|
||||
@@ -239,6 +239,8 @@ private:
|
||||
|
||||
mutable std::set<common::id_t> generated_participants_;
|
||||
|
||||
// Needed to add "participants" array in a temporary object accessible from
|
||||
// all methods of the generator
|
||||
mutable nlohmann::json json_;
|
||||
|
||||
mutable std::vector<std::reference_wrapper<nlohmann::json>>
|
||||
|
||||
@@ -69,7 +69,10 @@ std::string class_::full_name(bool relative) const
|
||||
|
||||
std::ostringstream ostr;
|
||||
|
||||
ostr << name_and_ns();
|
||||
if (relative)
|
||||
ostr << name();
|
||||
else
|
||||
ostr << name_and_ns();
|
||||
render_template_params(ostr, using_namespace(), relative);
|
||||
|
||||
std::string res;
|
||||
@@ -102,7 +105,7 @@ function::function(const common::model::namespace_ &using_namespace)
|
||||
|
||||
std::string function::full_name(bool relative) const
|
||||
{
|
||||
return fmt::format("{}({}){}", element::full_name(relative),
|
||||
return fmt::format("{}({}){}", participant::full_name(relative),
|
||||
fmt::join(parameters_, ","), is_const() ? " const" : "");
|
||||
}
|
||||
|
||||
@@ -195,8 +198,12 @@ void method::set_class_full_name(const std::string &name)
|
||||
|
||||
const auto &method::class_full_name() const { return class_full_name_; }
|
||||
|
||||
std::string method::full_name(bool /*relative*/) const
|
||||
std::string method::full_name(bool relative) const
|
||||
{
|
||||
if (relative)
|
||||
return fmt::format("{}({}){}", method_name(),
|
||||
fmt::join(parameters(), ","), is_const() ? " const" : "");
|
||||
|
||||
return fmt::format("{}::{}({}){}", class_full_name(), method_name(),
|
||||
fmt::join(parameters(), ","), is_const() ? " const" : "");
|
||||
}
|
||||
|
||||
@@ -88,7 +88,13 @@ public:
|
||||
*
|
||||
* @return Type name of the diagram element.
|
||||
*/
|
||||
std::string type_name() const override { return "class"; }
|
||||
std::string type_name() const override
|
||||
{
|
||||
if (is_lambda())
|
||||
return "lambda";
|
||||
|
||||
return "class";
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if class is a struct.
|
||||
|
||||
@@ -1083,10 +1083,6 @@ bool translation_unit_visitor::VisitCallExpr(clang::CallExpr *expr)
|
||||
|
||||
bool translation_unit_visitor::TraverseVarDecl(clang::VarDecl *decl)
|
||||
{
|
||||
LOG_TRACE("Traversing cxx variable declaration at {} [caller_id = {}]",
|
||||
decl->getBeginLoc().printToString(source_manager()),
|
||||
context().caller_id());
|
||||
|
||||
if (decl->isStaticLocal())
|
||||
within_static_variable_declaration_++;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#pragma once
|
||||
|
||||
namespace clanguml::version {
|
||||
static constexpr auto CLANG_UML_JSON_GENERATOR_SCHEMA_VERSION = 1U;
|
||||
static constexpr auto CLANG_UML_JSON_GENERATOR_SCHEMA_VERSION = 2U;
|
||||
static constexpr auto CLANG_UML_VERSION = "@GIT_VERSION@";
|
||||
static constexpr auto CLANG_UML_LIBCLANG_VERSION = "@LIBCLANG_VERSION_STRING@";
|
||||
} // namespace clanguml::version
|
||||
Reference in New Issue
Block a user