Refactored test cases implementation

This commit is contained in:
Bartek Kryza
2021-02-20 23:17:14 +01:00
parent 501a1f0466
commit ce7aab2a0f
11 changed files with 157 additions and 37 deletions

View File

@@ -18,13 +18,41 @@ struct plantuml {
std::vector<std::string> after;
};
struct filter {
std::vector<std::string> namespaces;
};
struct diagram {
virtual ~diagram() = default;
std::string name;
std::vector<std::string> glob;
std::vector<std::string> using_namespace;
filter include;
filter exclude;
plantuml puml;
bool should_include(const std::string &name) const
{
for (const auto &ex : exclude.namespaces) {
if (name.find(ex) == 0)
return false;
}
// If no inclusive namespaces are provided,
// allow all
if (include.namespaces.empty())
return true;
for (const auto &in : include.namespaces) {
if (name.find(in) == 0)
return true;
}
return false;
}
};
struct source_location {
@@ -34,7 +62,7 @@ struct source_location {
// std::variant requires unique types, so we cannot add
// marker here, we need sth like boost::mp_unique
// type function
using variant = std::variant<usr, file>;
using variant = std::variant<usr, /* marker, */ file>;
};
enum class class_scopes { public_, protected_, private_ };
@@ -84,6 +112,7 @@ config load(const std::string &config_file);
namespace YAML {
using clanguml::config::class_diagram;
using clanguml::config::config;
using clanguml::config::filter;
using clanguml::config::plantuml;
using clanguml::config::sequence_diagram;
using clanguml::config::source_location;
@@ -140,6 +169,18 @@ template <> struct convert<plantuml> {
}
};
//
// filter Yaml decoder
//
template <> struct convert<filter> {
static bool decode(const Node &node, filter &rhs)
{
if (node["namespaces"])
rhs.namespaces = node["namespaces"].as<decltype(rhs.namespaces)>();
return true;
}
};
//
// sequence_diagram Yaml decoder
//
@@ -151,6 +192,12 @@ template <> struct convert<sequence_diagram> {
rhs.glob = node["glob"].as<std::vector<std::string>>();
rhs.puml = node["plantuml"].as<plantuml>();
if (node["include"])
rhs.include = node["include"].as<decltype(rhs.include)>();
if (node["exclude"])
rhs.exclude = node["exclude"].as<decltype(rhs.exclude)>();
if (node["start_from"])
rhs.start_from = node["start_from"].as<decltype(rhs.start_from)>();
return true;
@@ -176,21 +223,21 @@ template <> struct convert<config> {
for (const auto &d : diagrams) {
const auto diagram_type = d.second["type"].as<std::string>();
auto name = d.first.as<std::string>();
if (diagram_type == "class") {
rhs.diagrams[d.first.as<std::string>()] =
std::make_shared<class_diagram>(
d.second.as<class_diagram>());
rhs.diagrams[name] = std::make_shared<class_diagram>(
d.second.as<class_diagram>());
}
if (diagram_type == "sequence") {
rhs.diagrams[d.first.as<std::string>()] =
std::make_shared<sequence_diagram>(
d.second.as<sequence_diagram>());
rhs.diagrams[name] = std::make_shared<sequence_diagram>(
d.second.as<sequence_diagram>());
}
else {
spdlog::warn(
"Diagrams of type {} are not supported at the moment... ",
diagram_type);
}
rhs.diagrams[name]->name = name;
}
return true;

View File

@@ -14,7 +14,13 @@ compilation_database::compilation_database(CXCompilationDatabase &&d)
compilation_database::~compilation_database()
{
clang_CompilationDatabase_dispose(m_database);
//clang_CompilationDatabase_dispose(m_database);
}
compilation_database::compilation_database(compilation_database &&d)
: m_database{std::move(d.m_database)}
, m_index{std::move(d.m_index)}
{
}
compilation_database compilation_database::from_directory(

View File

@@ -15,6 +15,8 @@ public:
compilation_database(CXCompilationDatabase &&d);
~compilation_database();
compilation_database(compilation_database &&d);
CXCompilationDatabase &db();
CXIndex &index();

View File

@@ -52,8 +52,7 @@ int main(int argc, const char *argv[])
spdlog::info("Loading compilation database from {} directory",
config.compilation_database_dir);
auto db =
compilation_database::from_directory(config.compilation_database_dir);
auto db = compilation_database::from_directory(config.compilation_database_dir);
for (const auto &[name, diagram] : config.diagrams) {
using clanguml::config::class_diagram;
@@ -82,5 +81,6 @@ int main(int argc, const char *argv[])
ofs.close();
}
return 0;
}

View File

@@ -156,7 +156,7 @@ clanguml::model::sequence_diagram::diagram generate(
spdlog::debug("Cursor name: {}",
clang_getCString(clang_getCursorDisplayName(cursor)));
clanguml::visitor::sequence_diagram::tu_context ctx(d);
clanguml::visitor::sequence_diagram::tu_context ctx(d, diagram);
auto res = clang_visitChildren(cursor,
clanguml::visitor::sequence_diagram::translation_unit_visitor,
&ctx);

View File

@@ -21,14 +21,16 @@ using clanguml::model::sequence_diagram::message;
using clanguml::model::sequence_diagram::message_t;
struct tu_context {
tu_context(diagram &d_)
tu_context(diagram &d_, const clanguml::config::sequence_diagram &config_)
: d{d_}
, config{config_}
{
}
std::vector<std::string> namespace_;
cx::cursor current_method;
clanguml::model::sequence_diagram::diagram &d;
const clanguml::config::sequence_diagram &config;
};
static enum CXChildVisitResult translation_unit_visitor(
@@ -71,20 +73,21 @@ static enum CXChildVisitResult translation_unit_visitor(
std::string file{clang_getCString(clang_getFileName(f))};
auto &d = ctx->d;
auto &config = ctx->config;
if (referenced.kind() == CXCursor_CXXMethod) {
if (true/*sp_name.find("clanguml::") == 0 ||
clang_Location_isFromMainFile(cursor.location())*/) {
if (config.should_include(sp_name)) {
// Get calling object
std::string caller{};
if (ctx->current_method.semantic_parent()
.is_translation_unit() ||
ctx->current_method.semantic_parent().is_namespace()) {
caller =
ctx->current_method.semantic_parent().fully_qualified() +
caller = ctx->current_method.semantic_parent()
.fully_qualified() +
"::" + ctx->current_method.spelling() + "()";
}
else {
caller = ctx->current_method.semantic_parent().fully_qualified();
caller = ctx->current_method.semantic_parent()
.fully_qualified();
}
auto caller_usr = ctx->current_method.usr();

View File

@@ -10,6 +10,9 @@ std::string namespace_relative(
const std::vector<std::string> &namespaces, const std::string &n)
{
for (const auto &ns : namespaces) {
if(ns.empty())
continue;
if (n == ns)
return "";