Added parser util function for unexposed template params
This commit is contained in:
@@ -41,6 +41,8 @@ public:
|
|||||||
|
|
||||||
friend bool operator==(const class_template &l, const class_template &r);
|
friend bool operator==(const class_template &l, const class_template &r);
|
||||||
|
|
||||||
|
std::vector<class_template> template_params_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string type_;
|
std::string type_;
|
||||||
std::string name_;
|
std::string name_;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include <cppast/cpp_template.hpp>
|
#include <cppast/cpp_template.hpp>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
|
#include <class_diagram/model/class_template.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
namespace clanguml {
|
namespace clanguml {
|
||||||
@@ -294,6 +295,81 @@ const cppast::cpp_type &unreferenced(const cppast::cpp_type &t)
|
|||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<class_diagram::model::class_template>
|
||||||
|
parse_unexposed_template_params(const std::string ¶ms)
|
||||||
|
{
|
||||||
|
using class_diagram::model::class_template;
|
||||||
|
|
||||||
|
std::vector<class_template> res;
|
||||||
|
|
||||||
|
int nested_template_level{0};
|
||||||
|
auto it = params.begin();
|
||||||
|
|
||||||
|
std::string type{};
|
||||||
|
std::vector<class_template> nested_params;
|
||||||
|
bool complete_class_template{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);
|
||||||
|
if (nested_params.empty())
|
||||||
|
nested_params.emplace_back(class_template{nested_params_str});
|
||||||
|
it = bracket_match_end - 1;
|
||||||
|
}
|
||||||
|
else if (*it == '>') {
|
||||||
|
complete_class_template = true;
|
||||||
|
}
|
||||||
|
else if (*it == ',') {
|
||||||
|
complete_class_template = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
type += *it;
|
||||||
|
}
|
||||||
|
if(complete_class_template) {
|
||||||
|
class_template t;
|
||||||
|
t.set_type(clanguml::util::trim(type));
|
||||||
|
type = "";
|
||||||
|
t.template_params_ = std::move(nested_params);
|
||||||
|
|
||||||
|
res.emplace_back(std::move(t));
|
||||||
|
complete_class_template = false;
|
||||||
|
}
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!type.empty()) {
|
||||||
|
class_template t;
|
||||||
|
t.set_type(clanguml::util::trim(type));
|
||||||
|
type = "";
|
||||||
|
t.template_params_ = std::move(nested_params);
|
||||||
|
|
||||||
|
res.emplace_back(std::move(t));
|
||||||
|
complete_class_template = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace util
|
} // namespace util
|
||||||
} // namespace cx
|
} // namespace cx
|
||||||
} // namespace clanguml
|
} // namespace clanguml
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include <cppast/cpp_entity.hpp>
|
#include <cppast/cpp_entity.hpp>
|
||||||
#include <cppast/cpp_type.hpp>
|
#include <cppast/cpp_type.hpp>
|
||||||
|
|
||||||
|
#include <class_diagram/model/class_template.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace clanguml {
|
namespace clanguml {
|
||||||
@@ -66,6 +67,10 @@ std::pair<common::model::namespace_, std::string> split_ns(
|
|||||||
const std::string &full_name);
|
const std::string &full_name);
|
||||||
|
|
||||||
bool is_inside_class(const cppast::cpp_entity &e);
|
bool is_inside_class(const cppast::cpp_entity &e);
|
||||||
|
|
||||||
|
std::vector<class_diagram::model::class_template>
|
||||||
|
parse_unexposed_template_params(const std::string ¶ms);
|
||||||
|
|
||||||
} // namespace util
|
} // namespace util
|
||||||
} // namespace cx
|
} // namespace cx
|
||||||
} // namespace clanguml
|
} // namespace clanguml
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#define CATCH_CONFIG_MAIN
|
#define CATCH_CONFIG_MAIN
|
||||||
|
|
||||||
#include "util/util.h"
|
#include "util/util.h"
|
||||||
|
#include <cx/util.h>
|
||||||
|
|
||||||
#include "catch.h"
|
#include "catch.h"
|
||||||
|
|
||||||
@@ -35,19 +36,6 @@ TEST_CASE("Test split", "[unit-test]")
|
|||||||
|
|
||||||
CHECK(split("std::vector::detail::", "::") == C{"std", "vector", "detail"});
|
CHECK(split("std::vector::detail::", "::") == C{"std", "vector", "detail"});
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// TEST_CASE("Test ns_relative", "[unit-test]")
|
|
||||||
//{
|
|
||||||
// using namespace clanguml::util;
|
|
||||||
//
|
|
||||||
// CHECK(ns_relative({}, "std::vector") == "std::vector");
|
|
||||||
// CHECK(ns_relative({"std"}, "std::vector") == "vector");
|
|
||||||
// CHECK(ns_relative({"std"}, "const std::vector&") == "const vector&");
|
|
||||||
// CHECK(ns_relative({"std", "clanguml::t0"},
|
|
||||||
// "static const std::vector<clanguml::t0::a>&") ==
|
|
||||||
// "static const vector<a>&");
|
|
||||||
// CHECK(ns_relative({"clanguml::t0"}, "clanguml::t0") == "t0");
|
|
||||||
//}
|
|
||||||
|
|
||||||
TEST_CASE("Test abbreviate", "[unit-test]")
|
TEST_CASE("Test abbreviate", "[unit-test]")
|
||||||
{
|
{
|
||||||
@@ -80,3 +68,44 @@ TEST_CASE("Test replace_all", "[unit-test]")
|
|||||||
|
|
||||||
CHECK(text == orig);
|
CHECK(text == orig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Test parse_unexposed_template_params", "[unit-test]")
|
||||||
|
{
|
||||||
|
using namespace clanguml::cx::util;
|
||||||
|
|
||||||
|
const std::string int_template_str{"ns1::ns2::class1<int>"};
|
||||||
|
|
||||||
|
auto int_template = parse_unexposed_template_params(int_template_str);
|
||||||
|
|
||||||
|
CHECK(int_template.size() == 1);
|
||||||
|
CHECK(int_template[0].template_params_.size() == 1);
|
||||||
|
CHECK(int_template[0].type() == "ns1::ns2::class1");
|
||||||
|
CHECK(int_template[0].template_params_[0].type() == "int");
|
||||||
|
|
||||||
|
const std::string int_int_template_str{"ns1::ns2::class1<int, int>"};
|
||||||
|
|
||||||
|
auto int_int_template =
|
||||||
|
parse_unexposed_template_params(int_int_template_str);
|
||||||
|
|
||||||
|
CHECK(int_int_template.size() == 1);
|
||||||
|
CHECK(int_int_template[0].template_params_.size() == 2);
|
||||||
|
CHECK(int_int_template[0].type() == "ns1::ns2::class1");
|
||||||
|
CHECK(int_int_template[0].template_params_[0].type() == "int");
|
||||||
|
CHECK(int_int_template[0].template_params_[1].type() == "int");
|
||||||
|
|
||||||
|
const std::string nested_template_str{
|
||||||
|
"class1<int, ns1::class2<int, std::vector<std::string>>>"};
|
||||||
|
|
||||||
|
auto nested_template = parse_unexposed_template_params(nested_template_str);
|
||||||
|
|
||||||
|
CHECK(nested_template.size() == 1);
|
||||||
|
CHECK(nested_template[0].template_params_.size() == 2);
|
||||||
|
CHECK(nested_template[0].type() == "class1");
|
||||||
|
CHECK(nested_template[0].template_params_[0].type() == "int");
|
||||||
|
const auto &class2 = nested_template[0].template_params_[1];
|
||||||
|
CHECK(class2.type() == "ns1::class2");
|
||||||
|
CHECK(class2.template_params_[0].type() == "int");
|
||||||
|
CHECK(class2.template_params_[1].type() == "std::vector");
|
||||||
|
CHECK(
|
||||||
|
class2.template_params_[1].template_params_[0].type() == "std::string");
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user