Added initial Doxygen config
This commit is contained in:
67
.clang-uml
67
.clang-uml
@@ -1,32 +1,63 @@
|
||||
compilation_database_dir: debug
|
||||
output_directory: docs/diagrams
|
||||
comment_parser: clang
|
||||
generate_links:
|
||||
link: https://github.com/bkryza/clang-uml/blob/{{ git.commit }}/{{ element.source.path }}#L{{ element.source.line }}
|
||||
tooltip: "{% if existsIn(element, \"comment\") and existsIn(element.comment, \"brief\") %}{{ abbrv(trim(replace(element.comment.brief.0, \"\\n+\", \" \")), 256) }}{% else %}{{ element.name }}{% endif %}"
|
||||
diagrams:
|
||||
main_package:
|
||||
include!: uml/main_package_diagram.yml
|
||||
# Class diagrams
|
||||
config_class:
|
||||
include!: uml/config_class_diagram.yml
|
||||
include!: uml/class/config_class.yml
|
||||
config_context_class:
|
||||
include!: uml/class/config_context_class.yml
|
||||
compilation_database_context_class:
|
||||
include!: uml/class/compilation_database_context_class.yml
|
||||
inheritable_diagram_options_context_class:
|
||||
include!: uml/class/inheritable_diagram_options_context_class.yml
|
||||
diagram_config_hierarchy_class:
|
||||
include!: uml/class/diagram_config_hierarchy_class.yml
|
||||
diagram_hierarchy_class:
|
||||
include!: uml/class/diagram_hierarchy_class.yml
|
||||
decorated_element_hierarchy_class:
|
||||
include!: uml/class/decorated_element_hierarchy_class.yml
|
||||
filter_visitor_hierarchy_class:
|
||||
include!: uml/class/filter_visitor_hierarchy_class.yml
|
||||
diagram_filter_context_class:
|
||||
include!: uml/class/diagram_filter_context_class.yml
|
||||
nested_trait_hierarchy_class:
|
||||
include!: uml/class/nested_trait_hierarchy_class.yml
|
||||
package_hierarchy_class:
|
||||
include!: uml/class/package_hierarchy_class.yml
|
||||
decorators_class:
|
||||
include!: uml/decorators_class_diagram.yml
|
||||
include!: uml/class/decorators_class.yml
|
||||
common_model_class:
|
||||
include!: uml/common_model_class_diagram.yml
|
||||
include!: uml/class/common_model_class.yml
|
||||
class_model_class:
|
||||
include!: uml/class_model_class_diagram.yml
|
||||
include!: uml/class/class_model_class.yml
|
||||
diagram_element_hierarchy_class:
|
||||
include!: uml/diagram_element_hierarchy_diagram.yml
|
||||
include!: uml/class/diagram_element_hierarchy_class.yml
|
||||
sequence_model_class:
|
||||
include!: uml/sequence_model_class_diagram.yml
|
||||
main_sequence:
|
||||
include!: uml/main_sequence_diagram.yml
|
||||
sequence_diagram_visitor_sequence:
|
||||
include!: uml/sequence_diagram_visitor_sequence_diagram.yml
|
||||
class_diagram_generator_sequence:
|
||||
include!: uml/class_diagram_generator_sequence_diagram.yml
|
||||
template_builder_sequence:
|
||||
include!: uml/template_builder_sequence_diagram.yml
|
||||
include!: uml/class/sequence_model_class.yml
|
||||
package_model_class:
|
||||
include!: uml/package_model_class_diagram.yml
|
||||
include!: uml/class/package_model_class.yml
|
||||
# Sequence diargams
|
||||
main_sequence:
|
||||
include!: uml/sequence/main_sequence.yml
|
||||
load_config_sequence:
|
||||
include!: uml/sequence/load_config_sequence.yml
|
||||
cli_handle_options_sequence:
|
||||
include!: uml/sequence/cli_handle_options_sequence.yml
|
||||
diagram_generate_generic_sequence:
|
||||
include!: uml/sequence/diagram_generate_generic_sequence.yml
|
||||
sequence_diagram_visitor_sequence:
|
||||
include!: uml/sequence/sequence_diagram_visitor_sequence.yml
|
||||
class_diagram_generator_sequence:
|
||||
include!: uml/sequence/class_diagram_generator_sequence.yml
|
||||
template_builder_sequence:
|
||||
include!: uml/sequence/template_builder_sequence.yml
|
||||
# Package diagrams
|
||||
main_package:
|
||||
include!: uml/package/main_package.yml
|
||||
# Include diagrams
|
||||
include_graph:
|
||||
include!: uml/include_diagram.yml
|
||||
include!: uml/include/include.yml
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -22,6 +22,7 @@ bin/
|
||||
/debug_tidy
|
||||
/.cache
|
||||
docs/diagrams
|
||||
docs/doxygen
|
||||
|
||||
coverage*.info
|
||||
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
@mainpage clang-uml
|
||||
|
||||
# Documentation
|
||||
|
||||
`clang-uml` is an automatic C++ to UML class, sequence, package and include diagram generator, driven by
|
||||
YAML configuration files. The main idea behind the
|
||||
project is to easily maintain up-to-date diagrams within a code-base or document
|
||||
legacy code. The configuration file or files for `clang-uml` define the
|
||||
types and contents of each generated diagram.
|
||||
The diagrams can be generated in [PlantUML](https://plantuml.com) and JSON formats.
|
||||
|
||||
`clang-uml` currently supports C++ up to version 17 with partial support for C++ 20.
|
||||
|
||||
To see what `clang-uml` can do, checkout the diagrams generated for unit
|
||||
test cases [here](./test_cases.md) or examples in
|
||||
[clang-uml-examples](https://github.com/bkryza/clang-uml-examples) repository.
|
||||
|
||||
* [Quick start](./quick_start.md)
|
||||
* [Installation](./installation.md)
|
||||
* Generating diagrams
|
||||
@@ -18,3 +33,6 @@
|
||||
* [Doxygen integration](./doxygen_integration.md)
|
||||
* [Test cases documentation](./test_cases.md)
|
||||
* [Troubleshooting](./troubleshooting.md)
|
||||
* Development
|
||||
* [Architecture](./architecture.md)
|
||||
* [Contributing](../CONTRIBUTING.md)
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
|
||||
<!-- toc -->
|
||||
|
||||
* [`namespaces` _[string or regex]_](#namespaces-_string-or-regex_)
|
||||
* [`elements` _[string or regex]_](#elements-_string-or-regex_)
|
||||
* [`element_types`](#element_types)
|
||||
* [`paths` _[string or glob]_](#paths-_string-or-glob_)
|
||||
* [`context` _[string or regex]_](#context-_string-or-regex_)
|
||||
* [`relationships`](#relationships)
|
||||
* [`subclasses` _[string or regex]_](#subclasses-_string-or-regex_)
|
||||
* [`parents` _[string or regex]_](#parents-_string-or-regex_)
|
||||
* [`specializations` _[string or regex]_](#specializations-_string-or-regex_)
|
||||
* [`access`](#access)
|
||||
* [`method_types`](#method_types)
|
||||
* [`dependants` and `dependencies` _[string or regex]_](#dependants-and-dependencies-_string-or-regex_)
|
||||
* [namespaces](#namespaces)
|
||||
* [elements](#elements)
|
||||
* [element_types](#element_types)
|
||||
* [paths](#paths)
|
||||
* [context](#context)
|
||||
* [relationships](#relationships)
|
||||
* [subclasses](#subclasses)
|
||||
* [parents](#parents)
|
||||
* [specializations](#specializations)
|
||||
* [access](#access)
|
||||
* [method_types](#method_types)
|
||||
* [dependants and dependencies](#dependants-and-dependencies)
|
||||
|
||||
<!-- tocstop -->
|
||||
|
||||
@@ -56,28 +56,28 @@ exclude:
|
||||
The following table specifies the values allowed in each filter:
|
||||
|
||||
| Filter name | Possible values | Example values |
|
||||
|-------------------|----------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `namespaces` | Qualified name or regex | - `ns1::ns2::ClassA` <br/>- `r: '.*detail.*'` |
|
||||
| `elements` | Qualified name or regex | - `ns1::ns2::ClassA` <br/>- `r: '.*detail.*'` |
|
||||
| `element_types` | Types of diagram elements | - `class`<br/>- `enum`<br/>- `concept` |
|
||||
| `paths` | File or dir path or glob pattern | - `src/dir1`<br/>- `src/dir2/a.cpp`<br/>- `src/dir3/*.cpp` |
|
||||
| `context` | Qualified name or regex | - `ns1::ns2::ClassA`<br/>- `r: 'ns1::ns2::ClassA.+'` |
|
||||
| `relationships` | Type of relationship | - `inheritance`<br/>- `composition`<br/>- `aggregation`<br/>- `ownership`<br/>- `association`<br/>- `instantiation`<br/>- `friendship`<br/>- `dependency` |
|
||||
| `subclasses` | Qualified name or regex | - `ns1::ns2::ClassA`<br/>- `r: 'ns1::ns2::ClassA.+'` |
|
||||
| `parents` | Qualified name or regex | - `ns1::ns2::ClassA`<br/>- `r: 'ns1::ns2::ClassA.+'` |
|
||||
| `specializations` | Qualified name or regex | - `ns1::ns2::ClassA`<br/>- `r: 'ns1::ns2::ClassA.+'` |
|
||||
| `access` | Method or member access scope | - `public`<br/>- `protected`<br/>- `private` |
|
||||
| `method_types` | Type of class method | - `constructor`<br/>- `destructor`<br/>- `assignment`<br/>- `operator`<br/>- `defaulted`<br/>- `deleted`<br/>- `static` |
|
||||
| `dependants` | Qualified name or regex | - `ns1::ns2::ClassA`<br/>- `r: 'ns1::ns2::ClassA.+'` |
|
||||
| `dependencies` | Qualified name or regex | - `ns1::ns2::ClassA`<br/>- `r: 'ns1::ns2::ClassA.+'` |
|
||||
|-------------------|----------------------------------|------------------------------------------------------------------------------------------------------------------------|
|
||||
| `namespaces` | Qualified name or regex | `ns1::ns2::ClassA`, `r: '.*detail.*'` |
|
||||
| `elements` | Qualified name or regex | `ns1::ns2::ClassA`,`r: '.*detail.*'` |
|
||||
| `element_types` | Types of diagram elements | `class`, `enum`, `concept` |
|
||||
| `paths` | File or dir path or glob pattern | `src/dir1`, `src/dir2/a.cpp`, `src/dir3/*.cpp` |
|
||||
| `context` | Qualified name or regex | `ns1::ns2::ClassA`, `r: 'ns1::ns2::ClassA.+'` |
|
||||
| `relationships` | Type of relationship | `inheritance`, `composition`, `aggregation`, `ownership`, `association`, `instantiation`, `friendship`, `dependency` |
|
||||
| `subclasses` | Qualified name or regex | `ns1::ns2::ClassA`, `r: 'ns1::ns2::ClassA.+'` |
|
||||
| `parents` | Qualified name or regex | `ns1::ns2::ClassA`, `r: 'ns1::ns2::ClassA.+'` |
|
||||
| `specializations` | Qualified name or regex | `ns1::ns2::ClassA`, `r: 'ns1::ns2::ClassA.+'` |
|
||||
| `access` | Method or member access scope | `public`, `protected`, `private` |
|
||||
| `method_types` | Type of class method | `constructor`, `destructor`, `assignment`, `operator`, `defaulted`, `deleted`, `static` |
|
||||
| `dependants` | Qualified name or regex | `ns1::ns2::ClassA`, `r: 'ns1::ns2::ClassA.+'` |
|
||||
| `dependencies` | Qualified name or regex | `ns1::ns2::ClassA`, `r: 'ns1::ns2::ClassA.+'` |
|
||||
|
||||
The following filters are available.
|
||||
|
||||
## `namespaces` _[string or regex]_
|
||||
## namespaces
|
||||
|
||||
Allows to include or exclude entities from specific namespaces.
|
||||
|
||||
## `elements` _[string or regex]_
|
||||
## elements
|
||||
|
||||
Allows to directly include or exclude specific entities from the diagrams, for instance to exclude a specific class
|
||||
from an included namespace:
|
||||
@@ -91,7 +91,7 @@ from an included namespace:
|
||||
- ns1::ns2::MyClass
|
||||
```
|
||||
|
||||
## `element_types`
|
||||
## element_types
|
||||
|
||||
Allows to include or exclude elements of specific type from the diagram, for instance
|
||||
to remove all enums from a diagram add the following:
|
||||
@@ -102,7 +102,7 @@ to remove all enums from a diagram add the following:
|
||||
- enum
|
||||
```
|
||||
|
||||
## `paths` _[string or glob]_
|
||||
## paths
|
||||
|
||||
This filter allows to include or exclude from the diagram elements declared
|
||||
in specific files.
|
||||
@@ -122,7 +122,7 @@ diagrams:
|
||||
Currently, this filter does not allow any globbing or wildcards, however
|
||||
paths to directories can be specified.
|
||||
|
||||
## `context` _[string or regex]_
|
||||
## context
|
||||
|
||||
This filter allows to limit the diagram elements only to classes which are in direct relationship (of any kind) with
|
||||
the specified class:
|
||||
@@ -134,7 +134,7 @@ the specified class:
|
||||
```
|
||||
|
||||
|
||||
## `relationships`
|
||||
## relationships
|
||||
|
||||
This filter allows to include or exclude specific types of relationships from the diagram, for instance to only
|
||||
include inheritance and template specialization/instantiation relationships add the following to the diagram:
|
||||
@@ -156,19 +156,19 @@ The following relationships can be used in this filter:
|
||||
* friendship
|
||||
* dependency
|
||||
|
||||
## `subclasses` _[string or regex]_
|
||||
## subclasses
|
||||
|
||||
This filter allows to include or exclude all subclasses of a given class in the diagram.
|
||||
|
||||
## `parents` _[string or regex]_
|
||||
## parents
|
||||
|
||||
This filter allows to include or exclude all parents (base classes) of a given class in the diagram.
|
||||
|
||||
## `specializations` _[string or regex]_
|
||||
## specializations
|
||||
|
||||
This filter allows to include or exclude specializations and instantiations of a specific template from the diagram.
|
||||
|
||||
## `access`
|
||||
## access
|
||||
|
||||
This filter allows to include or exclude class methods and members based on their access scope, allowed values ar:
|
||||
|
||||
@@ -176,7 +176,7 @@ This filter allows to include or exclude class methods and members based on thei
|
||||
* `protected`
|
||||
* `private`
|
||||
|
||||
## `method_types`
|
||||
## method_types
|
||||
|
||||
This filter allows to include or exclude various method types from the class diagram, allowed values ar:
|
||||
* constructor
|
||||
@@ -190,7 +190,7 @@ This filter allows to include or exclude various method types from the class dia
|
||||
This filter is independent of the `access` filter, which controls which methods
|
||||
are included based on access scope (e.g. `public`).
|
||||
|
||||
## `dependants` and `dependencies` _[string or regex]_
|
||||
## dependants and dependencies
|
||||
|
||||
These filters allow to specify that only dependants or dependencies of a given class should be included in the diagram.
|
||||
This can be useful for analyzing what classes in your project depend on some other class, which could have impact for
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* src/options/cli_handler.h
|
||||
*
|
||||
* Copyright (c) 2021-2023 Bartek Kryza <bkryza@gmail.com>
|
||||
@@ -25,9 +25,21 @@
|
||||
#include <optional>
|
||||
|
||||
namespace clanguml::cli {
|
||||
/**
|
||||
* This enum represents possible exit states of the command line parser.
|
||||
*/
|
||||
enum class cli_flow_t {
|
||||
kExit, /*!< The application should exit (e.g. `-h`) */
|
||||
kError, /*!< The options or configuration file were invalid */
|
||||
kContinue /*!< Continue with processing diagrams */
|
||||
};
|
||||
|
||||
enum class cli_flow_t { kExit, kError, kContinue };
|
||||
|
||||
/**
|
||||
* @brief Command line options handler
|
||||
*
|
||||
* This class is responsible for handling the command line options
|
||||
* and executing required actions.
|
||||
*/
|
||||
class cli_handler {
|
||||
public:
|
||||
cli_handler(std::ostream &ostr = std::cout,
|
||||
@@ -37,45 +49,55 @@ public:
|
||||
/**
|
||||
* Main CLI handling method.
|
||||
*
|
||||
* @embed{cli_handle_options_sequence.svg}
|
||||
*
|
||||
* @param argc
|
||||
* @param argv
|
||||
* @return
|
||||
* @return Command line handler state
|
||||
*/
|
||||
cli_flow_t handle_options(int argc, const char **argv);
|
||||
|
||||
/**
|
||||
* Print the program version and basic information
|
||||
*
|
||||
* @return Command line handler state
|
||||
*/
|
||||
cli_flow_t print_version();
|
||||
|
||||
/**
|
||||
* Print list of diagrams available in the configuration file
|
||||
*
|
||||
* @return Command line handler state
|
||||
*/
|
||||
cli_flow_t print_diagrams_list();
|
||||
|
||||
/**
|
||||
* Print list of available diagram templates, including their names
|
||||
* and types.
|
||||
*
|
||||
* @return Command line handler state
|
||||
*/
|
||||
cli_flow_t print_diagram_templates();
|
||||
|
||||
/**
|
||||
* Print definition of a specific diagram template.
|
||||
*
|
||||
* @param template_name
|
||||
* @return
|
||||
* @param template_name Name of the diagram template
|
||||
* @return Command line handler state
|
||||
*/
|
||||
cli_flow_t print_diagram_template(const std::string &template_name);
|
||||
|
||||
/**
|
||||
* Print effective config after loading and setting default values.
|
||||
*
|
||||
* @return Command line handler state
|
||||
*/
|
||||
cli_flow_t print_config();
|
||||
|
||||
/**
|
||||
* Generate sample configuration file and exit.
|
||||
*
|
||||
* @return 0 on success or error code
|
||||
* @return Command line handler state
|
||||
*/
|
||||
cli_flow_t create_config_file();
|
||||
|
||||
@@ -85,7 +107,7 @@ public:
|
||||
* @param type Type of the sample diagram to add
|
||||
* @param config_file_path Path to the config file
|
||||
* @param name Name of the new diagram
|
||||
* @return 0 on success or error code
|
||||
* @return Command line handler state
|
||||
*/
|
||||
cli_flow_t add_config_diagram(clanguml::common::model::diagram_t type,
|
||||
const std::string &config_file_path, const std::string &name);
|
||||
@@ -96,7 +118,7 @@ public:
|
||||
* @param config_file_path
|
||||
* @param template_name
|
||||
* @param template_variables
|
||||
* @return
|
||||
* @return Command line handler state
|
||||
*/
|
||||
cli_flow_t add_config_diagram_from_template(
|
||||
const std::string &config_file_path, const std::string &template_name,
|
||||
@@ -144,14 +166,39 @@ public:
|
||||
clanguml::config::config config;
|
||||
|
||||
private:
|
||||
/**
|
||||
* This method parses the command line options using CLI11 library.
|
||||
*
|
||||
* @param argc
|
||||
* @param argv
|
||||
* @return Command line handler state
|
||||
*/
|
||||
cli_flow_t parse(int argc, const char **argv);
|
||||
|
||||
/**
|
||||
* Handle command line options before parsing the configuration file
|
||||
*
|
||||
* @return Command line handler state
|
||||
*/
|
||||
cli_flow_t handle_pre_config_options();
|
||||
|
||||
/**
|
||||
* Load configuration file from file or stdin
|
||||
*
|
||||
* @return Command line handler state
|
||||
*/
|
||||
cli_flow_t load_config();
|
||||
|
||||
/**
|
||||
* Handle command line options before parsing the configuration file
|
||||
*
|
||||
* @return Command line handler state
|
||||
*/
|
||||
cli_flow_t handle_post_config_options();
|
||||
|
||||
/**
|
||||
* Setup spdlog library depending on provided command line options
|
||||
*/
|
||||
void setup_logging();
|
||||
|
||||
std::ostream &ostr_;
|
||||
|
||||
@@ -35,16 +35,18 @@ class NamespaceDecl;
|
||||
|
||||
namespace clanguml::common {
|
||||
/**
|
||||
* @brief Convert @link clang::AccessSpecifier to @link model::access_t
|
||||
* @brief Convert `clang::AccessSpecifier` to @see clanguml::model::access_t
|
||||
*
|
||||
* @param access_specifier Clang member access specifier
|
||||
* @return Enum value of @link model::access_t
|
||||
* @return Enum value of @see clanguml::model::access_t
|
||||
*/
|
||||
model::access_t access_specifier_to_access_t(
|
||||
clang::AccessSpecifier access_specifier);
|
||||
|
||||
/**
|
||||
* @brief Generate full qualified name for @link clang::TagDecl instance
|
||||
* @brief Generate full qualified name for
|
||||
* [clang::TagDecl](https://clang.llvm.org/doxygen/classclang_1_1TagDecl.html)
|
||||
* instance
|
||||
*
|
||||
* @param declaration Input declaration
|
||||
* @return String representation including any templates, parameters and
|
||||
@@ -52,6 +54,16 @@ model::access_t access_specifier_to_access_t(
|
||||
*/
|
||||
std::string get_tag_name(const clang::TagDecl &declaration);
|
||||
|
||||
/**
|
||||
* @brief Get qualified name of some Clang declaration
|
||||
*
|
||||
* This template is convenient for getting qualified name of various types of
|
||||
* clang declarations.
|
||||
*
|
||||
* @tparam T Type of Clang's declaration, e.g. `clang::TagDecl`
|
||||
* @param declaration Reference to a clang declaration
|
||||
* @return Fully qualified name
|
||||
*/
|
||||
template <typename T> std::string get_qualified_name(const T &declaration)
|
||||
{
|
||||
auto qualified_name = declaration.getQualifiedNameAsString();
|
||||
@@ -70,8 +82,20 @@ template <typename T> std::string get_qualified_name(const T &declaration)
|
||||
return qualified_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get namespace of a specific `clang::TagDecl`
|
||||
*
|
||||
* @param declaration Reference to clang::TagDecl
|
||||
* @return Namespace instance
|
||||
*/
|
||||
model::namespace_ get_tag_namespace(const clang::TagDecl &declaration);
|
||||
|
||||
/**
|
||||
* Get namespace of a specific `clang::TemplateDecl`
|
||||
*
|
||||
* @param declaration Reference to clang::TemplateDecl
|
||||
* @return Namespace instance
|
||||
*/
|
||||
model::namespace_ get_template_namespace(
|
||||
const clang::TemplateDecl &declaration);
|
||||
|
||||
@@ -94,12 +118,35 @@ std::string to_string(const clang::TypeConstraint *tc);
|
||||
|
||||
std::string to_string(const clang::TemplateName &templ);
|
||||
|
||||
/**
|
||||
* @brief Get raw text of specific source range
|
||||
*
|
||||
* @param range Source range
|
||||
* @param sm Source manager reference
|
||||
* @return Raw source text
|
||||
*/
|
||||
std::string get_source_text_raw(
|
||||
clang::SourceRange range, const clang::SourceManager &sm);
|
||||
|
||||
/**
|
||||
* @brief Get printable range of text of specific source range
|
||||
*
|
||||
* @param range Source range
|
||||
* @param sm Source manager reference
|
||||
* @return Printable source text
|
||||
*/
|
||||
std::string get_source_text(
|
||||
clang::SourceRange range, const clang::SourceManager &sm);
|
||||
|
||||
/**
|
||||
* @brief Extract template depth and index
|
||||
*
|
||||
* This function extracts template depth and index values from Clang's
|
||||
* `type-parameter-` names.
|
||||
*
|
||||
* @param type_parameter Clang's type parameter string
|
||||
* @return (depth, index, qualifier)
|
||||
*/
|
||||
std::tuple<unsigned int, unsigned int, std::string>
|
||||
extract_template_parameter_index(const std::string &type_parameter);
|
||||
|
||||
@@ -115,17 +162,14 @@ extract_template_parameter_index(const std::string &type_parameter);
|
||||
*/
|
||||
bool is_subexpr_of(const clang::Stmt *parent_stmt, const clang::Stmt *sub_stmt);
|
||||
|
||||
/**
|
||||
* @brief Forward template for convertions to ID from various entities
|
||||
/** @defgroup to_id Forward template for convertions to ID from various entities
|
||||
*
|
||||
* These methods provide the main mechanism for generating globally unique
|
||||
* identifiers for all elements in the diagrams. The identifiers must be unique
|
||||
* between different translation units in order for element relationships to
|
||||
* be properly rendered in diagrams.
|
||||
*
|
||||
* @tparam T Type of entity for which ID should be computed
|
||||
* @param declaration Element (e.g. declaration) for which the ID is needed
|
||||
* @return Unique ID
|
||||
* @{
|
||||
*/
|
||||
template <typename T> id_t to_id(const T &declaration);
|
||||
|
||||
@@ -148,10 +192,25 @@ template <> id_t to_id(const clang::EnumType &type);
|
||||
template <> id_t to_id(const clang::TemplateSpecializationType &type);
|
||||
|
||||
template <> id_t to_id(const std::filesystem::path &type);
|
||||
/** @} */ // end of to_id
|
||||
|
||||
/**
|
||||
* @brief Split qualified name to namespace and name
|
||||
*
|
||||
* @param full_name Fully qualified element name
|
||||
* @return (namespace, name)
|
||||
*/
|
||||
std::pair<common::model::namespace_, std::string> split_ns(
|
||||
const std::string &full_name);
|
||||
|
||||
/**
|
||||
* @brief Parse unexposed (available as string) template params
|
||||
*
|
||||
* @param params String parameters as provided by Clang
|
||||
* @param ns_resolve Namespace resolver function
|
||||
* @param depth Current depth in the template specification
|
||||
* @return Parsed template parameter
|
||||
*/
|
||||
std::vector<common::model::template_parameter> parse_unexposed_template_params(
|
||||
const std::string ¶ms,
|
||||
const std::function<std::string(const std::string &)> &ns_resolve,
|
||||
@@ -191,6 +250,17 @@ bool is_type_token(const std::string &t);
|
||||
|
||||
clang::QualType dereference(clang::QualType type);
|
||||
|
||||
/**
|
||||
* @brief Extract type context and return raw type
|
||||
*
|
||||
* This function removes the context for a type, for example for:
|
||||
* `std::string const&`
|
||||
* it will return
|
||||
* `(std::string, [const&])`
|
||||
*
|
||||
* @param type Type to process
|
||||
* @return (type, [qualifiers])
|
||||
*/
|
||||
std::pair<clang::QualType, std::deque<common::model::context>>
|
||||
consume_type_context(clang::QualType type);
|
||||
|
||||
|
||||
@@ -38,6 +38,16 @@ class compilation_database_error : public std::runtime_error {
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Custom compilation database class
|
||||
*
|
||||
* This class provides custom specialization of Clang's
|
||||
* [CompilationDatabase](https://clang.llvm.org/doxygen/classclang_1_1tooling_1_1CompilationDatabase.html),
|
||||
* which provides the possibility of adjusting the compilation flags after
|
||||
* they have been loaded from the `compile_commands.json` file.
|
||||
*
|
||||
* @embed{compilation_database_context_class.svg}
|
||||
*/
|
||||
class compilation_database : public clang::tooling::CompilationDatabase {
|
||||
public:
|
||||
compilation_database(
|
||||
@@ -46,19 +56,52 @@ public:
|
||||
|
||||
~compilation_database() override = default;
|
||||
|
||||
/**
|
||||
* Loads the compilation database from directory specified on command
|
||||
* line or in the configuration file.
|
||||
*
|
||||
* @param cfg Reference to config instance
|
||||
* @return Instance of compilation_database.
|
||||
*/
|
||||
static std::unique_ptr<compilation_database> auto_detect_from_directory(
|
||||
const clanguml::config::config &cfg);
|
||||
|
||||
/**
|
||||
* Retrieves and adjusts compilation commands from the database, for
|
||||
* a given translation unit.
|
||||
*
|
||||
* @return List of adjusted compile commands.
|
||||
*/
|
||||
std::vector<clang::tooling::CompileCommand> getCompileCommands(
|
||||
clang::StringRef FilePath) const override;
|
||||
|
||||
/**
|
||||
* Returns all files in the database.
|
||||
*
|
||||
* @return List of all files in compilation database.
|
||||
*/
|
||||
std::vector<std::string> getAllFiles() const override;
|
||||
|
||||
/**
|
||||
* Retrieves and adjusts all compilation commands from the database.
|
||||
*
|
||||
* @return List of adjusted compile commands.
|
||||
*/
|
||||
std::vector<clang::tooling::CompileCommand>
|
||||
getAllCompileCommands() const override;
|
||||
|
||||
/**
|
||||
* Returns reference to clanguml's config instance.
|
||||
*
|
||||
* @return Reference to config instance.
|
||||
*/
|
||||
const clanguml::config::config &config() const;
|
||||
|
||||
/**
|
||||
* Returns reference to CompilationDatabase as was loaded from file.
|
||||
*
|
||||
* @return Reference to CompilationDatabase.
|
||||
*/
|
||||
const clang::tooling::CompilationDatabase &base() const;
|
||||
|
||||
std::string guess_language_from_filename(const std::string &filename) const;
|
||||
@@ -67,11 +110,17 @@ private:
|
||||
void adjust_compilation_database(
|
||||
std::vector<clang::tooling::CompileCommand> &commands) const;
|
||||
|
||||
// Actual instance of the compilation database is stored in here
|
||||
// The inheritance is just to keep the interface
|
||||
/*!
|
||||
* Pointer to the Clang's original compilation database.
|
||||
*
|
||||
* Actual instance of the compilation database is stored in here.
|
||||
* The inheritance is just to keep the interface.
|
||||
*/
|
||||
std::unique_ptr<clang::tooling::CompilationDatabase> base_;
|
||||
|
||||
// Reference to the clang-uml config
|
||||
/*!
|
||||
* Reference to the instance of clanguml config.
|
||||
*/
|
||||
const clanguml::config::config &config_;
|
||||
};
|
||||
|
||||
|
||||
@@ -184,14 +184,13 @@ void generate_diagrams(const std::vector<std::string> &diagram_names,
|
||||
continue;
|
||||
}
|
||||
|
||||
futs.emplace_back(generator_executor.add(
|
||||
[&od, &generators, &name = name, &diagram = diagram, &indicator,
|
||||
db = std::ref(*db), translation_units = valid_translation_units,
|
||||
auto generator = [&od, &generators, &name = name, &diagram = diagram,
|
||||
&indicator, db = std::ref(*db),
|
||||
translation_units = valid_translation_units,
|
||||
verbose]() mutable {
|
||||
try {
|
||||
if (indicator)
|
||||
indicator->add_progress_bar(name,
|
||||
translation_units.size(),
|
||||
indicator->add_progress_bar(name, translation_units.size(),
|
||||
diagram_type_to_color(diagram->type()));
|
||||
|
||||
generate_diagram(od, name, diagram, db, translation_units,
|
||||
@@ -209,7 +208,9 @@ void generate_diagrams(const std::vector<std::string> &diagram_names,
|
||||
|
||||
LOG_ERROR(e.what());
|
||||
}
|
||||
}));
|
||||
};
|
||||
|
||||
futs.emplace_back(generator_executor.add(std::move(generator)));
|
||||
}
|
||||
|
||||
for (auto &fut : futs) {
|
||||
|
||||
@@ -49,8 +49,13 @@
|
||||
|
||||
namespace clanguml::common::generators {
|
||||
|
||||
// template trait for selecting diagram model type based on diagram config
|
||||
// type
|
||||
/** @defgroup diagram_model_t Diagram model selector
|
||||
*
|
||||
* Template traits for selecting diagram model type based on diagram config
|
||||
* type
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
template <typename DiagramConfig> struct diagram_model_t;
|
||||
template <> struct diagram_model_t<clanguml::config::class_diagram> {
|
||||
using type = clanguml::class_diagram::model::diagram;
|
||||
@@ -64,9 +69,15 @@ template <> struct diagram_model_t<clanguml::config::package_diagram> {
|
||||
template <> struct diagram_model_t<clanguml::config::include_diagram> {
|
||||
using type = clanguml::include_diagram::model::diagram;
|
||||
};
|
||||
/** @} */
|
||||
|
||||
// template trait for selecting diagram visitor type based on diagram config
|
||||
// type
|
||||
/** @defgroup diagram_visitor_t Diagram model selector
|
||||
*
|
||||
* Template traits for selecting diagram visitor type based on diagram config
|
||||
* type
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
template <typename DiagramConfig> struct diagram_visitor_t;
|
||||
template <> struct diagram_visitor_t<clanguml::config::class_diagram> {
|
||||
using type = clanguml::class_diagram::visitor::translation_unit_visitor;
|
||||
@@ -80,16 +91,29 @@ template <> struct diagram_visitor_t<clanguml::config::package_diagram> {
|
||||
template <> struct diagram_visitor_t<clanguml::config::include_diagram> {
|
||||
using type = clanguml::include_diagram::visitor::translation_unit_visitor;
|
||||
};
|
||||
/** @} */
|
||||
|
||||
// template trait for selecting diagram generator type based on diagram config
|
||||
// type
|
||||
/** @defgroup diagram_generator_tag Diagram model tags
|
||||
*
|
||||
* Tags to determine the generator output file extension
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
struct plantuml_generator_tag {
|
||||
inline static const std::string extension = "puml";
|
||||
};
|
||||
struct json_generator_tag {
|
||||
inline static const std::string extension = "json";
|
||||
};
|
||||
/** @} */
|
||||
|
||||
/** @defgroup diagram_generator_t Diagram generator selector
|
||||
*
|
||||
* Tags to determine the generator type based on diagram config type
|
||||
* and output format
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
template <typename DiagramConfig, typename GeneratorType>
|
||||
struct diagram_generator_t;
|
||||
template <>
|
||||
@@ -132,14 +156,40 @@ struct diagram_generator_t<clanguml::config::include_diagram,
|
||||
json_generator_tag> {
|
||||
using type = clanguml::include_diagram::generators::json::generator;
|
||||
};
|
||||
/** @} */
|
||||
|
||||
template <typename DiagramConfig> struct diagram_visitor_t;
|
||||
/**
|
||||
* @brief Assign translation units to diagrams
|
||||
*
|
||||
* This function assigns for each diagram to be generated the list of
|
||||
* translation units based on it's `glob` pattern if any.
|
||||
*
|
||||
* If `diagram_names` is empty, this function processes all diagrams in
|
||||
* `config`.
|
||||
*
|
||||
* @param diagram_names List of diagram names, applies to all if empty
|
||||
* @param config Reference to config instance
|
||||
* @param compilation_database_files List of files found in compilation database
|
||||
* @param translation_units_map Resulting translation units map is stored here
|
||||
*/
|
||||
void find_translation_units_for_diagrams(
|
||||
const std::vector<std::string> &diagram_names,
|
||||
clanguml::config::config &config,
|
||||
const std::vector<std::string> &compilation_database_files,
|
||||
std::map<std::string, std::vector<std::string>> &translation_units_map);
|
||||
|
||||
/**
|
||||
* @brief Specialization of
|
||||
* [clang::ASTConsumer](https://clang.llvm.org/doxygen/classclang_1_1ASTConsumer.html)
|
||||
*
|
||||
* This class provides overriden HandleTranslationUnit() method, which
|
||||
* calls a translation_unit_visitor for a specific diagram type on
|
||||
* each translation unit assigned to the diagram.
|
||||
*
|
||||
* @tparam DiagramModel Type of diagram_model
|
||||
* @tparam DiagramConfig Type of diagram_config
|
||||
* @tparam TranslationUnitVisitor Type of translation_unit_visitor
|
||||
*/
|
||||
template <typename DiagramModel, typename DiagramConfig,
|
||||
typename TranslationUnitVisitor>
|
||||
class diagram_ast_consumer : public clang::ASTConsumer {
|
||||
@@ -161,6 +211,17 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Specialization of
|
||||
* [clang::ASTFrontendAction](https://clang.llvm.org/doxygen/classclang_1_1ASTFrontendAction.html)
|
||||
*
|
||||
* This class overrides the BeginSourceFileAction() and CreateASTConsumer()
|
||||
* methods to create and setup an appropriate diagram_ast_consumer instance.
|
||||
*
|
||||
* @tparam DiagramModel Type of diagram_model
|
||||
* @tparam DiagramConfig Type of diagram_config
|
||||
* @tparam TranslationUnitVisitor Type of translation_unit_visitor
|
||||
*/
|
||||
template <typename DiagramModel, typename DiagramConfig,
|
||||
typename DiagramVisitor>
|
||||
class diagram_fronted_action : public clang::ASTFrontendAction {
|
||||
@@ -193,6 +254,8 @@ protected:
|
||||
{
|
||||
LOG_DBG("Visiting source file: {}", getCurrentFile().str());
|
||||
|
||||
// Update progress indicators, if enabled, on each translation
|
||||
// unit
|
||||
if (progress_)
|
||||
progress_();
|
||||
|
||||
@@ -216,6 +279,17 @@ private:
|
||||
std::function<void()> progress_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Specialization of
|
||||
* [clang::ASTFrontendAction](https://clang.llvm.org/doxygen/classclang_1_1tooling_1_1FrontendActionFactory.html)
|
||||
*
|
||||
* This class overrides the create() method in order to create an instance
|
||||
* of diagram_frontend_action of appropriate type.
|
||||
*
|
||||
* @tparam DiagramModel Type of diagram_model
|
||||
* @tparam DiagramConfig Type of diagram_config
|
||||
* @tparam TranslationUnitVisitor Type of translation_unit_visitor
|
||||
*/
|
||||
template <typename DiagramModel, typename DiagramConfig,
|
||||
typename DiagramVisitor>
|
||||
class diagram_action_visitor_factory
|
||||
@@ -241,6 +315,19 @@ private:
|
||||
std::function<void()> progress_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Specialization of
|
||||
* [clang::ASTFrontendAction](https://clang.llvm.org/doxygen/classclang_1_1tooling_1_1FrontendActionFactory.html)
|
||||
*
|
||||
* This is the entry point function to initiate AST frontend action for a
|
||||
* specific diagram.
|
||||
*
|
||||
* @embed{diagram_generate_generic_sequence.svg}
|
||||
*
|
||||
* @tparam DiagramModel Type of diagram_model
|
||||
* @tparam DiagramConfig Type of diagram_config
|
||||
* @tparam TranslationUnitVisitor Type of translation_unit_visitor
|
||||
*/
|
||||
template <typename DiagramModel, typename DiagramConfig,
|
||||
typename DiagramVisitor>
|
||||
std::unique_ptr<DiagramModel> generate(const common::compilation_database &db,
|
||||
@@ -275,6 +362,17 @@ std::unique_ptr<DiagramModel> generate(const common::compilation_database &db,
|
||||
return diagram;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Generate a single diagram
|
||||
*
|
||||
* @param od Output directory path
|
||||
* @param name Name of the diagram
|
||||
* @param diagram Effective diagram configuration
|
||||
* @param db Reference to compilation database
|
||||
* @param translation_units List of translation units for the diagram
|
||||
* @param generators List of generator types to be used for the diagram
|
||||
* @param verbose Log level
|
||||
*/
|
||||
void generate_diagram(const std::string &od, const std::string &name,
|
||||
std::shared_ptr<clanguml::config::diagram> diagram,
|
||||
const common::compilation_database &db,
|
||||
@@ -282,6 +380,19 @@ void generate_diagram(const std::string &od, const std::string &name,
|
||||
const std::vector<clanguml::common::generator_type_t> &generators,
|
||||
bool verbose);
|
||||
|
||||
/**
|
||||
* @brief Generate diagrams
|
||||
*
|
||||
* @param diagram_names List of diagram names to generate
|
||||
* @param config Reference to config instance
|
||||
* @param od Path to output directory
|
||||
* @param db Reference to compilation database
|
||||
* @param verbose Log level
|
||||
* @param thread_count Number of diagrams to be generated in parallel
|
||||
* @param progress Whether progress indicators should be displayed
|
||||
* @param generators List of generator types to use for each diagram
|
||||
* @param translation_units_map Map of translation units for each file
|
||||
*/
|
||||
void generate_diagrams(const std::vector<std::string> &diagram_names,
|
||||
clanguml::config::config &config, const std::string &od,
|
||||
const common::compilation_database_ptr &db, int verbose,
|
||||
@@ -290,6 +401,12 @@ void generate_diagrams(const std::vector<std::string> &diagram_names,
|
||||
const std::map<std::string, std::vector<std::string>>
|
||||
&translation_units_map);
|
||||
|
||||
/**
|
||||
* @brief Return indicators progress bar color for diagram type
|
||||
*
|
||||
* @param diagram_type Diagram type
|
||||
* @return Progress bar color
|
||||
*/
|
||||
indicators::Color diagram_type_to_color(model::diagram_t diagram_type);
|
||||
|
||||
} // namespace clanguml::common::generators
|
||||
@@ -334,7 +334,7 @@ void generator<C, D>::generate_plantuml_directives(
|
||||
// Render the directive with template engine first
|
||||
std::string directive{env().render(std::string_view{d}, context())};
|
||||
|
||||
// Now search for alias @A() directives in the text
|
||||
// Now search for alias `@A()` directives in the text
|
||||
// (this is deprecated)
|
||||
std::tuple<std::string, size_t, size_t> alias_match;
|
||||
while (util::find_element_alias(directive, alias_match)) {
|
||||
|
||||
@@ -34,26 +34,95 @@ namespace clanguml::common::model {
|
||||
|
||||
using comment_t = inja::json;
|
||||
|
||||
/**
|
||||
* @brief Base class for decorated diagram elements
|
||||
*
|
||||
* Decorators in `clang-uml` mean that custom `@uml{}` directives can be
|
||||
* applied to them in the code comments.
|
||||
*
|
||||
* @embed{decorated_element_hierarchy_class.svg}
|
||||
*
|
||||
* @see clanguml::decorators::decorator
|
||||
*
|
||||
*/
|
||||
class decorated_element {
|
||||
public:
|
||||
/**
|
||||
* Whether this element should be skipped from the diagram.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
bool skip() const;
|
||||
|
||||
/**
|
||||
* Whether this relationship should be skipped from the diagram.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
bool skip_relationship() const;
|
||||
|
||||
/**
|
||||
* If this element is a member or a method, get relationship decorator
|
||||
* if any.
|
||||
*
|
||||
* @code
|
||||
* /// @uml{aggregation[0..1:1..5]}
|
||||
* std::vector<C> ccc;
|
||||
* @endcode
|
||||
*
|
||||
* @return Relationship specified as a decorator on class member.
|
||||
*/
|
||||
std::pair<relationship_t, std::string> get_relationship() const;
|
||||
|
||||
/**
|
||||
* Get stype specification for this element, if any.
|
||||
*
|
||||
* @code
|
||||
* /// @uml{style[#back:lightgreen|yellow;header:blue/red]}
|
||||
* class A { };
|
||||
* @endcode
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
std::string style_spec() const;
|
||||
|
||||
/**
|
||||
* Get all decorators for this element.
|
||||
*
|
||||
* @return List of decorator pointers.
|
||||
*/
|
||||
const std::vector<std::shared_ptr<decorators::decorator>> &
|
||||
decorators() const;
|
||||
|
||||
/**
|
||||
* Add decorators to the element.
|
||||
*
|
||||
* @param decorators List of decorator pointers.
|
||||
*/
|
||||
void add_decorators(
|
||||
const std::vector<std::shared_ptr<decorators::decorator>> &decorators);
|
||||
|
||||
/**
|
||||
* Append decorators from another element.
|
||||
*
|
||||
* @param de Source element to copy decorators from.
|
||||
*/
|
||||
void append(const decorated_element &de);
|
||||
|
||||
/**
|
||||
* Get entire comment model for this element.
|
||||
*
|
||||
* @return Comment model.
|
||||
*/
|
||||
std::optional<comment_t> comment() const;
|
||||
|
||||
/**
|
||||
* Set comment model for this element.
|
||||
*
|
||||
* Comment model is currently a JSON object.
|
||||
*
|
||||
* @param c Comment model.
|
||||
*/
|
||||
void set_comment(const comment_t &c);
|
||||
|
||||
private:
|
||||
|
||||
@@ -31,22 +31,49 @@ class diagram_filter;
|
||||
class element;
|
||||
class relationship;
|
||||
|
||||
/**
|
||||
* @brief Base class for all diagram models
|
||||
*
|
||||
* @embed{diagram_hierarchy_class.svg}
|
||||
*/
|
||||
class diagram {
|
||||
public:
|
||||
diagram();
|
||||
|
||||
virtual ~diagram();
|
||||
|
||||
/**
|
||||
* @brief Return type of the diagram.
|
||||
*
|
||||
* @return Type of diagram
|
||||
*/
|
||||
virtual diagram_t type() const = 0;
|
||||
|
||||
/**
|
||||
* Return optional reference to a diagram_element by name.
|
||||
*
|
||||
* @param full_name Fully qualified name of a diagram element.
|
||||
* @return Optional reference to a diagram element.
|
||||
*/
|
||||
virtual opt_ref<clanguml::common::model::diagram_element> get(
|
||||
const std::string &full_name) const = 0;
|
||||
|
||||
/**
|
||||
* Return optional reference to a diagram_element by id.
|
||||
*
|
||||
* @param id Id of a diagram element.
|
||||
* @return Optional reference to a diagram element.
|
||||
*/
|
||||
virtual common::optional_ref<clanguml::common::model::diagram_element> get(
|
||||
diagram_element::id_t id) const = 0;
|
||||
|
||||
/// \brief Find element in diagram which can have full name or be
|
||||
/// relative to ns
|
||||
/**
|
||||
* Return optional reference to a diagram_element by name and namespace.
|
||||
*
|
||||
* @param name Name of the diagram element (e.g. a class name)
|
||||
* @param ns Namespace of the element.
|
||||
* @return Optional reference to a diagram element.
|
||||
*/
|
||||
virtual common::optional_ref<clanguml::common::model::diagram_element>
|
||||
get_with_namespace(const std::string &name, const namespace_ &ns) const;
|
||||
|
||||
@@ -55,13 +82,52 @@ public:
|
||||
diagram &operator=(const diagram &) = delete;
|
||||
diagram &operator=(diagram && /*unused*/) noexcept;
|
||||
|
||||
/**
|
||||
* Set diagram name.
|
||||
*
|
||||
* @param name Name of the diagram.
|
||||
*/
|
||||
void set_name(const std::string &name);
|
||||
|
||||
/**
|
||||
* Return the name of the diagram.
|
||||
*
|
||||
* @return Name of the diagram.
|
||||
*/
|
||||
std::string name() const;
|
||||
|
||||
/**
|
||||
* Set diagram filter for this diagram.
|
||||
*
|
||||
* @param filter diagram_filter instance
|
||||
*
|
||||
* @see clanguml::common::model::diagram_filter
|
||||
*/
|
||||
void set_filter(std::unique_ptr<diagram_filter> filter);
|
||||
|
||||
/**
|
||||
* Get diagram filter
|
||||
*
|
||||
* @return Reference to the diagrams element filter
|
||||
*/
|
||||
const diagram_filter &filter() const { return *filter_; }
|
||||
|
||||
/**
|
||||
* @brief Set diagram in a complete state.
|
||||
*
|
||||
* This must be called after the diagram's 'translation_unit_visitor' has
|
||||
* completed for all translation units, in order to apply filters which can
|
||||
* only work after the diagram is complete.
|
||||
*
|
||||
* @param complete Status of diagram visitor completion.
|
||||
*/
|
||||
void set_complete(bool complete);
|
||||
|
||||
/**
|
||||
* Whether the diagram is complete.
|
||||
*
|
||||
* @return Diagram completion status.
|
||||
*/
|
||||
bool complete() const;
|
||||
|
||||
// TODO: refactor to a template method
|
||||
@@ -80,6 +146,11 @@ public:
|
||||
virtual bool should_include(
|
||||
const namespace_ &ns, const std::string &name) const;
|
||||
|
||||
/**
|
||||
* Return diagrams JSON context for inja templates.
|
||||
*
|
||||
* @return JSON context.
|
||||
*/
|
||||
virtual inja::json context() const = 0;
|
||||
|
||||
private:
|
||||
|
||||
@@ -31,6 +31,12 @@
|
||||
|
||||
namespace clanguml::common::model {
|
||||
|
||||
/**
|
||||
* @brief Base class for standalone diagram elements.
|
||||
*
|
||||
* This is a base cass of any standalone elements such as classes, structs,
|
||||
* concepts, packages and so on participants and so on.
|
||||
*/
|
||||
class diagram_element : public decorated_element, public source_location {
|
||||
public:
|
||||
using id_t = int64_t;
|
||||
@@ -39,26 +45,91 @@ public:
|
||||
|
||||
virtual ~diagram_element() = default;
|
||||
|
||||
/**
|
||||
* @brief Returns diagram element id.
|
||||
*
|
||||
* Each element in the diagram is uniquely identified by id. The id
|
||||
* is currently calculated from the full string representation of the
|
||||
* element, in order to be uniquely identifiable among multiple translation
|
||||
* units.
|
||||
*
|
||||
* @return Elements id.
|
||||
*/
|
||||
id_t id() const;
|
||||
|
||||
/**
|
||||
* Set elements id.
|
||||
*
|
||||
* @param id Elements id.
|
||||
*/
|
||||
void set_id(id_t id);
|
||||
|
||||
/**
|
||||
* @brief Return elements' diagram alias.
|
||||
*
|
||||
* @todo This is a PlantUML specific method - it shouldn't be here.
|
||||
*
|
||||
* @return PlantUML's diagram element alias.
|
||||
*/
|
||||
virtual std::string alias() const;
|
||||
|
||||
/**
|
||||
* Set diagram elements name.
|
||||
*
|
||||
* @param name Elements name.
|
||||
*/
|
||||
void set_name(const std::string &name) { name_ = name; }
|
||||
|
||||
/**
|
||||
* Return diagram's name.
|
||||
*
|
||||
* @return Diagram's name.
|
||||
*/
|
||||
std::string name() const { return name_; }
|
||||
|
||||
/**
|
||||
* Return the type name of the diagram.
|
||||
*
|
||||
* @return Diagrams type name.
|
||||
*/
|
||||
virtual std::string type_name() const { return "__undefined__"; };
|
||||
|
||||
/**
|
||||
* @brief Return the elements fully qualified name.
|
||||
*
|
||||
* This method should be implemented in each subclass, and ensure that
|
||||
* for instance it includes fully qualified namespace, template params, etc.
|
||||
*
|
||||
* @return Full elements name.
|
||||
*/
|
||||
virtual std::string full_name(bool /*relative*/) const { return name(); }
|
||||
|
||||
/**
|
||||
* Return all relationships outgoing from this element.
|
||||
*
|
||||
* @return List of relationships.
|
||||
*/
|
||||
std::vector<relationship> &relationships();
|
||||
|
||||
/**
|
||||
* Return all relationships outgoing from this element.
|
||||
*
|
||||
* @return List of relationships.
|
||||
*/
|
||||
const std::vector<relationship> &relationships() const;
|
||||
|
||||
/**
|
||||
* Add relationships, whose source is this element.
|
||||
*
|
||||
* @param cr Relationship to another diagram element.
|
||||
*/
|
||||
void add_relationship(relationship &&cr);
|
||||
|
||||
/**
|
||||
* Add element to the diagram.
|
||||
*
|
||||
* @param e Diagram element.
|
||||
*/
|
||||
void append(const decorated_element &e);
|
||||
|
||||
friend bool operator==(const diagram_element &l, const diagram_element &r);
|
||||
@@ -66,14 +137,39 @@ public:
|
||||
friend std::ostream &operator<<(
|
||||
std::ostream &out, const diagram_element &rhs);
|
||||
|
||||
/**
|
||||
* Return elements inja JSON context.
|
||||
*
|
||||
* @return Element context.
|
||||
*/
|
||||
virtual inja::json context() const;
|
||||
|
||||
/**
|
||||
* Whether this element is nested in another element.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
bool is_nested() const;
|
||||
|
||||
/**
|
||||
* Set element's nested status.
|
||||
*
|
||||
* @param nested
|
||||
*/
|
||||
void nested(bool nested);
|
||||
|
||||
/**
|
||||
* Returns the diagrams completion status.
|
||||
*
|
||||
* @return Whether the diagram is complete.
|
||||
*/
|
||||
bool complete() const;
|
||||
|
||||
/**
|
||||
* Set the diagrams completion status.
|
||||
*
|
||||
* @param completed
|
||||
*/
|
||||
void complete(bool completed);
|
||||
|
||||
private:
|
||||
|
||||
@@ -36,7 +36,15 @@
|
||||
|
||||
namespace clanguml::common::model {
|
||||
|
||||
enum filter_t { kInclusive, kExclusive };
|
||||
/**
|
||||
* Diagram filters can be add in 2 modes:
|
||||
* - inclusive - the elements that match are included in the diagram
|
||||
* - exclusive - the elements that match are excluded from the diagram
|
||||
*/
|
||||
enum class filter_t {
|
||||
kInclusive, /*!< Filter is inclusive */
|
||||
kExclusive /*!< Filter is exclusve */
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template <typename ElementT, typename DiagramT>
|
||||
@@ -56,6 +64,16 @@ clanguml::common::id_t destination_comparator(
|
||||
const common::model::source_file &f);
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* @brief Base class for any diagram filter.
|
||||
*
|
||||
* This class acts as a visitor for diagram elements. It provides a set of
|
||||
* common methods which can be overriden by specific filters. If a filter
|
||||
* does not implement a specific method, it is ignored through the 3 value
|
||||
* logic implemented in @see clanguml::common::model::tvl
|
||||
*
|
||||
* @embed{filter_visitor_hierarchy_class.svg}
|
||||
*/
|
||||
class filter_visitor {
|
||||
public:
|
||||
filter_visitor(filter_t type);
|
||||
@@ -111,6 +129,10 @@ private:
|
||||
std::vector<std::unique_ptr<filter_visitor>> filters_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Match namespace or diagram element to a set of specified namespaces or
|
||||
* regex patterns.
|
||||
*/
|
||||
struct namespace_filter : public filter_visitor {
|
||||
namespace_filter(
|
||||
filter_t type, std::vector<common::namespace_or_regex> namespaces);
|
||||
@@ -125,6 +147,9 @@ private:
|
||||
std::vector<common::namespace_or_regex> namespaces_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Match element's name to a set of names or regex patterns.
|
||||
*/
|
||||
struct element_filter : public filter_visitor {
|
||||
element_filter(
|
||||
filter_t type, std::vector<common::string_or_regex> elements);
|
||||
@@ -137,6 +162,9 @@ private:
|
||||
std::vector<common::string_or_regex> elements_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Match diagram elements based on elements type (e.g. class).
|
||||
*/
|
||||
struct element_type_filter : public filter_visitor {
|
||||
element_type_filter(filter_t type, std::vector<std::string> element_types);
|
||||
|
||||
@@ -148,6 +176,9 @@ private:
|
||||
std::vector<std::string> element_types_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Match class methods based on their category (e.g. operator).
|
||||
*/
|
||||
struct method_type_filter : public filter_visitor {
|
||||
method_type_filter(
|
||||
filter_t type, std::vector<config::method_type> method_types);
|
||||
@@ -161,6 +192,10 @@ private:
|
||||
std::vector<config::method_type> method_types_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Match element based on whether it is a subclass of a set of base classes,
|
||||
* or one of them.
|
||||
*/
|
||||
struct subclass_filter : public filter_visitor {
|
||||
subclass_filter(filter_t type, std::vector<common::string_or_regex> roots);
|
||||
|
||||
@@ -172,6 +207,10 @@ private:
|
||||
std::vector<common::string_or_regex> roots_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Match element based on whether it is a parent of a set of children, or one
|
||||
* of them.
|
||||
*/
|
||||
struct parents_filter : public filter_visitor {
|
||||
parents_filter(filter_t type, std::vector<common::string_or_regex> roots);
|
||||
|
||||
@@ -183,6 +222,20 @@ private:
|
||||
std::vector<common::string_or_regex> children_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Common template for filters involving traversing relationship graph.
|
||||
*
|
||||
* This class template provides a common implementation of a diagram
|
||||
* relationship graph traversal. It is used for filters, which need to check
|
||||
* for instance, whether an element is in some kind of relationship with other
|
||||
* element.
|
||||
*
|
||||
* @tparam DiagramT Diagram type
|
||||
* @tparam ElementT Element type
|
||||
* @tparam ConfigEntryT Type of configuration option used to specify initial
|
||||
* elements for traversal
|
||||
* @tparam MatchOverrideT Type of the matched element
|
||||
*/
|
||||
template <typename DiagramT, typename ElementT,
|
||||
typename ConfigEntryT = std::string,
|
||||
typename MatchOverrideT = common::model::element>
|
||||
@@ -337,6 +390,9 @@ private:
|
||||
bool forward_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Match relationship types.
|
||||
*/
|
||||
struct relationship_filter : public filter_visitor {
|
||||
relationship_filter(
|
||||
filter_t type, std::vector<relationship_t> relationships);
|
||||
@@ -350,6 +406,9 @@ private:
|
||||
std::vector<relationship_t> relationships_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Match class members and methods based on access (public, protected, private).
|
||||
*/
|
||||
struct access_filter : public filter_visitor {
|
||||
access_filter(filter_t type, std::vector<access_t> access);
|
||||
|
||||
@@ -361,6 +420,10 @@ private:
|
||||
std::vector<access_t> access_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Match diagram elements which are in direct relationship to any of the
|
||||
* elements specified in context.
|
||||
*/
|
||||
struct context_filter : public filter_visitor {
|
||||
context_filter(filter_t type, std::vector<common::string_or_regex> context);
|
||||
|
||||
@@ -372,6 +435,10 @@ private:
|
||||
std::vector<common::string_or_regex> context_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Match elements based on their source location, whether it matches to
|
||||
* a specified file paths.
|
||||
*/
|
||||
struct paths_filter : public filter_visitor {
|
||||
paths_filter(filter_t type, const std::filesystem::path &root,
|
||||
const std::vector<std::string> &p);
|
||||
@@ -389,6 +456,9 @@ private:
|
||||
std::filesystem::path root_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Match class method based on specified method categories.
|
||||
*/
|
||||
struct class_method_filter : public filter_visitor {
|
||||
class_method_filter(filter_t type, std::unique_ptr<access_filter> af,
|
||||
std::unique_ptr<method_type_filter> mtf);
|
||||
@@ -403,6 +473,9 @@ private:
|
||||
std::unique_ptr<method_type_filter> method_type_filter_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Match class members.
|
||||
*/
|
||||
struct class_member_filter : public filter_visitor {
|
||||
class_member_filter(filter_t type, std::unique_ptr<access_filter> af);
|
||||
|
||||
@@ -415,16 +488,49 @@ private:
|
||||
std::unique_ptr<access_filter> access_filter_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Composite of all diagrams filters.
|
||||
*
|
||||
* Instances of this class contain all filters specified in configuration file
|
||||
* for a given diagram.
|
||||
*
|
||||
* @embed{diagram_filter_context_class.svg}
|
||||
*
|
||||
* @see clanguml::common::model::filter_visitor
|
||||
*/
|
||||
class diagram_filter {
|
||||
public:
|
||||
diagram_filter(const common::model::diagram &d, const config::diagram &c);
|
||||
|
||||
/**
|
||||
* Add inclusive filter.
|
||||
*
|
||||
* @param fv Filter visitor.
|
||||
*/
|
||||
void add_inclusive_filter(std::unique_ptr<filter_visitor> fv);
|
||||
|
||||
/** Add exclusive filter.
|
||||
*
|
||||
* @param fv Filter visitor.
|
||||
*/
|
||||
void add_exclusive_filter(std::unique_ptr<filter_visitor> fv);
|
||||
|
||||
/**
|
||||
* `should_include` overload for namespace and name.
|
||||
*
|
||||
* @param ns Namespace
|
||||
* @param name Name
|
||||
* @return Match result.
|
||||
*/
|
||||
bool should_include(const namespace_ &ns, const std::string &name) const;
|
||||
|
||||
/**
|
||||
* Generic `should_include` overload for various diagram elements.
|
||||
*
|
||||
* @tparam T Type to to match - must match one of filter_visitor's match(T)
|
||||
* @param e Value of type T to match
|
||||
* @return Match result.
|
||||
*/
|
||||
template <typename T> bool should_include(const T &e) const
|
||||
{
|
||||
auto exc = tvl::any_of(exclusive_.begin(), exclusive_.end(),
|
||||
@@ -440,11 +546,22 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Initialize filters.
|
||||
*
|
||||
* Some filters require initialization.
|
||||
*
|
||||
* @param c Diagram config.
|
||||
*/
|
||||
void init_filters(const config::diagram &c);
|
||||
|
||||
/*! List of inclusive filters */
|
||||
std::vector<std::unique_ptr<filter_visitor>> inclusive_;
|
||||
|
||||
/*! List of exclusive filters */
|
||||
std::vector<std::unique_ptr<filter_visitor>> exclusive_;
|
||||
|
||||
/*! Reference to the diagram model */
|
||||
const common::model::diagram &diagram_;
|
||||
};
|
||||
|
||||
|
||||
@@ -32,36 +32,83 @@
|
||||
|
||||
namespace clanguml::common::model {
|
||||
|
||||
/**
|
||||
* @brief Base class for any element qualified by namespace.
|
||||
*/
|
||||
class element : public diagram_element {
|
||||
public:
|
||||
element(namespace_ using_namespace);
|
||||
|
||||
~element() override = default;
|
||||
|
||||
/**
|
||||
* Return the elements fully qualified name, but without template
|
||||
* arguments or function params.
|
||||
*
|
||||
* @return Fully qualified element name.
|
||||
*/
|
||||
std::string name_and_ns() const
|
||||
{
|
||||
auto ns = ns_ | name();
|
||||
return ns.to_string();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set elements namespace.
|
||||
*
|
||||
* @param ns Namespace.
|
||||
*/
|
||||
void set_namespace(const namespace_ &ns) { ns_ = ns; }
|
||||
|
||||
/**
|
||||
* Return elements namespace.
|
||||
*
|
||||
* @return Namespace.
|
||||
*/
|
||||
namespace_ get_namespace() const { return ns_; }
|
||||
|
||||
/**
|
||||
* Return elements relative namespace.
|
||||
*
|
||||
* @return Namespace.
|
||||
*/
|
||||
namespace_ get_relative_namespace() const
|
||||
{
|
||||
return ns_.relative_to(using_namespace_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return elements namespace as path.
|
||||
*
|
||||
* Namespace is a nested path in diagrams where packages are generated
|
||||
* from namespaces.
|
||||
*
|
||||
* @return Namespace.
|
||||
*/
|
||||
const namespace_ &path() const { return ns_; }
|
||||
|
||||
/**
|
||||
* Return elements full name.
|
||||
*
|
||||
* @return Fully qualified elements name.
|
||||
*/
|
||||
std::string full_name(bool /*relative*/) const override
|
||||
{
|
||||
return name_and_ns();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return elements full name but without namespace.
|
||||
*
|
||||
* @return Elements full name without namespace.
|
||||
*/
|
||||
virtual std::string full_name_no_ns() const { return name(); }
|
||||
|
||||
/**
|
||||
* Return the relative namespace from config.
|
||||
*
|
||||
* @return Namespace.
|
||||
*/
|
||||
const namespace_ &using_namespace() const;
|
||||
|
||||
friend bool operator==(const element &l, const element &r);
|
||||
|
||||
@@ -25,6 +25,18 @@
|
||||
#include <vector>
|
||||
|
||||
namespace clanguml::common::model {
|
||||
|
||||
/**
|
||||
* @brief Base class for elements nested in the diagram.
|
||||
*
|
||||
* This class provides a common trait for diagram elements which can contain
|
||||
* other nested elements, e.g. packages.
|
||||
*
|
||||
* @embed{nested_trait_hierarchy_class.svg}
|
||||
*
|
||||
* @tparam T Type of element
|
||||
* @tparam Path Type of nested path (e.g. namespace or directory path)
|
||||
*/
|
||||
template <typename T, typename Path> class nested_trait {
|
||||
public:
|
||||
nested_trait() = default;
|
||||
@@ -37,6 +49,13 @@ public:
|
||||
|
||||
virtual ~nested_trait() = default;
|
||||
|
||||
/**
|
||||
* Add element at the current nested level.
|
||||
*
|
||||
* @tparam V Type of element
|
||||
* @param p Element
|
||||
* @return True, if element was added.
|
||||
*/
|
||||
template <typename V = T>
|
||||
[[nodiscard]] bool add_element(std::unique_ptr<V> p)
|
||||
{
|
||||
@@ -53,6 +72,14 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add element at a nested path.
|
||||
*
|
||||
* @tparam V Type of element
|
||||
* @param path Nested path (e.g. list of namespaces)
|
||||
* @param p Element
|
||||
* @return True, if element was added.
|
||||
*/
|
||||
template <typename V = T>
|
||||
bool add_element(const Path &path, std::unique_ptr<V> p)
|
||||
{
|
||||
@@ -77,6 +104,13 @@ public:
|
||||
"No parent element found for " + path.to_string());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get element at path, if exists.
|
||||
*
|
||||
* @tparam V Element type.
|
||||
* @param path Path to the element.
|
||||
* @return Optional reference to the element.
|
||||
*/
|
||||
template <typename V = T> auto get_element(const Path &path) const
|
||||
{
|
||||
if (path.is_empty() || !has_element(path[0])) {
|
||||
@@ -100,18 +134,13 @@ public:
|
||||
return optional_ref<V>{};
|
||||
}
|
||||
|
||||
template <typename V = T> auto get_element_parent(const T &element) const
|
||||
{
|
||||
auto path = element.path();
|
||||
auto parent = get_element(path);
|
||||
|
||||
if (parent.has_value())
|
||||
return optional_ref<V>{
|
||||
std::ref<V>(dynamic_cast<V &>(parent.value()))};
|
||||
|
||||
return optional_ref<V>{};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get element by name at the current nested level.
|
||||
*
|
||||
* @tparam V Type of element.
|
||||
* @param name Name of the element (cannot contain namespace or path)
|
||||
* @return Optional reference to the element.
|
||||
*/
|
||||
template <typename V = T> auto get_element(const std::string &name) const
|
||||
{
|
||||
assert(!util::contains(name, "::"));
|
||||
@@ -130,6 +159,13 @@ public:
|
||||
return optional_ref<V>{};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true of this nested level contains an element with specified
|
||||
* name.
|
||||
*
|
||||
* @param name Name of the element.
|
||||
* @return True if element exists.
|
||||
*/
|
||||
bool has_element(const std::string &name) const
|
||||
{
|
||||
return std::find_if(elements_.cbegin(), elements_.cend(),
|
||||
@@ -137,6 +173,12 @@ public:
|
||||
elements_.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return result of functor f applied to all_of elements.
|
||||
* @tparam F Functor type
|
||||
* @param f Functor value
|
||||
* @return True, if functor return true for elements, including nested ones.
|
||||
*/
|
||||
template <typename F> bool all_of(F &&f) const
|
||||
{
|
||||
return std::all_of(
|
||||
@@ -151,6 +193,11 @@ public:
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if nested element is empty.
|
||||
*
|
||||
* @return True if this nested element is empty.
|
||||
*/
|
||||
bool is_empty() const
|
||||
{
|
||||
return elements_.empty() ||
|
||||
@@ -170,6 +217,13 @@ public:
|
||||
auto begin() const { return elements_.begin(); }
|
||||
auto end() const { return elements_.end(); }
|
||||
|
||||
/**
|
||||
* Print the nested trait in the form of a tree.
|
||||
*
|
||||
* This method is used for debugging only.
|
||||
*
|
||||
* @param level Tree level
|
||||
*/
|
||||
void print_tree(const int level)
|
||||
{
|
||||
const auto &d = *this;
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
|
||||
namespace clanguml::common::model {
|
||||
|
||||
/**
|
||||
* @brief Diagram element representing namespace or directory package
|
||||
*
|
||||
* @embed{package_hierarchy_class.svg}
|
||||
*/
|
||||
class package : public element,
|
||||
public stylable_element,
|
||||
public nested_trait<element, path> {
|
||||
@@ -47,10 +52,25 @@ public:
|
||||
|
||||
std::string full_name(bool relative) const override;
|
||||
|
||||
/**
|
||||
* Returns whether the namespace is deprecated.
|
||||
*
|
||||
* @return True, if namespace is deprecated.
|
||||
*/
|
||||
bool is_deprecated() const;
|
||||
|
||||
/**
|
||||
* Set namespace deprecation status.
|
||||
*
|
||||
* @param deprecated True, if namespace is deprecated
|
||||
*/
|
||||
void set_deprecated(bool deprecated);
|
||||
|
||||
/**
|
||||
* Add subpackage.
|
||||
*
|
||||
* @param p Package.
|
||||
*/
|
||||
void add_package(std::unique_ptr<common::model::package> &&p);
|
||||
|
||||
private:
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
|
||||
namespace clanguml::common::model {
|
||||
|
||||
/**
|
||||
* @brief Base class of all diagram elements that have source location.
|
||||
*/
|
||||
class source_location {
|
||||
public:
|
||||
source_location() = default;
|
||||
@@ -32,31 +35,96 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Return absolute source file path.
|
||||
*
|
||||
* @return Absolute file path.
|
||||
*/
|
||||
const std::string &file() const { return file_; }
|
||||
|
||||
/**
|
||||
* Set absolute file path.
|
||||
*
|
||||
* @param file Absolute file path.
|
||||
*/
|
||||
void set_file(const std::string &file) { file_ = file; }
|
||||
|
||||
/**
|
||||
* Return source file path relative to `relative_to` config option.
|
||||
*
|
||||
* @return Relative file path.
|
||||
*/
|
||||
const std::string &file_relative() const { return file_relative_; }
|
||||
|
||||
/**
|
||||
* Set relative file path.
|
||||
*
|
||||
* @param file Relative file path.
|
||||
*/
|
||||
void set_file_relative(const std::string &file) { file_relative_ = file; }
|
||||
|
||||
/**
|
||||
* Get the translation unit, from which this source location was visited.
|
||||
*
|
||||
* @return Path to the translation unit.
|
||||
*/
|
||||
const std::string &translation_unit() const { return translation_unit_; }
|
||||
|
||||
/**
|
||||
* Set the path to translation unit, from which this source location was
|
||||
* visited.
|
||||
*
|
||||
* @param translation_unit Path to the translation unit.
|
||||
*/
|
||||
void set_translation_unit(const std::string &translation_unit)
|
||||
{
|
||||
translation_unit_ = translation_unit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the source location line number.
|
||||
*
|
||||
* @return Line number.
|
||||
*/
|
||||
unsigned int line() const { return line_; }
|
||||
|
||||
/**
|
||||
* Set the source location line number.
|
||||
*
|
||||
* @param line Line number.
|
||||
*/
|
||||
void set_line(const unsigned line) { line_ = line; }
|
||||
|
||||
/**
|
||||
* Get the source location column number.
|
||||
*
|
||||
* @return Column number.
|
||||
*/
|
||||
unsigned int column() const { return column_; }
|
||||
|
||||
/**
|
||||
* Set the source location column number.
|
||||
*
|
||||
* @param line Column number.
|
||||
*/
|
||||
void set_column(const unsigned column) { column_ = column; }
|
||||
|
||||
/**
|
||||
* Get the source location id.
|
||||
*
|
||||
* The location id is equivalent to Clang's SourceLocation::getHashValue()
|
||||
*
|
||||
* @return Location id.
|
||||
*/
|
||||
unsigned int location_id() const { return hash_; }
|
||||
|
||||
/**
|
||||
* Set the source location id.
|
||||
*
|
||||
* The location id is equivalent to Clang's SourceLocation::getHashValue()
|
||||
*
|
||||
* @param h Location id.
|
||||
*/
|
||||
void set_location_id(unsigned int h) { hash_ = h; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -31,10 +31,32 @@ namespace clanguml::common {
|
||||
|
||||
using id_t = int64_t;
|
||||
|
||||
enum class generator_type_t { plantuml, json };
|
||||
/**
|
||||
* Type of output diagram format generator.
|
||||
*/
|
||||
enum class generator_type_t {
|
||||
plantuml, /*!< Diagrams will be gnerated in PlantUML format */
|
||||
json /*!< Diagrams will be generated in JSON format */
|
||||
};
|
||||
|
||||
std::string to_string(const std::string &s);
|
||||
|
||||
/**
|
||||
* @brief Simple optional reference type.
|
||||
*
|
||||
* This class template provides a convenient way around the std::optional
|
||||
* limitation of not allowing references. This is useful for storing
|
||||
* references to diagram elements in various `views`, and writing methods
|
||||
* which return can return an empty value if the diagram does not contain
|
||||
* something.
|
||||
*
|
||||
* This is not an owning type - it will not accept an rvalue - the actual
|
||||
* value must be stored somewhere else as lvalue or some kind of smart pointer.
|
||||
*
|
||||
* @note Probably unsafe - do not use at home.
|
||||
*
|
||||
* @tparam T Type of reference
|
||||
*/
|
||||
template <typename T> class optional_ref {
|
||||
public:
|
||||
using optional_type = T;
|
||||
@@ -159,6 +181,13 @@ using reference_set = std::unordered_set<std::reference_wrapper<T>>;
|
||||
* @brief Wrapper around std::regex, which contains original pattern
|
||||
*/
|
||||
struct regex {
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param r Parsed regular expression
|
||||
* @param p Raw regular expression pattern used for regenerating config and
|
||||
* debugging
|
||||
*/
|
||||
regex(std::regex r, std::string p)
|
||||
: regexp{std::move(r)}
|
||||
, pattern{std::move(p)}
|
||||
@@ -170,18 +199,36 @@ struct regex {
|
||||
return std::regex_match(v, regexp);
|
||||
}
|
||||
|
||||
std::regex regexp;
|
||||
std::string pattern;
|
||||
std::regex regexp; /*!< Parsed regular expression */
|
||||
std::string pattern; /*!< Original regular expression pattern */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Convenience class for configuration options with regex support
|
||||
*
|
||||
* This template class provides a convenient way of handling configuraiton
|
||||
* options, which can be either some basic type like std::string or regex.
|
||||
*
|
||||
* @tparam T Type of alternative to regex (e.g. std::string)
|
||||
*/
|
||||
template <typename T> struct or_regex {
|
||||
or_regex() = default;
|
||||
|
||||
/**
|
||||
* @brief Constructor from alternative type
|
||||
*/
|
||||
or_regex(T v)
|
||||
: value_{std::move(v)}
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructor from regex
|
||||
*
|
||||
* @param r Parsed regular expression
|
||||
* @param p Raw regular expression pattern used for regenerating config and
|
||||
* debugging
|
||||
*/
|
||||
or_regex(std::regex r, std::string p)
|
||||
: value_{regex{std::move(r), std::move(p)}}
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,10 @@
|
||||
namespace clanguml {
|
||||
namespace config {
|
||||
|
||||
/**
|
||||
* @brief Return YAML with predefined diagram templates
|
||||
* @return YAML definition of predefined diagram templates
|
||||
*/
|
||||
const std::string &get_predefined_diagram_templates();
|
||||
|
||||
} // namespace config
|
||||
|
||||
@@ -24,9 +24,28 @@ namespace clanguml {
|
||||
namespace config {
|
||||
|
||||
template <typename T> void append_value(T &l, const T &r) { l = r; }
|
||||
/**
|
||||
* Possible option inheritance methods from top level to diagram level.
|
||||
*/
|
||||
enum class option_inherit_mode {
|
||||
kOverride, /*!< Override entire options */
|
||||
kAppend /*!< Append to list options */
|
||||
};
|
||||
|
||||
enum class option_inherit_mode { kOverride, kAppend };
|
||||
|
||||
/**
|
||||
* @brief Generic configuration option type
|
||||
*
|
||||
* This class template represents a single configuration option, which can
|
||||
* be either a simple type such as bool or std::string or can be a list
|
||||
* or dictionary.
|
||||
*
|
||||
* If the option is constructed only from default value, it's `is_declared`
|
||||
* member is false, so we can deduce whether user provided the option or not.
|
||||
*
|
||||
* For each option type, there has to be defined a YAML decoder and emitter.
|
||||
*
|
||||
* @tparam T The type of the configuration option
|
||||
*/
|
||||
template <typename T> struct option {
|
||||
option(std::string name_,
|
||||
option_inherit_mode im = option_inherit_mode::kOverride)
|
||||
@@ -44,6 +63,11 @@ template <typename T> struct option {
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the option value
|
||||
*
|
||||
* @param v Option value
|
||||
*/
|
||||
void set(const T &v)
|
||||
{
|
||||
value = v;
|
||||
@@ -51,6 +75,13 @@ template <typename T> struct option {
|
||||
has_value = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Override option value
|
||||
*
|
||||
* This method overrides the option depending on it's inheritance type.
|
||||
*
|
||||
* @param o New option value
|
||||
*/
|
||||
void override(const option<T> &o)
|
||||
{
|
||||
if (o.is_declared && inheritance_mode == option_inherit_mode::kAppend) {
|
||||
@@ -73,10 +104,22 @@ template <typename T> struct option {
|
||||
|
||||
operator bool() const { return has_value; }
|
||||
|
||||
/*! Option name, it is also the YAML key in the configuration file */
|
||||
std::string name;
|
||||
|
||||
/*! Option value */
|
||||
T value;
|
||||
|
||||
/*! Whether or not the value was provided by the user or default */
|
||||
bool is_declared{false};
|
||||
|
||||
/*!
|
||||
* Whether the option has value, if the option has no default value
|
||||
* and wasn't provided in the config this is set to `false`.
|
||||
*/
|
||||
bool has_value{false};
|
||||
|
||||
/*! The inheritance mode for this option */
|
||||
option_inherit_mode inheritance_mode;
|
||||
};
|
||||
} // namespace config
|
||||
|
||||
@@ -1809,6 +1809,10 @@ void translation_unit_visitor::process_template_specialization_argument(
|
||||
|
||||
// Otherwise just set the name for the template argument to
|
||||
// whatever clang says
|
||||
if (template_params.size() > argument_index &&
|
||||
template_params[argument_index].type())
|
||||
argument.set_type(type_name);
|
||||
else
|
||||
argument.set_name(type_name);
|
||||
}
|
||||
else
|
||||
|
||||
11
uml/class/compilation_database_context_class.yml
Normal file
11
uml/class/compilation_database_context_class.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
type: class
|
||||
include_relations_also_as_members: true
|
||||
generate_packages: false
|
||||
glob:
|
||||
- src/common/compilation_database.cc
|
||||
include:
|
||||
namespaces:
|
||||
- clanguml
|
||||
- clang::tooling
|
||||
context:
|
||||
- clanguml::common::compilation_database
|
||||
14
uml/class/config_context_class.yml
Normal file
14
uml/class/config_context_class.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
type: class
|
||||
include_relations_also_as_members: true
|
||||
glob:
|
||||
- src/config/config.cc
|
||||
include:
|
||||
namespaces:
|
||||
- clanguml::config
|
||||
context:
|
||||
- clanguml::config::config
|
||||
using_namespace:
|
||||
- clanguml::config
|
||||
plantuml:
|
||||
before:
|
||||
- 'title clanguml::config::config context diagram'
|
||||
20
uml/class/decorated_element_hierarchy_class.yml
Normal file
20
uml/class/decorated_element_hierarchy_class.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
type: class
|
||||
include_relations_also_as_members: true
|
||||
generate_packages: true
|
||||
glob:
|
||||
- src/common/model/*.cc
|
||||
- src/class_diagram/model/*.cc
|
||||
- src/sequence_diagram/model/*.cc
|
||||
- src/include_diagram/model/*.cc
|
||||
- src/package_diagram/model/*.cc
|
||||
include:
|
||||
namespaces:
|
||||
- clanguml
|
||||
subclasses:
|
||||
- clanguml::common::model::decorated_element
|
||||
relationships:
|
||||
- inheritance
|
||||
exclude:
|
||||
access: [public, protected, private]
|
||||
using_namespace:
|
||||
- clanguml
|
||||
19
uml/class/diagram_config_hierarchy_class.yml
Normal file
19
uml/class/diagram_config_hierarchy_class.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
type: class
|
||||
include_relations_also_as_members: true
|
||||
generate_packages: true
|
||||
glob:
|
||||
- src/config/config.cc
|
||||
include:
|
||||
namespaces:
|
||||
- clanguml
|
||||
subclasses:
|
||||
- clanguml::config::diagram
|
||||
parents:
|
||||
- clanguml::config::diagram
|
||||
exclude:
|
||||
access: [public, protected, private]
|
||||
using_namespace:
|
||||
- clanguml
|
||||
plantuml:
|
||||
before:
|
||||
- 'title clanguml::config::diagram class hierarchy'
|
||||
16
uml/class/diagram_filter_context_class.yml
Normal file
16
uml/class/diagram_filter_context_class.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
type: class
|
||||
include_relations_also_as_members: true
|
||||
generate_packages: true
|
||||
glob:
|
||||
- src/common/model/diagram_filter.cc
|
||||
- src/common/model/diagram.cc
|
||||
include:
|
||||
namespaces:
|
||||
- clanguml
|
||||
context:
|
||||
- clanguml::common::model::diagram_filter
|
||||
exclude:
|
||||
elements:
|
||||
- clanguml::common::model::path
|
||||
using_namespace:
|
||||
- clanguml
|
||||
21
uml/class/diagram_hierarchy_class.yml
Normal file
21
uml/class/diagram_hierarchy_class.yml
Normal file
@@ -0,0 +1,21 @@
|
||||
type: class
|
||||
include_relations_also_as_members: true
|
||||
generate_packages: true
|
||||
generate_method_arguments: none
|
||||
glob:
|
||||
- src/common/model/diagram.cc
|
||||
- src/class_diagram/model/diagram.cc
|
||||
- src/sequence_diagram/model/diagram.cc
|
||||
- src/include_diagram/model/diagram.cc
|
||||
- src/package_diagram/model/diagram.cc
|
||||
include:
|
||||
namespaces:
|
||||
- clanguml
|
||||
subclasses:
|
||||
- clanguml::common::model::diagram
|
||||
relationships:
|
||||
- inheritance
|
||||
exclude:
|
||||
access: [public, protected, private]
|
||||
using_namespace:
|
||||
- clanguml
|
||||
17
uml/class/filter_visitor_hierarchy_class.yml
Normal file
17
uml/class/filter_visitor_hierarchy_class.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
type: class
|
||||
include_relations_also_as_members: true
|
||||
generate_packages: true
|
||||
glob:
|
||||
- src/common/model/diagram_filter.cc
|
||||
include:
|
||||
namespaces:
|
||||
- clanguml
|
||||
subclasses:
|
||||
- clanguml::common::model::filter_visitor
|
||||
exclude:
|
||||
access: [public, protected, private]
|
||||
using_namespace:
|
||||
- clanguml
|
||||
plantuml:
|
||||
before:
|
||||
- left to right direction
|
||||
15
uml/class/inheritable_diagram_options_context_class.yml
Normal file
15
uml/class/inheritable_diagram_options_context_class.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
type: class
|
||||
include_relations_also_as_members: true
|
||||
glob:
|
||||
- src/config/config.cc
|
||||
include:
|
||||
namespaces:
|
||||
- clanguml::config
|
||||
context:
|
||||
- clanguml::config::inheritable_diagram_options
|
||||
using_namespace:
|
||||
- clanguml::config
|
||||
plantuml:
|
||||
before:
|
||||
- title clanguml::config::config context diagram
|
||||
- left to right direction
|
||||
13
uml/class/nested_trait_hierarchy_class.yml
Normal file
13
uml/class/nested_trait_hierarchy_class.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
type: class
|
||||
include_relations_also_as_members: true
|
||||
glob:
|
||||
- src/common/model/*.cc
|
||||
include:
|
||||
namespaces:
|
||||
- clanguml
|
||||
subclasses:
|
||||
- r: ".*nested_trait.*"
|
||||
exclude:
|
||||
access: [private, protected, public]
|
||||
using_namespace:
|
||||
- clanguml
|
||||
13
uml/class/package_hierarchy_class.yml
Normal file
13
uml/class/package_hierarchy_class.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
type: class
|
||||
include_relations_also_as_members: true
|
||||
glob:
|
||||
- src/common/model/package.cc
|
||||
include:
|
||||
namespaces:
|
||||
- clanguml
|
||||
parents:
|
||||
- clanguml::common::model::package
|
||||
exclude:
|
||||
access: [private, protected, public]
|
||||
using_namespace:
|
||||
- clanguml
|
||||
20
uml/sequence/cli_handle_options_sequence.yml
Normal file
20
uml/sequence/cli_handle_options_sequence.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
type: sequence
|
||||
combine_free_functions_into_file_participants: true
|
||||
generate_method_arguments: none
|
||||
glob:
|
||||
- src/cli/cli_handler.cc
|
||||
- src/config/config.cc
|
||||
- src/config/yaml_decoders.cc
|
||||
include:
|
||||
namespaces:
|
||||
- clanguml
|
||||
- YAML
|
||||
exclude:
|
||||
elements:
|
||||
- r: "clanguml::config::option.*"
|
||||
paths:
|
||||
- src/util/util.h
|
||||
using_namespace:
|
||||
- clanguml
|
||||
start_from:
|
||||
- function: "clanguml::cli::cli_handler::handle_options(int,const char **)"
|
||||
19
uml/sequence/diagram_generate_generic_sequence.yml
Normal file
19
uml/sequence/diagram_generate_generic_sequence.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
type: sequence
|
||||
combine_free_functions_into_file_participants: true
|
||||
generate_method_arguments: none
|
||||
glob:
|
||||
- src/common/generators/generators.cc
|
||||
using_namespace:
|
||||
- clanguml
|
||||
include:
|
||||
namespaces:
|
||||
- clang
|
||||
- clanguml::common::generators
|
||||
exclude:
|
||||
namespaces:
|
||||
- clanguml::model::tvl
|
||||
- clanguml::decorators
|
||||
paths:
|
||||
- src/common/model/source_location.h
|
||||
start_from:
|
||||
- function: "clanguml::common::generators::generate_diagram(const std::string &,const std::string &,std::shared_ptr<clanguml::config::diagram>,const common::compilation_database &,const std::vector<std::string> &,const std::vector<clanguml::common::generator_type_t> &,bool,std::function<void ()> &&)"
|
||||
19
uml/sequence/load_config_sequence.yml
Normal file
19
uml/sequence/load_config_sequence.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
type: sequence
|
||||
combine_free_functions_into_file_participants: true
|
||||
generate_method_arguments: none
|
||||
glob:
|
||||
- src/config/config.cc
|
||||
- src/config/yaml_decoders.cc
|
||||
include:
|
||||
namespaces:
|
||||
- clanguml
|
||||
- YAML
|
||||
exclude:
|
||||
elements:
|
||||
- r: "clanguml::config::option.*"
|
||||
paths:
|
||||
- src/util/util.h
|
||||
using_namespace:
|
||||
- clanguml
|
||||
start_from:
|
||||
- function: "clanguml::config::load(const std::string &,std::optional<bool>,std::optional<bool>)"
|
||||
Reference in New Issue
Block a user