Refactored handling of relative paths (#213)
This commit is contained in:
@@ -269,7 +269,10 @@ std::unique_ptr<class_> template_builder::build(const clang::NamedDecl *cls,
|
||||
template_instantiation.set_id(
|
||||
common::to_id(template_instantiation_ptr->full_name(false)));
|
||||
|
||||
visitor_.set_source_location(*template_decl, *template_instantiation_ptr);
|
||||
visitor_.set_source_location(*template_decl, template_instantiation);
|
||||
|
||||
LOG_DBG("**** {} -> {}", template_instantiation.full_name(false),
|
||||
template_instantiation.file());
|
||||
|
||||
return template_instantiation_ptr;
|
||||
}
|
||||
|
||||
@@ -724,7 +724,10 @@ paths_filter::paths_filter(filter_t type, const std::filesystem::path &root,
|
||||
|
||||
resolved_absolute_path.make_preferred();
|
||||
|
||||
paths_.emplace_back(resolved_absolute_path);
|
||||
LOG_DBG("Added path {} to paths_filter",
|
||||
resolved_absolute_path.string());
|
||||
|
||||
paths_.emplace_back(std::move(resolved_absolute_path));
|
||||
|
||||
match_successful = true;
|
||||
}
|
||||
@@ -738,8 +741,8 @@ paths_filter::paths_filter(filter_t type, const std::filesystem::path &root,
|
||||
|
||||
if (!match_successful)
|
||||
LOG_WARN("Paths filter pattern '{}' did not match "
|
||||
"any files...",
|
||||
path);
|
||||
"any files relative to '{}'",
|
||||
path, root_.string());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1059,8 +1062,7 @@ void diagram_filter::init_filters(const config::diagram &c)
|
||||
if (auto p = path.get<std::string>(); p.has_value()) {
|
||||
std::filesystem::path dep_path{*p};
|
||||
if (dep_path.is_relative()) {
|
||||
dep_path = c.base_directory() / *p;
|
||||
dep_path = relative(dep_path, c.relative_to());
|
||||
dep_path = relative(*p, c.root_directory());
|
||||
}
|
||||
|
||||
dependants.emplace_back(
|
||||
@@ -1072,8 +1074,7 @@ void diagram_filter::init_filters(const config::diagram &c)
|
||||
if (auto p = path.get<std::string>(); p.has_value()) {
|
||||
std::filesystem::path dep_path{*p};
|
||||
if (dep_path.is_relative()) {
|
||||
dep_path = c.base_directory() / *p;
|
||||
dep_path = relative(dep_path, c.relative_to());
|
||||
dep_path = relative(*p, c.root_directory());
|
||||
}
|
||||
|
||||
dependencies.emplace_back(
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace clanguml::common::visitor {
|
||||
translation_unit_visitor::translation_unit_visitor(
|
||||
clang::SourceManager &sm, const clanguml::config::diagram &config)
|
||||
: source_manager_{sm}
|
||||
, relative_to_path_{config.relative_to()}
|
||||
, relative_to_path_{config.root_directory()}
|
||||
{
|
||||
if (config.comment_parser() == config::comment_parser_t::plain) {
|
||||
comment_visitor_ =
|
||||
@@ -108,6 +108,8 @@ void translation_unit_visitor::set_source_location(
|
||||
const clang::SourceLocation &location,
|
||||
clanguml::common::model::source_location &element)
|
||||
{
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
std::string file;
|
||||
unsigned line{};
|
||||
unsigned column{};
|
||||
@@ -133,15 +135,25 @@ void translation_unit_visitor::set_source_location(
|
||||
}
|
||||
}
|
||||
|
||||
if (std::filesystem::path file_path{file}; !file_path.is_absolute()) {
|
||||
file_path =
|
||||
std::filesystem::canonical(std::filesystem::absolute(file_path));
|
||||
file = file_path.string();
|
||||
// ensure the path is absolute
|
||||
fs::path file_path{file};
|
||||
if (!file_path.is_absolute()) {
|
||||
file_path = fs::absolute(file_path);
|
||||
}
|
||||
|
||||
file_path = fs::canonical(file_path);
|
||||
|
||||
if (!util::is_relative_to(file_path, relative_to_path_)) {
|
||||
return;
|
||||
}
|
||||
|
||||
file = file_path.string();
|
||||
|
||||
element.set_file(file);
|
||||
element.set_file_relative(util::path_to_url(
|
||||
std::filesystem::relative(element.file(), relative_to_path_).string()));
|
||||
if (util::is_relative_to(file_path, relative_to_path_)) {
|
||||
element.set_file_relative(util::path_to_url(
|
||||
fs::relative(element.file(), relative_to_path_).string()));
|
||||
}
|
||||
element.set_translation_unit(tu_path().string());
|
||||
element.set_line(line);
|
||||
element.set_column(column);
|
||||
|
||||
@@ -233,8 +233,7 @@ std::vector<std::string> diagram::get_translation_units() const
|
||||
{
|
||||
std::vector<std::string> translation_units{};
|
||||
|
||||
LOG_DBG("Looking for translation units in {}",
|
||||
std::filesystem::current_path().string());
|
||||
LOG_DBG("Looking for translation units in {}", root_directory().string());
|
||||
|
||||
for (const auto &g : glob()) {
|
||||
std::string glob_path =
|
||||
|
||||
+24
-4
@@ -482,10 +482,6 @@ struct inheritable_diagram_options {
|
||||
// This is the absolute filesystem path to the directory containing
|
||||
// the current .clang-uml config file - it is set automatically
|
||||
option<std::filesystem::path> base_directory{"__parent_path"};
|
||||
// This is the relative path with respect to the `base_directory`,
|
||||
// against which all matches are made, if not provided it defaults to
|
||||
// the `base_directory`
|
||||
option<std::filesystem::path> relative_to{"relative_to"};
|
||||
option<bool> generate_system_headers{"generate_system_headers", false};
|
||||
option<relationship_hints_t> relationship_hints{"relationship_hints"};
|
||||
option<type_aliases_t> type_aliases{"type_aliases"};
|
||||
@@ -502,6 +498,30 @@ struct inheritable_diagram_options {
|
||||
"message_comment_width", clanguml::util::kDefaultMessageCommentWidth};
|
||||
option<bool> debug_mode{"debug_mode", false};
|
||||
option<bool> generate_metadata{"generate_metadata", true};
|
||||
|
||||
/**
|
||||
* @brief Get reference to `relative_to` diagram config option
|
||||
*
|
||||
* This method is only to allow access to `relative_to` for loading
|
||||
* and adjusting configuration file and for making test cases work.
|
||||
*
|
||||
* Instead use @see config::diagram::root_directory() method.
|
||||
*
|
||||
* @return Reference to `relative_to` config option.
|
||||
*/
|
||||
option<std::filesystem::path> &get_relative_to() { return relative_to; }
|
||||
|
||||
protected:
|
||||
// This is the relative path with respect to the `base_directory`,
|
||||
// against which all matches are made, if not provided it defaults to
|
||||
// the `base_directory`
|
||||
//
|
||||
// This option should not be accessed directly in code - instead use
|
||||
// @see config::diagram::root_directory()
|
||||
option<std::filesystem::path> relative_to{"relative_to"};
|
||||
|
||||
friend YAML::Emitter &operator<<(
|
||||
YAML::Emitter &out, const inheritable_diagram_options &c);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+12
-21
@@ -602,7 +602,7 @@ template <> struct convert<class_diagram> {
|
||||
get_option(node, rhs.skip_redundant_dependencies);
|
||||
get_option(node, rhs.relationship_hints);
|
||||
get_option(node, rhs.type_aliases);
|
||||
get_option(node, rhs.relative_to);
|
||||
get_option(node, rhs.get_relative_to());
|
||||
|
||||
rhs.initialize_relationship_hints();
|
||||
rhs.initialize_type_aliases();
|
||||
@@ -626,15 +626,15 @@ template <> struct convert<sequence_diagram> {
|
||||
get_option(node, rhs.combine_free_functions_into_file_participants);
|
||||
get_option(node, rhs.generate_return_types);
|
||||
get_option(node, rhs.generate_condition_statements);
|
||||
get_option(node, rhs.relative_to);
|
||||
get_option(node, rhs.get_relative_to());
|
||||
get_option(node, rhs.participants_order);
|
||||
get_option(node, rhs.generate_method_arguments);
|
||||
get_option(node, rhs.generate_message_comments);
|
||||
get_option(node, rhs.message_comment_width);
|
||||
|
||||
// Ensure relative_to has a value
|
||||
if (!rhs.relative_to.has_value)
|
||||
rhs.relative_to.set(
|
||||
if (!rhs.get_relative_to().has_value)
|
||||
rhs.get_relative_to().set(
|
||||
std::filesystem::current_path().lexically_normal());
|
||||
|
||||
rhs.initialize_type_aliases();
|
||||
@@ -653,12 +653,12 @@ template <> struct convert<package_diagram> {
|
||||
return false;
|
||||
|
||||
get_option(node, rhs.layout);
|
||||
get_option(node, rhs.relative_to);
|
||||
get_option(node, rhs.get_relative_to());
|
||||
get_option(node, rhs.package_type);
|
||||
|
||||
// Ensure relative_to has a value
|
||||
if (!rhs.relative_to.has_value)
|
||||
rhs.relative_to.set(
|
||||
if (!rhs.get_relative_to().has_value)
|
||||
rhs.get_relative_to().set(
|
||||
std::filesystem::current_path().lexically_normal());
|
||||
|
||||
return true;
|
||||
@@ -675,21 +675,12 @@ template <> struct convert<include_diagram> {
|
||||
return false;
|
||||
|
||||
get_option(node, rhs.layout);
|
||||
get_option(node, rhs.relative_to);
|
||||
get_option(node, rhs.get_relative_to());
|
||||
get_option(node, rhs.generate_system_headers);
|
||||
|
||||
if (!rhs.relative_to)
|
||||
rhs.relative_to.set(std::filesystem::current_path());
|
||||
|
||||
// Convert the path in relative_to to an absolute path, with respect
|
||||
// to the directory where the `.clang-uml` configuration file is
|
||||
// located
|
||||
if (rhs.relative_to) {
|
||||
auto absolute_relative_to =
|
||||
std::filesystem::path{node["__parent_path"].as<std::string>()} /
|
||||
rhs.relative_to();
|
||||
rhs.relative_to.set(absolute_relative_to.lexically_normal());
|
||||
}
|
||||
if (!rhs.get_relative_to().has_value)
|
||||
rhs.get_relative_to().set(
|
||||
std::filesystem::current_path().lexically_normal());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -824,7 +815,7 @@ template <> struct convert<config> {
|
||||
get_option(node, rhs.message_comment_width);
|
||||
|
||||
rhs.base_directory.set(node["__parent_path"].as<std::string>());
|
||||
get_option(node, rhs.relative_to);
|
||||
get_option(node, rhs.get_relative_to());
|
||||
|
||||
get_option(node, rhs.diagram_templates);
|
||||
|
||||
|
||||
@@ -95,12 +95,8 @@ void translation_unit_visitor::include_visitor::InclusionDirective(
|
||||
LOG_DBG("Processing include directive {} in file {}", include_path.string(),
|
||||
current_file.string());
|
||||
|
||||
auto relative_include_path = include_path;
|
||||
if (config().relative_to) {
|
||||
const std::filesystem::path relative_to{config().relative_to()};
|
||||
relative_include_path =
|
||||
std::filesystem::relative(include_path, relative_to);
|
||||
}
|
||||
auto relative_include_path =
|
||||
std::filesystem::relative(include_path, config().root_directory());
|
||||
|
||||
if (diagram().should_include(source_file{include_path})) {
|
||||
process_internal_header(include_path,
|
||||
@@ -133,12 +129,8 @@ void translation_unit_visitor::include_visitor::process_internal_header(
|
||||
const common::id_t current_file_id)
|
||||
{
|
||||
// Make the path relative with respect to relative_to config option
|
||||
auto relative_include_path = include_path;
|
||||
if (config().relative_to) {
|
||||
const std::filesystem::path relative_to{config().relative_to()};
|
||||
relative_include_path =
|
||||
std::filesystem::relative(include_path, relative_to);
|
||||
}
|
||||
auto relative_include_path =
|
||||
std::filesystem::relative(include_path, config().root_directory());
|
||||
|
||||
// Check if this source file is already registered in the diagram,
|
||||
// if not add it
|
||||
@@ -218,13 +210,9 @@ translation_unit_visitor::include_visitor::process_source_file(
|
||||
if (diagram().should_include(source_file{file_path})) {
|
||||
LOG_DBG("Processing source file {}", file.string());
|
||||
|
||||
// Relativize the path with respect to relative_to config option
|
||||
auto relative_file_path = file_path;
|
||||
if (config().relative_to) {
|
||||
const std::filesystem::path relative_to{config().relative_to()};
|
||||
relative_file_path =
|
||||
std::filesystem::relative(file_path, relative_to);
|
||||
}
|
||||
// Relativize the path with respect to effective root directory
|
||||
auto relative_file_path =
|
||||
std::filesystem::relative(file_path, config().root_directory());
|
||||
|
||||
[[maybe_unused]] const auto relative_file_path_str =
|
||||
relative_file_path.string();
|
||||
|
||||
@@ -400,7 +400,7 @@ void generator::generate_participant(
|
||||
if (is_participant_generated(file_id))
|
||||
return;
|
||||
|
||||
auto participant_name = util::path_to_url(std::filesystem::relative(
|
||||
auto participant_name = util::path_to_url(relative(
|
||||
std::filesystem::path{file_path}, config().root_directory())
|
||||
.string());
|
||||
|
||||
|
||||
@@ -2311,9 +2311,13 @@ std::string translation_unit_visitor::make_lambda_name(
|
||||
const auto location = cls->getLocation();
|
||||
const auto file_line = source_manager().getSpellingLineNumber(location);
|
||||
const auto file_column = source_manager().getSpellingColumnNumber(location);
|
||||
const std::string file_name = util::path_to_url(std::filesystem::relative(
|
||||
source_manager().getFilename(location).str(), config().relative_to())
|
||||
.string());
|
||||
const std::string file_name = config().make_path_relative(
|
||||
source_manager().getFilename(location).str());
|
||||
//
|
||||
// util::path_to_url(std::filesystem::relative(
|
||||
// source_manager().getFilename(location).str(),
|
||||
// config().relative_to())
|
||||
// .string());
|
||||
|
||||
if (context().caller_id() != 0 &&
|
||||
get_participant(context().caller_id()).has_value()) {
|
||||
|
||||
@@ -404,6 +404,15 @@ std::filesystem::path ensure_path_is_absolute(
|
||||
return result;
|
||||
}
|
||||
|
||||
bool is_relative_to(
|
||||
const std::filesystem::path &child, const std::filesystem::path &parent)
|
||||
{
|
||||
if (child.has_root_directory() != parent.has_root_directory())
|
||||
return false;
|
||||
|
||||
return starts_with(child, parent);
|
||||
}
|
||||
|
||||
std::string format_message_comment(const std::string &comment, unsigned width)
|
||||
{
|
||||
if (width == 0)
|
||||
|
||||
@@ -435,6 +435,17 @@ std::string path_to_url(const std::filesystem::path &p);
|
||||
std::filesystem::path ensure_path_is_absolute(const std::filesystem::path &p,
|
||||
const std::filesystem::path &root = std::filesystem::current_path());
|
||||
|
||||
/**
|
||||
* @brief Check if a given path is relative to another path.
|
||||
*
|
||||
* @param parent The path to be checked for relativity.
|
||||
* @param right The base path against which the relativity is checked.
|
||||
* @return True if the child path is relative to the parent path, false
|
||||
* otherwise.
|
||||
*/
|
||||
bool is_relative_to(
|
||||
const std::filesystem::path &parent, const std::filesystem::path &child);
|
||||
|
||||
std::string format_message_comment(
|
||||
const std::string &c, unsigned width = kDefaultMessageCommentWidth);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user