This commit is contained in:
Bartek Kryza
2022-07-18 23:41:37 +02:00
parent 88a87edc42
commit 8a7e89cb63
32 changed files with 491 additions and 648 deletions

View File

@@ -22,8 +22,6 @@
#include "namespace.h"
#include "source_file.h"
#include <type_safe/optional_ref.hpp>
#include <memory>
#include <string>
@@ -40,8 +38,9 @@ public:
virtual diagram_t type() const = 0;
virtual type_safe::optional_ref<const diagram_element> get(
const std::string &full_name) const = 0;
virtual std::optional<
std::reference_wrapper<const clanguml::common::model::diagram_element>>
get(const std::string &full_name) const = 0;
diagram(const diagram &) = delete;
diagram(diagram &&);
@@ -63,8 +62,12 @@ public:
bool should_include(const relationship r) const;
bool should_include(const relationship_t r) const;
bool should_include(const access_t s) const;
virtual bool has_element(const diagram_element::id_t id) const
{
return false;
}
bool should_include(const namespace_ &ns, const std::string &name) const;
virtual bool should_include(const namespace_ &ns, const std::string &name) const;
private:
std::string name_;

View File

@@ -27,26 +27,25 @@ namespace clanguml::common::model {
std::atomic_uint64_t diagram_element::m_nextId = 1;
diagram_element::diagram_element()
: m_id{m_nextId++}
: id_{0}
{
}
diagram_element::id_t diagram_element::id() const { return id_; }
void diagram_element::set_id(diagram_element::id_t id) { id_ = id; }
std::string diagram_element::alias() const
{
return fmt::format("C_{:010}", m_id);
assert(id_ >= 0);
return fmt::format("C_{:022}", id_);
}
void diagram_element::add_relationship(relationship &&cr)
{
if (cr.destination().empty()) {
LOG_DBG("Skipping relationship '{}' - {} - '{}' due empty "
"destination",
cr.destination(), to_string(cr.type()), full_name(true));
return;
}
if ((cr.type() == relationship_t::kInstantiation) &&
(cr.destination() == full_name(true))) {
(cr.destination() == id())) {
LOG_DBG("Skipping self instantiation relationship for {}",
cr.destination());
return;
@@ -86,7 +85,8 @@ inja::json diagram_element::context() const
bool operator==(const diagram_element &l, const diagram_element &r)
{
return l.full_name(false) == r.full_name(false);
return l.id() == r.id();
//return l.full_name(false) == r.full_name(false);
}
std::ostream &operator<<(std::ostream &out, const diagram_element &rhs)

View File

@@ -32,10 +32,16 @@ namespace clanguml::common::model {
class diagram_element : public decorated_element {
public:
using id_t = int64_t;
diagram_element();
virtual ~diagram_element() = default;
id_t id() const;
void set_id(id_t id);
std::string alias() const;
void set_name(const std::string &name) { name_ = name; }
@@ -59,10 +65,8 @@ public:
virtual inja::json context() const;
protected:
const uint64_t m_id{0};
private:
id_t id_;
std::string name_;
std::vector<relationship> relationships_;

View File

@@ -28,59 +28,59 @@ namespace clanguml::common::model {
namespace detail {
template <>
const std::vector<type_safe::object_ref<const class_diagram::model::class_>> &
view(const class_diagram::model::diagram &d)
const clanguml::common::reference_vector<class_diagram::model::class_> &view(
const class_diagram::model::diagram &d)
{
return d.classes();
}
template <>
const std::vector<type_safe::object_ref<const class_diagram::model::enum_>> &
view(const class_diagram::model::diagram &d)
const clanguml::common::reference_vector<class_diagram::model::enum_> &view(
const class_diagram::model::diagram &d)
{
return d.enums();
}
template <>
const std::vector<type_safe::object_ref<const common::model::package>> &view(
const clanguml::common::reference_vector<common::model::package> &view(
const package_diagram::model::diagram &d)
{
return d.packages();
}
template <>
const std::vector<type_safe::object_ref<const common::model::source_file>> &
view(const include_diagram::model::diagram &d)
const clanguml::common::reference_vector<common::model::source_file> &view(
const include_diagram::model::diagram &d)
{
return d.files();
}
template <>
const type_safe::optional_ref<const class_diagram::model::class_> get(
const clanguml::common::optional_ref<class_diagram::model::class_> get(
const class_diagram::model::diagram &d, const std::string &full_name)
{
return d.get_class(full_name);
}
template <>
const type_safe::optional_ref<const common::model::package> get(
const clanguml::common::optional_ref<const common::model::package> get(
const package_diagram::model::diagram &d, const std::string &full_name)
{
return d.get_package(full_name);
}
template <>
const type_safe::optional_ref<const common::model::source_file> get(
const clanguml::common::optional_ref<const common::model::source_file> get(
const include_diagram::model::diagram &d, const std::string &full_name)
{
return d.get_file(full_name);
}
template <>
std::string destination_comparator<common::model::source_file>(
clanguml::common::id_t destination_comparator<common::model::source_file>(
const common::model::source_file &f)
{
return f.alias();
return f.id();
}
} // namespace detail
@@ -221,9 +221,7 @@ tvl::value_t subclass_filter::match(const diagram &d, const element &e) const
const auto &cd = dynamic_cast<const class_diagram::model::diagram &>(d);
// First get all parents of element e
std::unordered_set<
type_safe::object_ref<const class_diagram::model::class_, false>>
parents;
clanguml::common::reference_set<class_diagram::model::class_> parents;
const auto &fn = e.full_name(false);
auto class_ref = cd.get_class(fn);
@@ -296,26 +294,25 @@ tvl::value_t context_filter::match(const diagram &d, const element &e) const
if (context_root.has_value()) {
// This is a direct match to the context root
if (context_root.value().full_name(false) == e.full_name(false))
if (context_root.value().get().id() == e.id())
return true;
// Return a positive match if the element e is in a direct
// relationship with any of the context_root's
for (const relationship &rel :
context_root.value().relationships()) {
if (rel.destination() == e.full_name(false))
context_root.value().get().relationships()) {
if (rel.destination() == e.id())
return true;
}
for (const relationship &rel : e.relationships()) {
if (rel.destination() ==
context_root.value().full_name(false))
if (rel.destination() == context_root.value().get().id())
return true;
}
// Return a positive match if the context_root is a parent
// of the element
for (const class_diagram::model::class_parent &p :
context_root.value().parents()) {
context_root.value().get().parents()) {
if (p.name() == e.full_name(false))
return true;
}
@@ -324,7 +321,8 @@ tvl::value_t context_filter::match(const diagram &d, const element &e) const
for (const class_diagram::model::class_parent &p :
static_cast<const class_diagram::model::class_ &>(e)
.parents()) {
if (p.name() == context_root.value().full_name(false))
if (p.name() ==
context_root.value().get().full_name(false))
return true;
}
}

View File

@@ -37,21 +37,20 @@ enum filter_t { kInclusive, kExclusive };
namespace detail {
template <typename ElementT, typename DiagramT>
const std::vector<type_safe::object_ref<const ElementT>> &view(
const DiagramT &d);
const clanguml::common::reference_vector<ElementT> &view(const DiagramT &d);
template <typename ElementT, typename DiagramT>
const type_safe::optional_ref<const ElementT> get(
const clanguml::common::optional_ref<ElementT> get(
const DiagramT &d, const std::string &full_name);
template <typename ElementT>
std::string destination_comparator(const ElementT &e)
template <typename ElementT> int64_t destination_comparator(const ElementT &e)
{
return e.full_name(false);
return e.id();
}
template <>
std::string destination_comparator(const common::model::source_file &f);
clanguml::common::id_t destination_comparator(
const common::model::source_file &f);
} // namespace detail
class filter_visitor {
@@ -177,7 +176,7 @@ struct edge_traversal_filter : public filter_visitor {
// Now check if the e element is contained in the calculated set
return std::any_of(matching_elements_.begin(), matching_elements_.end(),
[&e](const auto &te) {
return te->full_name(false) == e.full_name(false);
return te.get().full_name(false) == e.full_name(false);
});
}
@@ -192,12 +191,12 @@ private:
// Check if any of its relationships of type relationship_
// points to an element already in the matching_elements_
// set
for (const auto &rel : from_el->relationships()) {
for (const auto &rel : from_el.get().relationships()) {
// Consider only if connected by one of specified relationships
if (util::contains(relationships, rel.type())) {
for (const auto &to_el : to) {
if (rel.destination() ==
detail::destination_comparator(*to_el)) {
detail::destination_comparator(to_el.get())) {
const auto &to_add = forward_ ? to_el : from_el;
if (matching_elements_.insert(to_add).second)
added_new_element = true;
@@ -220,9 +219,9 @@ private:
cd, element.get().path().to_string());
while (parent.has_value()) {
parents.emplace(type_safe::ref(parent.value()));
parents.emplace(std::ref(parent.value()));
parent = detail::get<ElementT, DiagramT>(
cd, parent.value().path().to_string());
cd, parent.value().get().path().to_string());
}
});
@@ -272,8 +271,7 @@ private:
std::vector<std::string> roots_;
relationship_t relationship_;
mutable bool initialized_{false};
mutable std::unordered_set<type_safe::object_ref<const ElementT, false>>
matching_elements_;
mutable clanguml::common::reference_set<ElementT> matching_elements_;
bool forward_;
};

View File

@@ -29,10 +29,6 @@ element::element(const namespace_ &using_namespace)
{
}
element::id_t element::id() const { return id_; }
void element::set_id(element::id_t id) { id_ = id; }
void element::set_using_namespaces(const namespace_ &un)
{
using_namespace_ = un;

View File

@@ -34,16 +34,12 @@ namespace clanguml::common::model {
class element : public diagram_element, public source_location {
public:
using id_t = int64_t;
element(const namespace_ &using_namespace);
virtual ~element() = default;
id_t id() const;
void set_id(id_t id);
std::string name_and_ns() const
{
auto ns = ns_ | name();
@@ -77,7 +73,6 @@ public:
inja::json context() const override;
private:
id_t id_;
namespace_ ns_;
namespace_ using_namespace_;
};

View File

@@ -20,6 +20,7 @@
#include "common/model/element.h"
#include "common/model/nested_trait.h"
#include "common/model/stylable_element.h"
#include "common/types.h"
#include "util/util.h"
#include <spdlog/spdlog.h>
@@ -57,14 +58,14 @@ private:
namespace std {
template <>
struct hash<type_safe::object_ref<const clanguml::common::model::package>> {
struct hash<std::reference_wrapper<const clanguml::common::model::package>> {
std::size_t operator()(
const type_safe::object_ref<const clanguml::common::model::package>
const std::reference_wrapper<const clanguml::common::model::package>
&key) const
{
using clanguml::common::model::package;
using clanguml::common::id_t;
return std::hash<std::string>{}(key.get().full_name(false));
return std::hash<id_t>{}(key.get().id());
}
};
}
}

View File

@@ -20,7 +20,7 @@
namespace clanguml::common::model {
relationship::relationship(relationship_t type, const std::string &destination,
relationship::relationship(relationship_t type, int64_t destination,
access_t access, const std::string &label,
const std::string &multiplicity_source,
const std::string &multiplicity_destination)
@@ -37,12 +37,15 @@ void relationship::set_type(relationship_t type) noexcept { type_ = type; }
relationship_t relationship::type() const noexcept { return type_; }
void relationship::set_destination(const std::string &destination)
void relationship::set_destination(int64_t destination)
{
destination_ = destination;
}
std::string relationship::destination() const { return destination_; }
clanguml::common::id_t relationship::destination() const
{
return destination_;
}
void relationship::set_multiplicity_source(
const std::string &multiplicity_source)

View File

@@ -19,6 +19,7 @@
#include "common/model/decorated_element.h"
#include "common/model/stylable_element.h"
#include "common/types.h"
#include <string>
@@ -27,7 +28,7 @@ namespace clanguml::common::model {
class relationship : public common::model::decorated_element,
public common::model::stylable_element {
public:
relationship(relationship_t type, const std::string &destination,
relationship(relationship_t type, int64_t destination,
access_t access = access_t::kPublic, const std::string &label = "",
const std::string &multiplicity_source = "",
const std::string &multiplicity_destination = "");
@@ -37,8 +38,8 @@ public:
void set_type(relationship_t type) noexcept;
relationship_t type() const noexcept;
void set_destination(const std::string &destination);
std::string destination() const;
void set_destination(int64_t destination);
clanguml::common::id_t destination() const;
void set_multiplicity_source(const std::string &multiplicity_source);
std::string multiplicity_source() const;
@@ -57,7 +58,7 @@ public:
private:
relationship_t type_;
std::string destination_;
int64_t destination_;
std::string multiplicity_source_;
std::string multiplicity_destination_;
std::string label_;

View File

@@ -22,6 +22,7 @@
#include "common/model/path.h"
#include "common/model/source_location.h"
#include "common/model/stylable_element.h"
#include "common/types.h"
#include "util/util.h"
#include <spdlog/spdlog.h>
@@ -129,15 +130,19 @@ template <> struct hash<clanguml::common::model::filesystem_path> {
}
};
}
namespace std {
template <>
struct hash<type_safe::object_ref<const clanguml::common::model::source_file>> {
struct hash<
std::reference_wrapper<const clanguml::common::model::source_file>> {
std::size_t operator()(
const type_safe::object_ref<const clanguml::common::model::source_file>
const std::reference_wrapper<const clanguml::common::model::source_file>
&key) const
{
using clanguml::common::model::source_file;
using clanguml::common::id_t;
return std::hash<std::string>{}(key.get().full_name(false));
return std::hash<id_t>{}(key.get().id());
}
};
}
}