README.md 8.77 KB
Newer Older
1
# Dartdoc Generation
2

3 4
The Flutter API documentation contains code blocks that help provide context or
a good starting point when learning to use any of Flutter's APIs.
5 6 7 8 9 10 11 12

To generate these code blocks, Flutter uses dartdoc tools to turn documentation
in the source code into API documentation, as seen on https://api.flutter.dev/.

## Table of Contents

- [Types of code blocks](#types-of-code-blocks)
  - [Snippet tool](#snippet-tool)
13
  - [Sample tool](#sample-tool)
14 15
- [Skeletons](#skeletons)
- [Test Doc Generation Workflow](#test-doc-generation-workflow)
16

17
## Types of code blocks
18

19
There are three kinds of code blocks.
20

21
* A `snippet`, which is a more or less context-free code snippet that we
22
  magically determine how to analyze.
23

24
* A `dartpad` sample, which gets placed into a full-fledged application, and can
25
  be executed inline in the documentation on the web page using
26 27 28 29 30 31
  DartPad.

* A `sample`, which gets placed into a full-fledged application, but isn't
  placed into DartPad in the documentation because it doesn't make sense to do
  so.

32 33
Ideally, every sample is a DartPad sample, but some samples don't have any visual
representation and some just don't make sense that way (for example, sample
34 35
code for setting the system UI's notification area color on Android won't do
anything on the web).
36

37
### Snippet Tool
38

39
![Code snippet image](assets/code_snippet.png)
40

41 42
The code `snippet` tool generates a block containing a description and example
code. Here is an example of the code `snippet` tool in use:
43 44

```dart
45
/// {@tool snippet}
46 47 48 49
///
/// If the avatar is to have an image, the image should be specified in the
/// [backgroundImage] property:
///
50
/// ```dart
51 52 53 54 55 56 57
/// CircleAvatar(
///   backgroundImage: NetworkImage(userAvatarUrl),
/// )
/// ```
/// {@end-tool}
```

58 59
This will generate sample code that can be copied to the clipboard and added to
existing applications.
60

61 62
This uses the skeleton for [snippet](config/skeletons/snippet.html) snippets
when generating the HTML to put into the Dart docs.
63 64 65

#### Analysis

66
The `../bots/analyze_sample_code.dart` script finds code inside the `@tool
67
snippet` sections and uses the Dart analyzer to check them.
68 69 70

There are several kinds of sample code you can specify:

71 72
* Constructor calls, typically showing what might exist in a build method. These
  will be inserted into an assignment expression assigning to a variable of type
73
  "dynamic" and followed by a semicolon, for analysis.
74

75
* Class definitions. These start with "class", and are analyzed verbatim.
76

77 78 79
* Other code. It gets included verbatim, though any line that says `// ...` is
  considered to separate the block into multiple blocks to be processed
  individually.
80

81
The above means that it's tricky to include verbatim imperative code (e.g. a
82
call to a method) since it won't be valid to have such code at the top level.
83 84
Instead, wrap it in a function or even a whole class, or make it a valid
variable declaration.
85

86 87 88 89 90
You can declare code that should be included in the analysis but not shown in
the API docs by adding a comment "// Examples can assume:" to the file (usually
at the top of the file, after the imports), following by one or more
commented-out lines of code. That code is included verbatim in the analysis. For
example:
91 92 93 94 95 96 97 98 99 100

```dart
// Examples can assume:
// final BuildContext context;
// final String userAvatarUrl;
```

You can assume that the entire Flutter framework and most common
`dart:*` packages are imported and in scope; `dart:math` as `math` and
`dart:ui` as `ui`.
101

102
### Sample Tool
103

104
![Code sample image](assets/code_sample.png)
105

106 107 108 109 110 111
The code `sample` and `dartpad` tools can expand sample code into full Flutter
applications. These sample applications can be directly copied and used to
demonstrate the API's functionality in a sample application, or used with the
`flutter create` command to create a local project with the sample code. The
`dartpad` samples are embedded into the API docs web page and are live
applications in the API documentation.
112 113

```dart
114
/// {@tool sample --template=stateless_widget_material}
115 116
/// This example shows how to make a simple [FloatingActionButton] in a
/// [Scaffold], with a pink [backgroundColor] and a thumbs up [Icon].
117
///
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
/// ```dart
/// Widget build(BuildContext context) {
///   return Scaffold(
///     appBar: AppBar(
///       title: Text('Floating Action Button Sample'),
///     ),
///     body: Center(
///       child: Text('Press the button below!')
///     ),
///     floatingActionButton: FloatingActionButton(
///       onPressed: () {
///         // Add your onPressed code here!
///       },
///       child: Icon(Icons.thumb_up),
///       backgroundColor: Colors.pink,
///     ),
///   );
135
/// }
136
/// ```
137 138 139
/// {@end-tool}
```

140
This uses the skeleton for [application](config/skeletons/sample.html)
141
snippets.
142

143 144
The `sample` and `dartpad` tools also allow for quick Flutter app generation
using the following command:
145

146 147 148
```bash
flutter create --sample=[directory.File.sampleNumber] [name_of_project_directory]
```
149

150 151
This command is displayed as part of the sample in the API docs.

152
#### Templates
153

154
To support showing an entire app when you click on the right tab of the
155 156
code sample UI, we have to be able to insert the `sample` or `dartpad` block
into the template and instantiate the right parts.
157 158 159

To do this, there is a [config/templates](config/templates) directory that
contains a list of templates. These templates represent an entire app that the
160 161
`sample` or `dartpad` can be placed into, basically a replacement for
`lib/main.dart` in a flutter app package.
162

163 164 165
For more information about how to create, use, or update templates, see
[config/templates/README.md](config/templates/README.md).

166 167
#### Analysis

168
The `../bots/analyze_sample_code.dart` script finds code inside the `@tool
169 170
sample` sections and uses the Dart analyzer to check them after applying the
specified template.
171

172 173
## Skeletons

174
A skeleton (concerning this tool) is an HTML template into which the Dart
175
code blocks and descriptions are interpolated.
176 177

There is currently one skeleton for
178
[application](config/skeletons/sample.html) samples, one for
179
[dartpad](config/skeletons/dartpad-sample.html), and one for
180
[snippet](config/skeletons/snippet.html) code samples, but there could be more.
181 182

Skeletons use mustache notation (e.g. `{{code}}`) to mark where components will
183 184
be interpolated into the template. It doesn't use the mustache
package since these are simple string substitutions, but it uses the same
185 186
syntax.

187
The code block generation tools that process the source input and emit HTML for
188 189
output, which dartdoc places back into the documentation. Any options given to
the `{@tool ...}` directive are passed on verbatim to the tool.
190 191 192 193 194 195 196 197 198

The `snippets` tool renders these examples through a combination of markdown
and HTML using the `{@inject-html}` dartdoc directive.

## Test Doc Generation Workflow

If you are making changes to an existing code block or are creating a new code
block, follow these steps to generate a local copy of the API docs and verify
that your code blocks are showing up correctly:
199

200 201
1. Make an update to a code block or create a new code block.
2. From the root directory, run `./dev/bots/docs.sh`. This should start
202
   generating a local copy of the API documentation.
203
3. Once complete, check `./dev/docs/doc` to check your API documentation. The
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
   search bar will not work locally, so open `./dev/docs/doc/index.html` to
   navigate through the documentation, or search `./dev/docs/doc/flutter` for
   your page of interest.

Note that generating the sample output will not allow you to run your code in
DartPad, because DartPad pulls the code it runs from the appropriate docs server
(master or stable).

Copy the generated code and paste it into a regular DartPad instance to test if
it runs in DartPad. To get the code that will be produced by your documentation
changes, run sample analysis locally (see the next section) and paste the output
into a DartPad at https://dartpad.dartlang.org.

## Running sample analysis locally

If all you want to do is analyze the sample code you have written locally, then
generating the entire docs output takes a long time.

Instead, you can run the analysis locally with this command from the Flutter root:

```
225
TMPDIR=/tmp bin/cache/dart-sdk/bin/dart dev/bots/analyze_sample_code.dart --temp=samples
226 227
```

228 229 230 231 232 233 234 235 236 237
This will analyze the samples, and leave the generated files in `/tmp/samples`

You can find the sample you are working on in `/tmp/samples`. It is named using the
path to the file it is in, and the line of the file that the `{@tool ...}` directive
is on.

For example, the file `sample.src.widgets.animated_list.52.dart` points to the sample
in `packages/flutter/src/widgets/animated_list.dart` at line 52. You can then take the
contents of that file, and paste it into [Dartpad](https://dartpad.dev) and see if it
works. If the sample relies on new features that have just landed, it may not work
238
until the features make it into the `dev` branch.