Flutter Dart Documentation
In this article, we are going to see how to do the flutter code documentation effectively and in a stranded manner. Which improves the quality and clarity of your code.
Commenting is the “art” of describing what your program is going to do in “high level” English statements. Commenting is best done before actually writing the code for your program.
Comments
The following tips apply to comments that you don’t want included in the generated documentation.
DON’T use block comments for documentation.
Good:
void greet(String name) {
// Assume we have a valid name.
print('Hi, $name!');
}Bad:
void greet(String name) {
/* Assume we have a valid name. */
print('Hi, $name!');
}
You can use a block comment (/* ... */
) to temporarily comment out a section of code, but all other comments should use //
.
Dartdoc Tool/Plugin for flutter
Use dartdoc
to generate HTML documentation on for your Dart package.
Generating docs
Run dartdoc
from the root directory of a package. Your package must analyze without errors with dart analyze
or flutter analyze
as appropriate. Here is an example of dartdoc documenting itself:
$ dartdoc
Documenting dartdoc...
Initialized dartdoc with 766 libraries in 63.9 seconds
Generating docs for library dartdoc from package:dartdoc/dartdoc.dart...
Validating docs...
no issues found
Documented 1 public library in 17.9 seconds
Success! Docs generated into <path to dartdoc>/doc/api
By default, the documentation is generated to the doc/api
directory as static HTML files.
Run dartdoc -h
to see the available command-line options.
Doc comments
Doc comments are especially handy because dartdoc parses them and generates beautiful doc pages from them. A doc comment is any comment that appears before a declaration and uses the special ///
syntax that dartdoc looks for.
DO use ///
doc comments to document members and types.
Using a doc comment instead of a regular comment enables dartdoc to find it and generate documentation for it.
Good:
/// The number of characters in this chunk when unsplit.
int get length => ...Bad:
// The number of characters in this chunk when unsplit.
int get length => ...
CONSIDER writing doc comments for private APIs.
Doc comments aren’t just for external consumers of your library’s public API. They can also be helpful for understanding private members that are called from other parts of the library.
DO start doc comments with a single-sentence summary.
Start your doc comment with a brief, user-centric description ending with a period. A sentence fragment is often sufficient. Provide just enough context for the reader to orient themselves and decide if they should keep reading or look elsewhere for the solution to their problem.
/// Deletes the file at [path] from the file system.
void delete(String path) {
...
}
DO separate the first sentence of a doc comment into its own paragraph.
Add a blank line after the first sentence to split it out into its own paragraph. If more than a single sentence of explanation is useful, put the rest in later paragraphs.
This helps you write a tight first sentence that summarizes the documentation. Also, tools like dartdoc use the first paragraph as a short summary in places like lists of classes and members.
/// Deletes the file at [path].
///
/// Throws an [IOError] if the file could not be found. Throws a
/// [PermissionError] if the file is present but could not be deleted.
void delete(String path) {
...
}
AVOID redundancy with the surrounding context.
The reader of a class’s doc comment can clearly see the name of the class, what interfaces it implements, etc. When reading docs for a member, the signature is right there, and the enclosing class is obvious. None of that needs to be spelled out in the doc comment. Instead, focus on explaining what the reader doesn’t already know.
class RadioButtonWidget extends Widget {
/// Sets the tooltip to [lines], which should have been word wrapped using
/// the current font.
void tooltip(List<String> lines) {
...
}
}
PREFER starting function or method comments with third-person verbs.
The doc comment should focus on what the code does.
/// Returns `true` if every element satisfies the [predicate].
bool all(bool predicate(T element)) => ...
/// Starts the stopwatch if not already running.
void start() {
...
}
PREFER starting variable, getter, or setter comments with noun phrases.
Doc comments for classes are often the most important documentation in your program. They describe the type’s invariants, establish the terminology it uses, and provide context to the other doc comments for the class’s members. A little extra effort here can make all of the other members simpler to document.
/// A chunk of non-breaking output text terminated by a hard or soft newline.
///
/// ...
class Chunk { ... }
CONSIDER including code samples in doc comments.
/// Returns the lesser of two numbers.
///
/// ```dart
/// min(5, 3) == 3
/// ```
num min(num a, num b) => ...
Humans are great at generalizing from examples, so even a single code sample makes an API easier to learn.
DO use square brackets in doc comments to refer to in-scope identifiers.
If you surround things like variable, method, or type names in square brackets, then dartdoc looks up the name and links to the relevant API docs. Parentheses are optional, but can make it clearer when you’re referring to a method or constructor.
/// Throws a [StateError] if ...
/// similar to [anotherMethod()], but ...
To link to a member of a specific class, use the class name and member name, separated by a dot:
/// Similar to [Duration.inDays], but handles fractional days.
The dot syntax can also be used to refer to named constructors:
/// To create a point from polar coordinates, use [Point.polar()].
DO put doc comments before metadata annotations.
/// A button that can be flipped on and off.
@Component(selector: 'toggle')
class ToggleComponent {}
Markdown
You are allowed to use most markdown formatting in your doc comments and dartdoc will process it accordingly using the markdown package.
There are tons of guides out there already to introduce you to Markdown. Its universal popularity is why we chose it. Here’s just a quick example to give you a flavor of what’s supported:
/// This is a paragraph of regular text.
///
/// This sentence has *two* _emphasized_ words (italics) and **two**
/// __strong__ ones (bold).
///
/// A blank line creates a separate paragraph. It has some `inline code`
/// delimited using backticks.
///
/// * Unordered lists.
/// * Look like ASCII bullet lists.
/// * You can also use `-` or `+`.
///
/// 1. Numbered lists.
/// 2. Are, well, numbered.
/// 1. But the values don't matter.
///
/// * You can nest lists too.
/// * They must be indented at least 4 spaces.
/// * (Well, 5 including the space after `///`.)
///
/// Code blocks are fenced in triple backticks:
///
/// ```dart
/// this.code
/// .will
/// .retain(its, formatting);
/// ```
///
/// The code language (for syntax highlighting) defaults to Dart. You can
/// specify it by putting the name of the language after the opening backticks:
///
/// ```html
/// <h1>HTML is magical!</h1>
/// ```
///
/// Links can be:
///
/// * https://www.just-a-bare-url.com
/// * [with the URL inline](https://google.com)
/// * [or separated out][ref link]
///
/// [ref link]: https://google.com
///
/// # A Header
///
/// ## A subheader
///
/// ### A subsubheader
///
/// #### If you need this many levels of headers, you're doing it wrong
AVOID using markdown excessively.
When in doubt, format less. Formatting exists to illuminate your content, not replace it. Words are what matter.
AVOID using HTML for formatting.
It may be useful to use it in rare cases for things like tables, but in almost all cases, if it’s too complex to express in Markdown, you’re better off not expressing it.
PREFER backtick fences for code blocks.
Markdown has two ways to indicate a block of code: indenting the code four spaces on each line, or surrounding it in a pair of triple-backtick “fence” lines. The former syntax is brittle when used inside things like Markdown lists where indentation is already meaningful or when the code block itself contains indented code.
The backtick syntax avoids those indentation woes, lets you indicate the code’s language, and is consistent with using backticks for inline code.
/// You can use [CodeBlockExample] like this:
///
/// ```dart
/// var example = CodeBlockExample();
/// print(example.isItGreat); // "Yes."
/// ```
Viewing docs
You can view the generated docs directly from the file system, but if you want to use the search function, you must load them with an HTTP server.
An easy way to run an HTTP server locally is to use the dhttpd
package. For example:
$ pub global activate dhttpd
$ dhttpd --path doc/api
Navigate to http://localhost:8080
in your browser; the search function should now work.
Link structure
dartdoc produces static files with a predictable link structure.
index.html # homepage
index.json # machine-readable index
library-name/ # : is turned into a - e.g. dart:core => dart-core
ClassName-class.html # "homepage" for a class (and enum)
ClassName/
ClassName.html # constructor
ClassName.namedConstructor.html # named constructor
method.html
property.html
CONSTANT.html
property.html
top-level-function.html
File names are case-sensitive.
Excluding from documentation
dartdoc
will not generate documentation for a Dart element and its children that have the @nodoc
tag in the documentation comment.
Examples
After running a dartdoc in your project it creates a folder name doc and we know that dartdoc create only api documentation, so api folder is created and the project api documentation is done and the structure is given in the screenshot above
Conclusion
Many developers don’t write enough documentation, either because they don’t see the value or because they feel like they don’t have time. You don’t need to be one of those developers. With a little time and a lot of practice, you can add documentation for your code that makes reading it a joy to use for both you and anyone else who comes along.
Thank you for reading the article, All the best for your code documentation