Fixed package diagram generation
This commit is contained in:
@@ -25,13 +25,13 @@
|
|||||||
|
|
||||||
namespace clanguml::class_diagram::model {
|
namespace clanguml::class_diagram::model {
|
||||||
|
|
||||||
const std::vector<std::reference_wrapper<const class_>> &
|
const std::vector<std::reference_wrapper<class_>> &
|
||||||
diagram::classes() const
|
diagram::classes() const
|
||||||
{
|
{
|
||||||
return classes_;
|
return classes_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::reference_wrapper<const enum_>> &diagram::enums() const
|
const std::vector<std::reference_wrapper<enum_>> &diagram::enums() const
|
||||||
{
|
{
|
||||||
return enums_;
|
return enums_;
|
||||||
}
|
}
|
||||||
@@ -41,14 +41,11 @@ common::model::diagram_t diagram::type() const
|
|||||||
return common::model::diagram_t::kClass;
|
return common::model::diagram_t::kClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<
|
std::optional<std::reference_wrapper<clanguml::common::model::diagram_element>>
|
||||||
std::reference_wrapper<const clanguml::common::model::diagram_element>>
|
|
||||||
diagram::get(const std::string &full_name) const
|
diagram::get(const std::string &full_name) const
|
||||||
{
|
{
|
||||||
// type_safe::optional_ref<const clanguml::common::model::diagram_element>
|
|
||||||
// res;
|
|
||||||
std::optional<
|
std::optional<
|
||||||
std::reference_wrapper<const clanguml::common::model::diagram_element>>
|
std::reference_wrapper<clanguml::common::model::diagram_element>>
|
||||||
res;
|
res;
|
||||||
|
|
||||||
res = get_class(full_name);
|
res = get_class(full_name);
|
||||||
@@ -61,6 +58,23 @@ diagram::get(const std::string &full_name) const
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<std::reference_wrapper<clanguml::common::model::diagram_element>>
|
||||||
|
diagram::get(const clanguml::common::model::diagram_element::id_t id) const
|
||||||
|
{
|
||||||
|
std::optional<
|
||||||
|
std::reference_wrapper<clanguml::common::model::diagram_element>>
|
||||||
|
res;
|
||||||
|
|
||||||
|
res = get_class(id);
|
||||||
|
|
||||||
|
if (res.has_value())
|
||||||
|
return res;
|
||||||
|
|
||||||
|
res = get_enum(id);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
bool diagram::has_class(const class_ &c) const
|
bool diagram::has_class(const class_ &c) const
|
||||||
{
|
{
|
||||||
return std::any_of(classes_.cbegin(), classes_.cend(),
|
return std::any_of(classes_.cbegin(), classes_.cend(),
|
||||||
@@ -73,7 +87,7 @@ bool diagram::has_enum(const enum_ &e) const
|
|||||||
[&e](const auto &ee) { return ee.get().full_name() == e.full_name(); });
|
[&e](const auto &ee) { return ee.get().full_name() == e.full_name(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::reference_wrapper<const class_>> diagram::get_class(
|
std::optional<std::reference_wrapper<class_>> diagram::get_class(
|
||||||
const std::string &name) const
|
const std::string &name) const
|
||||||
{
|
{
|
||||||
for (const auto &c : classes_) {
|
for (const auto &c : classes_) {
|
||||||
@@ -87,7 +101,7 @@ std::optional<std::reference_wrapper<const class_>> diagram::get_class(
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::reference_wrapper<const class_>> diagram::get_class(
|
std::optional<std::reference_wrapper<class_>> diagram::get_class(
|
||||||
clanguml::common::model::diagram_element::id_t id) const
|
clanguml::common::model::diagram_element::id_t id) const
|
||||||
{
|
{
|
||||||
for (const auto &c : classes_) {
|
for (const auto &c : classes_) {
|
||||||
@@ -99,7 +113,7 @@ std::optional<std::reference_wrapper<const class_>> diagram::get_class(
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::reference_wrapper<const enum_>> diagram::get_enum(
|
std::optional<std::reference_wrapper<enum_>> diagram::get_enum(
|
||||||
const std::string &name) const
|
const std::string &name) const
|
||||||
{
|
{
|
||||||
for (const auto &e : enums_) {
|
for (const auto &e : enums_) {
|
||||||
@@ -111,6 +125,18 @@ std::optional<std::reference_wrapper<const enum_>> diagram::get_enum(
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<std::reference_wrapper<enum_>> diagram::get_enum(
|
||||||
|
clanguml::common::model::diagram_element::id_t id) const
|
||||||
|
{
|
||||||
|
for (const auto &e : enums_) {
|
||||||
|
if (e.get().id() == id) {
|
||||||
|
return {e};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
void diagram::add_type_alias(std::unique_ptr<type_alias> &&ta)
|
void diagram::add_type_alias(std::unique_ptr<type_alias> &&ta)
|
||||||
{
|
{
|
||||||
LOG_DBG(
|
LOG_DBG(
|
||||||
@@ -149,7 +175,7 @@ bool diagram::add_class(std::unique_ptr<class_> &&c)
|
|||||||
auto name = base_name;
|
auto name = base_name;
|
||||||
auto name_with_ns = c->name_and_ns();
|
auto name_with_ns = c->name_and_ns();
|
||||||
auto name_and_ns = ns | name;
|
auto name_and_ns = ns | name;
|
||||||
const auto &cc = *c;
|
auto &cc = *c;
|
||||||
|
|
||||||
auto cc_ref = std::ref(cc);
|
auto cc_ref = std::ref(cc);
|
||||||
|
|
||||||
|
|||||||
@@ -46,26 +46,33 @@ public:
|
|||||||
common::model::diagram_t type() const override;
|
common::model::diagram_t type() const override;
|
||||||
|
|
||||||
std::optional<
|
std::optional<
|
||||||
std::reference_wrapper<const clanguml::common::model::diagram_element>>
|
std::reference_wrapper<clanguml::common::model::diagram_element>>
|
||||||
get(const std::string &full_name) const override;
|
get(const std::string &full_name) const override;
|
||||||
|
|
||||||
const std::vector<std::reference_wrapper<const class_>> &classes() const;
|
std::optional<
|
||||||
|
std::reference_wrapper<clanguml::common::model::diagram_element>>
|
||||||
|
get(const clanguml::common::model::diagram_element::id_t id) const override;
|
||||||
|
|
||||||
const std::vector<std::reference_wrapper<const enum_>> &enums() const;
|
const std::vector<std::reference_wrapper<class_>> &classes() const;
|
||||||
|
|
||||||
|
const std::vector<std::reference_wrapper<enum_>> &enums() const;
|
||||||
|
|
||||||
bool has_class(const class_ &c) const;
|
bool has_class(const class_ &c) const;
|
||||||
|
|
||||||
bool has_enum(const enum_ &e) const;
|
bool has_enum(const enum_ &e) const;
|
||||||
|
|
||||||
std::optional<std::reference_wrapper<const class_>> get_class(
|
std::optional<std::reference_wrapper<class_>> get_class(
|
||||||
const std::string &name) const;
|
const std::string &name) const;
|
||||||
|
|
||||||
std::optional<std::reference_wrapper<const class_>> get_class(
|
std::optional<std::reference_wrapper<class_>> get_class(
|
||||||
clanguml::common::model::diagram_element::id_t id) const;
|
clanguml::common::model::diagram_element::id_t id) const;
|
||||||
|
|
||||||
std::optional<std::reference_wrapper<const enum_>> get_enum(
|
std::optional<std::reference_wrapper<enum_>> get_enum(
|
||||||
const std::string &name) const;
|
const std::string &name) const;
|
||||||
|
|
||||||
|
std::optional<std::reference_wrapper<enum_>> get_enum(
|
||||||
|
clanguml::common::model::diagram_element::id_t id) const;
|
||||||
|
|
||||||
void add_type_alias(std::unique_ptr<type_alias> &&ta);
|
void add_type_alias(std::unique_ptr<type_alias> &&ta);
|
||||||
|
|
||||||
bool add_class(std::unique_ptr<class_> &&c);
|
bool add_class(std::unique_ptr<class_> &&c);
|
||||||
@@ -85,11 +92,10 @@ public:
|
|||||||
const clanguml::common::model::diagram_element::id_t id) const override;
|
const clanguml::common::model::diagram_element::id_t id) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::reference_wrapper<const class_>> classes_;
|
std::vector<std::reference_wrapper<class_>> classes_;
|
||||||
std::vector<std::reference_wrapper<const enum_>> enums_;
|
|
||||||
|
std::vector<std::reference_wrapper<enum_>> enums_;
|
||||||
|
|
||||||
// std::vector<type_safe::object_ref<const class_, false>> classes_;
|
|
||||||
// std::vector<type_safe::object_ref<const enum_, false>> enums_;
|
|
||||||
std::map<std::string, std::unique_ptr<type_alias>> type_aliases_;
|
std::map<std::string, std::unique_ptr<type_alias>> type_aliases_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -783,8 +783,7 @@ bool translation_unit_visitor::find_relationships(const clang::QualType &type,
|
|||||||
found_relationships_t &relationships,
|
found_relationships_t &relationships,
|
||||||
clanguml::common::model::relationship_t relationship_hint)
|
clanguml::common::model::relationship_t relationship_hint)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result{false};
|
||||||
// std::string type_name =
|
|
||||||
|
|
||||||
if (type->isPointerType()) {
|
if (type->isPointerType()) {
|
||||||
relationship_hint = relationship_t::kAssociation;
|
relationship_hint = relationship_t::kAssociation;
|
||||||
|
|||||||
@@ -58,13 +58,10 @@ public:
|
|||||||
|
|
||||||
virtual bool VisitTypeAliasTemplateDecl(clang::TypeAliasTemplateDecl *cls);
|
virtual bool VisitTypeAliasTemplateDecl(clang::TypeAliasTemplateDecl *cls);
|
||||||
|
|
||||||
// virtual bool VisitVarDecl(clang::VarDecl *variable_declaration);
|
|
||||||
clanguml::class_diagram::model::diagram &diagram() { return diagram_; }
|
clanguml::class_diagram::model::diagram &diagram() { return diagram_; }
|
||||||
|
|
||||||
const clanguml::config::class_diagram &config() const { return config_; }
|
const clanguml::config::class_diagram &config() const { return config_; }
|
||||||
|
|
||||||
// void operator()();
|
|
||||||
|
|
||||||
void finalize();
|
void finalize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -34,14 +34,19 @@ class relationship;
|
|||||||
class diagram {
|
class diagram {
|
||||||
public:
|
public:
|
||||||
diagram();
|
diagram();
|
||||||
|
|
||||||
virtual ~diagram();
|
virtual ~diagram();
|
||||||
|
|
||||||
virtual diagram_t type() const = 0;
|
virtual diagram_t type() const = 0;
|
||||||
|
|
||||||
virtual std::optional<
|
virtual std::optional<
|
||||||
std::reference_wrapper<const clanguml::common::model::diagram_element>>
|
std::reference_wrapper<clanguml::common::model::diagram_element>>
|
||||||
get(const std::string &full_name) const = 0;
|
get(const std::string &full_name) const = 0;
|
||||||
|
|
||||||
|
virtual std::optional<
|
||||||
|
std::reference_wrapper<clanguml::common::model::diagram_element>>
|
||||||
|
get(const diagram_element::id_t id) const = 0;
|
||||||
|
|
||||||
diagram(const diagram &) = delete;
|
diagram(const diagram &) = delete;
|
||||||
diagram(diagram &&);
|
diagram(diagram &&);
|
||||||
diagram &operator=(const diagram &) = delete;
|
diagram &operator=(const diagram &) = delete;
|
||||||
@@ -62,6 +67,7 @@ public:
|
|||||||
bool should_include(const relationship r) const;
|
bool should_include(const relationship r) const;
|
||||||
bool should_include(const relationship_t r) const;
|
bool should_include(const relationship_t r) const;
|
||||||
bool should_include(const access_t s) const;
|
bool should_include(const access_t s) const;
|
||||||
|
|
||||||
virtual bool has_element(const diagram_element::id_t id) const
|
virtual bool has_element(const diagram_element::id_t id) const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -63,14 +63,14 @@ const clanguml::common::optional_ref<class_diagram::model::class_> get(
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
const clanguml::common::optional_ref<const common::model::package> get(
|
const clanguml::common::optional_ref<common::model::package> get(
|
||||||
const package_diagram::model::diagram &d, const std::string &full_name)
|
const package_diagram::model::diagram &d, const std::string &full_name)
|
||||||
{
|
{
|
||||||
return d.get_package(full_name);
|
return d.get_package(full_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
const clanguml::common::optional_ref<const common::model::source_file> get(
|
const clanguml::common::optional_ref<common::model::source_file> get(
|
||||||
const include_diagram::model::diagram &d, const std::string &full_name)
|
const include_diagram::model::diagram &d, const std::string &full_name)
|
||||||
{
|
{
|
||||||
return d.get_file(full_name);
|
return d.get_file(full_name);
|
||||||
|
|||||||
@@ -27,10 +27,10 @@ namespace clanguml::common {
|
|||||||
using id_t = int64_t;
|
using id_t = int64_t;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using optional_ref = std::optional<std::reference_wrapper<const T>>;
|
using optional_ref = std::optional<std::reference_wrapper<T>>;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using reference_vector = std::vector<std::reference_wrapper<const T>>;
|
using reference_vector = std::vector<std::reference_wrapper<T>>;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using reference_set = std::unordered_set<std::reference_wrapper<const T>>;
|
using reference_set = std::unordered_set<std::reference_wrapper<const T>>;
|
||||||
|
|||||||
@@ -34,6 +34,12 @@ common::optional_ref<common::model::diagram_element> diagram::get(
|
|||||||
return get_file(full_name);
|
return get_file(full_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
common::optional_ref<common::model::diagram_element> diagram::get(
|
||||||
|
const common::model::diagram_element::id_t /*id*/) const
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
void diagram::add_file(std::unique_ptr<common::model::source_file> &&f)
|
void diagram::add_file(std::unique_ptr<common::model::source_file> &&f)
|
||||||
{
|
{
|
||||||
LOG_DBG("Adding source file: {}, {}", f->name(), f->full_name(true));
|
LOG_DBG("Adding source file: {}, {}", f->name(), f->full_name(true));
|
||||||
@@ -94,7 +100,7 @@ std::string diagram::to_alias(const std::string &full_name) const
|
|||||||
return source_file.value().alias();
|
return source_file.value().alias();
|
||||||
}
|
}
|
||||||
|
|
||||||
const common::reference_vector<const common::model::source_file> &
|
const common::reference_vector<common::model::source_file> &
|
||||||
diagram::files() const
|
diagram::files() const
|
||||||
{
|
{
|
||||||
return files_;
|
return files_;
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ public:
|
|||||||
common::optional_ref<common::model::diagram_element> get(
|
common::optional_ref<common::model::diagram_element> get(
|
||||||
const std::string &full_name) const override;
|
const std::string &full_name) const override;
|
||||||
|
|
||||||
|
common::optional_ref<common::model::diagram_element> get(
|
||||||
|
const common::model::diagram_element::id_t id) const override;
|
||||||
|
|
||||||
void add_file(std::unique_ptr<common::model::source_file> &&f);
|
void add_file(std::unique_ptr<common::model::source_file> &&f);
|
||||||
|
|
||||||
common::optional_ref<common::model::source_file> get_file(
|
common::optional_ref<common::model::source_file> get_file(
|
||||||
@@ -51,11 +54,11 @@ public:
|
|||||||
|
|
||||||
std::string to_alias(const std::string &full_name) const;
|
std::string to_alias(const std::string &full_name) const;
|
||||||
|
|
||||||
const common::reference_vector<const common::model::source_file> &
|
const common::reference_vector<common::model::source_file> &
|
||||||
files() const;
|
files() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
common::reference_vector<const common::model::source_file> files_;
|
common::reference_vector<common::model::source_file> files_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ void generator::generate_relationships(
|
|||||||
try {
|
try {
|
||||||
relstr << p.alias()
|
relstr << p.alias()
|
||||||
<< " ..> "
|
<< " ..> "
|
||||||
//<< m_model.get_ to_alias(uns.relative(r.destination()))
|
<< m_model.to_alias(r.destination())
|
||||||
<< '\n';
|
<< '\n';
|
||||||
ostr << relstr.str();
|
ostr << relstr.str();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,8 +28,7 @@ common::model::diagram_t diagram::type() const
|
|||||||
return common::model::diagram_t::kPackage;
|
return common::model::diagram_t::kPackage;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<
|
const std::vector<std::reference_wrapper<clanguml::common::model::package>> &
|
||||||
std::reference_wrapper<const clanguml::common::model::package>> &
|
|
||||||
diagram::packages() const
|
diagram::packages() const
|
||||||
{
|
{
|
||||||
return packages_;
|
return packages_;
|
||||||
@@ -46,7 +45,7 @@ void diagram::add_package(std::unique_ptr<common::model::package> &&p)
|
|||||||
add_element(ns, std::move(p));
|
add_element(ns, std::move(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::reference_wrapper<const common::model::package>>
|
std::optional<std::reference_wrapper<common::model::package>>
|
||||||
diagram::get_package(const std::string &name) const
|
diagram::get_package(const std::string &name) const
|
||||||
{
|
{
|
||||||
for (const auto &p : packages_) {
|
for (const auto &p : packages_) {
|
||||||
@@ -59,30 +58,42 @@ diagram::get_package(const std::string &name) const
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<
|
std::optional<std::reference_wrapper<common::model::package>>
|
||||||
std::reference_wrapper<const clanguml::common::model::diagram_element>>
|
diagram::get_package(
|
||||||
|
const clanguml::common::model::diagram_element::id_t id) const
|
||||||
|
{
|
||||||
|
for (const auto &p : packages_) {
|
||||||
|
if (p.get().id() == id) {
|
||||||
|
return {p};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::reference_wrapper<clanguml::common::model::diagram_element>>
|
||||||
diagram::get(const std::string &full_name) const
|
diagram::get(const std::string &full_name) const
|
||||||
{
|
{
|
||||||
return get_package(full_name);
|
return get_package(full_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string diagram::to_alias(const std::string &full_name) const
|
std::optional<std::reference_wrapper<clanguml::common::model::diagram_element>>
|
||||||
|
diagram::get(const clanguml::common::model::diagram_element::id_t id) const
|
||||||
{
|
{
|
||||||
LOG_DBG("Looking for alias for {}", full_name);
|
return get_package(id);
|
||||||
|
}
|
||||||
|
|
||||||
auto path = common::model::namespace_{full_name};
|
std::string diagram::to_alias(
|
||||||
|
const clanguml::common::model::diagram_element::id_t id) const
|
||||||
|
{
|
||||||
|
LOG_DBG("Looking for alias for {}", id);
|
||||||
|
|
||||||
if (path.is_empty())
|
for (const auto &p : packages_) {
|
||||||
throw error::uml_alias_missing(
|
if (p.get().id() == id)
|
||||||
fmt::format("Missing alias for '{}'", path.to_string()));
|
return p.get().alias();
|
||||||
|
}
|
||||||
|
|
||||||
auto package = get_element<common::model::package>(path);
|
return {};
|
||||||
|
|
||||||
if (!package)
|
|
||||||
throw error::uml_alias_missing(
|
|
||||||
fmt::format("Missing alias for '{}'", path.to_string()));
|
|
||||||
|
|
||||||
return package.value().alias();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,24 +39,30 @@ public:
|
|||||||
|
|
||||||
common::model::diagram_t type() const override;
|
common::model::diagram_t type() const override;
|
||||||
|
|
||||||
const std::vector<
|
const std::vector<std::reference_wrapper<clanguml::common::model::package>>
|
||||||
std::reference_wrapper<const clanguml::common::model::package>> &
|
&packages() const;
|
||||||
packages() const;
|
|
||||||
|
|
||||||
std::optional<
|
std::optional<
|
||||||
std::reference_wrapper<const clanguml::common::model::diagram_element>>
|
std::reference_wrapper<clanguml::common::model::diagram_element>>
|
||||||
get(const std::string &full_name) const override;
|
get(const std::string &full_name) const override;
|
||||||
|
|
||||||
|
std::optional<
|
||||||
|
std::reference_wrapper<clanguml::common::model::diagram_element>>
|
||||||
|
get(const clanguml::common::model::diagram_element::id_t id) const override;
|
||||||
|
|
||||||
void add_package(std::unique_ptr<common::model::package> &&p);
|
void add_package(std::unique_ptr<common::model::package> &&p);
|
||||||
|
|
||||||
std::optional<
|
std::optional<std::reference_wrapper<clanguml::common::model::package>>
|
||||||
std::reference_wrapper<const clanguml::common::model::package>>
|
|
||||||
get_package(const std::string &name) const;
|
get_package(const std::string &name) const;
|
||||||
|
|
||||||
std::string to_alias(const std::string &full_name) const;
|
std::optional<std::reference_wrapper<common::model::package>> get_package(
|
||||||
|
const clanguml::common::model::diagram_element::id_t id) const;
|
||||||
|
|
||||||
|
std::string to_alias(
|
||||||
|
const clanguml::common::model::diagram_element::id_t) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::reference_wrapper<const clanguml::common::model::package>>
|
std::vector<std::reference_wrapper<clanguml::common::model::package>>
|
||||||
packages_;
|
packages_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,11 +29,21 @@ namespace clanguml::package_diagram::visitor {
|
|||||||
|
|
||||||
using clanguml::class_diagram::model::type_alias;
|
using clanguml::class_diagram::model::type_alias;
|
||||||
using clanguml::common::model::access_t;
|
using clanguml::common::model::access_t;
|
||||||
|
using clanguml::common::model::namespace_;
|
||||||
using clanguml::common::model::package;
|
using clanguml::common::model::package;
|
||||||
using clanguml::common::model::relationship;
|
using clanguml::common::model::relationship;
|
||||||
using clanguml::common::model::relationship_t;
|
using clanguml::common::model::relationship_t;
|
||||||
using clanguml::package_diagram::model::diagram;
|
using clanguml::package_diagram::model::diagram;
|
||||||
|
|
||||||
|
int64_t to_id(const clang::NamespaceDecl *ns)
|
||||||
|
{
|
||||||
|
auto qualified_name = ns->getQualifiedNameAsString();
|
||||||
|
util::replace_all(qualified_name, "(anonymous namespace)", "");
|
||||||
|
util::replace_all(qualified_name, "::::", "::");
|
||||||
|
|
||||||
|
return std::hash<std::string>{}(qualified_name) >> 3;
|
||||||
|
}
|
||||||
|
|
||||||
translation_unit_visitor::translation_unit_visitor(clang::SourceManager &sm,
|
translation_unit_visitor::translation_unit_visitor(clang::SourceManager &sm,
|
||||||
clanguml::package_diagram::model::diagram &diagram,
|
clanguml::package_diagram::model::diagram &diagram,
|
||||||
const clanguml::config::package_diagram &config)
|
const clanguml::config::package_diagram &config)
|
||||||
@@ -43,4 +53,362 @@ translation_unit_visitor::translation_unit_visitor(clang::SourceManager &sm,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool translation_unit_visitor::VisitNamespaceDecl(clang::NamespaceDecl *ns)
|
||||||
|
{
|
||||||
|
if (ns->isAnonymousNamespace() || ns->isInline())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
auto qualified_name = ns->getQualifiedNameAsString();
|
||||||
|
util::replace_all(qualified_name, "(anonymous namespace)", "");
|
||||||
|
util::replace_all(qualified_name, "::::", "::");
|
||||||
|
|
||||||
|
LOG_DBG("Visiting namespace declaration: {}", qualified_name);
|
||||||
|
|
||||||
|
auto package_path = namespace_{qualified_name};
|
||||||
|
auto package_parent = package_path;
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
if (!package_path.is_empty())
|
||||||
|
name = package_path.name();
|
||||||
|
|
||||||
|
if (!package_parent.is_empty())
|
||||||
|
package_parent.pop_back();
|
||||||
|
|
||||||
|
const auto usn = config().using_namespace();
|
||||||
|
|
||||||
|
auto p = std::make_unique<common::model::package>(usn);
|
||||||
|
package_path = package_path.relative_to(usn);
|
||||||
|
|
||||||
|
p->set_name(name);
|
||||||
|
p->set_namespace(package_parent);
|
||||||
|
p->set_id(to_id(ns));
|
||||||
|
|
||||||
|
assert(p->id() > 0);
|
||||||
|
|
||||||
|
if (diagram().should_include(*p) && !diagram().get(p->id())) {
|
||||||
|
process_comment(*ns, *p);
|
||||||
|
set_source_location(*ns, *p);
|
||||||
|
|
||||||
|
p->set_style(p->style_spec());
|
||||||
|
|
||||||
|
for (const auto *attr : ns->attrs()) {
|
||||||
|
if (attr->getKind() == clang::attr::Kind::Deprecated) {
|
||||||
|
p->set_deprecated(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!p->skip()) {
|
||||||
|
diagram().add_package(std::move(p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool translation_unit_visitor::VisitFunctionDecl(
|
||||||
|
clang::FunctionDecl *function_declaration)
|
||||||
|
{
|
||||||
|
assert(function_declaration != nullptr);
|
||||||
|
|
||||||
|
// Skip system headers
|
||||||
|
if (source_manager_.isInSystemHeader(
|
||||||
|
function_declaration->getSourceRange().getBegin()))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
found_relationships_t relationships;
|
||||||
|
|
||||||
|
find_relationships(function_declaration->getReturnType(), relationships);
|
||||||
|
|
||||||
|
for (const auto *param : function_declaration->parameters()) {
|
||||||
|
if (param != nullptr)
|
||||||
|
find_relationships(param->getType(), relationships);
|
||||||
|
}
|
||||||
|
|
||||||
|
add_relationships(function_declaration, relationships);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool translation_unit_visitor::VisitCXXRecordDecl(clang::CXXRecordDecl *cls)
|
||||||
|
{
|
||||||
|
assert(cls != nullptr);
|
||||||
|
|
||||||
|
// Skip system headers
|
||||||
|
if (source_manager_.isInSystemHeader(cls->getSourceRange().getBegin()))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Templated records are handled by VisitClassTemplateDecl()
|
||||||
|
if (cls->isTemplated() || cls->isTemplateDecl() ||
|
||||||
|
(clang::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>(cls) !=
|
||||||
|
nullptr))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
found_relationships_t relationships;
|
||||||
|
|
||||||
|
process_class_declaration(*cls, relationships);
|
||||||
|
|
||||||
|
add_relationships(cls, relationships);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void translation_unit_visitor::add_relationships(
|
||||||
|
clang::DeclContext *cls, found_relationships_t &relationships)
|
||||||
|
{
|
||||||
|
int64_t current_package_id{0};
|
||||||
|
|
||||||
|
const auto *namespace_context = cls->getEnclosingNamespaceContext();
|
||||||
|
if (namespace_context != nullptr && namespace_context->isNamespace()) {
|
||||||
|
current_package_id =
|
||||||
|
to_id(llvm::cast<clang::NamespaceDecl>(namespace_context));
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(current_package_id != 0);
|
||||||
|
|
||||||
|
auto current_package = diagram().get(current_package_id);
|
||||||
|
|
||||||
|
if (current_package) {
|
||||||
|
for (const auto &dependency : relationships) {
|
||||||
|
const auto destination_id = std::get<0>(dependency);
|
||||||
|
relationship r{relationship_t::kDependency, destination_id};
|
||||||
|
if (destination_id != current_package_id)
|
||||||
|
current_package.value().get().add_relationship(std::move(r));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void translation_unit_visitor::process_class_declaration(
|
||||||
|
const clang::CXXRecordDecl &cls, found_relationships_t &relationships)
|
||||||
|
{
|
||||||
|
// Look for dependency relationships in class children (fields, methods)
|
||||||
|
process_class_children(cls, relationships);
|
||||||
|
|
||||||
|
// Look for dependency relationships in class bases
|
||||||
|
process_class_bases(cls, relationships);
|
||||||
|
}
|
||||||
|
|
||||||
|
void translation_unit_visitor::process_class_children(
|
||||||
|
const clang::CXXRecordDecl &cls, found_relationships_t &relationships)
|
||||||
|
{
|
||||||
|
// Iterate over class methods (both regular and static)
|
||||||
|
for (const auto *method : cls.methods()) {
|
||||||
|
if (method != nullptr) {
|
||||||
|
process_method(*method, relationships);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate over class template methods
|
||||||
|
for (auto const *decl_iterator :
|
||||||
|
clang::dyn_cast_or_null<clang::DeclContext>(&cls)->decls()) {
|
||||||
|
auto const *method_template =
|
||||||
|
llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(decl_iterator);
|
||||||
|
if (method_template == nullptr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
process_template_method(*method_template, relationships);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate over regular class fields
|
||||||
|
for (const auto *field : cls.fields()) {
|
||||||
|
if (field != nullptr)
|
||||||
|
process_field(*field, relationships);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static fields have to be processed by iterating over variable
|
||||||
|
// declarations
|
||||||
|
for (const auto *decl : cls.decls()) {
|
||||||
|
if (decl->getKind() == clang::Decl::Var) {
|
||||||
|
const clang::VarDecl *variable_declaration{
|
||||||
|
dynamic_cast<const clang::VarDecl *>(decl)};
|
||||||
|
if (variable_declaration &&
|
||||||
|
variable_declaration->isStaticDataMember()) {
|
||||||
|
process_static_field(*variable_declaration, relationships);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cls.isCompleteDefinition())
|
||||||
|
for (const auto *friend_declaration : cls.friends()) {
|
||||||
|
if (friend_declaration != nullptr)
|
||||||
|
process_friend(*friend_declaration, relationships);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void translation_unit_visitor::process_class_bases(
|
||||||
|
const clang::CXXRecordDecl &cls, found_relationships_t &relationships)
|
||||||
|
{
|
||||||
|
for (auto &base : cls.bases()) {
|
||||||
|
find_relationships(base.getType(), relationships);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void translation_unit_visitor::process_method(
|
||||||
|
const clang::CXXMethodDecl &method, found_relationships_t &relationships)
|
||||||
|
{
|
||||||
|
find_relationships(method.getReturnType(), relationships);
|
||||||
|
|
||||||
|
for (const auto *param : method.parameters()) {
|
||||||
|
if (param != nullptr)
|
||||||
|
find_relationships(param->getType(), relationships);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void translation_unit_visitor::process_template_method(
|
||||||
|
const clang::FunctionTemplateDecl &method,
|
||||||
|
found_relationships_t &relationships)
|
||||||
|
{
|
||||||
|
// TODO: For now skip implicitly default methods
|
||||||
|
// in the future, add config option to choose
|
||||||
|
if (method.getTemplatedDecl()->isDefaulted() &&
|
||||||
|
!method.getTemplatedDecl()->isExplicitlyDefaulted())
|
||||||
|
return;
|
||||||
|
|
||||||
|
find_relationships(
|
||||||
|
method.getTemplatedDecl()->getReturnType(), relationships);
|
||||||
|
|
||||||
|
for (const auto *param : method.getTemplatedDecl()->parameters()) {
|
||||||
|
if (param != nullptr) {
|
||||||
|
find_relationships(param->getType(), relationships);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void translation_unit_visitor::process_field(
|
||||||
|
const clang::FieldDecl &field_declaration,
|
||||||
|
found_relationships_t &relationships)
|
||||||
|
{
|
||||||
|
find_relationships(field_declaration.getType(), relationships,
|
||||||
|
relationship_t::kDependency);
|
||||||
|
}
|
||||||
|
|
||||||
|
void translation_unit_visitor::process_static_field(
|
||||||
|
const clang::VarDecl &field_declaration,
|
||||||
|
found_relationships_t &relationships)
|
||||||
|
{
|
||||||
|
find_relationships(field_declaration.getType(), relationships,
|
||||||
|
relationship_t::kDependency);
|
||||||
|
}
|
||||||
|
|
||||||
|
void translation_unit_visitor::process_friend(
|
||||||
|
const clang::FriendDecl &friend_declaration,
|
||||||
|
found_relationships_t &relationships)
|
||||||
|
{
|
||||||
|
if (const auto *friend_type_declaration =
|
||||||
|
friend_declaration.getFriendDecl()) {
|
||||||
|
if (friend_type_declaration->isTemplateDecl()) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (const auto *friend_type = friend_declaration.getFriendType()) {
|
||||||
|
find_relationships(friend_type->getType(), relationships);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool translation_unit_visitor::find_relationships(const clang::QualType &type,
|
||||||
|
found_relationships_t &relationships, relationship_t relationship_hint)
|
||||||
|
{
|
||||||
|
bool result{false};
|
||||||
|
|
||||||
|
if (type->isVoidType() || type->isVoidPointerType()) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
else if (type->isPointerType()) {
|
||||||
|
relationship_hint = relationship_t::kAssociation;
|
||||||
|
find_relationships(
|
||||||
|
type->getPointeeType(), relationships, relationship_hint);
|
||||||
|
}
|
||||||
|
else if (type->isRValueReferenceType()) {
|
||||||
|
relationship_hint = relationship_t::kAggregation;
|
||||||
|
find_relationships(
|
||||||
|
type.getNonReferenceType(), relationships, relationship_hint);
|
||||||
|
}
|
||||||
|
else if (type->isLValueReferenceType()) {
|
||||||
|
relationship_hint = relationship_t::kAssociation;
|
||||||
|
find_relationships(
|
||||||
|
type.getNonReferenceType(), relationships, relationship_hint);
|
||||||
|
}
|
||||||
|
else if (type->isArrayType()) {
|
||||||
|
find_relationships(type->getAsArrayTypeUnsafe()->getElementType(),
|
||||||
|
relationships, relationship_t::kAggregation);
|
||||||
|
}
|
||||||
|
else if (type->isEnumeralType()) {
|
||||||
|
relationships.emplace_back(
|
||||||
|
type->getAs<clang::EnumType>()->getDecl()->getID(),
|
||||||
|
relationship_hint);
|
||||||
|
}
|
||||||
|
else if (auto *template_specialization_type =
|
||||||
|
type->getAs<clang::TemplateSpecializationType>()) {
|
||||||
|
if (template_specialization_type != nullptr) {
|
||||||
|
if (template_specialization_type->isTypeAlias())
|
||||||
|
template_specialization_type =
|
||||||
|
template_specialization_type->getAliasedType()
|
||||||
|
->getAs<clang::TemplateSpecializationType>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (template_specialization_type != nullptr) {
|
||||||
|
for (const auto &template_argument :
|
||||||
|
*template_specialization_type) {
|
||||||
|
const auto template_argument_kind = template_argument.getKind();
|
||||||
|
if (template_argument_kind ==
|
||||||
|
clang::TemplateArgument::ArgKind::Integral) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
else if (template_argument_kind ==
|
||||||
|
clang::TemplateArgument::ArgKind::Null) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
else if (template_argument_kind ==
|
||||||
|
clang::TemplateArgument::ArgKind::Expression) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
else if (template_argument.getKind() ==
|
||||||
|
clang::TemplateArgument::ArgKind::NullPtr) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
else if (template_argument_kind ==
|
||||||
|
clang::TemplateArgument::ArgKind::Template) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
else if (template_argument_kind ==
|
||||||
|
clang::TemplateArgument::ArgKind::TemplateExpansion) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
else if (template_argument.getAsType()
|
||||||
|
->getAs<clang::FunctionProtoType>()) {
|
||||||
|
for (const auto ¶m_type :
|
||||||
|
template_argument.getAsType()
|
||||||
|
->getAs<clang::FunctionProtoType>()
|
||||||
|
->param_types()) {
|
||||||
|
result = find_relationships(param_type, relationships,
|
||||||
|
relationship_t::kDependency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (template_argument_kind ==
|
||||||
|
clang::TemplateArgument::ArgKind::Type) {
|
||||||
|
result = find_relationships(template_argument.getAsType(),
|
||||||
|
relationships, relationship_hint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type->isRecordType()) {
|
||||||
|
const auto *namespace_context =
|
||||||
|
type->getAsCXXRecordDecl()->getEnclosingNamespaceContext();
|
||||||
|
if (namespace_context != nullptr && namespace_context->isNamespace()) {
|
||||||
|
const auto *namespace_declaration =
|
||||||
|
clang::cast<clang::NamespaceDecl>(namespace_context);
|
||||||
|
|
||||||
|
if (diagram().should_include(
|
||||||
|
namespace_declaration->getQualifiedNameAsString())) {
|
||||||
|
const auto target_id =
|
||||||
|
to_id(clang::cast<clang::NamespaceDecl>(namespace_context));
|
||||||
|
relationships.emplace_back(target_id, relationship_hint);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,10 @@
|
|||||||
|
|
||||||
namespace clanguml::package_diagram::visitor {
|
namespace clanguml::package_diagram::visitor {
|
||||||
|
|
||||||
|
using found_relationships_t =
|
||||||
|
std::vector<std::pair<clanguml::common::model::diagram_element::id_t,
|
||||||
|
common::model::relationship_t>>;
|
||||||
|
|
||||||
class translation_unit_visitor
|
class translation_unit_visitor
|
||||||
: public clang::RecursiveASTVisitor<translation_unit_visitor> {
|
: public clang::RecursiveASTVisitor<translation_unit_visitor> {
|
||||||
public:
|
public:
|
||||||
@@ -40,9 +44,75 @@ public:
|
|||||||
clanguml::package_diagram::model::diagram &diagram,
|
clanguml::package_diagram::model::diagram &diagram,
|
||||||
const clanguml::config::package_diagram &config);
|
const clanguml::config::package_diagram &config);
|
||||||
|
|
||||||
|
virtual bool VisitNamespaceDecl(clang::NamespaceDecl *ns);
|
||||||
|
|
||||||
|
virtual bool VisitCXXRecordDecl(clang::CXXRecordDecl *cls);
|
||||||
|
|
||||||
|
virtual bool VisitFunctionDecl(clang::FunctionDecl *function_declaration);
|
||||||
|
|
||||||
|
clanguml::package_diagram::model::diagram &diagram() { return diagram_; }
|
||||||
|
|
||||||
|
const clanguml::config::package_diagram &config() const { return config_; }
|
||||||
|
|
||||||
void finalize() { }
|
void finalize() { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void process_class_declaration(
|
||||||
|
const clang::CXXRecordDecl &cls, found_relationships_t &relationships);
|
||||||
|
|
||||||
|
void process_class_children(
|
||||||
|
const clang::CXXRecordDecl &cls, found_relationships_t &relationships);
|
||||||
|
|
||||||
|
void process_class_bases(
|
||||||
|
const clang::CXXRecordDecl &cls, found_relationships_t &relationships);
|
||||||
|
|
||||||
|
void process_method(const clang::CXXMethodDecl &method,
|
||||||
|
found_relationships_t &relationships);
|
||||||
|
|
||||||
|
void process_template_method(const clang::FunctionTemplateDecl &method,
|
||||||
|
found_relationships_t &relationships);
|
||||||
|
|
||||||
|
void process_field(const clang::FieldDecl &field_declaration,
|
||||||
|
found_relationships_t &relationships);
|
||||||
|
|
||||||
|
void process_static_field(const clang::VarDecl &field_declaration,
|
||||||
|
found_relationships_t &relationships);
|
||||||
|
|
||||||
|
void process_friend(const clang::FriendDecl &friend_declaration,
|
||||||
|
found_relationships_t &relationships);
|
||||||
|
|
||||||
|
bool find_relationships(const clang::QualType &type,
|
||||||
|
found_relationships_t &relationships,
|
||||||
|
common::model::relationship_t relationship_hint =
|
||||||
|
common::model::relationship_t::kDependency);
|
||||||
|
|
||||||
|
void add_relationships(clang::DeclContext *cls, found_relationships_t &relationships);
|
||||||
|
|
||||||
|
template <typename ClangDecl>
|
||||||
|
void process_comment(
|
||||||
|
const ClangDecl &decl, clanguml::common::model::decorated_element &e)
|
||||||
|
{
|
||||||
|
const auto *comment =
|
||||||
|
decl.getASTContext().getRawCommentForDeclNoCache(&decl);
|
||||||
|
|
||||||
|
if (comment != nullptr) {
|
||||||
|
e.set_comment(comment->getFormattedText(
|
||||||
|
source_manager_, decl.getASTContext().getDiagnostics()));
|
||||||
|
e.add_decorators(decorators::parse(e.comment().value()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_source_location(const clang::Decl &decl,
|
||||||
|
clanguml::common::model::source_location &element)
|
||||||
|
{
|
||||||
|
if (decl.getLocation().isValid()) {
|
||||||
|
element.set_file(
|
||||||
|
source_manager_.getFilename(decl.getLocation()).str());
|
||||||
|
element.set_line(
|
||||||
|
source_manager_.getSpellingLineNumber(decl.getLocation()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
clang::SourceManager &source_manager_;
|
clang::SourceManager &source_manager_;
|
||||||
|
|
||||||
// Reference to the output diagram model
|
// Reference to the output diagram model
|
||||||
|
|||||||
@@ -34,6 +34,12 @@ common::optional_ref<common::model::diagram_element> diagram::get(
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
common::optional_ref<common::model::diagram_element> diagram::get(
|
||||||
|
const common::model::diagram_element::id_t /*id*/) const
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
std::string diagram::to_alias(const std::string &full_name) const
|
std::string diagram::to_alias(const std::string &full_name) const
|
||||||
{
|
{
|
||||||
return full_name;
|
return full_name;
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ public:
|
|||||||
common::optional_ref<common::model::diagram_element> get(
|
common::optional_ref<common::model::diagram_element> get(
|
||||||
const std::string &full_name) const override;
|
const std::string &full_name) const override;
|
||||||
|
|
||||||
|
common::optional_ref<common::model::diagram_element> get(
|
||||||
|
const common::model::diagram_element::id_t id) const override;
|
||||||
|
|
||||||
std::string to_alias(const std::string &full_name) const;
|
std::string to_alias(const std::string &full_name) const;
|
||||||
|
|
||||||
bool started{false};
|
bool started{false};
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ TEST_CASE("t30001", "[test-case][package]")
|
|||||||
|
|
||||||
REQUIRE(diagram->name == "t30001_package");
|
REQUIRE(diagram->name == "t30001_package");
|
||||||
|
|
||||||
auto model = generate_package_diagram(db, diagram);
|
auto model = generate_package_diagram(*db, diagram);
|
||||||
|
|
||||||
REQUIRE(model->name() == "t30001_package");
|
REQUIRE(model->name() == "t30001_package");
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,14 @@ namespace A15 {
|
|||||||
struct CO {
|
struct CO {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
namespace A16 {
|
||||||
|
struct CP {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
namespace A17 {
|
||||||
|
struct CR {
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
namespace B::BB::BBB {
|
namespace B::BB::BBB {
|
||||||
class CBA : public A::AA::A6::CF {
|
class CBA : public A::AA::A6::CF {
|
||||||
@@ -75,11 +83,14 @@ public:
|
|||||||
std::shared_ptr<A::AA::A3::CC> cc_;
|
std::shared_ptr<A::AA::A3::CC> cc_;
|
||||||
std::map<std::string, std::unique_ptr<A::AA::A4::CD>> *cd_;
|
std::map<std::string, std::unique_ptr<A::AA::A4::CD>> *cd_;
|
||||||
std::array<A::AA::A15::CO, 5> co_;
|
std::array<A::AA::A15::CO, 5> co_;
|
||||||
|
static A::AA::A16::CP* cp_;
|
||||||
|
|
||||||
CBA() = default;
|
CBA() = default;
|
||||||
|
|
||||||
CBA(A::AA::A14::CN *cn) { }
|
CBA(A::AA::A14::CN *cn) { }
|
||||||
|
|
||||||
|
friend A::AA::A17::CR;
|
||||||
|
|
||||||
template <typename... Item> CBA(std::tuple<Item...> &items) { }
|
template <typename... Item> CBA(std::tuple<Item...> &items) { }
|
||||||
|
|
||||||
void ce(const std::vector<A::AA::A5::CE> /*ce_*/) { }
|
void ce(const std::vector<A::AA::A5::CE> /*ce_*/) { }
|
||||||
@@ -87,7 +98,7 @@ public:
|
|||||||
std::shared_ptr<A::AA::A7::CG> cg() { return {}; }
|
std::shared_ptr<A::AA::A7::CG> cg() { return {}; }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void ch(std::map<T, std::shared_ptr<A::AA::A8::CH>> & /*ch_*/)
|
void ch(std::map<T, std::shared_ptr<A::AA::A8::CH>> & ch_)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ TEST_CASE("t30002", "[test-case][package]")
|
|||||||
|
|
||||||
REQUIRE(diagram->name == "t30002_package");
|
REQUIRE(diagram->name == "t30002_package");
|
||||||
|
|
||||||
auto model = generate_package_diagram(db, diagram);
|
auto model = generate_package_diagram(*db, diagram);
|
||||||
|
|
||||||
REQUIRE(model->name() == "t30002_package");
|
REQUIRE(model->name() == "t30002_package");
|
||||||
|
|
||||||
@@ -48,6 +48,8 @@ TEST_CASE("t30002", "[test-case][package]")
|
|||||||
REQUIRE_THAT(puml, IsPackage("A13"));
|
REQUIRE_THAT(puml, IsPackage("A13"));
|
||||||
REQUIRE_THAT(puml, IsPackage("A14"));
|
REQUIRE_THAT(puml, IsPackage("A14"));
|
||||||
REQUIRE_THAT(puml, IsPackage("A15"));
|
REQUIRE_THAT(puml, IsPackage("A15"));
|
||||||
|
REQUIRE_THAT(puml, IsPackage("A16"));
|
||||||
|
REQUIRE_THAT(puml, IsPackage("A17"));
|
||||||
|
|
||||||
REQUIRE_THAT(puml, IsDependency(_A("BBB"), _A("A1")));
|
REQUIRE_THAT(puml, IsDependency(_A("BBB"), _A("A1")));
|
||||||
REQUIRE_THAT(puml, IsDependency(_A("BBB"), _A("A2")));
|
REQUIRE_THAT(puml, IsDependency(_A("BBB"), _A("A2")));
|
||||||
@@ -64,6 +66,8 @@ TEST_CASE("t30002", "[test-case][package]")
|
|||||||
REQUIRE_THAT(puml, IsDependency(_A("BBB"), _A("A13")));
|
REQUIRE_THAT(puml, IsDependency(_A("BBB"), _A("A13")));
|
||||||
REQUIRE_THAT(puml, IsDependency(_A("BBB"), _A("A14")));
|
REQUIRE_THAT(puml, IsDependency(_A("BBB"), _A("A14")));
|
||||||
REQUIRE_THAT(puml, IsDependency(_A("BBB"), _A("A15")));
|
REQUIRE_THAT(puml, IsDependency(_A("BBB"), _A("A15")));
|
||||||
|
REQUIRE_THAT(puml, IsDependency(_A("BBB"), _A("A16")));
|
||||||
|
REQUIRE_THAT(puml, IsDependency(_A("BBB"), _A("A17")));
|
||||||
|
|
||||||
save_puml(
|
save_puml(
|
||||||
"./" + config.output_directory() + "/" + diagram->name + ".puml", puml);
|
"./" + config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ TEST_CASE("t30003", "[test-case][package]")
|
|||||||
|
|
||||||
REQUIRE(diagram->name == "t30003_package");
|
REQUIRE(diagram->name == "t30003_package");
|
||||||
|
|
||||||
auto model = generate_package_diagram(db, diagram);
|
auto model = generate_package_diagram(*db, diagram);
|
||||||
|
|
||||||
REQUIRE(model->name() == "t30003_package");
|
REQUIRE(model->name() == "t30003_package");
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ TEST_CASE("t30004", "[test-case][package]")
|
|||||||
|
|
||||||
REQUIRE(diagram->name == "t30004_package");
|
REQUIRE(diagram->name == "t30004_package");
|
||||||
|
|
||||||
auto model = generate_package_diagram(db, diagram);
|
auto model = generate_package_diagram(*db, diagram);
|
||||||
|
|
||||||
REQUIRE(model->name() == "t30004_package");
|
REQUIRE(model->name() == "t30004_package");
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ TEST_CASE("t30005", "[test-case][package]")
|
|||||||
|
|
||||||
REQUIRE(diagram->name == "t30005_package");
|
REQUIRE(diagram->name == "t30005_package");
|
||||||
|
|
||||||
auto model = generate_package_diagram(db, diagram);
|
auto model = generate_package_diagram(*db, diagram);
|
||||||
|
|
||||||
REQUIRE(model->name() == "t30005_package");
|
REQUIRE(model->name() == "t30005_package");
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ TEST_CASE("t30006", "[test-case][package]")
|
|||||||
|
|
||||||
REQUIRE(diagram->name == "t30006_package");
|
REQUIRE(diagram->name == "t30006_package");
|
||||||
|
|
||||||
auto model = generate_package_diagram(db, diagram);
|
auto model = generate_package_diagram(*db, diagram);
|
||||||
|
|
||||||
REQUIRE(model->name() == "t30006_package");
|
REQUIRE(model->name() == "t30006_package");
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ TEST_CASE("t30007", "[test-case][package]")
|
|||||||
|
|
||||||
REQUIRE(diagram->name == "t30007_package");
|
REQUIRE(diagram->name == "t30007_package");
|
||||||
|
|
||||||
auto model = generate_package_diagram(db, diagram);
|
auto model = generate_package_diagram(*db, diagram);
|
||||||
|
|
||||||
REQUIRE(model->name() == "t30007_package");
|
REQUIRE(model->name() == "t30007_package");
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ TEST_CASE("t30008", "[test-case][package]")
|
|||||||
|
|
||||||
REQUIRE(diagram->name == "t30008_package");
|
REQUIRE(diagram->name == "t30008_package");
|
||||||
|
|
||||||
auto model = generate_package_diagram(db, diagram);
|
auto model = generate_package_diagram(*db, diagram);
|
||||||
|
|
||||||
REQUIRE(model->name() == "t30008_package");
|
REQUIRE(model->name() == "t30008_package");
|
||||||
|
|
||||||
|
|||||||
@@ -245,14 +245,14 @@ using namespace clanguml::test::matchers;
|
|||||||
////
|
////
|
||||||
//// Package diagram tests
|
//// Package diagram tests
|
||||||
////
|
////
|
||||||
//#include "t30001/test_case.h"
|
#include "t30001/test_case.h"
|
||||||
//#include "t30002/test_case.h"
|
#include "t30002/test_case.h"
|
||||||
//#include "t30003/test_case.h"
|
#include "t30003/test_case.h"
|
||||||
//#include "t30004/test_case.h"
|
#include "t30004/test_case.h"
|
||||||
//#include "t30005/test_case.h"
|
#include "t30005/test_case.h"
|
||||||
//#include "t30006/test_case.h"
|
#include "t30006/test_case.h"
|
||||||
//#include "t30007/test_case.h"
|
#include "t30007/test_case.h"
|
||||||
//#include "t30008/test_case.h"
|
#include "t30008/test_case.h"
|
||||||
//
|
//
|
||||||
////
|
////
|
||||||
//// Include diagram tests
|
//// Include diagram tests
|
||||||
|
|||||||
Reference in New Issue
Block a user