clang-uml
是一個自動 C++ 到 UML 類別、序列、套件和包含圖產生器,由 YAML 設定檔驅動。這個專案背後的主要想法是在程式碼庫或文件遺留程式碼中輕鬆維護最新的圖表。 clang-uml
的一個或多個設定檔定義了每個產生的圖表的類型和內容。圖表可以以 PlantUML、MermaidJS 和 JSON 格式產生。
clang-uml
目前支援 C++ 最高版本 20,以及 C 和 Objective-C。
完整文件可以在 clang-uml.github.io 找到。
要了解clang-uml
可以做什麼,請查看此處為單元測試用例產生的圖表或 clang-uml-examples 儲存庫中的範例。
目前支援的主要功能包括:
更全面的文件可以在 clang-uml.github.io 上找到。
可以在此處找到Linux
、 macos
和Windows
的安裝說明。
clang-uml
需要最新的compile_commands.json 文件,其中包含用於編譯原始碼的命令清單。
有關如何使用某些現有 C++ 建置系統產生compile_commands.json
的說明,請參閱此處。
預設情況下, clang-uml
會假設設定檔.clang-uml
和編譯資料庫compile_commands.json
檔案位於目前目錄中,因此如果它們位於專案的頂級目錄中,只需執行:
clang-uml
圖表的輸出路徑以及編譯資料庫的替代位置可以在.clang-uml
設定檔中或透過命令列參數指定。
其他選項,請參閱說明:
clang-uml --help
設定檔是用 YAML 編寫的,並提供應由clang-uml
產生的圖表的定義。基本範例如下:
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. '
請參閱此處以了解詳細的設定檔參考指南。
若要了解clang-uml
功能,請瀏覽此處的測試案例文件。
為了查看clang-uml
本身的圖表,請根據其自己的配置執行以下命令:
make clanguml_diagrams
並開啟docs/diagrams
資料夾中的 SVG 圖表。
以下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;
};
結果如下圖所示(透過 PlantUML):
在此處打開原始圖像,然後查看懸停工具提示以及類別和方法的超連結。
以下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 ;
}
}
}
結果如下圖所示(透過 PlantUML):
以下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 {
};
}
}
}
結果如下圖所示(透過 PlantUML):
如果您正在尋找一個更簡單的工具來視覺化和分析包含圖,請查看我的其他工具 - clang-include-graph
C++程式碼結構如下:
tests/t40001
├── include
│ ├── lib1
│ │ └── lib1.h
│ └── t40001_include1.h
└── src
└── t40001.cc
基於程式碼中的 include 指令,結果如下圖(透過 PlantUML):
統一建模語言 | 植物UML | 美人魚JS |
---|---|---|
遺產 | ||
協會 | ||
依賴性 | ||
聚合 | ||
作品 | ||
模板專業化/實例化 | ||
嵌套(內部類別/枚舉) | ||
包括(本地) | ||
包括(系統) |
對於典型的程式碼庫,從整個程式碼甚至單一命名空間產生的單一圖表可能太大而無法使用,例如作為文件的一部分。 clang-uml
允許使用簡單的 YAML 設定指定要包含在每個圖表中和從每個圖表中排除的內容:
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
有關此內容的更多詳細信息,請參閱圖表過濾器文件部分。
用於clang-uml
單元測試的內建測試案例可以在此處瀏覽。
該專案依賴以下強大的工具:
如果您想為該專案做出貢獻,請查看貢獻指南。
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.