Spinning Topp Logo BlackTopp Studios
inc
best_practices_doxygen.h
1 // © Copyright 2010 - 2016 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 #ifndef best_practices_doxygen_h
41 #define best_practices_doxygen_h
42 
43 /**
44  @page best_practices_doxygen Best Practices – Doxygen
45  Doxygen is a tool for extracting API documentation from source code. Doxygen reads source code
46  the same way a C, C++ or Java compiler would, but can also read special comments to include
47  extra information. This page is about making the most of doxygen by entering high quality
48  information. If you want to learn how to run doxygen see the page on @ref running_doxygen or if
49  you want to know how to install it see the appropriate page about our @ref dev_tools_menu.
50 
51  @section best_practices_doxygen_visibility D1 Improve Errors visibilty during builds
52  Errors can't be fixed if you cannot see them. Try to use tools that will show you the errors
53  that running the build process creates. When running doxygen you might redirect the errors to a
54  file and review the file to assist in troubleshooting syntax errors in documentation. Here is a
55  simple way to make "results.txt" from the warnings and errors doxygen emits:
56 
57  @verbatim
58  $ doxygen doxygen.config 2> results.txt
59  @endverbatim
60 
61  Another way to get good visibility is to read the doxygen logfile, but is needs to be set in the
62  doygen configuration. Use the "WARN_LOGFILE" directive to set this. You can also set the
63  "WARN_FORMAT" directive to something your IDE understands and get warnings your IDE understands.
64  With Qt Creator and Code::Blocks this allows a developer to click on the warnings in the build
65  results panel or windows and have an editor windows show them the offending file and line. Here
66  is the configuration required to do that:
67 
68  @verbatim
69  WARN_FORMAT = "$file:$line: $text"
70  WARN_LOGFILE = ../html/DoxygenWarnings.txt
71  @endverbatim
72 
73  @section best_practices_doxygen_minimum D2 Minimum Amount to Document
74  It is easy to document too much or too little. Too much and it will easily fall out of date when
75  the code changes and developers ignore the wall of text. Too little and people using the code
76  and documentation go WTF?! and use some other code or write from scratch.
77 
78  @n
79  Here is what we do. We probably tend to go a little too heavily, but we are writing an API and
80  we feel clarity is worth some maintanence cost.
81 
82  @subsection best_practices_doxygen_minimum_function Function/Methods Minimum Amount to Document
83  Each function/method should get:
84 
85  - \@brief Every function and method should get one of these unless the \@return or \@param
86  describe it so completely adding this would hurt. (leave \@brief off the int GetX() method on
87  2D point class for example).
88  - One \@param for each parameter describing its type, accepted values and any default values.
89  - \@return Unless it returns void then the return tty and value shoud be documented.
90  - \@throw If an exception is thrown, its type and conditions for causing the throw should be
91  noted.
92  - \@details or add \@remarks Should be added anytime the function has special preconditions.
93  Changes state on a class that is not obvious or is otherwise complex.
94 
95  @n
96  Here are some examples of Bad and Good doxygen comments on bad code. This code is terrible to
97  highlight how much of a difference good and bad documentation can make. In a real situation it
98  it likely that even good code with good variable names might still be complex enough to allow
99  misconceptions in.
100 
101  @n
102  Bad Dox:
103  @code
104  int sqrt(int x);
105 
106  /// @brief calculates absolute value
107  int abs(int x);
108 
109  /// @param Accepts a float.
110  /// @return Returns a float.
111  float log(float x)
112  @endcode
113 
114  Good Dox:
115  @code
116  /// @param x An Integer to take the square root of
117  /// @return An int containing the square root of x. Any floating part is truncated
118  int sqrt(int x);
119 
120  /// @brief Calculates absolute value, the distance from zero
121  /// @param x An int that might be postive or negative.
122  /// @return A positive int (or 0) that is the same as x but with an minus sign removed.
123  int abs(int x);
124 
125  /// @brief Calculate the natural logorithm of a value.
126  /// @param x A float to calculate the log2 of.
127  /// @return Returns a floatX.
128  float log(float x)
129  @endcode
130 
131  @subsection best_practices_doxygen_minimum_enum Enum Minimum Amount to Document
132  Most enums just need an \@brief and if the options are not self explanatory a using ///< seems
133  to be the easiest way to document them. You don't need \@enum unless you are placing the dox
134  far away from the enum. Here is an example:
135 
136 
137  @n
138  Bad Dox:
139  @code
140  /// @enum dir A direction
141  enum dir
142  {
143  MN, MS, MW, ME,
144  N, W, S, E
145  };
146  @endcode
147 
148  Good Dox:
149  @code
150  /// @brief A Compass direction
151  enum dir
152  {
153  MN, ///< Magnetic North
154  MS, ///< Magnetic South
155  MW, ///< Magnetic West
156  ME, ///< Magnetic East
157 
158  N, W, S, E
159  };
160  @endcode
161 
162  Good Code and Dox:
163  @code
164  /// @brief A Compass direction
165  enum CompassDirection
166  {
167  MagneticNorth, ///< Magnetic North
168  MagneticSouth, ///< Magnetic South
169  MagneticWest, ///< Magnetic West
170  MagneticEast, ///< Magnetic East
171 
172  North, ///< Geographic North
173  South, ///< Geographic South
174  West, ///< Geographic West
175  East ///< Geographic East
176  };
177  @endcode
178 
179 
180  @subsection best_practices_doxygen_minimum_class Class Minimum Amount to Document
181  Most classes should have an \@brief providing a simple overview, an \@details providing
182  additional rationle and perhaps a few examples in \@code/\@endcode or \@verbatim/\@endverbatim
183  sections if their use is complicated. Use \@code when you want systax highlighting and a
184  monospace font, use \@verbatim when you don't need syntax hightlighting. Since every method
185  should be well named and well documented hopefully class documentation can be small.
186 
187  @n
188  Try to document classes in the header file just ahead of the class keyword and \@class will not
189  be needed.
190 
191  @n
192  Example:
193  @code
194  /// @brief A 3x3 matrix intended for use in rotating 3d points.
195  /// @details This supports normal math operations via operator overloads and is contructable
196  /// to a unit matrix or accepts all 9 values in row major order:
197  /// @verbatim
198  /// Matrix UnitMatrix;
199  /// Matrix OtherMatrix(1,2,3,4,5,6,7,8,9);
200  /// Matrix Product = UnitMatrix * OtherMatrix;
201  /// @endverbatim
202  class Matrix
203  {
204  // Omitted
205  @endcode
206 
207  @subsection best_practices_doxygen_minimum_file File Minimum Amount to Document
208  All Files get an \@file and an \@brief describing a little more than the name of the file could
209  desribe. This mostly provides a link in doxygen that might not otherwise have been generated.
210  The \@file command accepts a filename, leave it out. If specified doxygen will interpret that
211  block as documentation for some other file which might not existor otherwise break when the file
212  is renamed.
213 
214  @n
215  Example in foo.h:
216  @code
217  /// @file
218  /// @brief This defines the class foo intended for use with @ref bar.
219  @endcode
220 
221  @section best_practices_doxygen_copydoc D3 \@copydoc Should Follow inheritance
222  The \@copydoc directive should primarily be used by following up inheritance heiarchies. When
223  used to in other ways it can creates logical dependencines in the documentation that do not
224  match the code which increases future maintanence effort. Consider the follow inheritance tree
225  of classes:
226 
227  @dot Sample inheritance tree
228  digraph interop {
229  Animal [shape=box];
230  Mammal [shape=box];
231  Reptile [shape=box];
232  Cat [shape=box];
233  Dog [shape=box];
234  Lizard [shape=box];
235  Animal -> Mammal -> Cat;
236  Mammal -> Dog;
237  Animal -> Reptile -> Lizard;
238  }
239  @enddot
240 
241  @n
242  Because the Lizard and the Cat have little to do with each other in code they will change in
243  different in the future. Even if they each have an int LegCount() const member function that
244  return 4, they should not copy documentation from eachother. Someone updating the lizard to have
245  6 legs is unlikely to be concerned the Cat class.
246 
247  @n
248  A more reasonable solution is to have Lizard copy documentation from Reptile and Cat from
249  Mammal. This makes it easy for someone changing code and documentation to know what other
250  documentation should be updated. Following a rule like this also implies that someone changing
251  a class has some responsibility to verify the documentation in each derived class.
252 
253  @n
254  Bad:
255  @code
256  /// @brief All lizards have 4 legs.
257  /// @return An integer of value 4
258  int Lizard::LegCount() const;
259 
260  /// @copydoc Lizard::LegCount() const
261  int Cat::LegCount() const;
262  @endcode
263 
264  @n
265  Good:
266  @code
267  /// @return All Mammals have 4 limbs so this returns an integer of value 4.
268  int Mammal::LegCount() const;
269 
270  /// @copydoc Mammal::LegCount() const
271  int Cat::LegCount() const;
272  @endcode
273 
274 
275  @section best_practices_doxygen_identifier D4 Identifier Commands
276  \@enum, \@typedef, \@class, and other specifiers of things to be documented should be used
277  when documenting things out of line. If the documentation comments precede what you are
278  documenting then these can be omitted. This makes documentation shorter and easier to maintain.
279 
280  @n
281  Some of our older and more stale dox have some of these dangling from when we did not know
282  better.
283 
284  @section best_practices_doxygen_ref D5 References
285  Use \@ref often. Anytime you define a class, page, function, section or any other code or
286  documentation structure you can refer to it with \@ref. If you simple put \@ref followed by the
287  class, function, section or page name you will get a link with the text of the name text from
288  the refferred item. If you want different text include link text in quotes. See some examples:
289 
290  To make:
291  @n
292  @ref Mezzanine::Vector3 and @ref best_practices_doxygen
293  @n
294  Use:
295  @code
296  @ref Mezzanine::Vector3 and @ref best_practices_doxygen
297  @endcode
298 
299  @n
300  To provide custom text like this:
301  @n
302  @ref Mezzanine::Vector3 "X/Y/Z Thingy" and
303  @ref best_practices_doxygen "Lexicographer's hate him"
304  @n
305  Use:
306  @code
307  @ref Mezzanine::Vector3 "X/Y/Z Thingy" and
308  @ref best_practices_doxygen "Lexicographer's hate him"
309  @endcode
310 */
311 
312 #endif