You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: doc/dart_documentation_comment_specification.md
+94-29Lines changed: 94 additions & 29 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -32,7 +32,7 @@ This document does not cover:
32
32
### **1.3. Terminology**
33
33
34
34
***Doc Comment:** A comment intended to be processed by documentation generation tools, like dartdoc.
35
-
***Element**: Dart declarations or directives that can have documentation or be referenced in a doc comment: library directives, top-level, or member declarations such as class, menthod, or variable.
35
+
***Element**: Dart declarations or directives that can have documentation or be referenced in a doc comment: library directives, import prefixes, top-level, or member declarations such as class, menthod, or variable, parameters such as type parameters, method parameters, record fields.
36
36
***Identifier:** An individual name in the code (e.g., `MyClass`, `myMethod`, `prefix`).
37
37
***Qualified Name:** A name composed of two or more *identifiers* separated by dots, used to access an element within a specific namespace (e.g., MyClass.myMethod, prefix.MyClass).
38
38
***Name:** A name is either a single *identifier* or a *qualified name*.
* All consecutive lines starting with `///` are treated as part of the same comment block.
45
+
A line-based doc comment is a comment that starts with `///`. One or more consecutive lines that begin with `///` form a doc comment block.
46
+
47
+
The block continues even if interrupted by single-line non-doc comments (lines starting with `//`) or by blank lines. The interrupting lines are ignored when extracting documentation text.
48
+
49
+
For each line that begins with `///`, the parser removes the three slashes and all leading whitespace to produce the documentation text. Exception: inside fenced code blocks (```), whitespace after the leading `///` is preserved to maintain code formatting.
50
+
51
+
**Example**
52
+
53
+
```dart
54
+
/// This line has leading whitespace after the slashes.
55
+
// This regular comment is ignored.
56
+
///
57
+
/// The line above is a rendered blank line (created by a `///` alone).
58
+
void myFunction() {}
59
+
```
60
+
61
+
The extracted documentation text from the example above would be:
62
+
63
+
```
64
+
This line has leading whitespace after the slashes.
65
+
66
+
This line above is a rendered blank line (created by a `///` alone).
67
+
```
68
+
69
+
**Example (preserving whitespace in fenced code blocks)**
70
+
71
+
```
72
+
/// ```dart
73
+
/// void main() {
74
+
/// print('Hello, World!');
75
+
/// }
76
+
/// ```
77
+
void anotherFunction() {}
78
+
```
79
+
80
+
The extracted documentation text from the example above would be:
81
+
82
+
```
83
+
void main() {
84
+
print('Hello, World!');
85
+
}
86
+
```
47
87
48
88
### **2.2. Block-Based Doc Comments (Historic, not recommended)**
49
89
50
-
* Starts with `/**` and ends with the matching `*/`.
51
-
* Block comments can be nested (e.g., `\*\* \* inner */ */`). Documentation tools must respect this, ensuring that the comment block only ends at the closing \*/ that matches the opening delimiter.
52
-
* The content within the delimiters is treated as the documentation.
53
-
* Leading whitespace followed by a single asterisk and a single following space on subsequent lines are considered stylistic and are stripped by doc generators.
90
+
A block-based doc comment is a comment that starts with `/**` and ends with the matching `*/`.
91
+
92
+
Block comments may contain nested comment sequences (for example: `/** outer /* inner */ outer */`). Documentation tools must respect nesting and ensure that the comment block only ends at the closing `*/` that matches the opening delimiter.
93
+
94
+
The content within the delimiters is treated as the documentation. On each line after the opening `/**`, any leading whitespace followed by a single asterisk (`*`) is considered stylistic and is stripped by doc generators. Any whitespace immediately following the asterisk is also stripped, if present.
54
95
55
96
**Example**
56
97
@@ -63,14 +104,23 @@ This document does not cover:
63
104
64
105
### **2.3. Content Format (Markdown)**
65
106
66
-
The text within a documentation comment block is parsed as CommonMark markdown, allowing for rich text formatting. This includes headings, lists, code blocks, and emphasis, which are converted for instance to HTML in the generated documentation.
107
+
The text within a documentation comment block is parsed as [GitHub Flavored Markdown (GFM)](https://github.github.com/gfm/), an extension of CommonMark, allowing for rich text formatting. This includes headings, lists, code blocks, tables, and emphasis, which are converted for instance to HTML in the generated documentation.
67
108
68
109
### **2.4. References**
69
110
70
111
A reference is a special directive within the Markdown content that creates a hyperlink to a Dart element. It is written by enclosing a name in square brackets (e.g., `[foo]`). See [Section 4](#4.-referenceable-elements) for detailed information about which elements can be referenced.
71
112
72
113
Conceptually, these behave like [reference-style links](https://www.markdownguide.org/basic-syntax/#reference-style-links) in Markdown. The documentation generator resolves the name against the available source code to create the link's destination. See [Section 5](#5.-reference-lookup-and-resolution) for detailed resolution rules.
73
114
115
+
It is important to distinguish references from other link syntaxes in GFM. Documentation comment references use the shorthand reference link syntax (`[name]`) for their own purpose. Other forms of Markdown links are not treated as references and are parsed as standard Markdown. This includes:
* Full reference links: `[A link][id]` (where `id` is a defined link reference `[id]:https://www.example.com "title"`)
120
+
* Footnotes: `[^1]`
121
+
122
+
Only a standalone `[name]` that does not correspond to a defined link reference in the Markdown document is treated as a reference to a Dart element.
123
+
74
124
## **3\. Placement of Documentation Comments**
75
125
76
126
Doc comments are associated with the declaration that immediately follows them. They are only considered valid when placed directly before the following types of declarations:
@@ -107,36 +157,46 @@ Doc comments are associated with the declaration that immediately follows them.
107
157
108
158
While not strictly disallowed by the language, any other placement of a comment with the /// syntax, is not considered a doc comment, and hence should be ignored by documentation tools.
109
159
160
+
**Note on Metadata Annotations:** Doc comments can be placed either before or after metadata annotations (e.g., `@override`, `@deprecated`). If doc comments appear in both locations, the doc comment closest to the declaration (after the annotation) takes precedence. The comment before the annotations is ignored, and documentation tools should issue a warning. For example:
161
+
162
+
```dart
163
+
/// This doc comment is ignored because there is another one after the
164
+
/// annotation.
165
+
@override
166
+
/// This doc comment takes precedence because it is closer to the declaration.
167
+
void foo(int s) {}
168
+
```
169
+
110
170
## **4\. Referenceable Elements**
111
171
112
-
A reference in a doc comment (e.g., `[name]`) can link to any Dart element that is visible from the Dart scope of the documented element. See [Section 5](#5.-reference-lookup-and-resolution) for more details about scoping. This includes:
172
+
A reference in a doc comment (e.g., `[name]`) can link to any Dart element that is visible from the Dart scope of the documented element. See [Section 5](#5.-reference-lookup-and-resolution) for more details about scoping. This includes:
113
173
114
-
### **4.1. Types**
174
+
### **4.1. Top-Level Declarations:**
115
175
116
176
* Classes (e.g., `[MyClass]`)
117
177
* Mixins (e.g., `[MyMixin]`)
118
178
* Enums (e.g., `[MyEnum]`)
119
179
* Named extensions (e.g., `[MyExtension]`)
120
180
* Extension types (e.g., `[MyExtensionType]`)
121
181
* Type aliases (Typedefs) (e.g., `[MyTypedef]`)
122
-
123
-
### **4.2. Top-Level Declarations:**
124
-
125
182
* Functions (e.g., `[myTopLevelFunction]`)
126
183
* Variables and constants (e.g., `[myTopLevelVar]`)
184
+
* Getters and Setters (See [Section 6.2.2](#6.2.2.-getters-and-setters) for full details)
### **4.4. Local Scope Parameters (within a member's doc comment):**
194
+
### **4.3. Parameters:**
137
195
138
-
*Parameters of the documented method/function (e.g., `[parameterName]`)
196
+
*Formal parameters of the documented method/function (e.g., `[parameterName]`)
139
197
* Type parameters of the documented element and the enclosing element (e.g., `[T]`)
198
+
* Fields of record typedefs (e.g., `[field]`)
199
+
* Parameters in function type typedefs (e.g., `[param]`)
140
200
141
201
## **5\. Reference Lookup and Resolution**
142
202
@@ -148,7 +208,7 @@ When a name is enclosed in square brackets (e.g., `[MyClass.myMethod]`), documen
148
208
149
209
***Disambiguation via Qualification:** To prevent ambiguity or to reference an element from a distant scope, a reference should be qualified. This is done by prefixing the name with a class name (e.g., `[ClassName.memberName]`) or an import prefix (e.g., `[prefix.elementName]`).
150
210
151
-
***Handling Ambiguity:** If a reference could resolve to multiple declarations within the same scope, or if no resolution is found after checking all scopes, documentation tools should issue a warning.
211
+
***Handling Ambiguity:** If a reference could resolve to multiple declarations within the same scope, it should not resolve to any element. If no resolution is found after checking all scopes, documentation tools should issue a warning.
152
212
153
213
### **5.2. Scope Precedence Hierarchy**
154
214
@@ -161,7 +221,7 @@ The hierarchy is searched from the inside out. Below is an example for an instan
@@ -192,7 +252,7 @@ This applies to doc comments on methods, constructors, and operators within a cl
192
252
***Starting Scope**: Formal Parameter Scope
193
253
194
254
**Example**
195
-
```
255
+
```dart
196
256
/// @docImport 'dart:math';
197
257
198
258
import 'dart:convert';
@@ -202,8 +262,6 @@ class AnotherClass {}
202
262
class MyClass<T> {
203
263
T? value;
204
264
205
-
MyClass.named();
206
-
207
265
/// A method.
208
266
///
209
267
/// Lookup examples:
@@ -223,6 +281,14 @@ class MyClass<T> {
223
281
// ...
224
282
}
225
283
284
+
/// A non-redirecting generative constructor.
285
+
///
286
+
/// Lookup examples:
287
+
/// * [value]: Resolves to the parameter (Formal Parameter Scope).
288
+
/// * [param]: Resolves to the parameter (Formal Parameter Scope).
289
+
/// * [named]: Resolves to this constructor itself (Class Member Scope).
290
+
MyClass.named(this.value, int param);
291
+
226
292
static void myStaticMethod() {
227
293
// ...
228
294
}
@@ -231,7 +297,7 @@ class MyClass<T> {
231
297
232
298
```
233
299
234
-
#### **5.3.2. Instance Fields**
300
+
#### **5.3.2. Fields**
235
301
236
302
This applies to doc comments on fields within a class, enum, or mixin. Since fields have no parameters, the search starts at the member level, but otherwise follows the same route as instance methods.
237
303
@@ -249,7 +315,7 @@ For top-level variables, the search has no local context and must begin at the f
249
315
250
316
***Starting Scope**: Library Scope
251
317
252
-
#### **5.3.5. Top-Level Declarations**
318
+
#### **5.3.5. Class-like Top-Level Declarations**
253
319
254
320
For doc comments placed directly on classes, enums, mixins, extensions, extension types.
When a reference contains a qualified name (e.g., `[prefix.ClassName.member]`), the resolution process is an iterative, left-to-right evaluation of each Identifier.
420
+
When a reference contains a qualified name (e.g., `[prefix.ClassName.member]`), the resolution process is an iterative, left-to-right evaluation of each identifier.
356
421
357
422
#### **1\. Resolve the First Identifier**
358
423
@@ -371,7 +436,7 @@ If an Identifier resolves to one of the following elements, it establishes a new
371
436
*Case 1: Import Prefix*
372
437
373
438
***Namespace:** The export scope of the imported library, as filtered by any show or hide combinators on the import directive.
374
-
***Example:** In `[math.pi]`, the identifier `math` resolves to an import prefix (e.g., from `import 'dart:math' as math;`). The tool then searches the public namespace of dart:mathfor the identifier pi.
439
+
***Example:** In `[math.pi]`, the identifier `math` resolves to an import prefix (e.g., from `import 'dart:math' as math;`). The tool then searches the prefixed import namespace for the identifier `pi`.
375
440
***Combinator Example:** If the import was `import 'dart:math' as math show sin;`, the namespace for `math` would *only* contain `sin`. A reference to `[math.pi]` would fail to resolve, as `pi` was not included in the show list.
376
441
377
442
*Case 2: Class-like top-level declaration*
@@ -470,7 +535,7 @@ A getter and a setter that share the same name are treated as a single *conceptu
470
535
471
536
Documentation tools should handle this property with the following rules:
472
537
473
-
***Display:** The getter and setter should be presented as a single item in the final documentation.
538
+
***Display:** The getter and setter should be presented as a single item in the API reference.
474
539
***Precedence:**
475
540
* Documentation for the property should only be placed on the getter.
476
541
* The tooling should *issue a warning* if both a getter and its corresponding setter have unique doc comments.
0 commit comments