Skip to content

Commit c876086

Browse files
committed
comments
1 parent 7ab2bc8 commit c876086

File tree

1 file changed

+94
-29
lines changed

1 file changed

+94
-29
lines changed

doc/dart_documentation_comment_specification.md

Lines changed: 94 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ This document does not cover:
3232
### **1.3. Terminology**
3333

3434
* **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.
3636
* **Identifier:** An individual name in the code (e.g., `MyClass`, `myMethod`, `prefix`).
3737
* **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).
3838
* **Name:** A name is either a single *identifier* or a *qualified name*.
@@ -42,15 +42,56 @@ This document does not cover:
4242

4343
### **2.1. Line-Based Doc Comments (Recommended standard)**
4444

45-
* Starts with `///`.
46-
* 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+
```
4787

4888
### **2.2. Block-Based Doc Comments (Historic, not recommended)**
4989

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.
5495

5596
**Example**
5697

@@ -63,14 +104,23 @@ This document does not cover:
63104

64105
### **2.3. Content Format (Markdown)**
65106

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.
67108

68109
### **2.4. References**
69110

70111
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.
71112

72113
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.
73114

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:
116+
117+
* Inline links: `[A link](https://www.example.com)`
118+
* Image links: `![An image](https://www.example.com/image.png)`
119+
* 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+
74124
## **3\. Placement of Documentation Comments**
75125

76126
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.
107157

108158
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.
109159

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+
110170
## **4\. Referenceable Elements**
111171

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:
113173

114-
### **4.1. Types**
174+
### **4.1. Top-Level Declarations:**
115175

116176
* Classes (e.g., `[MyClass]`)
117177
* Mixins (e.g., `[MyMixin]`)
118178
* Enums (e.g., `[MyEnum]`)
119179
* Named extensions (e.g., `[MyExtension]`)
120180
* Extension types (e.g., `[MyExtensionType]`)
121181
* Type aliases (Typedefs) (e.g., `[MyTypedef]`)
122-
123-
### **4.2. Top-Level Declarations:**
124-
125182
* Functions (e.g., `[myTopLevelFunction]`)
126183
* Variables and constants (e.g., `[myTopLevelVar]`)
184+
* Getters and Setters (See [Section 6.2.2](#6.2.2.-getters-and-setters) for full details)
127185

128-
### **4.3. Members**
186+
### **4.2. Members:**
129187

130-
* Methods (e.g., `[myMethod]`, `[MyClass.myMethod]`)
131-
* Fields (constants and variables) (e.g., `[myField]`, `[MyClass.myField]`)
188+
* Methods (instance and static) (e.g., `[myMethod]`, `[MyClass.myMethod]`)
189+
* Fields (instance and static) (e.g., `[myField]`, `[MyClass.myField]`)
132190
* Getters and Setters (See [Section 6.2.2](#6.2.2.-getters-and-setters) for full details)
133191
* Constructors (e.g., `[MyClass.new]`, `[MyClass.named]`)
134192
* Enum constants (e.g., `[MyEnum.value]`)
135193

136-
### **4.4. Local Scope Parameters (within a member's doc comment):**
194+
### **4.3. Parameters:**
137195

138-
* Parameters of the documented method/function (e.g., `[parameterName]`)
196+
* Formal parameters of the documented method/function (e.g., `[parameterName]`)
139197
* 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]`)
140200

141201
## **5\. Reference Lookup and Resolution**
142202

@@ -148,7 +208,7 @@ When a name is enclosed in square brackets (e.g., `[MyClass.myMethod]`), documen
148208

149209
* **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]`).
150210

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.
152212

153213
### **5.2. Scope Precedence Hierarchy**
154214

@@ -161,7 +221,7 @@ The hierarchy is searched from the inside out. Below is an example for an instan
161221
| +----------------------------------------------------------------------+ |
162222
| | 6. Imported Scopes (all 'import' directives + implicit 'dart:core') | |
163223
| | +------------------------------------------------------------------+ | |
164-
| | | 5. Library Scope (all other declarations in the file) | | |
224+
| | | 5. Library Scope (all declarations incl. prefixes in the file). | | |
165225
| | | +--------------------------------------------------------------+ | | |
166226
| | | | 4. Class Type Parameter Scope (e.g., <T>) | | | |
167227
| | | | +----------------------------------------------------------+ | | | |
@@ -192,7 +252,7 @@ This applies to doc comments on methods, constructors, and operators within a cl
192252
* **Starting Scope**: Formal Parameter Scope
193253

194254
**Example**
195-
```
255+
```dart
196256
/// @docImport 'dart:math';
197257
198258
import 'dart:convert';
@@ -202,8 +262,6 @@ class AnotherClass {}
202262
class MyClass<T> {
203263
T? value;
204264
205-
MyClass.named();
206-
207265
/// A method.
208266
///
209267
/// Lookup examples:
@@ -223,6 +281,14 @@ class MyClass<T> {
223281
// ...
224282
}
225283
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+
226292
static void myStaticMethod() {
227293
// ...
228294
}
@@ -231,7 +297,7 @@ class MyClass<T> {
231297
232298
```
233299

234-
#### **5.3.2. Instance Fields**
300+
#### **5.3.2. Fields**
235301

236302
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.
237303

@@ -249,7 +315,7 @@ For top-level variables, the search has no local context and must begin at the f
249315

250316
* **Starting Scope**: Library Scope
251317

252-
#### **5.3.5. Top-Level Declarations**
318+
#### **5.3.5. Class-like Top-Level Declarations**
253319

254320
For doc comments placed directly on classes, enums, mixins, extensions, extension types.
255321

@@ -295,7 +361,6 @@ class MyClass<T> {
295361
void myMethod() {}
296362
297363
}
298-
299364
```
300365

301366
#### **5.3.6. Typedefs**
@@ -352,7 +417,7 @@ typedef F<T> = void Function(void Function<S>(void Function(T p)) fun);
352417

353418
### **5.4. Resolving Qualified Names**
354419

355-
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.
356421

357422
#### **1\. Resolve the First Identifier**
358423

@@ -371,7 +436,7 @@ If an Identifier resolves to one of the following elements, it establishes a new
371436
*Case 1: Import Prefix*
372437

373438
* **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:math for 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`.
375440
* **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.
376441

377442
*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
470535

471536
Documentation tools should handle this property with the following rules:
472537

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.
474539
* **Precedence:**
475540
* Documentation for the property should only be placed on the getter.
476541
* The tooling should *issue a warning* if both a getter and its corresponding setter have unique doc comments.

0 commit comments

Comments
 (0)