clang-uml
es un generador automático de diagramas de inclusión, secuencias, paquetes y clases de C++ a UML, impulsado por archivos de configuración YAML. La idea principal detrás del proyecto es mantener fácilmente diagramas actualizados dentro de una base de código o código heredado de documento. El archivo o archivos de configuración para clang-uml
definen los tipos y contenidos de cada diagrama generado. Los diagramas se pueden generar en formatos PlantUML, MermaidJS y JSON.
clang-uml
actualmente admite C++ hasta la versión 20, así como C y Objective-C.
La documentación completa se puede encontrar en clang-uml.github.io.
Para ver qué puede hacer clang-uml
, consulte los diagramas generados para casos de prueba unitaria aquí o los ejemplos en el repositorio clang-uml-examples.
Las principales características admitidas hasta ahora incluyen:
Puede encontrar documentación más completa en clang-uml.github.io.
Las instrucciones de instalación para Linux
, macos
y Windows
se pueden encontrar aquí.
clang-uml
requiere un archivo compile_commands.json actualizado, que contenga la lista de comandos utilizados para compilar el código fuente.
Consulte aquí para obtener instrucciones sobre cómo generar compile_commands.json
utilizando algunos de los sistemas de compilación C++ existentes.
De forma predeterminada, clang-uml
asumirá que el archivo de configuración .clang-uml
y los archivos de la base de datos de compilación compile_commands.json
están en el directorio actual, por lo que si están en el directorio de nivel superior de un proyecto, simplemente ejecute:
clang-uml
La ruta de salida de los diagramas, así como la ubicación alternativa de la base de datos de compilación, se pueden especificar en el archivo de configuración .clang-uml
o mediante parámetros de línea de comando.
Para otras opciones ver ayuda:
clang-uml --help
Los archivos de configuración están escritos en YAML y proporcionan una definición de diagramas que deben generarse mediante clang-uml
. El ejemplo básico es el siguiente:
compilation_database_dir : .
output_directory : diagrams
diagrams :
myproject_class :
type : class
glob :
- src/*.cc
using_namespace : myproject
include :
namespaces :
- myproject
exclude :
namespaces :
- myproject::detail
plantuml :
after :
- ' note left of {{ alias("MyProjectMain") }}: Main class of myproject library. '
Consulte aquí para obtener una guía de referencia detallada del archivo de configuración.
Para ver qué puede hacer clang-uml
, consulte la documentación de casos de prueba aquí.
Para ver diagramas del propio clang-uml
, según su propia configuración, ejecute lo siguiente:
make clanguml_diagrams
y abra los diagramas SVG en la carpeta docs/diagrams
.
El siguiente código C++:
template < typename T, typename P> struct A {
T t;
P p;
};
struct B {
std::string value;
};
template < typename T> using AString = A<T, std::string>;
template < typename T> using AStringPtr = A<T, std::unique_ptr<std::string>>;
template < typename T>
using PairPairBA = std::pair<std::pair<B, A< long , T>>, long >;
template < class T > using VectorPtr = std::unique_ptr<std::vector<T>>;
template < class T > using APtr = std::unique_ptr<A< double , T>>;
template < class T > using ASharedPtr = std::shared_ptr<A< double , T>>;
template < class T , class U >
using AAPtr = std::unique_ptr<std::pair<A< double , T>, A< long , U>>>;
template < typename T> using SimpleCallback = std::function< void (T, int )>;
template < typename ... T> using GenericCallback = std::function< void (T..., int )>;
using VoidCallback = GenericCallback< void *>;
using BVector = std::vector<B>;
using BVector2 = BVector;
using AIntString = AString< int >;
using ACharString = AString< char >;
using AStringString = AString<std::string>;
using BStringString = AStringString;
template < typename T> class R {
using AWCharString = AString< wchar_t >;
PairPairBA< bool > bapair;
APtr< bool > abool;
AAPtr< bool , float > aboolfloat;
ASharedPtr< float > afloat;
A< bool , std::string> boolstring;
AStringPtr< float > floatstring;
AIntString intstring;
AStringString stringstring;
BStringString bstringstring;
AAPtr<T, float > atfloat;
protected:
BVector bs;
public:
BVector2 bs2;
SimpleCallback<ACharString> cb;
GenericCallback<AWCharString> gcb;
VoidCallback vcb;
VectorPtr<B> vps;
};
da como resultado el siguiente diagrama (a través de PlantUML):
Abra la imagen sin formato aquí y consulte la información sobre herramientas y los hipervínculos a clases y métodos.
El siguiente código C++:
# include < atomic >
# include < functional >
# include < iostream >
# include < memory >
# include < string >
namespace clanguml {
namespace t20029 {
std::string encode_b64 (std::string &&content) { return std::move (content); }
template < typename T> class Encoder : public T {
public:
bool send (std::string &&msg)
{
return T::send ( std::move (
// Encode the message using Base64 encoding and pass it to the next
// layer
encode ( std::move (msg))));
}
protected:
std::string encode (std::string &&msg) { return encode_b64 ( std::move (msg)); }
};
template < typename T> class Retrier : public T {
public:
bool send (std::string &&msg)
{
std::string buffer{ std::move (msg)};
int retryCount = 5 ;
// Repeat until send() succeeds or retry count is exceeded
while (retryCount--) {
if ( T::send (buffer))
return true ;
}
return false ;
}
};
class ConnectionPool {
public:
void connect ()
{
if (!is_connected_. load ())
connect_impl ();
}
bool send ( const std::string &msg) { return true ; }
private:
void connect_impl () { is_connected_ = true ; }
std::atomic< bool > is_connected_;
};
int tmain ()
{
auto pool = std::make_shared<Encoder<Retrier<ConnectionPool>>>();
// Establish connection to the remote server synchronously
pool-> connect ();
// Repeat for each line in the input stream
for (std::string line; std::getline (std::cin, line);) {
if (!pool-> send ( std::move (line)))
break ;
}
return 0 ;
}
}
}
da como resultado el siguiente diagrama (a través de PlantUML):
El siguiente código C++:
namespace clanguml {
namespace t30003 {
namespace ns1 {
namespace ns2_v1_0_0 {
class A {
};
}
namespace [ [deprecated]] ns2_v0_9_0 {
class A {
};
}
namespace {
class Anon final {
};
}
}
namespace [ [deprecated]] ns3 {
namespace ns1 ::ns2 {
class Anon : public t30003 ::ns1::ns2_v1_0_0::A {
};
}
class B : public ns1 ::ns2::Anon {
};
}
}
}
da como resultado el siguiente diagrama (a través de PlantUML):
En caso de que esté buscando una herramienta más sencilla para visualizar y analizar gráficos de inclusión, consulte mi otra herramienta: clang-include-graph.
La siguiente estructura de código C++:
tests/t40001
├── include
│ ├── lib1
│ │ └── lib1.h
│ └── t40001_include1.h
└── src
└── t40001.cc
da como resultado el siguiente diagrama (a través de PlantUML) basado en directivas de inclusión en el código:
UML | PlantaUML | sirenajs |
---|---|---|
Herencia | ||
Asociación | ||
Dependencia | ||
Agregación | ||
Composición | ||
Especialización/instanciación de plantillas | ||
Anidamiento (clase interna/enum) | ||
Incluir (local) | ||
Incluir (sistema) |
Para bases de código típicas, un único diagrama generado a partir de un código completo o incluso un único espacio de nombres puede ser demasiado grande para ser útil, por ejemplo, como parte de la documentación. clang-uml
permite especificar el contenido que se incluirá y excluirá de cada diagrama mediante una configuración YAML simple:
include :
# Include only elements from these namespaces
namespaces :
- clanguml::common
- clanguml::config
# Include all subclasses of ClassA (including ClassA)
subclasses :
- clanguml::common::ClassA
# and specializations of template Class<T> (including Class<T>)
specializations :
- clanguml::common::ClassT<T>
# and all classes depending on Class D
dependants :
- clanguml::common::ClassD
# and all dependencies of ClassE
dependencies :
- clanguml::common::ClassE
# and classes in direct relation to ClassB (including ClassB)
context :
- clanguml::common::ClassB
# Include only inheritance relationships
relationships :
- inheritance
exclude :
# Exclude all elements from detail namespace
namespaces :
- clanguml::common::detail
# and also exclude ClassF
elements :
- clanguml::common::ClassF
Se pueden encontrar más detalles sobre esto en la sección de documentación de filtros de diagrama.
Los casos de prueba integrados utilizados para las pruebas unitarias de clang-uml
se pueden explorar aquí.
Este proyecto se basa en las siguientes excelentes herramientas:
Si desea contribuir al proyecto, consulte las pautas de contribución.
Copyright 2021-present Bartek Kryza <[email protected]>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.