Removed dead code and improve test coverage

This commit is contained in:
Bartek Kryza
2023-01-18 21:32:21 +01:00
parent 00b9321034
commit a9f793e407
30 changed files with 98 additions and 174 deletions

View File

@@ -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;

View File

@@ -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_;
};

View File

@@ -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));

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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);

View File

@@ -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;

View File

@@ -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> &current_messages) const;

View File

@@ -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_;
};

View File

@@ -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())

View File

@@ -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;

View File

@@ -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));

View File

@@ -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

View File

@@ -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}

View File

@@ -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);

View File

@@ -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)

View File

@@ -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.

View File

@@ -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'

View File

@@ -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);
}

View File

@@ -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 }}'

View File

@@ -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);
}

View File

@@ -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'

View 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);
}

View File

@@ -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 &note = "",
CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes)

View File

@@ -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);

View File

@@ -58,4 +58,20 @@ diagrams:
plantuml:
# Add this line to the beginning of the resulting puml file
before:
- 'title clang-uml class diagram model'
- '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

View File

@@ -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));
}