diff --git a/src/class_diagram/model/diagram.h b/src/class_diagram/model/diagram.h index e8a999ac..74c9192e 100644 --- a/src/class_diagram/model/diagram.h +++ b/src/class_diagram/model/diagram.h @@ -43,7 +43,7 @@ using nested_trait_ns = clanguml::common::model::nested_trait; -class diagram : public common::model::diagram::diagram, +class diagram : public common::model::diagram, public element_view, public element_view, public element_view, diff --git a/src/class_diagram/visitor/template_builder.cc b/src/class_diagram/visitor/template_builder.cc index 13e57ee2..c823a3f5 100644 --- a/src/class_diagram/visitor/template_builder.cc +++ b/src/class_diagram/visitor/template_builder.cc @@ -1090,7 +1090,7 @@ std::optional template_builder::try_as_template_parm_type( argument.is_variadic(is_variadic); - ensure_lambda_type_is_relative(type_parameter_name); + visitor_.ensure_lambda_type_is_relative(type_parameter_name); return argument; } @@ -1109,7 +1109,7 @@ std::optional template_builder::try_as_lambda( auto argument = template_parameter::make_argument(""); type = consume_context(type, argument); - ensure_lambda_type_is_relative(type_name); + visitor_.ensure_lambda_type_is_relative(type_name); argument.set_type(type_name); return argument; @@ -1257,40 +1257,4 @@ bool template_builder::add_base_classes(class_ &tinst, return variadic_params; } -void template_builder::ensure_lambda_type_is_relative( - std::string ¶meter_type) const -{ -#ifdef _MSC_VER - auto root_name = fmt::format( - "{}\\", std::filesystem::current_path().root_name().string()); - if (root_name.back() == '\\') { - root_name.pop_back(); - root_name.push_back('/'); - } -#else - auto root_name = std::string{"/"}; -#endif - - std::string lambda_prefix{fmt::format("(lambda at {}", root_name)}; - - while (parameter_type.find(lambda_prefix) != std::string::npos) { - auto lambda_begin = parameter_type.find(lambda_prefix); - - auto absolute_lambda_path_end = - parameter_type.find(':', lambda_begin + lambda_prefix.size()); - auto absolute_lambda_path = - parameter_type.substr(lambda_begin + lambda_prefix.size() - 1, - absolute_lambda_path_end - - (lambda_begin + lambda_prefix.size() - 1)); - - auto relative_lambda_path = util::path_to_url(std::filesystem::relative( - absolute_lambda_path, config().relative_to()) - .string()); - - parameter_type = fmt::format("{}(lambda at {}{}", - parameter_type.substr(0, lambda_begin), relative_lambda_path, - parameter_type.substr(absolute_lambda_path_end)); - } -} - } // namespace clanguml::class_diagram::visitor diff --git a/src/class_diagram/visitor/template_builder.h b/src/class_diagram/visitor/template_builder.h index 177f3a93..a214122a 100644 --- a/src/class_diagram/visitor/template_builder.h +++ b/src/class_diagram/visitor/template_builder.h @@ -181,8 +181,6 @@ public: clang::SourceManager &source_manager() const; private: - void ensure_lambda_type_is_relative(std::string ¶meter_type) const; - // Reference to the output diagram model clanguml::class_diagram::model::diagram &diagram_; diff --git a/src/class_diagram/visitor/translation_unit_visitor.cc b/src/class_diagram/visitor/translation_unit_visitor.cc index 0d9dfd4a..50bef538 100644 --- a/src/class_diagram/visitor/translation_unit_visitor.cc +++ b/src/class_diagram/visitor/translation_unit_visitor.cc @@ -1690,11 +1690,7 @@ void translation_unit_visitor::ensure_lambda_type_is_relative( { #ifdef _MSC_VER auto root_name = fmt::format( - "{}\\", std::filesystem::current_path().root_name().string()); - if (root_name.back() == '\\') { - root_name.pop_back(); - root_name.push_back('/'); - } + "{}", std::filesystem::current_path().root_name().string()); #else auto root_name = std::string{"/"}; #endif @@ -1703,13 +1699,17 @@ void translation_unit_visitor::ensure_lambda_type_is_relative( while (parameter_type.find(lambda_prefix) != std::string::npos) { auto lambda_begin = parameter_type.find(lambda_prefix); - + auto lambda_prefix_size = lambda_prefix.size(); +#ifdef _MSC_VER + // Skip the `\` or `/` after drive letter and semicolon + lambda_prefix_size++; +#endif auto absolute_lambda_path_end = - parameter_type.find(':', lambda_begin + lambda_prefix.size()); + parameter_type.find(':', lambda_begin + lambda_prefix_size); auto absolute_lambda_path = - parameter_type.substr(lambda_begin + lambda_prefix.size() - 1, + parameter_type.substr(lambda_begin + lambda_prefix_size - 1, absolute_lambda_path_end - - (lambda_begin + lambda_prefix.size() - 1)); + (lambda_begin + lambda_prefix_size - 1)); auto relative_lambda_path = util::path_to_url( config().make_path_relative(absolute_lambda_path).string()); @@ -2102,7 +2102,7 @@ void translation_unit_visitor::add_class(std::unique_ptr &&c) const auto file = config().make_path_relative(c->file()); - common::model::path p{file, common::model::path_type::kFilesystem}; + common::model::path p{file.string(), common::model::path_type::kFilesystem}; p.pop_back(); diagram().add(p, std::move(c)); @@ -2120,7 +2120,7 @@ void translation_unit_visitor::add_enum(std::unique_ptr &&e) const auto file = config().make_path_relative(e->file()); - common::model::path p{file, common::model::path_type::kFilesystem}; + common::model::path p{file.string(), common::model::path_type::kFilesystem}; p.pop_back(); diagram().add(p, std::move(e)); @@ -2138,7 +2138,7 @@ void translation_unit_visitor::add_concept(std::unique_ptr &&c) const auto file = config().make_path_relative(c->file()); - common::model::path p{file, common::model::path_type::kFilesystem}; + common::model::path p{file.string(), common::model::path_type::kFilesystem}; p.pop_back(); diagram().add(p, std::move(c)); diff --git a/src/class_diagram/visitor/translation_unit_visitor.h b/src/class_diagram/visitor/translation_unit_visitor.h index 943943e7..671766e2 100644 --- a/src/class_diagram/visitor/translation_unit_visitor.h +++ b/src/class_diagram/visitor/translation_unit_visitor.h @@ -125,6 +125,8 @@ public: void add_enum(std::unique_ptr &&e); void add_concept(std::unique_ptr &&c); + void ensure_lambda_type_is_relative(std::string ¶meter_type) const; + private: bool should_include(const clang::NamedDecl *decl); @@ -189,8 +191,6 @@ private: const found_relationships_t &relationships, bool break_on_first_aggregation = false); - void ensure_lambda_type_is_relative(std::string ¶meter_type) const; - void process_record_parent( clang::RecordDecl *cls, class_ &c, const namespace_ &ns); diff --git a/src/common/clang_utils.cc b/src/common/clang_utils.cc index 4e0e87f6..31d45682 100644 --- a/src/common/clang_utils.cc +++ b/src/common/clang_utils.cc @@ -745,8 +745,19 @@ bool parse_source_location(const std::string &location_str, std::string &file, return false; file = tokens.at(0); - line = std::stoi(tokens.at(1)); - column = std::stoi(tokens.at(2)); + try { + line = std::stoi(tokens.at(1)); + } + catch(std::invalid_argument &e) { + line = 0; + } + + try { + column = std::stoi(tokens.at(2)); + } + catch(std::invalid_argument &e) { + column = 0; + } return true; } diff --git a/src/package_diagram/visitor/translation_unit_visitor.cc b/src/package_diagram/visitor/translation_unit_visitor.cc index 3f3a77d2..861fbc68 100644 --- a/src/package_diagram/visitor/translation_unit_visitor.cc +++ b/src/package_diagram/visitor/translation_unit_visitor.cc @@ -207,11 +207,12 @@ void translation_unit_visitor::add_relationships( // package for current directory is already in the model if (config().package_type() == config::package_type_t::kDirectory) { auto file = source_manager().getFilename(cls->getLocation()).str(); - auto relative_file = - util::path_to_url(config().make_path_relative(file)); + + auto relative_file = config().make_path_relative(file); + relative_file.make_preferred(); common::model::path parent_path{ - relative_file, common::model::path_type::kFilesystem}; + relative_file.string(), common::model::path_type::kFilesystem}; parent_path.pop_back(); auto pkg_name = parent_path.name(); parent_path.pop_back(); @@ -261,9 +262,10 @@ common::model::diagram_element::id_t translation_unit_visitor::get_package_id( auto file = source_manager().getFilename(cls->getSourceRange().getBegin()).str(); - auto relative_file = util::path_to_url(config().make_path_relative(file)); + auto relative_file = config().make_path_relative(file); + relative_file.make_preferred(); common::model::path parent_path{ - relative_file, common::model::path_type::kFilesystem}; + relative_file.string(), common::model::path_type::kFilesystem}; parent_path.pop_back(); return common::to_id(parent_path.to_string()); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9265d456..a2f8b649 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -60,7 +60,7 @@ foreach(TEST_NAME ${TEST_CASES}) $<$,$>: -Wno-unused-parameter -Wno-unused-private-field -Wno-unused-variable -Wno-attributes -Wno-nonnull -Wno-deprecated-enum-enum-conversion> - $<$:/MP /W1 /bigobj /wd4624>>) + $<$:/W1 /bigobj /wd4624>>) target_link_libraries(${TEST_NAME} PRIVATE ${CLANG_UML_TEST_LIBRARIES}) endforeach() diff --git a/tests/t30011/libraries/lib1/lib1.h b/tests/t30011/libraries/lib1/lib1.h index 0b82d65b..46156a10 100644 --- a/tests/t30011/libraries/lib1/lib1.h +++ b/tests/t30011/libraries/lib1/lib1.h @@ -1,3 +1,5 @@ #pragma once -struct t30011_A { }; +struct t30011_A { + int a; +}; diff --git a/tests/t30011/libraries/lib2/lib2.h b/tests/t30011/libraries/lib2/lib2.h index ebc93b2d..51a3033a 100644 --- a/tests/t30011/libraries/lib2/lib2.h +++ b/tests/t30011/libraries/lib2/lib2.h @@ -1,3 +1,5 @@ #pragma once -struct t30011_B { }; +struct t30011_B { + int b; +}; diff --git a/tests/t30011/libraries/lib4/lib4.h b/tests/t30011/libraries/lib4/lib4.h index 408898b0..fb252050 100644 --- a/tests/t30011/libraries/lib4/lib4.h +++ b/tests/t30011/libraries/lib4/lib4.h @@ -1,3 +1,5 @@ #pragma once -struct t30011_C { }; +struct t30011_C { + int c; +};