0.5.4
C++ to UML diagram generator based on Clang
Loading...
Searching...
No Matches
source_file.h
Go to the documentation of this file.
1/**
2 * @file src/common/model/source_file.h
3 *
4 * Copyright (c) 2021-2024 Bartek Kryza <bkryza@gmail.com>
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18#pragma once
19
20#include "common/clang_utils.h"
23#include "common/model/path.h"
26#include "common/types.h"
27#include "util/util.h"
28
29#include <spdlog/spdlog.h>
30
31#include <set>
32#include <string>
33#include <vector>
34
36
37/**
38 * This enum represents different kinds of files in the diagram.
39 */
40enum class source_file_t {
41 kDirectory, /*!< Diagram element is a directory */
42 kHeader, /*!< Diagram element is a header */
43 kImplementation /*!< Diagram element is a source file (e.g. cpp) */
44};
45
46std::string to_string(source_file_t sf);
47
49#ifdef _WIN32
50 static constexpr std::string_view value = "\\";
51#else
52 static constexpr std::string_view value = "/";
53#endif
54};
55
57
58/**
59 * @brief Diagram element representing some file or directory.
60 *
61 * @embed{source_file_hierarchy_class.svg}
62 */
66 public common::model::nested_trait<common::model::source_file,
67 filesystem_path> {
68public:
69 source_file() = default;
70
71 explicit source_file(const std::filesystem::path &p)
72 {
73 auto preferred = p;
74 preferred.make_preferred();
75 set_path({preferred.parent_path().string(), path_type::kFilesystem});
76 set_name(preferred.filename().string());
77 is_absolute_ = preferred.is_absolute();
78 set_id(common::to_id(preferred));
79 }
80
81 source_file(const source_file &) = delete;
82 source_file(source_file &&) = default;
83 source_file &operator=(const source_file &) = delete;
85
86 bool operator==(const source_file &right) const
87 {
88 return (path_ == right.path_) && (name() == right.name()) &&
89 (type_ == right.type_);
90 }
91
92 /**
93 * Set the path to the element in the diagram.
94 *
95 * @param p Diagram path.
96 */
97 void set_path(const filesystem_path &p) { path_ = p; }
98
99 /**
100 * Is the elements path absolute?
101 *
102 * @return True if the elements path is absolute.
103 */
104 bool is_absolute() const { return is_absolute_; }
105
106 /**
107 * Set the type of the source file.
108 *
109 * @param type Type of the source file.
110 */
112
113 /**
114 * Get the source file elements type.
115 *
116 * @return Type of the source file.
117 */
118 source_file_t type() const { return type_; }
119
120 /**
121 * Set whether the file is a system header
122 *
123 * @param is_system Whether the file is a system header
124 */
125 void set_system_header(bool is_system) { is_system_header_ = is_system; }
126
127 /**
128 * Is the file a system header?
129 *
130 * @return True, if the source file is a system header
131 */
132 bool is_system_header() const { return is_system_header_; }
133
134 /**
135 * Get the source file's parent path.
136 *
137 * @return Source file parent path.
138 */
139 const filesystem_path &path() const { return path_; }
140
141 /**
142 * Return the full path string, i.e. parent path and elements name.
143 *
144 * @return Full source file path as string.
145 */
146 std::string full_name(bool /*relative*/) const override
147 {
148 return (path_ | name()).to_string();
149 }
150
151 /**
152 * Return full path, i.e. parent path and elements name.
153 *
154 * @return Full source file path.
155 */
156 auto full_path() const { return path() | name(); }
157
158 /**
159 * Convert the source file path to std::filesystem::path, relative to `base`
160 *
161 * @param base Base path
162 * @return Filesystem path to the source file.
163 */
164 std::filesystem::path fs_path(const std::filesystem::path &base = {}) const
165 {
166 std::filesystem::path res;
167
168 for (const auto &path_element : path_) {
169 res /= path_element;
170 }
171
172 res /= name();
173
174 if (is_absolute_)
175 res = fs_path_sep::value / res;
176 else
177 res = base / res;
178
179 return res.lexically_normal();
180 }
181
182 /**
183 * Return inja context for this element.
184 *
185 * @return Inja context.
186 */
187 inja::json context() const override
188 {
189 inja::json ctx = diagram_element::context();
190
191 std::filesystem::path fullNamePath{ctx["full_name"].get<std::string>()};
192 fullNamePath.make_preferred();
193 ctx["full_name"] = fullNamePath.string();
194
195 return ctx;
196 }
197
198private:
201 bool is_absolute_{false};
202 bool is_system_header_{false};
203};
204} // namespace clanguml::common::model
205
206namespace std {
207template <>
208struct hash<std::reference_wrapper<clanguml::common::model::source_file>> {
209 std::size_t operator()(
210 const std::reference_wrapper<clanguml::common::model::source_file> &key)
211 const
212 {
213 return key.get().id().value();
214 }
215};
216} // namespace std