Added initial support for include graph diagrams
This commit is contained in:
@@ -85,4 +85,12 @@ bool diagram::should_include(
|
||||
return filter_->should_include(ns, name);
|
||||
}
|
||||
|
||||
bool diagram::should_include(const common::model::source_file &f) const
|
||||
{
|
||||
if (filter_.get() == nullptr)
|
||||
return true;
|
||||
|
||||
return filter_->should_include(f);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "diagram_element.h"
|
||||
#include "enums.h"
|
||||
#include "namespace.h"
|
||||
#include "source_file.h"
|
||||
|
||||
#include <type_safe/optional_ref.hpp>
|
||||
|
||||
@@ -58,9 +59,11 @@ public:
|
||||
// TODO: refactor to a template method
|
||||
bool should_include(const element &e) const;
|
||||
bool should_include(const std::string &e) const;
|
||||
bool should_include(const source_file &path) const;
|
||||
bool should_include(const relationship r) const;
|
||||
bool should_include(const relationship_t r) const;
|
||||
bool should_include(const access_t s) const;
|
||||
|
||||
bool should_include(const namespace_ &ns, const std::string &name) const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -49,6 +49,12 @@ tvl::value_t filter_visitor::match(
|
||||
return {};
|
||||
}
|
||||
|
||||
tvl::value_t filter_visitor::match(
|
||||
const diagram &d, const common::model::source_file &f) const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
bool filter_visitor::is_inclusive() const
|
||||
{
|
||||
return type_ == filter_t::kInclusive;
|
||||
@@ -254,6 +260,40 @@ tvl::value_t context_filter::match(const diagram &d, const element &e) const
|
||||
});
|
||||
}
|
||||
|
||||
paths_filter::paths_filter(filter_t type, const std::filesystem::path &root,
|
||||
std::vector<std::filesystem::path> p)
|
||||
: filter_visitor{type}
|
||||
, root_{root}
|
||||
{
|
||||
for (auto &&path : p) {
|
||||
std::filesystem::path absolute_path;
|
||||
|
||||
if (path.is_relative())
|
||||
absolute_path = root / path;
|
||||
|
||||
absolute_path = absolute_path.lexically_normal();
|
||||
|
||||
paths_.emplace_back(std::move(absolute_path));
|
||||
}
|
||||
}
|
||||
|
||||
tvl::value_t paths_filter::match(
|
||||
const diagram &d, const common::model::source_file &p) const
|
||||
{
|
||||
|
||||
if (paths_.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto pp = p.fs_path(root_);
|
||||
for (const auto &path : paths_) {
|
||||
if (util::starts_with(pp, path))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
diagram_filter::diagram_filter(
|
||||
const common::model::diagram &d, const config::diagram &c)
|
||||
: diagram_{d}
|
||||
@@ -295,6 +335,8 @@ void diagram_filter::init_filters(const config::diagram &c)
|
||||
filter_t::kInclusive, c.include().relationships));
|
||||
inclusive_.emplace_back(std::make_unique<access_filter>(
|
||||
filter_t::kInclusive, c.include().access));
|
||||
inclusive_.emplace_back(std::make_unique<paths_filter>(
|
||||
filter_t::kInclusive, c.base_directory(), c.include().paths));
|
||||
|
||||
// Include any of these matches even if one them does not match
|
||||
std::vector<std::unique_ptr<filter_visitor>> element_filters;
|
||||
@@ -305,6 +347,7 @@ void diagram_filter::init_filters(const config::diagram &c)
|
||||
element_filters.emplace_back(std::make_unique<context_filter>(
|
||||
filter_t::kInclusive, c.include().context));
|
||||
|
||||
|
||||
inclusive_.emplace_back(std::make_unique<anyof_filter>(
|
||||
filter_t::kInclusive, std::move(element_filters)));
|
||||
}
|
||||
@@ -323,6 +366,8 @@ void diagram_filter::init_filters(const config::diagram &c)
|
||||
filter_t::kExclusive, c.exclude().subclasses));
|
||||
exclusive_.emplace_back(std::make_unique<context_filter>(
|
||||
filter_t::kExclusive, c.exclude().context));
|
||||
exclusive_.emplace_back(std::make_unique<paths_filter>(
|
||||
filter_t::kInclusive, c.base_directory(), c.exclude().paths));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,8 +25,11 @@
|
||||
#include "config/config.h"
|
||||
#include "cx/util.h"
|
||||
#include "diagram.h"
|
||||
#include "source_file.h"
|
||||
#include "tvl.h"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
namespace clanguml::common::model {
|
||||
|
||||
enum filter_t { kInclusive, kExclusive };
|
||||
@@ -47,6 +50,9 @@ public:
|
||||
virtual tvl::value_t match(
|
||||
const diagram &d, const common::model::namespace_ &ns) const;
|
||||
|
||||
virtual tvl::value_t match(
|
||||
const diagram &d, const common::model::source_file &f) const;
|
||||
|
||||
bool is_inclusive() const;
|
||||
bool is_exclusive() const;
|
||||
|
||||
@@ -125,6 +131,18 @@ private:
|
||||
std::vector<std::string> context_;
|
||||
};
|
||||
|
||||
struct paths_filter : public filter_visitor {
|
||||
paths_filter(filter_t type, const std::filesystem::path &root,
|
||||
std::vector<std::filesystem::path> p);
|
||||
|
||||
tvl::value_t match(const diagram &d,
|
||||
const common::model::source_file &r) const override;
|
||||
|
||||
private:
|
||||
std::vector<std::filesystem::path> paths_;
|
||||
std::filesystem::path root_;
|
||||
};
|
||||
|
||||
class diagram_filter {
|
||||
public:
|
||||
diagram_filter(const common::model::diagram &d, const config::diagram &c);
|
||||
@@ -144,7 +162,9 @@ public:
|
||||
return false;
|
||||
|
||||
auto inc = tvl::all_of(inclusive_.begin(), inclusive_.end(),
|
||||
[this, &e](const auto &in) { return in->match(diagram_, e); });
|
||||
[this, &e](const auto &in) {
|
||||
return in->match(diagram_, e);
|
||||
});
|
||||
|
||||
if (tvl::is_undefined(inc) || tvl::is_true(inc))
|
||||
return true;
|
||||
|
||||
@@ -52,7 +52,8 @@ public:
|
||||
}
|
||||
|
||||
template <typename V = T>
|
||||
void add_element(const Path &path, std::unique_ptr<V> p)
|
||||
void add_element(
|
||||
const Path &path, std::unique_ptr<V> p)
|
||||
{
|
||||
assert(p);
|
||||
|
||||
|
||||
19
src/common/model/source_file.cc
Normal file
19
src/common/model/source_file.cc
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* src/common/model/source_file.cc
|
||||
*
|
||||
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "source_file.h"
|
||||
119
src/common/model/source_file.h
Normal file
119
src/common/model/source_file.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* src/common/model/source_file.h
|
||||
*
|
||||
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "common/model/diagram_element.h"
|
||||
#include "common/model/nested_trait.h"
|
||||
#include "common/model/path.h"
|
||||
#include "common/model/stylable_element.h"
|
||||
#include "util/util.h"
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <type_safe/optional_ref.hpp>
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace clanguml::common::model {
|
||||
|
||||
enum class source_file_t { kDirectory, kHeader, kImplementation };
|
||||
|
||||
struct fs_path_sep {
|
||||
static constexpr std::string_view value = "/";
|
||||
};
|
||||
|
||||
using filesystem_path = common::model::path<fs_path_sep>;
|
||||
|
||||
class source_file
|
||||
: public common::model::diagram_element,
|
||||
public common::model::stylable_element,
|
||||
public common::model::nested_trait<common::model::source_file,
|
||||
filesystem_path> {
|
||||
public:
|
||||
source_file() = default;
|
||||
|
||||
void set_path(const filesystem_path &p) { path_ = p; }
|
||||
|
||||
void set_absolute() { is_absolute_ = true; }
|
||||
|
||||
void set_type(source_file_t type) { type_ = type; }
|
||||
|
||||
source_file_t type() const { return type_; }
|
||||
|
||||
source_file(const source_file &) = delete;
|
||||
source_file(source_file &&) = default;
|
||||
source_file &operator=(const source_file &) = delete;
|
||||
source_file &operator=(source_file &&) = delete;
|
||||
|
||||
const filesystem_path &path() const { return path_; }
|
||||
|
||||
std::string full_name(bool relative) const override
|
||||
{
|
||||
return (path_ | name()).to_string();
|
||||
}
|
||||
|
||||
void add_file(std::unique_ptr<source_file> &&f)
|
||||
{
|
||||
LOG_DBG("Adding source file: {}, {}", f->name(), f->full_name(true));
|
||||
|
||||
add_element(f->path(), std::move(f));
|
||||
}
|
||||
|
||||
std::filesystem::path fs_path(const std::filesystem::path &base = {}) const
|
||||
{
|
||||
std::filesystem::path res;
|
||||
|
||||
for (const auto &pe : path_) {
|
||||
res /= pe;
|
||||
}
|
||||
|
||||
if (is_absolute_)
|
||||
res = "/" / res;
|
||||
else
|
||||
res = base / res;
|
||||
|
||||
return res.lexically_normal();
|
||||
}
|
||||
|
||||
private:
|
||||
filesystem_path path_;
|
||||
source_file_t type_{source_file_t::kDirectory};
|
||||
bool is_absolute_{false};
|
||||
};
|
||||
}
|
||||
|
||||
namespace std {
|
||||
|
||||
template <> struct hash<clanguml::common::model::filesystem_path> {
|
||||
std::size_t operator()(
|
||||
const clanguml::common::model::filesystem_path &key) const
|
||||
{
|
||||
using clanguml::common::model::path;
|
||||
|
||||
std::size_t seed = key.size();
|
||||
for (const auto &ns : key) {
|
||||
seed ^= std::hash<std::string>{}(ns) + 0x6a3712b5 + (seed << 6) +
|
||||
(seed >> 2);
|
||||
}
|
||||
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user