0.5.4
C++ to UML diagram generator based on Clang
Loading...
Searching...
No Matches
diagram_filter_factory.cc
Go to the documentation of this file.
1/**
2 * @file src/common/model/filters/diagram_filter_factory.cc
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
20
22
24{
25 // Process inclusive filters
27 df.add_inclusive_filter(std::make_unique<namespace_filter>(
29
30 df.add_inclusive_filter(std::make_unique<modules_filter>(
32
33 df.add_inclusive_filter(std::make_unique<module_access_filter>(
35
36 df.add_inclusive_filter(std::make_unique<relationship_filter>(
38
39 df.add_inclusive_filter(std::make_unique<access_filter>(
41
42 df.add_inclusive_filter(std::make_unique<paths_filter>(
45
47 std::make_unique<class_method_filter>(filter_t::kInclusive,
48 std::make_unique<access_filter>(
50 std::make_unique<method_type_filter>(filter_t::kInclusive,
51 diagram_config.include().method_types)));
52
54 std::make_unique<class_member_filter>(filter_t::kInclusive,
55 std::make_unique<access_filter>(
57
58 // Include any of these matches even if one them does not match
59 std::vector<std::unique_ptr<filter_visitor>> element_filters;
60
61 element_filters.emplace_back(std::make_unique<element_filter>(
63
64 element_filters.emplace_back(std::make_unique<element_type_filter>(
66
68 element_filters.emplace_back(std::make_unique<subclass_filter>(
70
71 element_filters.emplace_back(std::make_unique<parents_filter>(
73
74 element_filters.emplace_back(
75 std::make_unique<specializations_filter_t>(filter_t::kInclusive,
76 diagram_config.include().specializations,
78
79 element_filters.emplace_back(
80 std::make_unique<class_dependants_filter_t>(
83
84 element_filters.emplace_back(
85 std::make_unique<class_dependencies_filter_t>(
88 }
90 element_filters.emplace_back(std::make_unique<callee_filter>(
92 }
94 element_filters.emplace_back(
95 std::make_unique<package_dependants_filter_t>(
98
99 element_filters.emplace_back(
100 std::make_unique<package_dependencies_filter_t>(
103 }
105 std::vector<std::string> dependants;
106 std::vector<std::string> dependencies;
107
108 for (auto &&path : diagram_config.include().dependants) {
109 if (auto p = path.get<std::string>(); p.has_value()) {
110 const std::filesystem::path dep_path{*p};
111 dependants.emplace_back(
112 dep_path.lexically_normal().string());
113 }
114 }
115
116 for (auto &&path : diagram_config.include().dependencies) {
117 if (auto p = path.get<std::string>(); p.has_value()) {
118 const std::filesystem::path dep_path{*p};
119 dependencies.emplace_back(
120 dep_path.lexically_normal().string());
121 }
122 }
123
124 element_filters.emplace_back(
125 std::make_unique<source_file_dependency_filter_t>(
126 filter_t::kInclusive, dependants,
128
129 element_filters.emplace_back(
130 std::make_unique<source_file_dependency_filter_t>(
131 filter_t::kInclusive, dependencies,
133 }
134
135 element_filters.emplace_back(std::make_unique<context_filter>(
137
138 df.add_inclusive_filter(std::make_unique<anyof_filter>(
139 filter_t::kInclusive, std::move(element_filters)));
140 }
141
142 // Process exclusive filters
144 df.add_exclusive_filter(std::make_unique<namespace_filter>(
146
147 df.add_exclusive_filter(std::make_unique<modules_filter>(
149
150 df.add_exclusive_filter(std::make_unique<module_access_filter>(
152
153 df.add_exclusive_filter(std::make_unique<paths_filter>(
156
157 df.add_exclusive_filter(std::make_unique<element_filter>(
159
160 df.add_exclusive_filter(std::make_unique<element_type_filter>(
162
163 df.add_exclusive_filter(std::make_unique<relationship_filter>(
165
166 df.add_exclusive_filter(std::make_unique<access_filter>(
168
170 std::make_unique<class_method_filter>(filter_t::kExclusive,
171 std::make_unique<access_filter>(
173 std::make_unique<method_type_filter>(filter_t::kExclusive,
174 diagram_config.exclude().method_types)));
175
177 std::make_unique<class_member_filter>(filter_t::kExclusive,
178 std::make_unique<access_filter>(
180
181 df.add_exclusive_filter(std::make_unique<subclass_filter>(
183
184 df.add_exclusive_filter(std::make_unique<parents_filter>(
186
187 df.add_exclusive_filter(std::make_unique<specializations_filter_t>(
190
192 df.add_exclusive_filter(std::make_unique<class_dependants_filter_t>(
195
197 std::make_unique<class_dependencies_filter_t>(
200 }
202 df.add_exclusive_filter(std::make_unique<callee_filter>(
204 }
207 std::make_unique<package_dependencies_filter_t>(
210
212 std::make_unique<package_dependants_filter_t>(
215 }
217 std::vector<std::string> dependants;
218 std::vector<std::string> dependencies;
219
220 for (auto &&path : diagram_config.exclude().dependants) {
221 if (auto p = path.get<std::string>(); p.has_value()) {
222 std::filesystem::path dep_path{*p};
223 dependants.emplace_back(
224 dep_path.lexically_normal().string());
225 }
226 }
227
228 for (auto &&path : diagram_config.exclude().dependencies) {
229 if (auto p = path.get<std::string>(); p.has_value()) {
230 std::filesystem::path dep_path{*p};
231 dependencies.emplace_back(
232 dep_path.lexically_normal().string());
233 }
234 }
235
237 std::make_unique<source_file_dependency_filter_t>(
238 filter_t::kExclusive, dependants,
240
242 std::make_unique<source_file_dependency_filter_t>(
243 filter_t::kExclusive, dependencies,
245 }
246
247 df.add_exclusive_filter(std::make_unique<context_filter>(
249 }
250}
251
252template <>
254 source_file_dependency_filter_t>(const filter_t &filter_type,
255 const std::vector<common::string_or_regex> &filter_config,
256 std::vector<std::unique_ptr<filter_visitor>> &result,
257 relationship_t &&rt, // NOLINT
258 bool &&direction // NOLINT
259)
260{
261 std::vector<std::string> deps;
262 for (auto &&path : filter_config) {
263 if (auto p = path.get<std::string>(); p.has_value()) {
264 const std::filesystem::path dep_path{*p};
265 deps.emplace_back(dep_path.lexically_normal().string());
266 }
267 }
268
269 result.emplace_back(std::make_unique<source_file_dependency_filter_t>(
270 filter_type, deps, rt, direction));
271}
272
273std::vector<std::unique_ptr<filter_visitor>>
275 filter_t filter_type, const config::filter &filter_config)
276{
277 std::vector<std::unique_ptr<filter_visitor>> result;
278
279 // At any level, only allof, anyof, or a set of other non-operator
280 // filters can be present
281 if (filter_config.allof) {
282 std::vector<std::unique_ptr<filter_visitor>> allof_filters =
283 build(filter_type, *filter_config.allof);
284
285 auto allof_filter = std::make_unique<common::model::allof_filter>(
286 filter_type, std::move(allof_filters));
287
288 result.emplace_back(std::move(allof_filter));
289 }
290
291 if (filter_config.anyof) {
292 std::vector<std::unique_ptr<filter_visitor>> anyof_filters =
293 build(filter_type, *filter_config.anyof);
294
295 auto anyof_filter = std::make_unique<common::model::anyof_filter>(
296 filter_type, std::move(anyof_filters));
297
298 result.emplace_back(std::move(anyof_filter));
299 }
300
301 add_filter<namespace_filter>(filter_type, filter_config.namespaces, result);
302 add_filter<modules_filter>(filter_type, filter_config.modules, result);
303 add_filter<module_access_filter>(
304 filter_type, filter_config.module_access, result);
305 add_filter<relationship_filter>(
306 filter_type, filter_config.relationships, result);
307 add_filter<access_filter>(filter_type, filter_config.access, result);
308 add_filter<method_type_filter>(
309 filter_type, filter_config.method_types, result);
310
311 add_filter<paths_filter>(filter_type, filter_config.paths, result,
313
314 add_filter<element_filter>(filter_type, filter_config.elements, result);
315 add_filter<element_type_filter>(
316 filter_type, filter_config.element_types, result);
317 add_filter<subclass_filter>(filter_type, filter_config.subclasses, result);
318 add_filter<parents_filter>(filter_type, filter_config.parents, result);
319
320 add_filter<specializations_filter_t>(filter_type,
321 filter_config.specializations, result, relationship_t::kInstantiation,
322 false);
323 add_filter<class_dependants_filter_t>(filter_type, filter_config.dependants,
324 result, relationship_t::kDependency, false);
325 add_filter<class_dependencies_filter_t>(filter_type,
326 filter_config.dependencies, result, relationship_t::kDependency, true);
327
328 add_filter<callee_filter>(filter_type, filter_config.callee_types, result);
329
330 add_filter<package_dependants_filter_t>(filter_type,
331 filter_config.dependants, result, relationship_t::kDependency, false);
332 add_filter<package_dependencies_filter_t>(filter_type,
333 filter_config.dependencies, result, relationship_t::kDependency, true);
334
335 add_filter<context_filter>(filter_type, filter_config.context, result);
336
338 add_filter<source_file_dependency_filter_t>(filter_type,
339 filter_config.dependants, result, relationship_t::kAssociation,
340 false);
341 add_filter<source_file_dependency_filter_t>(filter_type,
342 filter_config.dependencies, result, relationship_t::kAssociation,
343 true);
344 }
345
346 return result;
347}
348
350{
352 auto inclusive_filter =
354 for (auto &f : inclusive_filter)
355 df.add_filter(filter_t::kInclusive, std::move(f));
356 }
357
359 auto exclusive_filter =
361 for (auto &f : exclusive_filter)
362 df.add_filter(filter_t::kExclusive, std::move(f));
363 }
364}
365
366} // namespace clanguml::common::model