From da6001728b876b5cf66a1eed5ea1fc4ab10d24e7 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 10 Dec 2023 21:10:51 +0100 Subject: [PATCH] Improved docs (#208) --- CHANGELOG.md | 8 +++- README.md | 6 +-- docs/architecture.md | 8 +--- docs/class_diagrams.md | 50 ++++++++++++-------- docs/common_options.md | 26 +++++------ docs/diagram_filters.md | 72 ++++++++++++++++------------- docs/generator_types.md | 2 +- docs/img/mermaid_aggregation.png | Bin 1128 -> 7127 bytes docs/img/mermaid_association.png | Bin 772 -> 6135 bytes docs/img/mermaid_composition.png | Bin 867 -> 6461 bytes docs/img/mermaid_dependency.png | Bin 1047 -> 7084 bytes docs/img/mermaid_inheritance.png | Bin 1098 -> 7003 bytes docs/img/mermaid_instantiation.png | Bin 1338 -> 7713 bytes docs/img/mermaid_nested.png | Bin 976 -> 6765 bytes docs/include_diagrams.md | 42 ++++++++--------- docs/installation.md | 11 +++-- docs/interactive_svg_diagrams.md | 10 ++-- docs/package_diagrams.md | 7 +-- docs/quick_start.md | 8 ++-- docs/sequence_diagrams.md | 41 ++++++++-------- docs/troubleshooting.md | 32 +++++++------ 21 files changed, 173 insertions(+), 150 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bcc9d88..fc27819d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # CHANGELOG - - * Added radius parameter to context filter (#201) + + * Fixed random typos and omissions in docs (#208) + * Fixed handling of diagram hyperlinks with sources outside of project dir (#213) + * Fixed test case t00014 on macos (#176) + * Added automatic generation of diagram images using PlantUML and MermaidJS (#204) + * Added radius parameter to context filter (#201) ### 0.4.1 * Enabled manual call expression injection through comments (#196) diff --git a/README.md b/README.md index 40d85354..a0aa5e89 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ test cases [here](./docs/test_cases.md) or examples in Main features supported so far include: * **Class diagram generation** - * Class properties and methods including access - [_example_](docs/test_cases/t00003.md) + * Class properties and methods including access scope - [_example_](docs/test_cases/t00003.md) * Class inheritance - [_example_](docs/test_cases/t00002.md) * Other class relationships including associations, aggregations, dependencies and friendship - [_example_](docs/test_cases/t00006.md) * Template instantiation relationships - [_example_](docs/test_cases/t00014.md) @@ -38,8 +38,8 @@ Main features supported so far include: * Diagram content filtering based on namespaces, elements and relationships - [_example_](docs/test_cases/t00040.md) * Optional package generation from namespaces (only PlantUML) - [_example_](docs/test_cases/t00036.md) * Optional package generation from subdirectories (only PlantUML) - [_example_](docs/test_cases/t00065.md) - * Interactive links to online code to classes, methods and class fields in SVG diagrams - [_example_](https://raw.githubusercontent.com/bkryza/clang-uml/master/docs/test_cases/t00002_class.svg) - * Support for plain C99/C11 code (struct and units relationships) - [_example_](docs/test_cases/t00057.md) + * Interactive links to online code or docs for classes, methods and class fields in SVG diagrams - [_example_](https://raw.githubusercontent.com/bkryza/clang-uml/master/docs/test_cases/t00002_class.svg) + * Support for plain C99/C11 code (struct, units and their relationships) - [_example_](docs/test_cases/t00057.md) * C++20 concept constraints - [_example_](docs/test_cases/t00059.md) * **Sequence diagram generation** * Generation of sequence diagram from specific method or function - [_example_](docs/test_cases/t20001.md) diff --git a/docs/architecture.md b/docs/architecture.md index 2367eb42..9f519101 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -27,7 +27,7 @@ This section presents general architecture and components of `clang-uml`. uses [Clang LibTooling API](https://releases.llvm.org/16.0.0/tools/clang/docs/LibTooling.html) to traverse the AST (Abstract Syntax Tree) of the source code and extract any information -relevant for a specified diagram. +relevant for a specific diagram. The code is divided into several packages (namespaces), the main of them are: @@ -131,11 +131,7 @@ generator. ## Diagram generators Diagram generators convert the `clang-uml`'s internal UML model into actual -diagram in one of the supported formats: - -- PlantUML -- MermaidJS -- JSON +diagram in one of the supported formats: PlantUML, MermaidJS and JSON. Each diagram generator extends a common interface appropriate for the selected output format, i.e.: diff --git a/docs/class_diagrams.md b/docs/class_diagrams.md index 26240c4f..a652f2dd 100644 --- a/docs/class_diagrams.md +++ b/docs/class_diagrams.md @@ -7,7 +7,7 @@ * [Relationships](#relationships) * [Relationships to classes in containers or smart pointers](#relationships-to-classes-in-containers-or-smart-pointers) * [Inheritance diagrams](#inheritance-diagrams) -* [Including packages in the diagram](#including-packages-in-the-diagram) +* [Generating UML packages in the diagram](#generating-uml-packages-in-the-diagram) * [Class context diagram](#class-context-diagram) * [Disabling dependency relationships](#disabling-dependency-relationships) @@ -72,18 +72,18 @@ To render only classes without any properties an exclusion filter can be added: ## Relationships -The following table presents the PlantUML arrows representing each relationship -in the class diagrams. +The following table presents the PlantUML and MermaidJS arrows representing each +type of relationship generated in the class diagrams. -| UML | PlantUML | -| ---- | --- | -| Inheritance | ![extension](img/puml_inheritance.png) | -| Association | ![association](img/puml_association.png) | -| Dependency | ![dependency](img/puml_dependency.png) | -| Aggregation | ![aggregation](img/puml_aggregation.png) | -| Composition | ![composition](img/puml_composition.png) | -| Template specialization/instantiation | ![specialization](img/puml_instantiation.png) | -| Nesting (inner class/enum) | ![nesting](img/puml_nested.png) | +| UML | PlantUML | MermaidJS | +| ---- | --- |--------------------------------------------| +| Inheritance | ![extension](img/puml_inheritance.png) | ![extension](img/mermaid_inheritance.png) | +| Association | ![association](img/puml_association.png) | ![extension](img/mermaid_association.png) | +| Dependency | ![dependency](img/puml_dependency.png) | ![extension](img/mermaid_dependency.png) | +| Aggregation | ![aggregation](img/puml_aggregation.png) | ![extension](img/mermaid_aggregation.png) | +| Composition | ![composition](img/puml_composition.png) | ![extension](img/mermaid_composition.png) | +| Template specialization/instantiation | ![specialization](img/puml_instantiation.png) | ![extension](img/mermaid_instantiation.png) | +| Nesting (inner class/enum) | ![nesting](img/puml_nested.png) | ![extension](img/mermaid_nested.png) | By default, a member from which a relationship has been added to the diagram @@ -131,7 +131,7 @@ rendered. This can be easily achieved in `clang-uml` through inclusion filters: - inheritance ``` -## Including packages in the diagram +## Generating UML packages in the diagram By default, `clang-uml` will render all element names including a namespace (relative to `using_namespace` property), e.g. `ns1::ns2::MyClass`. In order to generate packages in the diagram for each namespace instead, the @@ -145,9 +145,10 @@ which results in the following diagram: ![t00036_class](test_cases/t00036_class.svg) -In case the code base is structured based on subdirectory instead of namespaces, -packages can be generated based on the location of a given declaration in the -filesystem tree, by adding also the following option: +In case the code base is structured based on subdirectory instead of namespaces +(or this is a C project, where namespaces are not available), packages can be +generated based on the location of a given declaration in the filesystem tree, +by adding also the following option: ```yaml package_type: directory @@ -173,6 +174,19 @@ this can be easily achieved using `context` inclusion filter: - ns1::MyClass ``` +By default, the diagram will include only elements in direct relationship to +`ns1::MyClass`, but an addition option called `radius` can be added to this +filter, which will extend the context to elements related to `ns1::MyClass` +through at most N relationships, e.g: + +```yaml + include: + context: + - match: + radius: 3 + pattern: ns1::MyClass +``` + ## Disabling dependency relationships Dependency relationships are inferred whenever a class uses another class, thus often dependency relationship will be rendered in addition to other @@ -185,8 +199,8 @@ skip_redundant_dependencies: false ``` In many cases, dependency relationships between classes can clutter the diagram -too much. In such cases it might be useful to disable dependency relationships -completely for this diagram completely using the following exclusion filter: +too much. In such cases, it might be useful to disable dependency relationships +completely for this diagram using the following exclusion filter: ```yaml exclude: relationships: diff --git a/docs/common_options.md b/docs/common_options.md index f1483374..38513e05 100644 --- a/docs/common_options.md +++ b/docs/common_options.md @@ -15,8 +15,8 @@ ## Overall configuration file structure -By default, `clang-uml` will look for file `.clang-uml` in the projects directory and read all diagrams definitions -from it. The file must be specified in YAML and it's overall structure is as follows: +By default, `clang-uml` will look for file `.clang-uml` in the project's directory and read all diagrams definitions +configuration from it. The file must be specified in YAML and it's overall structure is as follows: ```yaml # common options for all diagrams @@ -68,16 +68,16 @@ The syntax is simple and based on glob patterns, which can be added to the confi ``` The glob patterns only need to match the translation units, which are also in the `compile_commands.json` file, i.e. -any files that match the glob patterns but are not in `compile_commands.json` will be ignored. In case the `glob` +any files that match the glob patterns, but are not in `compile_commands.json` will be ignored. In case the `glob` pattern set does not match any translation units an error will be printed on the standard output. For small projects, the `glob` property can be omitted, which will result in `clang-uml` parsing all translation units -from `compile_commands.json` for the diagram. However for large projects, constraining the number of translation units +from `compile_commands.json` for the diagram. However, for large projects, constraining the number of translation units for each diagram to absolute minimum will significantly decrease the diagram generation times. ## Custom directives In case it's necessary to add some custom PlantUML or MermaidJS declarations -before or after the generated diagram content, it can be achieved simply using +before or after the generated diagram content, it can be achieved using the `plantuml` or `mermaid` configuration properties, for instance for PlantUML: ```yaml @@ -98,11 +98,12 @@ or for MermaidJS: - note for {{ alias("ns1::ns2::MyClass") }} "This is my class." ``` -These directive are useful for instance for adding notes to elements in the -diagrams or customizing diagram layout or style. +These directives are useful for instance for adding notes to elements in the +diagrams or customizing diagram layout and style. -Please note that when referring to diagram elements in the PlantUML directives, -they must be added using Jinja templates `alias` command as in the example above. +Please note that when referring to diagram elements in PlantUML or MermaidJS +directives, they must be added using Jinja templates `alias` command as in the +example above. More options can be found in the official docs for each respective generator: * [PlantUML](https://plantuml.com/) @@ -118,8 +119,7 @@ debug_mode: true ``` the generated PlantUML diagram will contain comments before each line containing -the source location of the -specific diagram element. +the source location of the specific diagram element. ## Resolving include path and compiler flags issues Due to the fact, that your project can be compiled with different compilers @@ -175,8 +175,8 @@ command: ``` If you want to include the system headers reported by the compiler specified -already as `argv[0]` in your `compile_commands.json`, you can simply invoke -`clang-uml` as: +already as first argument of each compile command in your +`compile_commands.json`, you can simply invoke `clang-uml` as: ```bash clang-uml --query-driver . diff --git a/docs/diagram_filters.md b/docs/diagram_filters.md index 01c94f5a..3bfd9f38 100644 --- a/docs/diagram_filters.md +++ b/docs/diagram_filters.md @@ -41,10 +41,10 @@ Some filters accept either specified exact values, some support regular expressions while some except glob patterns. For filters which accept regular expressions, the regular expression has to -be provided as a map `r: 'pattern'` due to the fact the pointer (`*`) otherwise -would have to be escaped in situations such as `mycontainer`, so for +be provided as a map ```r: 'pattern'``` due to the fact the pointer (```*```) otherwise +would have to be escaped in situations such as ```mycontainer```, so for instance to specify that the diagram should exclude all classes containing the -word `test` simply add the following filter: +word ```test``` simply add the following filter: ```yaml exclude: @@ -73,12 +73,21 @@ The following table specifies the values allowed in each filter: | `dependencies` | Qualified name or regex | ```ns1::ns2::ClassA```, ```r: 'ns1::ns2::ClassA.+'``` | | `callee_types` | Callee types in sequence diagrams| ```constructor```, ```assignment```, ```operator```, ```defaulted```, ```static```, ```method```, ```function```, ```function_template```, ```lambda``` | -The following filters are available. +The following filters are available: ## namespaces Allows to include or exclude entities from specific namespaces. +```yaml + include: + namespaces: + - ns1::ns2 + exclude: + namespaces: + - ns1::ns2::detail +``` + ## elements Allows to directly include or exclude specific entities from the diagrams, for instance to exclude a specific class @@ -113,10 +122,11 @@ in specific files. diagrams: t00061_class: type: class - relative_to: ../../tests/t00061 - glob: [t00061.cc] + glob: + - t00061.cc include: - paths: [include/t00061_a.h] + paths: + - include/t00061_a.h using_namespace: - clanguml::t00061 ``` @@ -166,14 +176,14 @@ include inheritance and template specialization/instantiation relationships add ``` The following relationships can be used in this filter: - * inheritance - * composition - * aggregation - * ownership - * association - * instantiation - * friendship - * dependency + * `inheritance` + * `composition` + * `aggregation` + * `ownership` + * `association` + * `instantiation` + * `friendship` + * `dependency` ## subclasses @@ -198,13 +208,13 @@ This filter allows to include or exclude class methods and members based on thei ## method_types This filter allows to include or exclude various method types from the class diagram, allowed values ar: - * constructor - * destructor - * assignment - * operator - * defaulted - * deleted - * static + * `constructor` + * `destructor` + * `assignment` + * `operator` + * `defaulted` + * `deleted` + * `static` This filter is independent of the `access` filter, which controls which methods are included based on access scope (e.g. `public`). @@ -217,15 +227,15 @@ a `callee` is the receiver of a message, and this filter specifies which types of receivers should match. The following callee types are supported: - * constructor - * assignment - * operator - * defaulted - * static - * method - * function - * function_template - * lambda + * `constructor` + * `assignment` + * `operator` + * `defaulted` + * `static` + * `method` + * `function` + * `function_template` + * `lambda` ## dependants and dependencies diff --git a/docs/generator_types.md b/docs/generator_types.md index c364fbd5..214e7554 100644 --- a/docs/generator_types.md +++ b/docs/generator_types.md @@ -12,7 +12,7 @@ Currently, there are 3 types of diagram generators: `plantuml`, `mermaid` and `json`. To specify, which generators should be used on the command line use option `-g`. -For instance to generate both types of diagrams run `clang-uml` as follows: +For instance to generate all types of diagrams run `clang-uml` as follows: ```bash clang-uml -g plantuml -g mermaid -g json diff --git a/docs/img/mermaid_aggregation.png b/docs/img/mermaid_aggregation.png index 10a052b7102374c3d7a03876ddadb0b96cdaa83f..04d9b0fb7b90d9966f14ea60ae24213da0a8c3b5 100644 GIT binary patch literal 7127 zcmeHLc{r5o`=5?Bgmj!1DbrX=HD+OknT#bvwy_L_gvQKZFf)v?lOjqfS&EXVD0^gA zi0qOjvM)_U7<(ne_oYs!bN#;moa_31|2uPC@Af>O`}5rQ=f2-(p63lQ)ITA>C&~u` zfdsU*@I>HB0FFIdd4RKetuYw{;@JCM zWQkz}FRsps_-qUq6BQlb2q|Co>THGqd zQLsopt>kU(kuSY(1}iypsQvLf=HAcE)GvLC^L@TQv8+_<4DtHn@|&^om4fkE?aav#JgG!s?mD|EfUbohar{L0{l?Gj3 z27C(oYVMd<)!sDe=y=e7YeDgSX`P62-lpSe*)tZqAK?1q3J^^XMBLA~%v!ZdU8uQv z)FSu{ChUEL#$`<04bg)#8Hr(6A3;Cm$}8V^4^=>Mi`C>ldcU}bDye~l(R|LlL&PHH zb}|SRXRQRS&s}<=?EIu4;PS}RQ3+GuM?-be+fKYzDH6aBl}4Q2&wI|t{~RWhFQ6)C z0@|uQ;VX!^y4<*N5p=pJ+u8SXLhd)w^CAeh1G|m3gHSDylQz03Avd&m64XYuUGIRw zNr{9TGHIu>vWJZ4v?6OVQY2-!WUAYOjdC4$Vl#QNSh8&f4VnVi9!NzK9cWcLu!jzf zd2OdH+=yZX3&D)s?$bGMd*FFaRjDYsaWqzpk9Nz-XZ)>?cpzqrgwVbHz3^&1W4n7& zudqG2T_a{uP4#K%#obTaJ349O!7A>3^qxr{F-%lz-Q&C7-Pv!N3ZuH)o#&th{qEe) z$NG(Y$`|{V_>=4S^X66SnNCy5E_rzc2P!`%D%yf>9pAZ~DY#)%oLG*1gez-EET{9n z3N!?Km7HHC%v0_wdGiRfGiV;)7QS?%FzA-b;H?#rqQPcA;i4&*C1Ho2uZ$|YW8S;G zi4R--dgUT!0#B8Q*9?9^+vLUAc`ot#Zb?{!i-SecK7!mN*e#H-S;TTn^(g9Qm&~4_ z^8uj;2U?~${rP;n5Baz8fZ)`|7^d-uit`&a4dP;zf}k~S53grZjTGjz2CCxiK+XFH zjUUoY{2gw0z4{2H&MHc!8z;*|@JV71z06E|b?S_E^`4yL1=9i#&TiiNFgj?EmtlYM z_WRewCnw5Px9#`p{vhl1S))Y?X3>?Q`?$+pC9WzC&*%BGiMbhn&450=Q z^Jch+ci1 zw)chw`uy}n@7}{9n)SFB#}RVwN<95p>hGU=^XnK4dx8U9+2WiSjVF0sltbACn86K} zyFQGTn3d8{S0(f0gOzh6D|@C-Ty*AB*<*R|qPni`%;HqR-B;ppt2jSL=;q(3=R4Bp zX*{2A=eFZ*eFjM&C)U!VlUn0uZ9D9tSI(yUIgFW&wjDmaH#+v1we#bd61Tn#*NzL~o!7yyW?w$404bC)8P_Q7&iXoxZ?U{a~q`6c@g9Cq&9k^c8sX6(7O3 z{9!GdO`@na0ka%4*Q;1N``vr16LjtUI$P3Jd)%^Hk~u*d8Bd7e=gkp9LRYxKqoJte zC?Y!ZA-{F@E=0Hgk{Dsr{=99C(L<~Rw}+T)1#LH`gS6ezo#>#~N5^d+UrgE4Sh(|P zbi%d#xeGUh{*V(cHNUmLPWx2*=#I;YhMqky3u*Dg`z#FVdr*#%U4u%6r%M8D2RbJ9 z=ZcmF)al2|@cTswf;t@i+8Y<&ZNi*7Q6FQdMWU%}m6SI}^pZkNmF4(A6 zzpNM|&bti+`2BI&5-l$klYNDF<}{wdP&jBf!u51-Q>zIY_PB(XJ`*g2Z`>Ze*^-9d z?T4Hv8wjQ-B!4Z&W%?Y}bQwr#=o5Ch?!{(gxE67{4?YT+CWOs9nS3bp)D_iCw;vu> zI@p~3lVcu58NOQHVTA}*%ny(!4|l#Ooav8YS6TM!SW;{;lbxMT`+Rx3 zC<(nclOj+;$&dx!23*(D*G#z@W&X^7G(C0WA#RV*(radre|Z+QPHxL;ylxk18i^9LzeW*w_No|H_J=LffTOgAeY;W(Q{ zjW13t>VK}bfHl@#zi^z^OV!=M1CMl)axZtPRUS}xdkQ|xNj`b#c#z?d z+_AH)kK*zONg3Je0gmP6@l~mTS93B2GXua2Je)C3;wVJwT(rpPN>67Gp(($qhCYw; z&B@5dF;O1*KD1m)Vobx6%lA$3+cm{AjBcA(r%NWiJ61X=Jh)^TVE47-8|HySxs9r- zHqkN9zRA89x|gPBRz-X(c%sF*XecO;_Wx290wk4DTT)a~> zlS5@>rOU}TGS;8yTE`bo!hH-nW5Ej4Q^4z}??V%B*Lt?l;{g85Rj!V@eHRviz1 z9jUyc)&UFGJz%;iRBW#E{N}Dtfve?H{imx!TwpR08;h;QM##Ija(`M$7on&I@1U79S}!`}1Ek zEh)`=?Xn1>q?mr(J2<#~w~W!}J5A4guuGqrgfxE@;R)9HbPpv7U{x$i16IFg1U)R7 zNtY#2m^M^dPr5U(ItGE1R6LzYWJf9+Y(ur9F>sKnXJrsDje>)iq6lz;vpUtDrsd6| z8hh)Tki8wr7z#v1nNP_R3lPw$Y!cX$?!<7#dg37Kyjb9Vtr-RZuS3|5IEWd+5UkE* zQNi-E^0IKKh9}J(2~p+)E3qiHSR!8Y2L3-8pU@GJk^!VqB*l^Oa^$3lVrnmW8)wYpdb9Fe{^R8;U_)A z^@j?89xzXmGYlaMhtcV_koYupkkYQ9ODjk5j0;3}SHslFyg5gh#H3{r!bmw&|K=zg0vaCxWUTK-yYF3OdlJKr3cTMx3hK{x+J8wF84ah%0Z~Hb z;ffd_-xztQB3zyX#n{?X(PTxm0$Gl_9>!00SEeo7gT$h$*#VIP(EtUs9u4@=x|A}1 zM|;>)*K~p-<)8>86ahCuC}I)vSS0!g9DxOr2m28)Z0)W7Gh!v!|ItKg9q`LE0N8zR z1Ev>Xwu1efu6}5?CgcC`_ahho!w~@Le+T(T`u;1|zjFN}1^yBE-|G5Tu79M!KLY<- zUH@-#@%^>op)!C~kO#1xseaRJ4eVM!8S0s6M7s2JHO{WCuJ-o!)YQ~0E-o%DEfp0N z85$ZYDJfmLbZK~acye+wJUm=gRh7;5iHwZX($Y0GJyl#>{PpYCw{PD%H~_m}jhL8+ zLqngq+||0e4hDm*qM{lY7|7vpa&mI?^z=+kEuKBAotRjem{^^hT)lrkO-F}dVq%h? zpTDrM0DM`va^;GOii)SFe|!7z`1tCpS3NA2m%qRN;NW0$b2FJt#^W{P;*y7lza%AP z69|SzMn*X~PrrQm(%UqjmX@ZarDb7ZT~^lE)HLAXan8rbr?0Os%B80`^G#4tpr7Bx z&d$-1k%iRMd?Ogo{@5ex=HO%1rY%i+xR^-bQmai_Mn z_S?5_Gcz;M(a~yZYIM5m>(_nHpVwPkQ(|IbxLmG*0WmA9WNd7CY6?ixL}=(ub#=VG zy?tY2MXy~n+oH9#Gn-eEa+`D&gdU|?(em)@~0gu->c1(#*r?<4U zWMpK_&dx>>Ctd-2VP0n~b5{_E|M#_H1L)4(-9Y0Owl+ay%g8o9VL{Q~`@;2rLNU_D ztC=V^kk3AlKD+zyBScOXu~8oFE~qcdsMm|-BhO6F&hT&LRT#i*h8%6E9V{y8t z`$Fl>!&9T7+%ahtnCeqMqhMPDruFK@kVt8R+x7Sqnx5X9M@=yp$Io|*=8}y|8?CdP zTR2k2DJMVcQ_YJ*E1njlgxvY`8%p3ID{d3$LrZvbe4d8n+7}6J4Sjs(@v{N{0qlGM A?f?J) delta 594 zcmca^{(@tIvK0eMx}&cn1H;CC?mvmF3=9kk$sR$z3=CCj3=9n|3=F@3LJcn%7)lKo z7+xhXFj&oCU=S~uvn$YMv#SIPQ$1snx4R2d8h1?!P$7GXr>`sfb533XJ~6*}3^N%R z7`;7R978NlCnqGNERsu*&{}4=c|*`y6SFctKfOGyna2*FKCZ8zp`zo&d)eja5ml9? zOHxywKG8Jm4Rs9kjC2hR^$m)34)&gHbh)JD>lfZDA-s(Nr%ps%J2FM+@|iQb^*U>p z@PsxpWXzemwRi1Y+nLKOGpwyFcduB{#M?aM`75>8?;NLP&WpQOW4AA>;P8QCKYy~b zu(7sJ;E`}Td`S7v6@fIzGu=I1eVx6^k_HAx)K%0xy%eR>HI`1AGilbed5%U2AI_XP zHSO%lP-ialt$S*^n+_=%J)W|5$C52;WU^%HFC^-TP7SpZS+ae?t68_KGz+SNSLX|u z=jSX^*lTELx_!&Gt<1IBq4zFI-oENPFS4U1YRbZ!mv3LUPkglGWbm>{*%CpLM!COw zW^PV9KhwHDXLG=*?LWE2^rH5()U+?0bPsW9Gg3}ld5$tL9GTL4HleR*7BH+; zOI#yLQtA^+QmvAUQh^kMk%5u1u7Rblp>c?znU#Tom8rQlkTfv(nxZ}*t^=eYH$Npa ztrA6psgbP0l+XkKDmml} diff --git a/docs/img/mermaid_association.png b/docs/img/mermaid_association.png index 005737e6941822bac3947354fead6089ffd071d1..91819408af0fae848787e7b85cea0f8a31d997c0 100644 GIT binary patch literal 6135 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 wF`CCC3(45bDP z46hOx7_4S6Fo+k-*%fHB`HUzZV?AS%x4R2d8h1?!P$7GXr>`sfb533XUc&=BpBVy$ z?s~d7hFF}wdL=XLkOL3<;{A z*l+HsmU!m)%R}c}KeNBs(w(3ov+&ZQ>ERnKrk2fRC|rCoq^f$l%bxmxBYaV>>I2;; zo?DSr{Z^CP$gz9-35OX@65AcTCO+onEn2=j^cig$HyK?PoI{x z_P=?`)-to`P2ETKo;$BU_t^iK$pOLVHM6bjHA_71q$|b?0==qQ;u=wsl30>zm0Xkx zq!^40jEr>+EOiZyLk!KV3@ogSOtlRRtPBjQU)D#XXvob^$xN$6*I;I43e_OD;~y|i x7$iY91m~xflqVLYGNk9_=gOq&76WZd%`48xFL}?r-wvpX!PC{xWt~$(697`|x9k7_ diff --git a/docs/img/mermaid_composition.png b/docs/img/mermaid_composition.png index 3562b65a0f2ecfd89821d998d428751bc1f8474b..c21bc1eed61c24fe80789bf9bb9978ced71ebaef 100644 GIT binary patch literal 6461 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 Jlc(hn_#YF3nz8@@ delta 539 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 V&MrsM(9QP;Xgw3%f>ZYX{{d%o?P>r3 delta 639 zcmZ2uKAmHNvK0eMx}&cn1H;CC?mvmF3=9kk$sR$z3=CCj3=9n|3=F@3LJcn%7)lKo z7+xhXFj&oCU=S~uvn$YMbB;tCV?AS%x4R2d8h1?!P$7GXr>`sfb533XK9x4lKuHD$ z#tKgt#}JFtSEpneGdl{jg)6fNZWcN=Qy?W*#(JHKhtj&#^4{4;Bwz3A{Qcu&)WSav zbNRnaU-@eL>zVt~R8}$^nfWC?qt*3M#?f_?g0^c!MOL;h4-z>W?fN8Z{tU0bruAE= zT)S%BQhQlSYW9jdG6h_}7qLcjL}hz0tX;cT*{9RVI`p`~1f|%!wnk~sUS5rme>Z#g zd_%K_QwxsW5LouQ+i2NQyW5RUGVOLYhi+sTIw*DaiEyP>^r-R*3Z)tnG7dtAg=UQU9eZS9dhFde;4qaY&$qX1XswJ)w zB`Jv|saDBFsX&Us$iT>0*T7QO&^W}<%*w#X%EVaPz`)AD;AF{VeH0D3`6-!cm6#d~ zErA*=fI32UTI~etkOWx~oS#-wo>-L1ke-*Ho2pw3v@JESI3vI0J@bA$pdtoOS3j3^ HP6RlToC|n0bd`FlNRQSraLd6w;#27E(gU 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 delta 578 zcmca@c8X(yvK0eMx}&cn1H;CC?mvmF3=9kk$sR$z3=CCj3=9n|3=F@3LJcn%7)lKo z7+xhXFj&oCU=S~uvn$YM^E2_UjP;C3-tI0;Y1}m_K!xljp1!W^&pCMo_;flZ-PC4a zV6^dcaSX9Iot%)6vPdpLqG_4o<_((yPn(qS`RV1!t(tM{^l^O!4HX?Fubr7mkAx;Q z1zj@QRP<@eE?>t$&q&u$-&p5hZ|~@KrOPE>zwq+(_W1go-E!uvu8F4M*-NKx)gQZd z?%u(Rp5B-59J+I7PR!*wGh<@z-m$gWyQj8hp_`+RvbNZtKg>+cP0mh-1%Q0+eg#Pb z7dO}A97m5G%~q6THPUsoGwe(`Fk#N5S<~iCoH=#v%GRV=+iLvs8ccxzXc?u!0;O)td-IrlEyP`PpE(k-?=UM^o|rs?1M z{Q4KHdp9pm*Y^~Vf7&iV>)m{V!b?vyMV<#6T$pQ>`>SW>=CtZ_3)?b%7TmE9ue?|D zYD#{B!nOoO_OCw7Oya9%xv?!+m&tJB{=|lxS`%u3fvZ~L8c~vxSdwa$T$Bo=7>o>z zjH`7GEOiZyLk!KV42-ReEVK;_tPBhu-FupYq9ZpyB{QuOtOH4dk(H?tM8l;o2|Ixr vBtcdL=ckpFCl;kLr03=5rs@_0ZA;B7&d4u$&%ECbsEEPS)z4*}Q$iB}&J5$x diff --git a/docs/img/mermaid_instantiation.png b/docs/img/mermaid_instantiation.png index cde3a2659ee19b9d3ff37b18d20e602bb9b8e889..49ecf28929afa5e4d64e95bb0217d0578c9eeef5 100644 GIT binary patch literal 7713 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 delta 712 zcmZ2zvx{qjvK0eMx}&cn1H;CC?mvmF3=9kk$sR$z3=CCj3=9n|3=F@3LJcn%7)lKo z7+xhXFj&oCU=S~uvn$YM^C8JZrh3LCZ+91_H13)dphET%PhVH|=bXF({31KM1HLdY zFdp!9aSX9Iot%)6vPdpLqG_4o<_((yPn(qS`RV1!t(tM{^l^O!4HX?Fubr7mkAx;Q z1zj@QRP<@eE?>t$&q&u$-&p5hZ|~@KrOPE>zwq+(_W1go-E!uvu8F4M*-NKx)gQZd z?%u(Rp5B-59J+I7PR!*wGh<@z-m$gWyQj8hp_`+RvbNZtKg>+cP0mh-1%Q0+{*EnO zOjg!bMn+0(E2gL#85vER*{P{#XJn)}vGb%Vr^W=HDGBVCH1!T7_@{b!pFbgT>eRW5 zPDWfQQR`~r>KqdVg@X${9qTeB1A;4E>+4wUFKjub<$U;6gxa!Mx4QoPv0C7=H?hvu znO8VCOW8TN*gHGA+C6>xGO@1ATc7UQ?yYrDfAQ`6w{JcSSzdE*SQ`puM15Rx@7~Ga z88a3w^Lz7lF5483S8wN9$iC>FA<4sIJhS3=`q_EL<@f%udayCo?wat%B6dr~$xD__ zr>Cv2ztHq+#v&1>Q_r-+*NVk#F1uS*kQ0z0C9uQi_Js$6TM92f(~X)nWi}hjwCKi_ z6}P|1T9?0FW--61G4Iv9y{x~#$$zl%;JrMaEyEP5fP zy*v)Fml;mA^rX$rvFtIW) z(>5@$GB6O5Xfj37k(-~AnO2Fe!Pv^g1fpS*kDW45gCxj`;QX|b^2DN4hV;Dr+*I9S dplzvn#Toe}@0s`80TnTLy85}Sb4p-r0suEN8pi+t diff --git a/docs/img/mermaid_nested.png b/docs/img/mermaid_nested.png index 144c5c4f4b5e8c2d8caad612aef2884f0da7e9e1..ae0725c6698e77d25d0fe28485c65fc0b7cd9fc6 100644 GIT binary patch literal 6765 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 aDWKRGipPgy%{y!7ezfrcqdNvi!~O?ET`TGU delta 540 zcmaEBa)Et1MJ+3~n+6AO?5N;6q^oGiIdlG;NnW0F+LkR<&J-7UE~s$dAmQAp z6K9+XHdhwuoG|Cfh{}trV>Ic^6crPl9#Eekv4ThQX^@`w`W0)|Bxr}NTea+nLBUV8 znBddF;qmdug|9e7HnQkeOIv=OH7mL%O4B%72OC7#SED>l#?<8XAWfnp&A!SQ(pX8yHv_7AqY5 diff --git a/docs/include_diagrams.md b/docs/include_diagrams.md index 0a2041e0..401a0ede 100644 --- a/docs/include_diagrams.md +++ b/docs/include_diagrams.md @@ -6,17 +6,13 @@ -Include diagrams allow to document the include dependencies among different parts of the project. This can be very useful -for instance to detect that a file was included from a module directory, on which specific part of the project -should not ever depend. +Include diagrams allow to document the include dependencies among different +parts of the project. This can be very useful for instance to detect that a file +was included from a module directory, on which specific part of the project +should never depend. The minimal config required to generate an include diagram is presented below: ```yaml -# Path to the directory where `compile_commands.json` can be found -compilation_database_dir: _build -# Output directory for the diagrams -output_directory: diagrams -# Diagrams definitions diagrams: # Diagram name my_class_diagram: @@ -25,8 +21,6 @@ diagrams: # Include only translation units matching the following patterns glob: - src/*.cc - # Render the paths relative to this directory - relative_to: src # Include also external system headers generate_system_headers: true # Include only classes and functions from files in `src` directory @@ -36,29 +30,31 @@ diagrams: - src ``` -One distinctive option in `include` diagrams is `relative_to`, which tells `clang-uml` to render all filename -paths relative to this directory. +One distinctive option in `include` diagrams is `relative_to`, which tells +`clang-uml` to render all filename paths relative to this directory. -The following table presents the PlantUML arrows representing relationships in the include diagrams. +The following table presents the PlantUML arrows representing relationships in +the include diagrams. -| UML | PlantUML | -| ---- | --- | -| Include (local) | ![association](img/puml_association.png) | -| Include (system) | ![dependency](img/puml_dependency.png) | +| UML | PlantUML | MermaidJS | +|-----------------------------------------|------------------------------------------|---------------------------------------------| +| Include (local) | ![association](img/puml_association.png) | ![association](img/mermaid_association.png) | +| Include (system) | ![dependency](img/puml_dependency.png) | ![association](img/mermaid_dependency.png) | ## Tracking system headers directly included by project sources -In case you would like to include the information about what system headers your projects file include simply add -the following option to the diagram: +In case you would like to include the information about what system headers your +project files include simply add the following option to the diagram: ```yaml generate_system_headers: true ``` -This will include only system headers directly included from the projects source files (matched by `glob`) and not -their dependencies, for example: +This will include only system headers directly included from the project's +source files (matched by `glob`) and not their dependencies, for example: ![t40001_include](./test_cases/t40001_include.svg) -Please note that generating include diagram, which contains third party and system library headers will result -in a huge diagram that will be unlikely to be useful. \ No newline at end of file +Please note that generating include diagram, which contains third party and +system library headers will result in a huge diagram that will be unlikely to +be useful. \ No newline at end of file diff --git a/docs/installation.md b/docs/installation.md index 5a8b71bf..e1af79e8 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -64,8 +64,8 @@ Download and run the latest Windows installer from First make sure that you have the following dependencies installed: ```bash -# Ubuntu (clang version will vary depending on Ubuntu version) -apt install ccache cmake libyaml-cpp-dev clang-12 libclang-12-dev libclang-cpp12-dev +# Ubuntu (Clang version will vary depending on Ubuntu version - below example is for Ubuntu 22.04) +apt install make gcc g++ ccache cmake libyaml-cpp-dev llvm-15 clang-15 libclang-15-dev libclang-cpp15-dev clang-format-15 ``` Then proceed with building the sources: @@ -81,6 +81,9 @@ release/src/clang-uml --help LLVM_VERSION=16 make release # or specify path to a specific llvm-config binary, e.g.: LLVM_CONFIG_PATH=/usr/bin/llvm-config-16 make release +# or directly specify the path where LLVMConfig.cmake can be found on your system, e.g.: +CMAKE_PREFIX=/usr/lib/llvm-16/lib/cmake/llvm make release + # Optionally, to install in default prefix make install @@ -96,8 +99,10 @@ export PATH=$PATH:$PWD/release brew install ccache cmake llvm yaml-cpp export CC=/usr/local/opt/llvm/bin/clang -export CCX=/usr/local/opt/llvm/bin/clang++ +export CXX=/usr/local/opt/llvm/bin/clang++ LLVM_VERSION=16 make release +# or, if this fails, try: +CMAKE_PREFIX=/usr/local/opt/llvm/lib/cmake/llvm make release ``` #### Windows diff --git a/docs/interactive_svg_diagrams.md b/docs/interactive_svg_diagrams.md index aadb6375..3358057e 100644 --- a/docs/interactive_svg_diagrams.md +++ b/docs/interactive_svg_diagrams.md @@ -6,13 +6,13 @@ -`clang-uml` in combination with PlantUML's link generation in diagrams allows to -generate interactive diagrams, where clicking on any class, method or call -expression can direct the user directly to the source code or some other -diagram or document available online. +`clang-uml` in combination with PlantUML and MermaidJS link generation in +diagrams allows to generate interactive diagrams, where clicking on any class, +method or call expression can direct the user directly to the source code or +some other diagram or document available online. For instance to generate links to GitHub repository directly for most diagram -elements simple add this to your `.clang-uml` file: +elements simply add this to your `.clang-uml` file: ```yaml generate_links: diff --git a/docs/package_diagrams.md b/docs/package_diagrams.md index 756e3b72..5e542be2 100644 --- a/docs/package_diagrams.md +++ b/docs/package_diagrams.md @@ -7,16 +7,11 @@ Package diagrams are simple diagrams, which can be useful to visualize a high -level structure of a C++ project, by rendering all projects namespaces or +level structure of a C++ project, by rendering project's namespaces or subdirectories as UML packages and their interdependencies. The minimal config required to generate a package diagram is presented below: ```yaml -# Path to the directory where `compile_commands.json` can be found -compilation_database_dir: _build -# Output directory for the diagrams -output_directory: diagrams -# Diagrams definitions diagrams: # Diagram name my_class_diagram: diff --git a/docs/quick_start.md b/docs/quick_start.md index d696c2f0..3ff1bad1 100644 --- a/docs/quick_start.md +++ b/docs/quick_start.md @@ -8,7 +8,7 @@ To add an initial class diagram to your project, follow these steps: -1. Enter your projects top level directory and run: +1. Enter your project's top level directory and run: ```bash clang-uml --init ``` @@ -36,10 +36,10 @@ To add an initial class diagram to your project, follow these steps: namespaces: - myproject::detail ``` -3. Run `clang-uml` in the projects top directory: +3. Run `clang-uml` in the project's top directory: ```bash clang-uml - # or to see generation progress for each diagram run + # or to see generation progress for each diagram clang-uml --progress ``` 4. Generate SVG images from the PlantUML diagrams: @@ -62,7 +62,7 @@ To add an initial class diagram to your project, follow these steps: ```bash clang-uml --add-sequence-diagram another_diagram ``` -6. Now list the diagrams defined in the config: +6. Now list the diagrams defined in the config file: ```bash clang-uml -l The following diagrams are defined in the config file: diff --git a/docs/sequence_diagrams.md b/docs/sequence_diagrams.md index 60b150c6..fea46abb 100644 --- a/docs/sequence_diagrams.md +++ b/docs/sequence_diagrams.md @@ -55,23 +55,23 @@ C++ code, the following assumptions were made: from plain old C code). Functions can also be aggregated into file participants, based on their place of declaration * Call expressions in conditional expressions in block statements (e.g. `if` - or `while`) are rendered inside the PlantUML `alt` or `loop` blocks but - wrapped in `[`, `]` brackets + or `while`) are rendered inside the PlantUML or MermaidJS `alt` or `loop` + blocks but wrapped in `[`, `]` brackets * Lambda expressions are generated as standalone participants, whose name comprises the parent context where they are defined and the exact source code location ## Specifying diagram location constraints -Sequence diagrams require a specification of location constraints in order to +Sequence diagrams require specification of location constraints in order to determine, which call chains should be included in the diagram. Currently, there are 3 types of constraints: -* `from` - will include all message call chains which start at the +* `from` - will include all message call chains, which start at the locations specified in this constraint (this was previously named `start_from`) -* `to` - will include all message call chains which end at the specified +* `to` - will include all message call chains, which end at the specified locations -* `from_to` - will include all call chains which start and end at the specified - location constraints +* `from_to` - will include all call chains, which start and end at the specified + locations Currently, the constraints can be a method or a free function, both specified using the full signature of the function, e.g. @@ -97,7 +97,7 @@ and `to` locations as follows: function: "clanguml::t20034::A::a2()"] ``` -To find the exact function signature which can be used as a `from` location, +To find the exact function signature which, can be used as a `from` location, run `clang-uml` as follows: ```bash @@ -255,18 +255,16 @@ results in the following diagram: ## Customizing participants order The default participant order in the sequence diagram can be suboptimal in the sense that consecutive calls can go right, then left, then right again -depending on the specific call chain in the code. It is however -possible to override this order in the diagram definition using -`participants_order` property, for instance like this test case: +depending on the specific call chain in the code. It is however possible to +override this order in the diagram definition using `participants_order` +property, for instance like this test case: ```yaml -compilation_database_dir: .. -output_directory: diagrams diagrams: t20029_sequence: type: sequence glob: - - ../../tests/t20029/t20029.cc + - t20029.cc include: namespaces: - clanguml::t20029 @@ -296,13 +294,12 @@ following configuration option: generate_return_types: true ``` -This option only affects the `plantuml` generation, in `json` generator -`return_type` property is always present in the message nodes. +This option only affects the `plantuml` and `mermaid` generators, in `json` +generator `return_type` property is always present in the message nodes. The diagram below presents what it looks like in a PlantUML generated diagram: ![extension](test_cases/t20032_sequence.svg) - ## Generating condition statements Sometimes, it is useful to include actual condition statements (for instance contents of the `if()` condition in the `alt` or `loop` blocks in the sequence @@ -323,8 +320,12 @@ in some line of code. This can include passing function or method address to some executor (e.g. thread), async calls etc. However, a call expression can be injected manually through a comment -directive `\uml{note CALLEE}`, when placed just before such line of code, for -example: +directive +```cpp +// \uml{note CALLEE} +``` + +It should be placed in the comment just before such line of code, for example: ```cpp // \uml{call clanguml::t20038::B::bbb()} @@ -346,7 +347,7 @@ add_compile_flags: otherwise Clang will skip these comments during AST traversal. ## Including comments in sequence diagrams -`clang-uml` can add code comments placed directly before are next to a call +`clang-uml` can add code comments placed directly before or next to a call expression as notes in the diagram (see for instance [t20038](test_cases/t20038_sequence.svg)). diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 49705bac..d708e181 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -9,7 +9,7 @@ * [Clang produces several warnings during diagram generation](#clang-produces-several-warnings-during-diagram-generation) * [Cannot generate diagrams from header-only projects](#cannot-generate-diagrams-from-header-only-projects) * [YAML anchors and aliases are not fully supported](#yaml-anchors-and-aliases-are-not-fully-supported) -* [Schema validation error is thrown, but the configuration file is correct](#schema-validation-error-is-thrown-but-the-configuration-file-is-correct) + * [Schema validation error is thrown, but the configuration file is correct](#schema-validation-error-is-thrown-but-the-configuration-file-is-correct) * [Class diagrams](#class-diagrams) * ["fatal error: 'stddef.h' file not found"](#fatal-error-stddefh-file-not-found) * [How can I generate class diagram of my entire project](#how-can-i-generate-class-diagram-of-my-entire-project) @@ -27,7 +27,7 @@ If `clang-uml` crashes with a segmentation fault, it is possible to trace the exact stack trace of the fault using the following steps: -First, build `clang-uml` from source in debug mode, e.g.: +First, build `clang-uml` from source in debug mode, i.e.: ```bash make debug @@ -35,15 +35,16 @@ make debug Then run `clang-uml`, preferably with `-vvv` for verbose log output. If your `.clang-uml` configuration file contains more than 1 diagram, specify only -a single diagram to make it easier to trace the root cause of the crash, e.g.: +the diagram causing the crash, to make it easier to trace the root cause of +the crash, e.g.: ```bash debug/src/clang-uml -vvv -n my_diagram ``` After `clang-uml` crashes again, detailed backtrace (generated using -[backward-cpp](https://github.com/bombela/backward-cpp)) should be visible -on the console. +[backward-cpp](https://github.com/bombela/backward-cpp) library) should be +visible on the console. If possible, [create an issue](https://github.com/bkryza/clang-uml/issues) and paste the stack trace and few last logs from the console. @@ -52,8 +53,7 @@ paste the stack trace and few last logs from the console. `clang-uml` uses Clang's [RecursiveASTVisitor](https://clang.llvm.org/doxygen/classclang_1_1RecursiveASTVisitor.html), -to -traverse the source code. By default, this visitor is invoked on every +to traverse the source code. By default, this visitor is invoked on every translation unit (i.e. each entry in your `compile_commands.json`), including all of their header dependencies recursively. This means, that for large code bases with hundreds or thousands of translation units, traversing all of them @@ -201,7 +201,7 @@ the configuration file to `clang-uml` using `stdin`, e.g.: yq 'explode(.)' .clang-uml | clang-uml --config - ``` -## Schema validation error is thrown, but the configuration file is correct +### Schema validation error is thrown, but the configuration file is correct Current version of `clang-uml` performs automatic configuration file schema validation, and exits if the configuration file is invalid. @@ -325,11 +325,10 @@ Hopefully this will be eventually resolved. ### Generated diagram is empty -In order to generate sequence diagram the `start_from` configuration option must -have a valid starting point +In order to generate sequence diagram the location constraints (`from`, `to` +or `from_to`) in configuration file must point to valid locations in the code for the diagram (e.g. `function`), which must match exactly the function or method signature in the `clang-uml` diagram model. - Look for error in the console output such as: ```bash @@ -341,16 +340,19 @@ configuration file, or that the function was not defined in the translation units you specified in the `glob` patterns for this diagram. +Except for simplest methods and functions, it is unlikely to write by hand +the exact string representation of the function signature as seen by `clang-uml`. + To find the exact function signature run `clang-uml` as follows: ```bash clang-uml -n my_sequence_diagram --print-start-from | grep foo ``` -Command line flag `--print-start-from` will print on stdout all functions -and methods available in the diagram model, and each line of this output -can be directly used as a value of `start_from` option in the config file. - +Command line flag `--print-from` will print on stdout all functions +and methods available in the diagram model which can be used as starting +points for a sequence diagram (similarly `--print-to` can be used to list +all valid functions to be used as call chain end constraints). ### Generated diagram contains several empty control blocks or calls which should not be there