Removed dead code and improve test coverage
This commit is contained in:
@@ -93,12 +93,6 @@ std::string class_::base_template() const { return base_template_full_name_; }
|
||||
|
||||
bool operator==(const class_ &l, const class_ &r) { return l.id() == r.id(); }
|
||||
|
||||
void class_::add_type_alias(type_alias &&ta)
|
||||
{
|
||||
LOG_DBG("Adding class alias: {} -> {}", ta.alias(), ta.underlying_type());
|
||||
type_aliases_[ta.alias()] = std::move(ta);
|
||||
}
|
||||
|
||||
std::string class_::full_name_no_ns() const
|
||||
{
|
||||
using namespace clanguml::util;
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "common/model/stylable_element.h"
|
||||
#include "common/types.h"
|
||||
#include "template_parameter.h"
|
||||
#include "type_alias.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -68,8 +67,6 @@ public:
|
||||
|
||||
friend bool operator==(const class_ &l, const class_ &r);
|
||||
|
||||
void add_type_alias(type_alias &&ta);
|
||||
|
||||
std::string full_name(bool relative = true) const override;
|
||||
|
||||
std::string full_name_no_ns() const override;
|
||||
@@ -100,7 +97,6 @@ private:
|
||||
std::vector<class_parent> bases_;
|
||||
std::vector<template_parameter> templates_;
|
||||
std::string base_template_full_name_;
|
||||
std::map<std::string, type_alias> type_aliases_;
|
||||
|
||||
std::string full_name_;
|
||||
};
|
||||
|
||||
@@ -126,14 +126,6 @@ common::optional_ref<enum_> diagram::get_enum(
|
||||
return {};
|
||||
}
|
||||
|
||||
void diagram::add_type_alias(std::unique_ptr<type_alias> &&ta)
|
||||
{
|
||||
LOG_DBG(
|
||||
"Adding global alias: {} -> {}", ta->alias(), ta->underlying_type());
|
||||
|
||||
type_aliases_[ta->alias()] = std::move(ta);
|
||||
}
|
||||
|
||||
bool diagram::add_package(std::unique_ptr<common::model::package> &&p)
|
||||
{
|
||||
LOG_DBG("Adding namespace package: {}, {}", p->name(), p->full_name(true));
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "common/model/package.h"
|
||||
#include "common/types.h"
|
||||
#include "enum.h"
|
||||
#include "type_alias.h"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
@@ -69,8 +68,6 @@ public:
|
||||
common::optional_ref<enum_> get_enum(
|
||||
clanguml::common::model::diagram_element::id_t id) const;
|
||||
|
||||
void add_type_alias(std::unique_ptr<type_alias> &&ta);
|
||||
|
||||
bool add_class(std::unique_ptr<class_> &&c);
|
||||
|
||||
bool add_enum(std::unique_ptr<enum_> &&e);
|
||||
@@ -93,8 +90,6 @@ private:
|
||||
common::reference_vector<class_> classes_;
|
||||
|
||||
common::reference_vector<enum_> enums_;
|
||||
|
||||
std::map<std::string, std::unique_ptr<type_alias>> type_aliases_;
|
||||
};
|
||||
} // namespace clanguml::class_diagram::model
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/**
|
||||
* src/class_diagram/model/type_alias.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 "type_alias.h"
|
||||
|
||||
namespace clanguml::class_diagram::model {
|
||||
|
||||
void type_alias::set_alias(const std::string &alias) { alias_ = alias; }
|
||||
|
||||
std::string type_alias::alias() const { return alias_; }
|
||||
|
||||
void type_alias::set_underlying_type(const std::string &type)
|
||||
{
|
||||
underlying_type_ = type;
|
||||
}
|
||||
|
||||
std::string type_alias::underlying_type() const { return underlying_type_; }
|
||||
|
||||
} // namespace clanguml::class_diagram::model
|
||||
@@ -1,37 +0,0 @@
|
||||
/**
|
||||
* src/class_diagram/model/type_alias.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 <string>
|
||||
|
||||
namespace clanguml::class_diagram::model {
|
||||
|
||||
class type_alias {
|
||||
public:
|
||||
void set_alias(const std::string &alias);
|
||||
std::string alias() const;
|
||||
|
||||
void set_underlying_type(const std::string &type);
|
||||
std::string underlying_type() const;
|
||||
|
||||
private:
|
||||
std::string alias_;
|
||||
std::string underlying_type_;
|
||||
};
|
||||
|
||||
} // namespace clanguml::class_diagram::model
|
||||
@@ -149,9 +149,8 @@ YAML::Emitter &operator<<(YAML::Emitter &out, const layout_hint &c)
|
||||
YAML::Emitter &operator<<(YAML::Emitter &out, const source_location &sc)
|
||||
{
|
||||
out << YAML::BeginMap;
|
||||
out << YAML::Key << "location" << YAML::Value << sc.location;
|
||||
out << YAML::Key << "location_type" << YAML::Value
|
||||
<< to_string(sc.location_type);
|
||||
out << YAML::Key << to_string(sc.location_type) << YAML::Value
|
||||
<< sc.location;
|
||||
out << YAML::EndMap;
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -96,6 +96,8 @@ void generator::generate(const source_file &f, std::ostream &ostr) const
|
||||
|
||||
void generator::generate(std::ostream &ostr) const
|
||||
{
|
||||
update_context();
|
||||
|
||||
ostr << "@startuml" << '\n';
|
||||
|
||||
if (m_config.puml)
|
||||
|
||||
@@ -97,6 +97,8 @@ void generator::generate(const package &p, std::ostream &ostr) const
|
||||
|
||||
void generator::generate(std::ostream &ostr) const
|
||||
{
|
||||
update_context();
|
||||
|
||||
ostr << "@startuml" << '\n';
|
||||
|
||||
generate_plantuml_directives(ostr, m_config.puml().before);
|
||||
|
||||
@@ -369,6 +369,8 @@ bool generator::is_participant_generated(common::id_t id) const
|
||||
|
||||
void generator::generate(std::ostream &ostr) const
|
||||
{
|
||||
update_context();
|
||||
|
||||
m_model.print();
|
||||
|
||||
ostr << "@startuml" << std::endl;
|
||||
|
||||
@@ -110,6 +110,22 @@ public:
|
||||
active_participants() const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* This method checks the last messages in sequence (current_messages),
|
||||
* if they represent a block sequence identified by statement_begin
|
||||
* (e.g. if/else) and there are no actual call expressions within this block
|
||||
* statement the entire block statement is removed from the end of the
|
||||
* sequence.
|
||||
*
|
||||
* Otherwise the block statement is ended with a proper statement
|
||||
* (e.g. endif)
|
||||
*
|
||||
* @param m Message to add to the sequence
|
||||
* @param statement_begin Type of message which begins this type of block
|
||||
* statement (e.g. message_t::kIf)
|
||||
* @param current_messages Reference to the sequence messages which should
|
||||
* be amended
|
||||
*/
|
||||
void fold_or_end_block_statement(message &&m,
|
||||
common::model::message_t statement_begin,
|
||||
std::vector<message> ¤t_messages) const;
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "class_diagram/model/template_parameter.h"
|
||||
#include "class_diagram/model/type_alias.h"
|
||||
#include "common/model/element.h"
|
||||
|
||||
#include <string>
|
||||
@@ -122,9 +121,6 @@ private:
|
||||
bool is_alias_{false};
|
||||
bool is_lambda_{false};
|
||||
|
||||
std::map<std::string, clanguml::class_diagram::model::type_alias>
|
||||
type_aliases_;
|
||||
|
||||
std::string full_name_;
|
||||
};
|
||||
|
||||
|
||||
@@ -126,22 +126,6 @@ void call_expression_context::update(
|
||||
current_function_template_decl_ = function_template;
|
||||
}
|
||||
|
||||
bool call_expression_context::in_class_method() const
|
||||
{
|
||||
return current_class_decl_ != nullptr;
|
||||
}
|
||||
|
||||
bool call_expression_context::in_function() const
|
||||
{
|
||||
return current_class_decl_ == nullptr && current_function_decl_ != nullptr;
|
||||
}
|
||||
|
||||
bool call_expression_context::in_function_template() const
|
||||
{
|
||||
return current_function_decl_ != nullptr &&
|
||||
current_function_template_decl_ != nullptr;
|
||||
}
|
||||
|
||||
std::int64_t call_expression_context::caller_id() const
|
||||
{
|
||||
return current_caller_id_;
|
||||
@@ -207,12 +191,6 @@ void call_expression_context::enter_elseifstmt(clang::IfStmt *stmt)
|
||||
elseif_stmt_stack_.push(stmt);
|
||||
}
|
||||
|
||||
void call_expression_context::leave_elseifstmt()
|
||||
{
|
||||
if (!elseif_stmt_stack_.empty())
|
||||
elseif_stmt_stack_.pop();
|
||||
}
|
||||
|
||||
clang::IfStmt *call_expression_context::current_elseifstmt() const
|
||||
{
|
||||
if (elseif_stmt_stack_.empty())
|
||||
|
||||
@@ -51,12 +51,6 @@ struct call_expression_context {
|
||||
|
||||
void update(clang::FunctionTemplateDecl *function_template);
|
||||
|
||||
bool in_class_method() const;
|
||||
|
||||
bool in_function() const;
|
||||
|
||||
bool in_function_template() const;
|
||||
|
||||
std::int64_t caller_id() const;
|
||||
|
||||
std::int64_t lambda_caller_id() const;
|
||||
@@ -73,7 +67,6 @@ struct call_expression_context {
|
||||
void leave_ifstmt();
|
||||
|
||||
void enter_elseifstmt(clang::IfStmt *stmt);
|
||||
void leave_elseifstmt();
|
||||
clang::IfStmt *current_elseifstmt() const;
|
||||
|
||||
clang::Stmt *current_loopstmt() const;
|
||||
|
||||
@@ -577,6 +577,7 @@ bool translation_unit_visitor::TraverseIfStmt(clang::IfStmt *stmt)
|
||||
if ((current_caller_id != 0) && !stmt->isConstexpr() && !elseif_block) {
|
||||
diagram().end_block_message(
|
||||
{message_t::kIfEnd, current_caller_id}, message_t::kIf);
|
||||
context().leave_ifstmt();
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -769,7 +770,8 @@ bool translation_unit_visitor::TraverseCaseStmt(clang::CaseStmt *stmt)
|
||||
|
||||
const auto current_caller_id = context().caller_id();
|
||||
|
||||
if (current_caller_id != 0) {
|
||||
if ((current_caller_id != 0) &&
|
||||
(context().current_switchstmt() != nullptr)) {
|
||||
model::message m{message_t::kCase, current_caller_id};
|
||||
m.set_message_name(common::to_string(stmt->getLHS()));
|
||||
diagram().add_case_stmt_message(std::move(m));
|
||||
@@ -786,7 +788,8 @@ bool translation_unit_visitor::TraverseDefaultStmt(clang::DefaultStmt *stmt)
|
||||
|
||||
const auto current_caller_id = context().caller_id();
|
||||
|
||||
if (current_caller_id != 0) {
|
||||
if ((current_caller_id != 0) &&
|
||||
(context().current_switchstmt() != nullptr)) {
|
||||
model::message m{message_t::kCase, current_caller_id};
|
||||
m.set_message_name("default");
|
||||
diagram().add_case_stmt_message(std::move(m));
|
||||
|
||||
@@ -28,10 +28,4 @@ struct uml_alias_missing : public virtual std::runtime_error {
|
||||
}
|
||||
};
|
||||
|
||||
struct substring_delimiter_not_found : public virtual std::runtime_error {
|
||||
substring_delimiter_not_found(const std::string &message)
|
||||
: std::runtime_error(message)
|
||||
{
|
||||
}
|
||||
};
|
||||
} // namespace clanguml::error
|
||||
|
||||
@@ -19,10 +19,6 @@
|
||||
#include "thread_pool_executor.h"
|
||||
|
||||
namespace clanguml::util {
|
||||
thread_pool_executor::thread_pool_executor()
|
||||
: thread_pool_executor{0}
|
||||
{
|
||||
}
|
||||
|
||||
thread_pool_executor::thread_pool_executor(unsigned int pool_size)
|
||||
: done_{false}
|
||||
|
||||
@@ -25,15 +25,13 @@
|
||||
namespace clanguml::util {
|
||||
class thread_pool_executor {
|
||||
public:
|
||||
thread_pool_executor();
|
||||
explicit thread_pool_executor(unsigned int pool_size);
|
||||
|
||||
thread_pool_executor(const thread_pool_executor &) = delete;
|
||||
thread_pool_executor(thread_pool_executor &&) = delete;
|
||||
thread_pool_executor &operator=(const thread_pool_executor &) = delete;
|
||||
thread_pool_executor &operator=(thread_pool_executor &&) = delete;
|
||||
|
||||
explicit thread_pool_executor(unsigned int pool_size);
|
||||
|
||||
~thread_pool_executor();
|
||||
|
||||
std::future<void> add(std::function<void()> &&task);
|
||||
|
||||
@@ -191,20 +191,6 @@ std::string join(
|
||||
return fmt::format("{}", fmt::join(toks, delimiter));
|
||||
}
|
||||
|
||||
std::string unqualify(const std::string &s)
|
||||
{
|
||||
auto toks = clanguml::util::split(s, " ");
|
||||
const std::vector<std::string> qualifiers = {"static", "const", "volatile",
|
||||
"register", "constexpr", "mutable", "struct", "enum"};
|
||||
|
||||
toks.erase(toks.begin(),
|
||||
std::find_if(toks.begin(), toks.end(), [&qualifiers](const auto &t) {
|
||||
return std::count(qualifiers.begin(), qualifiers.end(), t) == 0;
|
||||
}));
|
||||
|
||||
return fmt::format("{}", fmt::join(toks, " "));
|
||||
}
|
||||
|
||||
std::string abbreviate(const std::string &s, const unsigned int max_length)
|
||||
{
|
||||
if (s.size() <= max_length)
|
||||
|
||||
@@ -96,15 +96,6 @@ std::vector<std::string> split(
|
||||
std::string join(
|
||||
const std::vector<std::string> &toks, std::string_view delimiter);
|
||||
|
||||
/**
|
||||
* @brief Remove any qualifiers (e.g. const) from type.
|
||||
*
|
||||
* @param s String spelling of the type.
|
||||
*
|
||||
* @return Unqualified type spelling.
|
||||
*/
|
||||
std::string unqualify(const std::string &s);
|
||||
|
||||
/**
|
||||
* @brief Abbreviate string to max_length, and replace last 3 characters
|
||||
* with ellipsis.
|
||||
|
||||
@@ -17,6 +17,6 @@ diagrams:
|
||||
- function: "clanguml::t20001::tmain()"
|
||||
plantuml:
|
||||
before:
|
||||
- "' t20001 test sequence diagram"
|
||||
- "' t20001 test diagram of type {{ diagram.type }}"
|
||||
after:
|
||||
- '{% set e=element("clanguml::t20001::tmain()") %} note over {{ e.alias) }}: Main test function'
|
||||
|
||||
@@ -44,6 +44,8 @@ TEST_CASE("t20001", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, HasCall(_A("A"), "__log_result(int)__"));
|
||||
REQUIRE_THAT(puml, HasCall(_A("B"), _A("A"), "__log_result(int)__"));
|
||||
|
||||
REQUIRE_THAT(puml, HasComment("t20001 test diagram of type sequence"));
|
||||
|
||||
save_puml(
|
||||
"./" + config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ diagrams:
|
||||
- clanguml::t30001
|
||||
plantuml:
|
||||
before:
|
||||
- "' t30001 test package diagram"
|
||||
- "' t30001 test diagram of type {{ diagram.type }}"
|
||||
after:
|
||||
- 'note right of {{ alias("A::AA::AAA") }}: A AAA note...'
|
||||
- '{% set e=element("A::AA") %} note top of {{ alias("A::AA") }} : {{ e.comment.formatted }}'
|
||||
|
||||
@@ -43,7 +43,7 @@ TEST_CASE("t30001", "[test-case][package]")
|
||||
REQUIRE_THAT(puml, IsPackage("AAA"));
|
||||
|
||||
// TODO: Fix _A() to handle fully qualified names, right
|
||||
// now it only finds the first element with unqalified
|
||||
// now it only finds the first element with unqualified
|
||||
// name match
|
||||
REQUIRE_THAT(
|
||||
puml, HasNote(_A("AA"), "top", "This is namespace AA in namespace A"));
|
||||
@@ -62,6 +62,8 @@ TEST_CASE("t30001", "[test-case][package]")
|
||||
clanguml::util::get_git_commit()),
|
||||
"BBB"));
|
||||
|
||||
REQUIRE_THAT(puml, HasComment("t30001 test diagram of type package"));
|
||||
|
||||
save_puml(
|
||||
"./" + config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ diagrams:
|
||||
- .
|
||||
plantuml:
|
||||
before:
|
||||
- "' t40001 test include diagram"
|
||||
- "' t40001 test diagram of type {{ diagram.type }}"
|
||||
after:
|
||||
- 'note right of {{ alias("include/lib1") }}: This is a lib1 include dir'
|
||||
- 'note right of {{ alias("include/t40001_include1.h") }}: This is a t40001_include1.h include file'
|
||||
@@ -48,6 +48,8 @@ TEST_CASE("t40001", "[test-case][include]")
|
||||
|
||||
REQUIRE_THAT(puml, IsDependency(_A("t40001_include1.h"), _A("string")));
|
||||
|
||||
REQUIRE_THAT(puml, HasComment("t40001 test diagram of type include"));
|
||||
|
||||
save_puml(
|
||||
"./" + config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
}
|
||||
|
||||
@@ -423,6 +423,13 @@ ContainsMatcher IsLayoutHint(std::string const &from, std::string const &hint,
|
||||
fmt::format("{} -[hidden]{}- {}", from, hint, to), caseSensitivity));
|
||||
}
|
||||
|
||||
ContainsMatcher HasComment(std::string const &comment,
|
||||
CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes)
|
||||
{
|
||||
return ContainsMatcher(
|
||||
CasedString(fmt::format("' {}", comment), caseSensitivity));
|
||||
}
|
||||
|
||||
ContainsMatcher HasNote(std::string const &cls, std::string const &position,
|
||||
std::string const ¬e = "",
|
||||
CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes)
|
||||
|
||||
@@ -201,7 +201,7 @@ TEST_CASE("Test config emitters", "[unit-test]")
|
||||
|
||||
// Write the emitted YAML to a temp file
|
||||
auto tmp_file = std::filesystem::temp_directory_path() /
|
||||
fmt::format("clang-uml-{:16}", rand());
|
||||
fmt::format("clang-uml-{:016}", rand());
|
||||
|
||||
{
|
||||
std::ofstream stream(tmp_file.string().c_str(), std::ios::binary);
|
||||
|
||||
@@ -59,3 +59,19 @@ diagrams:
|
||||
# Add this line to the beginning of the resulting puml file
|
||||
before:
|
||||
- 'title clang-uml class diagram model'
|
||||
config_sequence:
|
||||
type: sequence
|
||||
start_from:
|
||||
- function: main(int,const char**)
|
||||
config_include:
|
||||
type: include
|
||||
include:
|
||||
paths:
|
||||
- src
|
||||
config_package:
|
||||
type: package
|
||||
using_namespace:
|
||||
- ns1
|
||||
include:
|
||||
namespaces:
|
||||
- ns1::ns2
|
||||
@@ -170,6 +170,30 @@ TEST_CASE("Test parse_unexposed_template_params", "[unit-test]")
|
||||
CHECK(declaration_template[2].type() == "Tail");
|
||||
}
|
||||
|
||||
TEST_CASE("Test remove_prefix", "[unit-test]")
|
||||
{
|
||||
using namespace clanguml::util;
|
||||
|
||||
const std::vector<std::string> collection_base = {"aa", "bb", "cc", "dd"};
|
||||
std::vector<std::string> collection = collection_base;
|
||||
|
||||
const std::vector<std::string> prefix1 = {"xx", "yy"};
|
||||
const std::vector<std::string> prefix2 = {"aa", "bb"};
|
||||
const std::vector<std::string> prefix3 = {"cc", "dd"};
|
||||
|
||||
remove_prefix(collection, prefix1);
|
||||
|
||||
CHECK(collection == collection_base);
|
||||
|
||||
remove_prefix(collection, prefix2);
|
||||
|
||||
CHECK(collection == prefix3);
|
||||
|
||||
remove_prefix(collection, prefix3);
|
||||
|
||||
CHECK(collection.empty());
|
||||
}
|
||||
|
||||
TEST_CASE("Test path_to_url", "[unit-test]")
|
||||
{
|
||||
namespace fs = std::filesystem;
|
||||
@@ -203,3 +227,12 @@ TEST_CASE("Test path_to_url", "[unit-test]")
|
||||
CHECK(path_to_url(p7) == "A/B/include.h");
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("Test hash_seed", "[unit-test]")
|
||||
{
|
||||
using namespace clanguml::util;
|
||||
|
||||
CHECK(hash_seed(1) != 1);
|
||||
CHECK(hash_seed(1) == hash_seed(1));
|
||||
CHECK(hash_seed(1) != hash_seed(2));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user