Refactored cx utils to clang_utils

This commit is contained in:
Bartek Kryza
2023-01-25 22:42:49 +01:00
parent 9a7d66f93f
commit 21e7c3d3a0
11 changed files with 129 additions and 188 deletions

View File

@@ -18,7 +18,6 @@
#include "translation_unit_visitor.h" #include "translation_unit_visitor.h"
#include "common/clang_utils.h" #include "common/clang_utils.h"
#include "cx/util.h"
#include <clang/Basic/FileManager.h> #include <clang/Basic/FileManager.h>
#include <clang/Lex/Preprocessor.h> #include <clang/Lex/Preprocessor.h>
@@ -1358,9 +1357,8 @@ void translation_unit_visitor::process_template_specialization_argument(
declaration_text.find(cls->getNameAsString()) + declaration_text.find(cls->getNameAsString()) +
cls->getNameAsString().size() + 1); cls->getNameAsString().size() + 1);
auto template_params = auto template_params = common::parse_unexposed_template_params(
cx::util::parse_unexposed_template_params( declaration_text, [](const auto &t) { return t; });
declaration_text, [](const auto &t) { return t; });
if (template_params.size() > argument_index) if (template_params.size() > argument_index)
type_name = template_params[argument_index].to_string( type_name = template_params[argument_index].to_string(
@@ -1404,9 +1402,8 @@ void translation_unit_visitor::process_template_specialization_argument(
declaration_text.find(cls->getNameAsString()) + declaration_text.find(cls->getNameAsString()) +
cls->getNameAsString().size() + 1); cls->getNameAsString().size() + 1);
auto template_params = auto template_params = common::parse_unexposed_template_params(
cx::util::parse_unexposed_template_params( declaration_text, [](const auto &t) { return t; });
declaration_text, [](const auto &t) { return t; });
if (template_params.size() > argument_index) if (template_params.size() > argument_index)
type_name = template_params[argument_index].to_string( type_name = template_params[argument_index].to_string(
@@ -1472,7 +1469,7 @@ void translation_unit_visitor::
process_unexposed_template_specialization_parameters( process_unexposed_template_specialization_parameters(
const std::string &type_name, template_parameter &tp, class_ &c) const std::string &type_name, template_parameter &tp, class_ &c)
{ {
auto template_params = cx::util::parse_unexposed_template_params( auto template_params = common::parse_unexposed_template_params(
type_name, [](const std::string &t) { return t; }); type_name, [](const std::string &t) { return t; });
found_relationships_t relationships; found_relationships_t relationships;
@@ -2211,7 +2208,7 @@ void translation_unit_visitor::process_field(
[&d = diagram()](const std::string &full_name) { [&d = diagram()](const std::string &full_name) {
if (full_name.empty()) if (full_name.empty())
return false; return false;
auto [ns, name] = cx::util::split_ns(full_name); auto [ns, name] = common::split_ns(full_name);
return d.should_include(ns, name); return d.should_include(ns, name);
}); });
} }

View File

@@ -300,4 +300,104 @@ template <> id_t to_id(const clang::TemplateArgument &template_argument)
throw std::runtime_error("Cannot generate id for template argument"); throw std::runtime_error("Cannot generate id for template argument");
} }
std::pair<common::model::namespace_, std::string> split_ns(
const std::string &full_name)
{
assert(!full_name.empty());
auto name_before_template = ::clanguml::util::split(full_name, "<")[0];
auto ns = common::model::namespace_{
::clanguml::util::split(name_before_template, "::")};
auto name = ns.name();
ns.pop_back();
return {ns, name};
}
std::vector<common::model::template_parameter> parse_unexposed_template_params(
const std::string &params,
const std::function<std::string(const std::string &)> &ns_resolve,
int depth)
{
using common::model::template_parameter;
std::vector<template_parameter> res;
auto it = params.begin();
while (std::isspace(*it) != 0)
++it;
std::string type{};
std::vector<template_parameter> nested_params;
bool complete_class_template_argument{false};
while (it != params.end()) {
if (*it == '<') {
int nested_level{0};
auto bracket_match_begin = it + 1;
auto bracket_match_end = bracket_match_begin;
while (bracket_match_end != params.end()) {
if (*bracket_match_end == '<') {
nested_level++;
}
else if (*bracket_match_end == '>') {
if (nested_level > 0)
nested_level--;
else
break;
}
else {
}
bracket_match_end++;
}
std::string nested_params_str(
bracket_match_begin, bracket_match_end);
nested_params = parse_unexposed_template_params(
nested_params_str, ns_resolve, depth + 1);
if (nested_params.empty())
nested_params.emplace_back(
template_parameter{nested_params_str});
it = bracket_match_end - 1;
}
else if (*it == '>') {
complete_class_template_argument = true;
if (depth == 0) {
break;
}
}
else if (*it == ',') {
complete_class_template_argument = true;
}
else {
type += *it;
}
if (complete_class_template_argument) {
template_parameter t;
t.set_type(ns_resolve(clanguml::util::trim(type)));
type = "";
for (auto &&param : nested_params)
t.add_template_param(std::move(param));
res.emplace_back(std::move(t));
complete_class_template_argument = false;
}
it++;
}
if (!type.empty()) {
template_parameter t;
t.set_type(ns_resolve(clanguml::util::trim(type)));
type = "";
for (auto &&param : nested_params)
t.add_template_param(std::move(param));
res.emplace_back(std::move(t));
}
return res;
}
} // namespace clanguml::common } // namespace clanguml::common

View File

@@ -17,8 +17,11 @@
*/ */
#pragma once #pragma once
#include "cx/util.h" #include "common/model/enums.h"
#include "common/model/namespace.h"
#include "common/model/template_parameter.h"
#include "types.h" #include "types.h"
#include "util/util.h"
#include <clang/AST/RecursiveASTVisitor.h> #include <clang/AST/RecursiveASTVisitor.h>
@@ -131,4 +134,12 @@ template <> id_t to_id(const clang::EnumType &type);
template <> id_t to_id(const clang::TemplateSpecializationType &type); template <> id_t to_id(const clang::TemplateSpecializationType &type);
template <> id_t to_id(const std::filesystem::path &type); template <> id_t to_id(const std::filesystem::path &type);
std::pair<common::model::namespace_, std::string> split_ns(
const std::string &full_name);
std::vector<common::model::template_parameter> parse_unexposed_template_params(
const std::string &params,
const std::function<std::string(const std::string &)> &ns_resolve,
int depth = 0);
} // namespace clanguml::common } // namespace clanguml::common

View File

@@ -612,7 +612,7 @@ bool diagram_filter::should_include<std::string>(const std::string &name) const
if (name.empty()) if (name.empty())
return false; return false;
auto [ns, n] = cx::util::split_ns(name); auto [ns, n] = common::split_ns(name);
return should_include(ns, n); return should_include(ns, n);
} }

View File

@@ -18,12 +18,12 @@
#pragma once #pragma once
#include "class_diagram/model/diagram.h" #include "class_diagram/model/diagram.h"
#include "common/clang_utils.h"
#include "common/model/diagram.h" #include "common/model/diagram.h"
#include "common/model/element.h" #include "common/model/element.h"
#include "common/model/enums.h" #include "common/model/enums.h"
#include "common/model/namespace.h" #include "common/model/namespace.h"
#include "config/config.h" #include "config/config.h"
#include "cx/util.h"
#include "diagram.h" #include "diagram.h"
#include "include_diagram/model/diagram.h" #include "include_diagram/model/diagram.h"
#include "source_file.h" #include "source_file.h"

View File

@@ -1,128 +0,0 @@
/**
* src/cx/util.cc
*
* Copyright (c) 2021-2023 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 "cx/util.h"
#include "util/util.h"
#include <spdlog/spdlog.h>
#include <list>
namespace clanguml::cx::util {
std::pair<common::model::namespace_, std::string> split_ns(
const std::string &full_name)
{
assert(!full_name.empty());
auto name_before_template = ::clanguml::util::split(full_name, "<")[0];
auto ns = common::model::namespace_{
::clanguml::util::split(name_before_template, "::")};
auto name = ns.name();
ns.pop_back();
return {ns, name};
}
std::vector<common::model::template_parameter> parse_unexposed_template_params(
const std::string &params,
const std::function<std::string(const std::string &)> &ns_resolve,
int depth)
{
using common::model::template_parameter;
std::vector<template_parameter> res;
auto it = params.begin();
while (std::isspace(*it) != 0)
++it;
std::string type{};
std::vector<template_parameter> nested_params;
bool complete_class_template_argument{false};
while (it != params.end()) {
if (*it == '<') {
int nested_level{0};
auto bracket_match_begin = it + 1;
auto bracket_match_end = bracket_match_begin;
while (bracket_match_end != params.end()) {
if (*bracket_match_end == '<') {
nested_level++;
}
else if (*bracket_match_end == '>') {
if (nested_level > 0)
nested_level--;
else
break;
}
else {
}
bracket_match_end++;
}
std::string nested_params_str(
bracket_match_begin, bracket_match_end);
nested_params = parse_unexposed_template_params(
nested_params_str, ns_resolve, depth + 1);
if (nested_params.empty())
nested_params.emplace_back(
template_parameter{nested_params_str});
it = bracket_match_end - 1;
}
else if (*it == '>') {
complete_class_template_argument = true;
if (depth == 0) {
break;
}
}
else if (*it == ',') {
complete_class_template_argument = true;
}
else {
type += *it;
}
if (complete_class_template_argument) {
template_parameter t;
t.set_type(ns_resolve(clanguml::util::trim(type)));
type = "";
for (auto &&param : nested_params)
t.add_template_param(std::move(param));
res.emplace_back(std::move(t));
complete_class_template_argument = false;
}
it++;
}
if (!type.empty()) {
template_parameter t;
t.set_type(ns_resolve(clanguml::util::trim(type)));
type = "";
for (auto &&param : nested_params)
t.add_template_param(std::move(param));
res.emplace_back(std::move(t));
}
return res;
}
} // namespace clanguml::cx::util

View File

@@ -1,36 +0,0 @@
/**
* src/cx/util.h
*
* Copyright (c) 2021-2023 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/namespace.h"
#include "common/model/template_parameter.h"
#include <string>
namespace clanguml::cx::util {
std::pair<common::model::namespace_, std::string> split_ns(
const std::string &full_name);
std::vector<common::model::template_parameter> parse_unexposed_template_params(
const std::string &params,
const std::function<std::string(const std::string &)> &ns_resolve,
int depth = 0);
} // namespace clanguml::cx::util

View File

@@ -20,7 +20,6 @@
#include "common/clang_utils.h" #include "common/clang_utils.h"
#include "common/model/namespace.h" #include "common/model/namespace.h"
#include "cx/util.h"
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>

View File

@@ -18,8 +18,8 @@
#include "translation_unit_visitor.h" #include "translation_unit_visitor.h"
#include "common/clang_utils.h"
#include "common/model/namespace.h" #include "common/model/namespace.h"
#include "cx/util.h"
namespace clanguml::sequence_diagram::visitor { namespace clanguml::sequence_diagram::visitor {
@@ -1731,9 +1731,8 @@ void translation_unit_visitor::process_template_specialization_argument(
declaration_text.find(cls->getNameAsString()) + declaration_text.find(cls->getNameAsString()) +
cls->getNameAsString().size() + 1); cls->getNameAsString().size() + 1);
auto template_params = auto template_params = common::parse_unexposed_template_params(
cx::util::parse_unexposed_template_params( declaration_text, [](const auto &t) { return t; });
declaration_text, [](const auto &t) { return t; });
if (template_params.size() > argument_index) if (template_params.size() > argument_index)
type_name = template_params[argument_index].to_string( type_name = template_params[argument_index].to_string(
@@ -1789,9 +1788,8 @@ void translation_unit_visitor::process_template_specialization_argument(
declaration_text.find(cls->getNameAsString()) + declaration_text.find(cls->getNameAsString()) +
cls->getNameAsString().size() + 1); cls->getNameAsString().size() + 1);
auto template_params = auto template_params = common::parse_unexposed_template_params(
cx::util::parse_unexposed_template_params( declaration_text, [](const auto &t) { return t; });
declaration_text, [](const auto &t) { return t; });
if (template_params.size() > argument_index) if (template_params.size() > argument_index)
type_name = template_params[argument_index].to_string( type_name = template_params[argument_index].to_string(
@@ -2043,7 +2041,7 @@ void translation_unit_visitor::
const std::string &type_name, common::model::template_parameter &tp, const std::string &type_name, common::model::template_parameter &tp,
model::class_ & /*c*/) const model::class_ & /*c*/) const
{ {
auto template_params = cx::util::parse_unexposed_template_params( auto template_params = common::parse_unexposed_template_params(
type_name, [](const std::string &t) { return t; }); type_name, [](const std::string &t) { return t; });
for (auto &param : template_params) { for (auto &param : template_params) {

View File

@@ -22,8 +22,8 @@
#include "class_diagram/generators/plantuml/class_diagram_generator.h" #include "class_diagram/generators/plantuml/class_diagram_generator.h"
#include "class_diagram/model/diagram.h" #include "class_diagram/model/diagram.h"
#include "class_diagram/visitor/translation_unit_visitor.h" #include "class_diagram/visitor/translation_unit_visitor.h"
#include "common/clang_utils.h"
#include "config/config.h" #include "config/config.h"
#include "cx/util.h"
#include "include_diagram/generators/plantuml/include_diagram_generator.h" #include "include_diagram/generators/plantuml/include_diagram_generator.h"
#include "include_diagram/visitor/translation_unit_visitor.h" #include "include_diagram/visitor/translation_unit_visitor.h"
#include "package_diagram/generators/plantuml/package_diagram_generator.h" #include "package_diagram/generators/plantuml/package_diagram_generator.h"

View File

@@ -18,7 +18,7 @@
#define CATCH_CONFIG_MAIN #define CATCH_CONFIG_MAIN
#include "util/util.h" #include "util/util.h"
#include <cx/util.h> #include <common/clang_utils.h>
#include <filesystem> #include <filesystem>
@@ -96,7 +96,7 @@ TEST_CASE("Test replace_all", "[unit-test]")
TEST_CASE("Test parse_unexposed_template_params", "[unit-test]") TEST_CASE("Test parse_unexposed_template_params", "[unit-test]")
{ {
using namespace clanguml::cx::util; using namespace clanguml::common;
const std::string int_template_str{"ns1::ns2::class1<int>"}; const std::string int_template_str{"ns1::ns2::class1<int>"};